trf2.1.4/0000755000175000017500000000000011216344734011557 5ustar sergeisergeitrf2.1.4/ChangeLog0000644000175000017500000030037511216343142013331 0ustar sergeisergei2009-05-06 Andreas Kupries * generic/digest.c (DeleteEncoder, DeleteDecoder): Fixed the * generic/registry.c (TrfClose): memory leaks reported by [Bug 2788106]. * configure.in: Version bumped to 2.1.4. * configure: Regenerated. * generic/asc85code.c: Replaced all uses of Tcl_Alloc/Free/Realloc * generic/b64code.c: with ckalloc, ckfree, and ckrealloc. The Tcl_ * generic/bincode.c: functions are apparently not respecting a * generic/binio.c: TCL_MEM_DEBUG setting. * generic/bz2.c: * generic/bz2_opt.c: * generic/convert.c: * generic/dig_opt.c: * generic/digest.c: * generic/hexcode.c: * generic/octcode.c: * generic/otpcode.c: * generic/qpcode.c: * generic/ref_opt.c: * generic/reflect.c: * generic/registry.c: * generic/rs_ecc.c: * generic/uucode.c: * generic/zip.c: * generic/zip_opt.c: * generic/templates/cvt_template.c: 2008-12-11 Andreas Kupries * Makefile.in: Applied Daniel Steffen's OSX patch, plus an * configure: ActiveState fix for building on HPUX-IA64. The * configure.in: patch updates handling of bz2 compression, md5, * test.setup.in: updates to TEA 3.7, adds some darwin specific * trf.m4: ifdef's in the digests to properly handle 64bit. * compat/tclLoadShl.c: * generic/bz2lib.c: * generic/loadman.c: * generic/loadman.h: * generic/md5dig.c: * generic/transformInt.h: * generic/haval.1996/haval.h: * generic/ripemd/rmd128.h: * generic/ripemd/rmd160.h: * generic/rs-ecc/Makefile.in: * generic/sha/sha.h: * tclconfig/tcl.m4: 2008-12-05 Andreas Kupries * Updated everything to 2.1.3 for release. 2007-11-13 Andreas Kupries * teapot.txt: New file, basic meta data of the package for TEApot compatible repositories. 2007-10-12 Andreas Kupries * generic/zip.c: Fixed problem in the zip (de)compressor. Had a * configure.in: possible case where it thought output space was * configure: exhausted and requiring more operations, with no input to process. Now aborting the loop if there is no input. Version bumped to 2.1.2. 2007-10-04 Andreas Kupries * configure.in: Version bumped to 2.1.1. Source directory belongs into the list of include paths. Accept MINGW32_NT as indication of a Win32 system. * configure: Regenerated. * tclconfig/tcl.m4: Added definition which allows us to recognize building for OS X. * compat/tclLoadWin.c: Added cast to silence compiler warning. * generic/init.c: Ditto. * generic/loadman.c: Recognize building on OS X and choose appropriate library names. * generic/loadman.h: Use __P (of trf_features.h) over _ANSI_ARGS_ to silence warnings. * generic/registry.c: Changed name of macro DELAY to avoid clash with system macro, and constification. * generic/sha.c: Reordered things a bit for proper set up of endianess definitions. * generic/transformInt.h: Added more checks for proper set up of endianess on OS X for universal builds. * generic/trfStubLib.c: Constification and cast to silence warnings. * generic/util.c: Changed name of macro MASK to avoid clash with system macro. * generic/haval/haval.c: Added inclusion of transformInt.h to get * generic/haval/havalapp.h: proper set up of endianess. * generic/haval.1996/havalapp.h: * md5-crypt/md5.c: Ditto. 2006-01-24 Andreas Kupries * tclconfig/tcl.m4: Updated to TEA 3.5 * configure.in: Ditto. * configure: Regenerated. 2005-10-06 Andreas Kupries * generic/rmd128.c (MDrmd128_UpdateBuf): Fixed length-dependent * generic/rmd160.c (MDrmd160_UpdateBuf): miscalculation of the hash value. A bad condition for the loop processing the chunks in the incoming buffer caused it to ignore the last one if we got full multiples of 64 bytes. Fixes [SF Trf Bug 1119773]. 2004-02-18 Andreas Kupries * tests/base64.test: Extended the tests to use not only memchan, but also files as data source. For comparison. 2003-04-04 Andreas Kupries * configure.in: * tclconfig/tcl.m4: Updated to newest tcl.m4, regenerated configure's. 2003-03-27 Andreas Kupries * tea.tests/base64_bb.test: * tests/base64.test: * generic/b64code.c (Decode): Added code to ignore any illegal character found in the input. This makes the [base64] command conform to RFC 2045. Changed the test-case base64-2.0 to reflect this. This fixes bug #696325 reported by Keith Vetter . * md5-crypt/md5.c (md5_process_bytes): Accepted patch #667168 by Olly Stephens . Without the the patch new md5 test-case (see yesterday) causes a crash on the solaris machine, and with it the new test passes cleanly (also generates the expected result). 2003-03-26 Andreas Kupries * tools/svfiles: Added 'doc/common/trf_version.inc' to list of files which have to be patched when updating the version of the package. * doc/common/trf_version.inc: Set true version, 2.1.3. * tea.tests/md5_crash.test: * tests/md5_crash.test: Added tests to check against/for bug #667168. Preparation of tests on machine reproducing the bug and that the patch actually fixes the problem. ... Note: The test suite should be converted to use the tcltest package instead of its own set of commands, which are near to tcltest, but not quite the same, as they are older. * tests/defs: Made it a bit nearer to the same command in tcltest (returning the path of the file). 2003-03-12 Andreas Kupries * doc/adler.man: Added doctools based documentation to Trf. * doc/ascii85.man: * doc/base64.man: * doc/bin.man: * doc/bz2.man: * doc/common/options.inc: * doc/common/sections.inc: * doc/common/trf_header.inc: * doc/common/trf_version.inc: * doc/compress/footer.inc: * doc/compress/header.inc: * doc/compress/middle.inc: * doc/compress/options.inc: * doc/crc-zlib.man: * doc/crc.man: * doc/crypt.man: * doc/digest/footer.inc: * doc/digest/header.inc: * doc/digest/main.inc: * doc/digest/options.inc: * doc/digest/ripemd.inc: * doc/encoding/footer.inc: * doc/encoding/header.inc: * doc/encoding/middle.inc: * doc/encoding/options.inc: * doc/haval.man: * doc/hex.man: * doc/md2.man: * doc/md5.man: * doc/md5_otp.man: * doc/md5crypt.man: * doc/oct.man: * doc/otp_words.man: * doc/quoted-printable.man: * doc/ripemd128.man: * doc/ripemd160.man: * doc/rs_ecc.man: * doc/sha.man: * doc/sha1.man: * doc/sha1_otp.man: * doc/transform.man: * doc/trf.man: * doc/unstack.man: * doc/uuencode.man: * doc/zip.man: 2003-01-20 Andreas Kupries * tools/rules/manpage.html.site: Redone in the likeness of memchan. * tools/mpexpand: Now ready for documentation of trf * tools/manpage_regen: in doctools format. * tools/nroff_regen: * tools/watch_cvs: 2003-01-09 Andreas Kupries * ./tclconfig/tcl.m4: Added code to look for and load * ./Makefile.in: the package zlibtcl if possible. * ./configure.in: This makes loading zip functionality * ./generic/adler.c: considerably easier (if present). * ./generic/zlib.c: We will fall back to libz.so if * ./generic/transformInt.h: zlibtcl was not present at runtime. * ./generic/crc_zlib.c: Some declarations were changed to * ./generic/zip.c: avoid a clashing of names (and * ./generic/bz2.c: subsequent compiler errors due to * ./configure: expansion of macros in the wrong place. 2002-11-22 Andreas Kupries * Makefile.in: Deactivated target for MD5 library. HPUX balked with a syntax error because the variable to the left of the colon is now empty. 2002-11-04 Andreas Kupries * The changes below fix the following bug reports: ActiveState Bugzilla 21643. ActiveState Bugzilla 21628. SourceForge 619404. * md5-crypt/md5.c: (HAVE_MEMCPY): Enforce usage on Windows. * md5-crypt/md5.c: * compat/stpncpy.c: Added tcl header on Win32 to get definitions like size_t. * md5-crypt/md5-crypt.c: Excluded header not known on Win32. * generic/loadman.c: * generic/md5dig.c: * generic/otpmd5.c: * configure.in: Changed code to compile md5 functionality directly into the trf library if 'md5crypt' is not accessible via '-lcrypt'. This eliminates any trouble with a missing md5crypt library and is easier to do than creating and installing a second (helper) library. * configure: Regenerated. 2002-10-15 Andreas Kupries * Makefile.in (Trf_INCLUDES): Continuation to empty line followed by comment tripped the HP make. It extended the continuation over the emppty line to include the comment, thus disabling the code generation. Fixed by removing the continuation. * configure.in: Changed to propagate an initial CFLAGS value to the final definition. A TEA condition (SHARED_BUILD == 1) squashed it, causing it the build system to loose the +DAportable we specify for the AS PA-RISC2.2 build host. This is a problem for _all_ TEA and TEA 2 based configure files. 2002-10-02 Andreas Kupries * configure.in (crypt): Check for crypt forced to false on Windows. 2002-10-01 Andreas Kupries * configure.in: Readded check for 'eprintf'. * compat/tclLoadShl.c (dlopen): mode is 'unsigned int'. * trf.m4: Moved the calls to CYGPATH behind the corresponding 'test -z' conditions as the result of that call generates a non-empty string from an empty string on some platforms. Missing paths are set to '.' so that they do not disturb the interpretation of -I / -L options by the compiler. * configure.in: Readded check for endianess. Moved ltoa, etc. block just after tea_setup_compiler. Determination of flags for shared build messes up these tests. 2002-09-27 Andreas Kupries * compat/tclLoadWin.c: Removed inclusion of windows header to prevent clashes between winsock and winsock2/ * configure.in: * Makefile.in: * aclocal.m4: * trf.m4: * tclconfig: Rewritten build system, now based on TEA 2. 2002-09-14 Andreas Kupries * tools/htdocs_setup: * ./tools/rules/site: * ./tools/rules/trf: * ./tools/htdocs_refresh: Made code more robust for case of non yet existing manpages. Also added markers to distinguish output from memchan. 2002-08-26 Andreas Kupries * generic/registry.c (ChannelHandlerTimer): Fix of bug found by Michael A. Cleverly . * Big cleanup and restructuring in prepration of moving this CVS to SourceForge. 2001-08-18 Andreas Kupries * generic/transformInt.h: Added definitions for "Tcl_GetTopChannel" for use by cores older than 8.3.2. See bug below. * generic/registry.c (AttachTransform, Lines 2665f): Forgot to compensate for stacking when remembering the parent channel for a 8.3.2+ core. Tcl_StackChannel does, but the Tcl_*Raw don't. Thanks to Adrian Koren for reporting the problem and providing a script exercising the bug. * generic/digest.c (WriteDigest): See Tue Jun 20 20:49:05 2000 (reflect.c) for a similar fix. This one is thanks to Adrian Koren . 2001-03-27 Andreas Kupries * PREPARE: Moves contents of subdirectory 'tea' into main directory, they are the main build chain now. * tea/mkIndex.tcl.in: Updated to current state from sample extension. Also added fix for changed Cygwin environment. * tea/configure.in: * tea/Makefile.in: Prepared for execution in toplevel directory. Also updated for usage of new mkIndex.tcl. * BUILDINFO: * DEPENDENCIES: New file, integration into the TclPro build system. * generic/loadman.h: * generic/reflect.h: * generic/transform.h: * generic/transformInt.h: Changed BUILD_trf to BUILD_Trf Sun Nov 26 16:53:24 2000 Andreas Kupries * --- Release of 2.1p1 --- * Removed binary distributions from CVS. Sat Nov 18 17:55:01 2000 Andreas Kupries * tea.tests/common_all.test: * tea.tests/common_conv.test: * tea.tests/common_md.test: Adapted tests to the patch below. * tests/common.all.test: * tests/common.conv.test: * tests/common.md.test: Adapted tests to the patch below. * generic/ref_opt.c: * ./generic/ref_opt.c: * ./generic/zip_opt.c: * ./generic/dig_opt.c: * ./generic/convert.c: * ./generic/registry.c: * ./generic/bz2_opt.c: Patch by Dave Bodenstab for better error messages. * generic/crypt.c (TrfCryptObjCmd): Added #ifdef to deactivate crypt when compiled on or for Windows. Sat Nov 11 13:14:05 2000 Andreas Kupries * generic/zip.c: Added 'MaxRead' vector to restrict the number of read characters to at most one (decompressor only). This will cause most probably a loss of performance, but also makes the transformation robust against garbage following after the compressed stream. Without this change the transformation ran into an error (Z_BUF_ERROR = no progress) or an infinite loop after reaching Z_STREAM_END. Future: Extend the Tcl API to allow transformations to push back any unconsumed bytes. This will allow us to read large chunks again (= higher performance), while also getting the problem solved. Will have to write a TIP for this. Wed Oct 4 20:44:40 2000 Andreas Kupries * tools/fixhbline: * tools/findinpath: Fixed problem with tool combo when an interp-app (wish and/or tclsh) is not found by 'findinpath'. We must not stop the installation, only 'fixhbline' is able to decide which of the two interp-apps will be required. Wed Aug 9 20:52:41 2000 Andreas Kupries * -- Released 2.1 -- * Consolidation complete to the point that Trf passes its testsuite for the following combinations of core compiled against and core run against: X = Version of core the extension was running against. Y = Version of core the extension was compiled against. +-+----+ (a) 8.0.5 |a|* | '-' = not passed. (b) 8.1.1 |b| ***| '*' = passed. (c) 8.2.3 |c| ***| ' ' = untested combination. (d) 8.3.2 |d| ***| +-+----+ Y |abcd| +X-----+ Tue Aug 8 00:19:26 2000 Andreas Kupries * generic/registry.c: Consolidation complete to the point that Trf compiles against 8.0.5, 8.1.1, 8.2.3 and 8.3.2 without warnings (-Wall active). Tue Aug 1 20:08:08 2000 Andreas Kupries * generic/registry.c: Consolidation. Started to merge patch for 8.3.2 and higher into the codebase, should work from 8.0.x to 8.3.2+. Sat Jul 29 00:53:24 2000 Andreas Kupries * generic/adler.c: * generic/crc.c: * generic/crc_zlib.c: * generic/haval.c: * generic/md2.c: * generic/md5dig.c: * generic/rmd128.c: * generic/rmd160.c: * generic/sha.c: * generic/sha1.c: Cosmetic changes, renamed all functions with prefix MD_ to MD_. No benefit of these unique names from a compilation POV as they are all static anyway, but it makes the work of a tool like SourceNavigator simpler (and its views less ambiguous). * generic/md5dig.c: * generic/crypt.c: Removed unneeded header references. Tue Jun 20 20:49:05 2000 Andreas Kupries * md5-crypt/trf_crypt.h: Changed __const to CONST. Thanks to Robert Karen . * generic/reflect.c (RefExecuteCallback): Line 715f (transmit_down). spotted that I didn't make use of Tcl_ByteArrays in case of 8.1 or higher. Sun May 28 19:25:52 2000 Andreas Kupries * win/makefile.vc5 (TRF_DEFINES): Added missing -DTRF_VERSION. * generic/otpcode.c (insert): Added casts to prevent some warnings about unsigned long to unsigned char assignement. The operations causing them are ok. Sat Apr 29 00:14:23 2000 Andreas Kupries * -- Release 2.0p7 -- * generic/qpcode.c * generic/registry.c: Applied patch from Darren New fixing a buffer overun in quoted_printable. Fixed nagging from purify too. Tue Apr 18 19:01:27 2000 Andreas Kupries * tea/tcl.m4: * tea/configure.in: Accepted patch from Jan Nijtmans to enable usage of tea build with mingw32 environment on Win. Wed Mar 22 19:48:30 2000 Andreas Kupries * generic/init.c (Trf_Init, line 90): Removed '&& defined(USE_TRF_STUBS)', see Feb 25, as it messes up package initialization for normal compilation (Trfcrypt thinks 'This implementation of trf does not support stubs', uh). Tue Mar 21 21:22:06 2000 Andreas Kupries * unix/Makefile.in (genstubs): Fixed usage of wrong variable (tools -> tool), with thanks to Oisin Grehan . Wed Mar 15 22:57:48 2000 Andreas Kupries * generic/reflect.c (Clear(En/De)coder): Darren New pointed out that ClearEncoder and -Decoder use strings which do not match the docs (clear_read instead of clear/write). Fixed that. Sat Mar 11 13:24:33 2000 Andreas Kupries * doc/nodes/md.node: Added reference to 'TclAH', another extension providing message digests (a.k.a. authentication hashes). Author is Greg Retkowski . Fri Feb 25 17:27:47 2000 Andreas Kupries * -- Release 2.0p6 -- * generic/registry.c (TransformImmediate): Thomas Schwarze catched a little nasty memory leak. The block from lines 2512-2526 had a call to 'ResultClear' in one branch, but not the other, leaking memory the size of the result for each successful! call to a trf command. Ouch. Fixed. * generic/init.c (Trf_Init): Little bugfix for compilation of Trf as static library (line 90, +'&& defined(USE_TRF_STUBS)'). * generic/loadman.c, md5dig.c: See below. Base changes came from Jean-Claude Wippler . * tea/trf.m4: * unix/configure.in: Added changes to allow static compilation of MD5 too. Mon Jan 24 12:46:11 2000 Andreas Kupries * -- Release 2.0p5 -- * Integrated a fix into the TEA configure(.in) solving a problem reported by Patrick D'Cruze . It was the equivalent problem as described on 'Wed Dec 15', but for TEA this time. Sat Jan 15 00:30:22 2000 Andreas Kupries * generic/crypt.c (Trf[Md5]CryptObjCmd): Fixed argument checks. Reported by Patrick D'Cruze . * tea/Makefile.in (install-lib-binaries): Fixed error in this target. Mailed problem and fix to TEA mailing list. * Released 2.0p4 without announcement so that JCW can use it for his static builds of TclKit. Wed Dec 15 19:27:01 1999 Andreas Kupries * -- Release 2.0p3 -- * unix/configure.in: Changed to use SHARED_LIBS instead of LIBS to add -lcrypt to the link options of libtrf.so This finally solved the RH problem. My thanks to Mick Lester who provided the configure and Make logs which allowed me to track this in detail. Mon Dec 13 20:08:07 1999 Andreas Kupries * -- Release 2.0p2 -- Fri Dec 10 18:32:48 1999 Andreas Kupries * tea/configure.in: * unix/configure.in: Fixed problem with definition of CRYPT_LIB_NAME, reported by Tyler Riddle . * Backed out all of the changes below, they cause miscompilation here. Now the radical approach: Go and remove all gcc/libc dependencies from the code. * md5-crypt/crypt.h: Now switchable between inclusion of features.h and trf_features.h. Switch based on information coming from the configure. See below. * md5-crypt/trf_features.h: The hacked 'features.h' under a new name, to avoid name clashes with an existing features.h (glibc-based Linux). * tea/configure.in: * unix/configure.in: Added check for features.h. New code to add -lcrypt to LIBS if we have to compile md5 crypt with crypt present. Required to get both the real 'crypt' and the 'md5 crypt'. Wed Dec 1 21:07:57 1999 Andreas Kupries * tea/configure.in (MD5_LIB_FILE): * unix/configure.in (MD5_LIB_FILE): Added check to differentiate between the mere existence of libcrypt and a libcrypt having md5 functionality. Solaris f.e. has a libcrypt without md5 and we have to make sure that our version does not clash with it. Mon Nov 29 22:12:34 1999 Andreas Kupries * generic/digest.c (WriteDigest): Mikhail Teterin noticed that I had bungled access to array elements. Added TCL_PARSE_PART1 to the flags of Tcl_ObjSetVar2 to rectify this. Thu Nov 25 22:14:28 1999 Andreas Kupries * generic/registry.c (TrfClose): Added patch suggested by Mikhail Teterin to avoid a crash of the interpreter upon exit. Restricted to usage without stubs / 8.0 series. Some platforms seem to call TrfClose with bogus instanceData and interpreter references (NULL) during exit with transformation channels left open. * unix/Makefile.in (install-lib): Added '-' to avoid stop on error if compiled against 8.0, i.e. without stubs. Fri Nov 12 18:02:17 1999 Andreas Kupries * tea/configure.in: Added forgotten check for endianess to the TEA configure. Tue Nov 9 22:19:55 1999 Andreas Kupries * PREPARE: Added generation of 'news' page from ChangeLog.short. * doc/nodes/home.node: Added reference to 'news' page. * md5-crypt/crypt.h: Moved structure out of the conditional (__USE_GNU). Mon Nov 8 20:43:24 1999 Andreas Kupries * ------ 2.0 re-release ------ * win/makefile.vc: Jan Nijtmans expanded the original makefile.vc and makefile.vc to allow the usage of MS VC++ 2.0 up to 6.0. Got a new binary distribution of 2.0 as well, usable for tcl 8.0. and 8.1.x. Wed Oct 27 21:05:07 1999 Andreas Kupries * tests/common_seek.test/transform.test: Slight differences for 8.0. * generic/registry.c: Some parts of the new code contained 8.1 specific code. Added code for 8.0 too. GT81 used to differentiate. Mon Oct 25 22:10:01 1999 Andreas Kupries * ------ 2.0 released ------ * Got new bindist too, and a self extracting executable/installer. The latter is now a new bindist. * Applied patch from Jan to make zip compatible to the official distribution fo zlib. This additionally fixes the problem with the -nowrap option where I had to resort to some hackery to stop a Z_BUF_ERROR from bothering me. The new code is the official sanctioned way of making it work (Additional dummy input byte). Sat Oct 23 00:54:38 1999 Andreas Kupries * tea.tests/transform_bb.test: Adapted traces to changed behaviour (query/maxRead, query/ratio). * generic/reflect.c (ExecuteCallback): Setting command to NULL now after DecrRefCount after the eval. Not doing and then going through the cleanup causes a second free for the object, trashing the free obj management. gIOt has the same problem. Corrected there too now. Fri Oct 22 23:20:34 1999 Andreas Kupries * generic/*.c: Added NULL initializer for MaxRead to all Trf_Typedefinitions flying around. * generic/reflect.c: Changed many things to allow the querying of 'maxRead' and the natural seek ratio. * generic/ref_opt.c (SeekQueryOptions): New procedure, queries the tcl-level transform about its natural seek ratio. * generic/reflect.h: New file, contains definitions shared between reflect.c and ref_opt.c (The latter needs access to 'ExecuteCallback' to query a transform about its natural seek ratio. * generic/transform.h: Added 'interp' argument to 'Trf_SeekQueryOptions'. (Trf_QueryMaxRead): Added this vector to 'Trf_Vectors'. Nullable. Thu Oct 21 00:25:23 1999 Andreas Kupries * doc/nodes/zip.node: Added documentation -nowrap. * generic/zip.c: Traced the problem uncovered by the new tests and added a workaround to 'FlushDecoder'. Search for 'hackish flavor'. * doc/nodes/home.node: Added Tcl MIME to the list of extensions using Trf or its core feature. * doc/nodes/urls.def: Added entry for Tcl MIME. * doc/nodes/people.def: Added entries for Matt Newman and Marshall Rose. * Made minor modifications to the patch (formatting, removed 7.6 support, added analogous tests to the TEA part of the distrib.). * tea.tests/zip.test: * tests/zip.test: * generic/zip.c: * generic/zip_opt.c: * generic/zlib.c: * generic/transformInt.h: Finally applied the nowrap patch sent in by Jan Nijtmans quite some time ago (June 26, 1999). Tue Oct 19 21:41:26 1999 Andreas Kupries * generic/init.c: Added registration of the two new commands. * Adapted makefiles to compile the new file. * generic/crypt.c: New file, implements 'crypt' and 'md5crypt'. Sat Oct 16 00:55:39 1999 Andreas Kupries * Worked on the MD5 binding in the last days, using md5-crypt now, coming from glibc (is under LGPL). MD5 shared liib now loaded on demand. Changed all makefiles and configures to check for a libcrypt containing MD5. If none, the code we carry around (see md5-crypt) is compiled. Mon Oct 11 18:48:49 1999 Andreas Kupries * tea.tests/common_seek.test: Did the same for the tea test suite. * tests/common_seek.test: Applied patch by Jan Nijtmans. file6 is different on Windows, using some sort of hexcode. He inserted regsubs to normalize this part of the error messages. * generic/bincode.c (DecodeBuffer): * generic/octcode.c (DecodeBuffer): New, analogous to hexcode.c * generic/hexcode.c (DecodeBuffer): New, decode whole buffers instead of single characters. Actually did that yesterday. * tests/common.all.test: See below. * tea.tests/common_all.test: Added test for -in, -out. Sun Oct 10 21:14:39 1999 Andreas Kupries * generic/registry.c (PutDestinationImm): New, variant of 'PutDestination', specialized for writing into a channel during an immediate transform. Now necessary, after changing the call to 'PutDestination' in 'AttachTransform' (clientData). Sat Oct 9 13:20:58 1999 Andreas Kupries * Added more tests yesterday. Decided to pack the current state into a pre-release. Thu Oct 7 22:56:36 1999 Andreas Kupries * generic/registry.c (TrfGetOption): Fixed some minor problems in this procedure revealed by the first bunch of tests. (SeekCalculatePolicies): Fixed incorrect condition in this code leading sometimes to improper initialization of the chosen transform. Detected by test suite (1.0 / 1.5). (TrfExecuteObjCmd): Added processing of '-seekpolicy'. (AttachTransform): Added application of initial '-seekpolicy'. * generic/registry.c (TrfSeek): Changed code to check new location for 'modulo numBytesTransform == 0' instead of the offset. Wed Oct 6 23:22:19 1999 Andreas Kupries * Next steps no 1 (see below) now done. * generic/registry.c (TrfSetOption): Implemented -seekpolicy. (TrfGetOption): Added -seekpolicy to set of readable options. * doc/nodes/seek.node: Worked on the documentation of the new behaviour. Actually started on that yesterday. Sun Oct 3 01:39:02 1999 Andreas Kupries * generic/bincode.c, * generic/octcode.c: * generic/hexcode.c (EncodeBuffer): New procedure to encode whole blocks. Written out of a desire to shorten the log produced by the debug facility (-DTRF_DEBUG) while playing with seek. * generic/registry.c (TrfGetOption): Added proceudre to allow retrieval of new options (-seekstate, -seekcfg). Deactivated 'trfinfo' for now. * generic/convert.c (SeekQueryOptions): First procedure to change the natural seek policy based upon options. Used by all conversions, swaps the in/out-ratio for -mode decode. Everything else does not use this interface. * Added interface to the option vectors to allow them to change the natural seek policy. * ------------------------------------------------------------ * Next steps: 1) Add options to set/change/query seek related configuration information (subset of trfinfo). 2) Think up test cases for the various possibilities. * Such an interface to allow runtime configuration of natural ratio is required by the encryptions in TrfCrypt too. Their seek behaviour is dependent on their actual options. * The generic 'transform' stays unseekable for now, until its interface is extended to allow the tcl level to specify the ratio. * Ascii85 is conversion, mainly 4->5, but contains irregularities making it nonlinear. So it stays unseekable. Digests and both compressors stays unseekable. Same for quoted-printable and otp coder. * Modified conversions (hex, oct, bin, uu, base64) to allow seeking. Error correcting codec too (ratio 248 -> 255!). * Tests ok, no errors. Debug output (seek dumps) look ok too, so far (all transforms defined as unseekable). * generic/registry.c: Seek state and configuration placed into separate structures. Result buffer now has a reference to the seek state, possibly NULL. Buffer positions are now updated by the Result... procedures, if possible (state reference != NULL). Some other code simplified. Sat Oct 2 01:10:21 1999 Andreas Kupries * generic/registry.c (TrfInput): Added new seek handling code. (SeekDump): New procedure for debugging the seek handling. * generic/init.c (Trf_Init): Added initialization of 'trfinfo'. * generic/registry.c (TrfInfoObjCmd): New command, 'trfinfo', to query a transformation about its internals. F.e. the current configuration and state of the seek handling (-> tests). * generic/unstack.c (TrfUnstackCmd): Objectified 'unstack'. * generic/registry.c (TrfSeek): Completely rewritten for new way of doing this. Handling of SEEK_END not yet. (SeekClearBuffer): New procedure encapsulating some common code. (TrfOutput): Added code to handle the new seek state. (SeekSynchronize): New procedure, used in code above. * generic/registry.c (SeekInitialize, SeekCalculatePolicies): New procedures to compute runtime configuration and initial state. (AttachTransform): Initialization of seek added. Fri Oct 1 22:12:24 1999 Andreas Kupries * generic/registry.c: Added runtime configuration and state to the state structure of a transformation channel. * generic/transform.h: Changed the seek specification from a vector to two integer numbers specifying the ratio of input to output. Seekable is thus restricted to linear relations between pre- and post-transformation data. Haven't ever seen higher polynomials or other functions. Changed all places already using the vector (initializations). Thu Sep 30 22:10:39 1999 Andreas Kupries * generic/registry.c: Copied the procedures operating on the result buffer from giot. They made the procedures having to deal with it before much simpler. And easier to read. Especially 'TrfInput'. Tue Sep 28 22:39:48 1999 Andreas Kupries * generic/registry.c: Added information about chosen/used seek policy, seek transformations, etc. to transformation instances (TrfTransformationInstance). * Added initialization of new item in typedefinition to all relevant transformations (or transformation frameworks (= message digest handling)). See zip.c, uucode.c, rs_ecc.c, reflect.c, qpcode.c, otpcode.c, octcode.c, hexcode.c, digest.c, bz2.c, bincode.c, b64code.c, asc85code.c Initialized with NULL == 'unseekable', for now. Mon Sep 27 21:15:50 1999 Andreas Kupries * generic/transform.h: Added 'Trf_SeekTransformation' interface. Added vector to 'Trf_TypeDefinition' using it. * unix/Makefile.in * unix/configure.in: The introduction of an exported stub table broke the 'unix' build for 8.0.x. Added more configure variables etc. to switch of compilation of trfStub*.o and linkage of libtrfstub.a Reported by Stefan Studer while trying the unofficial distribution. Sat Sep 25 20:24:12 1999 Andreas Kupries * doc/nodes/: Upgraded the documentation a bit. * Well, not so ready anymore. Got some bug reports and patches from Matt Newman. Bugfixes added in so far, application to 1.8 will be done too. Seek handling will be reworked, so state is not RSN anymore, but ASAP, or 'without date'. Wed Sep 22 22:35:38 1999 Andreas Kupries * --- Version 2.0 ready for release --- * generic/transform.h: Removed old definitions of exported procedures. * generic/sha/sha.h: Protected BYTE typedef, BYTE is defined as macro on Windows platforms. Sent in by Jan Nijtmans. Tue Sep 21 20:10:37 1999 Andreas Kupries * generic/trf.decls: Extended the stub table to cover all public procedures. Mon Sep 20 21:53:56 1999 Andreas Kupries * Added checks into 'configure' to search for the bz2 library. The corresponding tests are skipped if it is not available. * Used his changes to win/Makefile.gnu as template for the changes to unix/Makefile.in, tea/Makefile.in and win/makefile.vc*. Had to change the configure.in's as well. * Jan Nijtmans provided the basic changes to stubify Trf, to let it export its own stub table, for usage by extensions like TrfCrypt. Sun Sep 19 01:29:23 1999 Andreas Kupries * generic/zip_opt.c, * generic/registry.c, * generic/reflect.c, * generic/ref_opt.c, * generic/digest.c, * generic/dig_opt.c, * generic/convert.c, * generic/bz2_opt.c: Removed support for Tcl 7.6 and below. * generic/bz2.c (FlushEncoder): Killed the bug that plagued the 'bzip' transformation. It was an error in the compressor, although the test of the decompressor failed. BZ_FLUSH -> BZ_FINISH solved that problem (incomplete output from the compressor!). (FlushDecoder, Decode(Buffer)): Remembered result from last call too 'bzDecompress' to skip flushing if the stream is already in the state BZ_END_STREAM. Else we will get a sequence error. This problem was shadowed by the first so far. * Worked on a TEA compliant build chain (since yesterday evening). Now complete. Tue Sep 14 23:07:50 1999 Andreas Kupries * Applied patch sent in by Jan Nijtmans. Fri Sep 10 21:10:55 1999 Andreas Kupries * doc/nodes/intro.node: * doc/nodes/install.node: * doc/nodes/patch.node: * doc/nodes/future.node: Updated to include information about Tcl 8.2 and its integration of the Trf patch. Thu Sep 2 21:23:21 1999 Andreas Kupries * doc/nodes/md.node: Added reference to Bruce Adams Md5 extension at http:///www.cybernetics.demon.co.uk/projects/md5/md5.html Sat Jul 17 18:10:28 1999 Andreas Kupries * generic/reflect.c: Changed to use a byte-array for the buffer argument in case of compilation against 8.1 or higher. * generic/registry.c: Finalized adaption to 8.2, and the runtime switching too. Tue Jul 13 18:40:44 1999 Andreas Kupries * generic/registry.c: Changed the registry from a hashtable to a real structure (containing the old hashtable and some more), changed all places acessing. Added 'patchIntegrated' flag and changed all places using 'trans->parent' to check 'patchIntegrated' to determine the correct method of finding the downstream channel. Reason: Trf is now able to work with 8.1 and 8.2 without recompilation for the specific interpreter. Compilation may happen with 8.1 or 8.2, it makes no difference, the extension adapts itself to the changed semantics. * unix/configure.in: Fixed a bug in the parameter generation for shared libraries, sent in by Jan, modeled after fix in Tk. * generic/transformInt.h: See below. * generic/registry.c (TrfExecuteObjCmd): See below. * generic/unstack.c (TrfUnstackCmd): See below. * patches/v8.1/standard.patch: Modified to use the new and official names for the functions in the patch (Tcl_StackChannel, Tcl_UnstackChannel). * generic/loadman.h: See below. * unix/configure.in: Newer versions of OpenSSL place their includes in .../openssl/include/openssl/ instead of .../openssl/include/. Changed to allow both, with the new placement considered first. * generic/qpcode.c: More corrections from Marshall Rose, quoted-printable this time. Fri Jul 9 16:51:14 1999 Andreas Kupries * tests/base64.test: Adapted to changes in 'base64'. * unix/Makefile.in: Added all necessary code for bz2 from Jan. * win/makefile.vc: * win/makefile.vc5 (TRFOBJS): Added bz2*.obj to the definition. * win/Makefile.gnu: Corrections sent by Jan Nijtmans. Additionally adds 'bz2' compression. Incomplete. * Marshall sent some corrections to his new transform ('quoted-printable') and to his changes to 'base64'. Tue Jul 6 20:01:49 1999 Andreas Kupries * generic/b64code.c: Accepted change from Marshall Rose inserting a newline after every 76 characters. This makes the encoder MIME compliant. Newlines in the input are ignored. Mon Jul 5 23:21:34 1999 Andreas Kupries * doc/nodes/conv.node: See below. * doc/nodes/cmds.node: See below. * win/Makefile.gnu, win/makefile.vc*: See below. * unix/Makefile.in: See below. * generic/qpcode.c: New transform, donated by "Marshall Rose" . The transform is 'quoted-printable', one of the encodings for mail and news, as defined by MIME (RFC 2045). Tue Jun 29 21:20:23 1999 Andreas Kupries * unix/configure.in: Extended the code to deal with the upcoming Tcl 8.2. * compat/md2.h (MD2_INT): Weird bug discovered by Jan on Windows (Cygwin compiler) solved, again by Jan. The header in OpenSSL changed the definition from unsigned char to unsigned int. Now using the compat header could do nasty things. Got a new DLL too, making the Windows binary distribution usable. Mon Jun 28 23:17:35 1999 Andreas Kupries * unix/configure.in: * unix/Makefile.in: Matt Newman sent in some changes to built the extension on HPUX (Basically check for .sl extension too). Tue Jun 15 00:00:36 1999 Andreas Kupries * tests/*.test: The tests for all commands dependent on external shared libraries now have constraints set on them. * unix/Makefile.in (test): Added code to define more constraints, the variable used is set by the 'configure' script to define, which external libraries are available and therefore testable. * tests/defs: Updated to code from Tcl 8.0.5, copied my definitions from the old 'defs' to it, added code to define more constraints. * unix/configure.in (ZLIB_INCLUDE_DIR): Changed error into warning, allows falling back to compatibility headers. (SSL_INCLUDE_DIR): See above. (Variable: TRF_DEFS). (TRF_TESTS): New variable, contains constraint information about tests to skip. Mon Jun 14 20:39:21 1999 Andreas Kupries * generic/zlib.c, * generic/zip.c, * generic/crc_zip.c: Renamed 'z' to 'zf', as the Gnu Tools on Windows have a bug with regard to the handling of single-character variable names. Note by Jan Nijtmans. * generic/transformInt.h: 'DllEntryPoint' removed. See below. * generic/init.c: 'DllEntryPoint' removed. See below. * win/: Added 'dllEntry.c', contains 'DllEntryPoint'. Added 'Makefile.gnu'. Both from Jan Nijtmans. * win/makefile.vc: * win/makefile.vc5 (TRFOBJS): Added 'dllEntry.obj'. Sun May 30 10:49:42 1999 Andreas Kupries * patches/v8.1*/standard.patch: Fixed bug in the handling of encodings. Caused the system to lose references to the system encoding, which crashed the interpreter after some time (testsuite, ________.test (digests, tools/md) seg.faulted). * tests/otp_words.test, otpsha1.test, otpmd5.test: Added testsuite for new OTP commands (See May 27). * generic/otpcode.c, init.c, b64code.c, rs_ecc.c: Nits (comment in comment, unused variable, implicit function declarations). * Threading: Done. Sat May 29 22:56:31 1999 Andreas Kupries * The patchkit for Tcl 8.1 is usable for Tcl 8.1.1 too. No new patchkit was made. * generic/*.[ch]: Went through the code and looked for possible problems with regard to multi-threading (written global variables). Marked all found places with /* THREADING */ and some additional explanation. Thu May 27 00:16:17 1999 Andreas Kupries * doc/nodes/md.node: * doc/nodes/conv.node: * doc/nodes/cmd.node: Integrated OTP documentation from Marshall Rose. * generic/transformInt.h: * generic/registry.c: * generic/init.c: * generic/otpcode.c: * generic/otpmd5.c: * generic/otpsha1.c: * generic/md5.c: * generic/sha1.c: Integrated OTP code from Marshall Rose . Tue May 25 23:22:21 1999 Andreas Kupries * generic/*.h: Added preprocessor definitions allowing the usage of the headers with a C++ compiler. Fri May 7 20:47:56 1999 Andreas Kupries * --------------- 1.6 re-release ------------------ * patches/v8.1: Added patch kit for 8.1 final. Thu Apr 22 21:46:12 1999 Andreas Kupries * --------------- 1.6 released -------------------- * Tested compilation against unpatched core. The resulting library was usable for a patched core (-attach, unstack), and rejected these features if loaded by an unpatched interpreter. Wonderful. No compilation trouble anymore, and only nearly normal usage in conjunction with an unpatched interpreter. * generic/unstack.c (TrfUnstackCmd): Fixed minor spelling errors. * generic/transformInt.h (Tcl_UndoReplaceChannel): Fixed spelling error in the macro. Wed Apr 21 21:06:02 1999 Andreas Kupries * generic/unstack.c (TrfUnstackCmd): See item below, the same check is added here too. * generic/registry.c (TrfExecuteObjCmd): Added a runtime check verifying that the interpreter using the extension is patched. Done only for a stub-aware interpreter (see item below too), and while accessing features depending on the patch. * generic/transformInt.h (Trf_ReplaceChannelStub): New macro, to get at the location of 'Tcl_ReplaceChannel' in the stubs-table. Mon Apr 19 20:25:41 1999 Andreas Kupries * --------------- 1.5 released -------------------- Sun Apr 18 14:59:05 1999 Andreas Kupries * doc/nodes/danger.node: Added comments about usage of trf with respect to 'filevent's. * patches/*: With the exception of the patchess for 8.0a* and 8.0b* all kits were modified to fix a bug with my changes to the refcounting code which tripped attaching a transform inside of a socket acceptor script. Detected by Matt Newman. Modified files are 'standard.patch' and 'tclIO.c'. Fix was delayed to wait for possible problems with it, but got none. Tue Apr 13 08:28:10 1999 Andreas Kupries * generic/registry.c: Added code to flush out information waiting in various channels buffers. Timers are used to create artificial 'readable'-events. The socket/file/pipe might not generate them as all data could have been sucked already completely into the stack of transforms. Completes the fileevent support begun with the patch from Matt, see below. * generic/registry.c: Accepted patch from Matt Newman () fixing problems with blocking mode and handling of fileevents. * win/makefile.vc: * win/makefile.vc5: Added definition of SSL_LIB_NAME to configuration section. * generic/loadman.c: Changed to allow the makefile to define the value of SSL_LIB_NAME. Sat Apr 10 16:05:04 1999 Andreas Kupries * --------------- 1.4 released, again -------------------- * Added patchkit for 8.1b3. Thu Mar 25 12:40:20 1999 Andreas Kupries * --------------- 1.4 released -------------------- * --------------- Ready to release 1.4 -------------------- * generic/init.c: Added initialization of stubs, for 8.1. * generic/digest.c: Restored usage of 'Tcl_SetObjVar2'. Change between 8.1b1 and 8.1b2. No change between 8.0.x and 8.1b2. * generic/reflect.c: Restored usage of 'Tcl_GlobalEvalObj'. Change between 8.1b1 and 8.1b2. No change between 8.0.x and 8.1b2. * generic/binio.c, * generic/util.c, * generic/dig_opt.c, * generic/transformInt.h: Conditionalized usage of 'panic'. Now using 'Tcl_Panic' in case of compilation against tcl 8.1. * unix/Makefile.in: Changed to allow usage of stubs. * generic/sha/fip180-1.pdf: Added description of SHA-1. * doc/ToDo: Added: Create stub-table for Trf too, to be used by TrfCrypt and other extensions to this one. * doc/nodes/where.node: Added note that the Windows binary distribution is not usable for Win95/98. * PREPARE: Exclusion of 'generic/pkgIndex.tcl.in'. * unix/pkgIndex.tcl.in: Moved from 'generic' to this place. Changed to check the tcl version, allowed version depends on usage of stubs, analogous to package index of Memchan. * unix/configure.in: Added code to handle stubs, as in 'memchan'. Added code to disallow 'binio' for tcl 8.x and beyond. The user is refered to 'binary' instead. 'binio' is deprecated from now on, and the associated byteorder patch will be phased out, no new versions will be made. Sun Mar 21 16:01:44 1999 Andreas Kupries * Generated patches for 8.1b2, fixed a bug in the byteorder patch. Sun Mar 14 19:29:33 1999 Andreas Kupries * Generated patches for 8.0.4 and 8.0.5. Mon Feb 22 18:19:58 1999 Andreas Kupries * win/makefile.vc (TRF_DEFINES): Added -DBUILD_trf to the definition of this variable. Already in makefile.vc5, forgot to include it here before. Sync problem :-(. Thanks to Stefan Speidel for finding this. Tue Jan 12 20:53:36 1999 Andreas Kupries * generic/binio.c: * generic/digest.c: * generic/reflect.c: * generic/registry.c: * generic/load.c: * generic/init.c: * generic/loadman.h: * generic/transformInt.h: * generic/transform.h: See below. * Fought against the MS environment today and won. Integrated the changes made there now into the master. Mon Jan 11 22:40:19 1999 Andreas Kupries * doc/nodes/techintro.node: New node, contains a technical explanation of the inner working of Trf, with images. * doc/nodes/intro.node: Added reference to technical information. Mon Dec 14 22:04:35 1998 Andreas Kupries * patches/v8.1b1: Started yesterday with the trf patches for the newly announced 8.1b1 version. Completed it today. Fri Nov 13 18:25:26 1998 Andreas Kupries * generic/util.c: * bincode.c: * hexcode.c: * octcode.c: * asc85code.c: * reflect.c: * rs_ecc.c: * zip.c: * generic/registry.c: Fixed several char/uchar mismatches. Reported by Larry. Thu Oct 1 17:46:49 1998 Andreas Kupries * generic/reflect.c: * generic/asc85code.c: Fixed several char / unsigned char mismatches, detected by Larry Virden on his UltraSparc. Wed Sep 30 15:49:24 1998 Andreas Kupries * unix/Makefile.in: Added [ZLIB|SSL]_[LIB|INCLUDE]_DIR, analogous to TCL_[LIB|INCLUDE]_DIR. Extended runtime library search path and compiler include options. * unix/configure.in (TCL_LIB/INCLUDE_DIR): Added some additional intelligence: Setting one of the variables, but not the other causes automatic definition of the missing part with a value derived from the defined directory. Suggested by Larry Virden. Added 8.0.3 to the paths to search. Added $exec_prefix/lib to the paths to search for the tcl-library. Added searches for zlib.h / sha1.h / md2.h, and appropriate configure options (--with-zlib, --with-ssl, handling analogous to --with-tcl). Tue Sep 29 23:20:11 1998 Andreas Kupries * generic/digest.c: Added fixes for nits discovered by Larry Virden on his Sun: added explicit comparison to NULL, added casts for 'char*' to 'unsigned char*'. Mon Jul 27 22:11:59 1998 Andreas Kupries * win/: Got a windows dll from Jan Nijtmans (Jan.Nijtmans@wxs.nl) and assorted goodies (makefile for vc 5.0, rc file, icon file, better pkgIndex.tcl). Sun Jul 19 22:24:43 1998 Andreas Kupries * tools/mmencode: * tools/mmdecode: Minimal replacements for the named applications (metamail). Conversion of a bytestream from and to base64. * tools/demo: Visual demonstration application, sent to Jan for inclusion into his win installation (Consosrtium CD ROM Project). The logo too. * doc/nodes/img/logo-120x181.gif: * doc/nodes/img/logo-16x16.gif: * doc/nodes/img/logo-32x32.gif: * doc/nodes/img/logo-60x90.gif: * doc/nodes/img/logo-64x64.gif: Designed a logo for trf, built in various sizes. Sat Jul 4 21:29:26 1998 Andreas Kupries * unix/configure.in: Fixed a bug noted by David Herron in memchan. This package had it too. From its mail: > In the section that checks for the TCL library there > is a loop looking for different library extensions. > In my case it needs to match the ".so.*" case of > the loop, but it doesn't. > > Changing the test to read as follows fixes the problem. > > if test -f $dir/libtcl$version$libsuff; then > memchan_cv_lib_TCL_LIB="-L$dir -ltcl$version" > TCL_LIB_DIR="$dir" > fi > > The difference is removal of the quote marks around > the file name. This allows the "*" to be evaluated > by the shell & find the file name. > > Another change that would be convenient is, in > the 'for version in ...' part, to add "80" to > the list of choices. With (at least) tcl8.0pl2 > on FreeBSD the library is "libtcl80.so.1.0" and > since the configure script only looks for "libtcl8.0" > it is not found again because of that. Thu Jul 2 00:24:59 1998 Andreas Kupries * doc/nodes/*: Removed the descriptions of the various encryption algorithms. Wed Jul 1 20:28:20 1998 Andreas Kupries * generic/pkgIndex.tcl.in: Changed to load trf immediately upon request, and not while trying to execute the first command. Without that the separate crypto package will have problems attaching itself to the trf core. Tue Jun 30 22:41:18 1998 Andreas Kupries * PREPARE: Using the 'webTemplate' system (*) to generate documentation for linkage into my westend site and for standalone distribution. (Ad *) webTemplate is a system for the generation of a whole web site using node descriptions and a selectable layout/style definition. Current state: *INTERNAL*. * doc/: Replaced latex documentation by native HTML. Added 'nodes' directory. Mon Jun 29 20:13:55 1998 Andreas Kupries * Done. System compiles without problems. The only thing containing references to encryption is the documentation. * Started the removal of encryption related code. * ---------------------------------------------------- Wed Jun 17 21:38:32 1998 Andreas Kupries * doc/def.tex: * doc/man.tex: * doc/install.tex: Checked the urls, removed some broken ones. Added some notes about binio, see below, and 'bzip' (future section). * patches/v8.1a2/byteorder.patch: Reworked to expose a minimal set of declarations in the patched tcl.h. First step towards complete removal of 'binio' and its support in favor of the official 'binary' command. Sat Jun 13 13:38:19 1998 Andreas Kupries * The patch required an adaption to I18N/UTF: A channel X replacing another channel C via Tcl_ReplaceChannel takes over the encoding information from C. Acess to the filter channel via 'puts' will now encode/decode the given strings prior to the transformation of X. Below X no encoding will take place. * The extension itself did not require adaptions to I18N and UTF. This is because an attached channel uses 'Tcl_Read' and 'Tcl_Write' to access the underlying channel, thus bypassing its encoding stage. * Passed all tests. * Fixed problem in new 'standard.patch', forgot to initialize 'chanPtr->outputStage'. transform.test 2.1 and base64.test 7.1 solved. * generic/reflect.c (Execute): Fixed refcount problem. Tcl_Eval now increments and decrements the refcount of the given script object. As 'Tcl_DuplicateObj' returns an object having refcount 0 I caused a problem by not incrementing the refcount, but decrementing it, thus trying to free the object a second time. => transform.test 1.x solved. Fri Jun 12 16:13:26 1998 Andreas Kupries * 2 tests failing: transform.test (1.x, 2.1), base64.test (7.1) * -------------------------------------------------------- Ok, this completes the basic adaption to the new version of tcl. Still missing: Insinuation of the channel hooks into 'tclIO.c', and adaptions to the new I18N features (UTF et. al.). * generic/digest.c (WriteDigest): Added code to adapt to an API change between 8.0 and 8.1 (Tcl_ObjSetVar2 renamed to Tcl_SetObjVar2, and type changes for the part1/2 parameters, 'Tcl_Obj*' to 'char*'). * generic/reflect.c (Execute): Added code to adapt to an API change between 8.0 and 8.1 (Tcl_GlobalEvalObj was removed, Tcl_EvalObj got an additional flag instead). * generic/registry.c (Trf_Register): Added code special to 8.1: Initialization of the 'close2Proc' driver procedure (NULL). Mon Aug 18 21:18:31 1997 Andreas Kupries * -------------- 1.0 relased ----------------------------- * win/makefile.vc, PREPARE: finishing touches, removed last remnants of '8.0b2'. * patches/v8.0: Added patches for tcl 8.0 final. Tue Jul 29 00:18:21 1997 Andreas Kupries * Ready for relase of Tcl 8.0 final now. * Distribution running again under 7.6 and 8.x. Mon Jul 28 20:34:05 1997 Andreas Kupries * doc/man.tex (section {Message digests}): Added explanation of transparent mode. * generic/dig_opt.c: * generic/digest.c: * generic/transformInt.h: Added transparent mode to general message digest code. A mixture of absorb and write, see 'doc/man.tex' for more. * doc/defs.tex: Some more homepages found, updated references to Jan Nijtmans. * doc/man.tex (chapter {Copyrights}\label {copyright}): Added section about SAFER. Sat Jul 26 18:32:35 1997 Andreas Kupries * tests/safer.test: New file, testing safer implementation. Fri Jul 25 18:13:12 1997 Andreas Kupries * unix/Makefile.in (CRYPT_ALG_SRC): Added SAFER. * win/makefile.vc (TRFOBJS): Added SAFER. * generic/safer.c: New cipher. First one with cipher specific options (choice between 2 keyschedules, standard and strong, allows specification of number of rounds). * generic/rc4.c: * generic/rot.c (C_Schedule): Adapted to changes in type 'Trf_CSchedule'. * generic/rc2.c, * generic/idea.c, * generic/blowfish.c, * generic/des.c (BC_Schedule): Adapted to changes in type 'Trf_BCSchedule'. * generic/blockcipher.c (InitializeState): Cipher specific option information is given to the scheduler for incorporation into the internal key of this cipher. * generic/transform.h (Trf_BCSchedule): Added parameter for inclusion of cipher specific option information. * generic/bc_opt.c: Added calls to cipher specific option processing to all procedures. * And now the analogouos changes to the blockcipher code. Thu Jul 24 00:41:05 1997 Andreas Kupries * generic/cipher.c (InitializeState): Cipher specific option information is given to the scheduler for incorporation into the internal key of this cipher. * generic/transform.h (Trf_CSchedule): Added parameter for inclusion of cipher specific option information. * generic/c_opt.c: Added calls to cipher specific option processing to all procedures. * generic/transformInt.h: Added items to hold references to cipher specific option information to structures 'TrfBlockcipherOptionBlock' and 'TrfCipherOptionBlock'. * generic/blowfish.c, * generic/des.c, * generic/idea.c, * generic/rc4.c, * generic/rc2.c, * generic/rot.c: Updated to new structure definition (NULL == no additional options). * generic/transform.h: Added references to Trf_OptionVrctors to 'Trf_CipherDescription' and 'Trf_BlockcipherDescription', to allow specification and usage of additional, cipher specific options. * -- evening again -- * doc/install.tex, man.tex: Brought up to date now. Wed Jul 23 00:02:03 1997 Andreas Kupries * Both distributions running now (7.6, 8.x). Go ahead and update documentation now. * generic/reflect.c (Execute): Added missing separators in 7.6 code. * unix/Makefile.in (test): Added SSL_INSTALL_DIR/lib to library search path, just to be prepared. * tests/transform.test: New file, check behaviour of transformation using scripts to do the work. * generic/registry.c (TransformImmediate): checking for empty results now. * generic/c_util.c (TrfGetChannelData): Missing assignment to *length in bound case caused blockcipher blowup. Were used by 7.6 tests only, had therefore no problems in 8.x. * -- evening again -- * tools/md: See below. * tests/defs: Force usage of Memchan 1.2 for tcl 7.6. Tue Jul 22 00:07:21 1997 Andreas Kupries * generic/registry.c (TransformImmediate): Added \0 behind internal result buffer to prevent using a longer buffer than really given (7.6 only). * Checked distributions. 8.0(b2) working, 7.6 not. Things done to get that state: > tests/*.test: The md's had 'text' as command. Corrected. > README: Changed reference to 8.0b1 to 8.0. Removed package references. > PREPARE: Crunching .html files below doc/html/ now. * tools/md: Small adaptions to new syntax. All operations were attach'ed, no change there. Had to define '-read-type channel' nevertheless, because of default geared towards 8.x. * ChangeLog.short: New file, used in generation of ANNOUNCE. * ANNOUNCE, LSM: Removed, see below. * PREPARE: Modified to take advantage of progress in 'makedist'. ANNOUNCE / LSM generated now. * -- evening again -- * All tests ok again. * generic/registry.c (TransformImmediate): Restructured this procedure, and 'PutInterpResult', to avoid smashing any intermediate result generated by a transformation. We must write a result only after all transformation vectors were executed. Each of these may need the result area by themselves. Example: 'transform'-command. Mon Jul 21 21:26:17 1997 Andreas Kupries * tests/crc.test, * tests/haval.test, * tests/md5.test, * tests/rmd128.test, * tests/rmd160.test, * tests/sha.test, * tests/md2.test, * tests/adler.test, * tests/crc_zlib.test: Rewritten. Message digests done now. * tests/common.md.test: New tests, checking common behaviour of all message digests, as implemented in 'dig_opt.c' and 'digest.c', see below. * generic/digest.c, dig_opt.c: Rewritten. Fri Jul 18 00:19:45 1997 Andreas Kupries * tests/idea.test: * tests/des.test: * tests/blowfish.test: Rewritten. Block ciphers are done now. Thu Jul 17 22:29:49 1997 Andreas Kupries * generic/registry.c (TrfExecuteObjCmd, TrfExecuteCmd): Changed to check for transformation in case of option not matching one of the standard ones. New standard option -in blocked check for blockcipher option '-iv'. This is an old error, in since the beginning, but due to no conflicts in options names it never showed up before. * tests/common.bc.test: New file, checks common behaviour of all block ciphers. * generic/bc_opt.c: * generic/c_opt.c: * generic/c_util.c: Moved interpretation of argument to '-xx-type' into a separate procedure, then simplified the option processors. Wed Jul 16 23:23:11 1997 Andreas Kupries * generic/bc_opt.c: Rewritten according to 'doc/changes.final'. Blockciphers done. Used generic code in 'c_util.c' to simplify changes. * generic/c_opt.c: Simplified, calling code in 'c_util.c' now. * generic/c_util.c: New file. Contains generic code of rewritten 'c_opt.c', see below. Tue Jul 15 23:29:16 1997 Andreas Kupries * tests/rot.test: New test. * tests/rc4.test: Rewritten. * generic/c_opt.c: Rewritten according to 'doc/changes.final'. Ciphers done. Mon Jul 14 00:04:52 1997 Andreas Kupries * tests/zip.test: * tests/rs_ecc.test: Rewritten now. * tests/ascii85.test, uu.test: New tests, all conversions are checked now. * tests/hex.test: * tests/oct.test: * tests/base64.test: Rewritten, as with bin.test * generic/octcode.c, * generic/bincode.c, * generic/hexcode.c, * generic/uucode.c, * generic/b64code.c, * generic/asc85code.c: Added 'Tcl_ResetResult' to all error generating returns, to clear out any partial result written via 'PutInterpResult' (registry.c). * -- evening again -- * tests/bin.test: Started rewrite of tests, to handle and take advantage of new syntax. Sun Jul 13 22:16:39 1997 Andreas Kupries * tests/common.all.test: New. Checks common behaviour of all commands, as implemented in 'generic/registry.c'. * generic/registry.c: Rewritten according to 'doc/changes.final'. Manual mini tests (hex, base64) ok. * generic/*.c: Removed all occurences of ADD_RES. Using 'Tcl_AppendResult' again. See May 29 too. Wed Jul 9 20:40:20 1997 Andreas Kupries * generic/rot13.c: New cipher: rot. Just fore fun, not for strength. * doc/man.tex (chapter {Copyrights}): Updated due to changes in the copyright of HAVAL. Added info about sabbatical leave in japan, and associated email address. * generic/haval.c: updated. * tests/haval.test: updated. * generic/haval.1996/havalapp.h, * generic/haval.1996/haval.h, * generic/haval.1996/haval.c: Changes made to old haval added in here too. See January 5 and 13. Retained original files, with suffix '.orig'. * generic/haval.1996/*: Added 1996 revision of HAVAL. * tests/md2.test: New file, tests from RFC 1319 test suite. * tests/md5.test: Added tests from RFC 1321 test suite. Mon Jul 7 18:14:43 1997 Andreas Kupries * doc/man.tex (chapter {Acknowledgements}): Update. * generic/digest.c (CreateDecoder): Fixed wrong assignment to c->writeClientData. (FlushDecoder): removed superfluous '&'-operators (c->digest_buffer). Both problems found by Hyoung-Gook Kimn . Tue Jun 17 19:07:42 1997 Andreas Kupries * win/makefile.vc (TRFOBJS): Added reflect.o, ref_opt.o. Sun Jun 15 12:53:57 1997 Andreas Kupries * doc/man.tex (section {Misc.}): Added documentation of general transformation command. * generic/registry.c (TrfInput): Tests showed multiple 'flush/read'. Corrected, added missing check for 'readIsFlushed'. Remembering mask of parent channel now, for attached channels. This is used to optimize away the calls to unused parts of a transformation. * generic/ref_opt.c (SetOption): Added forgotten 'break'. (CheckOptions): corrected wrong condition for mode-check (attached channels). Added default mode for attached channels * General transformation: First tests using 'identity'. Sat Jun 14 21:43:06 1997 Andreas Kupries * generic/ref_opt.c: Option processing for channel defined below. * generic/reflect.c: New transformation channel. Reflects the requested operations up into the script level. In other words: The real transformation is done by a script. DANGER: Will have problems with embedded \0's if used by tcl 7.6. Sun Jun 8 09:14:24 1997 Andreas Kupries * patches/v7.6p2: Added directory and files in it. Sat Jun 7 18:31:55 1997 Andreas Kupries * doc/install.tex (chapter {Patching the core}): Corrected information about working directories of the various patch files. * patches/v7.6p2/: New directory. The patches are the same, the prepatched versions of various files not. Sun Jun 1 12:03:58 1997 Andreas Kupries * ---------------- Release 1.0b3 ---------------- * Compiled under windows, ok. Added reference to binary distribution to manual. Sat May 31 00:04:27 1997 Andreas Kupries * doc/install.tex: brought uptodate, some enhancements. * unix/configure.in: Removed references to a2 relase of tcl 8.0. * doc/man.tex: brought uptodate, some enhancements. * win/makefile.vc (BINIO): see '--enable-binio' below. * --------- morning --------- * tests went through without problems. * trf now compiles again, without warnings. * tcl 8.0b1 with patches compiles, links and tests sucessfully (iocmd 8.8, 8.9 fail due to the new option '-byteorder'). * patches/v8.0b1: Added directory and files in it. These are the patches to the tcl 8.0b1 core. * generic/binio.c: See --enable-binio below. Added the appropriate ifdefs. * unix/configure.in (--enable-shared): changed to --disable-shared, making build of shared libraries the default behaviour. (--enable-binio): new option to enable compilation of 'binio' command. Default: NO compilation. See commands 'binary' and 'fcopy' of 8.0b1 for equivalent functionality. Fri May 30 23:49:38 1997 Andreas Kupries * generic/registry.c: compiles, only warnings due to unpatched core remain. * generic/registry.c (TrfExecuteObjCmd): Added CONST to 'objv', as required by new API. (TrfReady): Excluded for 8.0b1, due to new notifier mechanism. (TrfGetFile): Updated to new interface. (TrfRegister): Updated command creation to changed interface of 'Tcl_CreateObjCommand'. Updated initialisation of 'entry->transtype', due to changed notifier. (TrfWatch): Updated to changed notifier ('watchChannelProc' now named 'watchProc'). Thu May 29 21:16:05 1997 Andreas Kupries * All files, with exception of 'unstack.c', 'binio.c' and 'registry.c' compile without flaws now. The named files depend (partially) on the patches to the core, and the C-API to channels. Near midnight, tackle them tomorrow. * generic/bc_opt.c (SetOption): see 'CheckOptions' below. * generic/zip_opt.c (CheckOptions): Removed special code to transfer string to object result. See below. (SetOption): changed 'long' to 'int' for 3rd arg. to 'Tcl_GetIntFromObj'. * generic/util.c (TrfGetChannel): Disabled this code, not required anymore, see below. See Feb 11 too. * generic/transformInt.h (ADD_RES, RESET_RES): 8.0b1 has smoothed out the problems arising from having two results (string, obj). No dependency on version anymore. Definitions left in to avoid immediate conversion of all affected files. Wed May 24 22:11:25 1997 Andreas Kupries * doc/man.tex: * doc/install.tex: Made urls into hyperlinks, at least in the HTML version of the manuals. Done in the last days. Wed May 21 18:16:42 1997 Andreas Kupries * PREPARE: use newly installed 'latex2html' to generate and distribute html versions of the manuals. The urls inside are currently not hyperized yet. -- switched from custom code to procedure now provided by 'makedist'. Mon May 19 22:35:19 1997 Andreas Kupries * doc/man.tex: * doc/install.tex: checked with 'ispell', added new message digests. * generic/ripemd/rmd128.c: see below. * generic/ripemd/rmd128.h: Made usable for AXP (64bit long's), added unique prefix to function names. Added tcl.h, _ANSI_ARGS_ to let it compile for K&R too. * tests/rmd128.test: see below. * win/makefile.vc (TRFOBJS): see below. * unix/Makefile.in (rmd128.o): see below. * generic/init.c: see below. * generic/rmd128.c: Added message digest RIPEMD-128. Thu May 15 20:32:49 1997 Andreas Kupries * generic/ripemd/rmd160.c: see below. * generic/ripemd/rmd160.h: Made usable for AXP (64bit long's), added unique prefix to function names. Added tcl.h, _ANSI_ARGS_ to let it compile for K&R too. * win/makefile.vc (TRFOBJS): see below. * tests/rmd160.test: see below. * unix/Makefile.in (rmd160.o): see below. * generic/init.c: see below. * generic/rmd160.c: Added message digest RIPEMD-160. Sun May 11 21:36:46 1997 Andreas Kupries * doc/install.tex, man.tex: Adapted to made changes. * generic/transformInt.h: Definitions concerning DES moved to 'loadman.h'. * win/makefile.vc (TRFOBJS): Added the new files, named below. * unix/Makefile.in: Added rules for new files named below. * generic/init.c (Trf_Init): Added initializators for algorithms below. * generic/md2.c, rc2.c, sha1.c: New files. Glue to incorporate MD2, SHA1 message digests and RC2 block cipher. All are searched for in SSLeay only. WARNING: RC2 keylength is artificially limited to a maximum of 1024 bytes. * win/makefile.vc (LIBDES): Removed this configuration variable. See Feb 26 too. Superfluous now, see below. * generic/loadman.c: * generic/loadman.h: new files, supercede 'libdes.c', which is removed from the distribution now. This manager allows for individual loading of functionality from a variety of libraries. Currently uses 'libcrypto.so' (SSLeay) and 'libdes.so' only. Sat May 10 21:56:46 1997 Andreas Kupries * first step to change from 'libdes' over to 'SSLeay' ('libcrypto'). * generic/zlib.c: * generic/libdes.c: Changed to use the new functionality described below. * generic/load.c: New file. Used last the 2 functions of 'imgInit.c' (Img library, Jan Nijtmans) to factor out the common components of loading a shared library. Mon Mar 17 18:18:05 1997 Andreas Kupries * unix/Makefile.in (distclean): removed 'patchlevel.h' from command, is part of distribution now. * patches/v8.0a2/tclIO.c (Tcl_GetHostByteorder): Had superfluous 'chan'-argument, despite correction in the patch. Thu Mar 6 20:13:55 1997 Andreas Kupries * Integrated patch send by Jan. Description: "Further on, I improved the test for the need of _eprintf.o, because I noted that sometimes _eprintf.o is included when it is not needed at all. Finally I implemented the LD_LIBRARY_PATH environment variable in tclLoadAout.c, such that it works the same as on other machines. See patches below. Both of these improvements are already in the current Img1.0b1, but they are useful in Trf as well." Sun Mar 2 11:27:49 1997 Andreas Kupries * PORTING: new file. database of porting notes, hints, tricks, etc. * generic/idea/idea.c (MulInv): Fred Meyer (fred@sga.co.za) had a problem with IDEA on its DEC Alpha. Tracked down to this procedure. Must not be compiled with -O, -O2 or higher. The overoptimized code will return 0 for many arguments, resulting in a bad decryption key. The option -O1 is possible though. Sat Mar 1 15:50:50 1997 Andreas Kupries * generic/binio.c (READ_CHUNK_SIZE): allow redefinition of value via makefile!. Default bumped up to 16k (4k before). * PREPARE: see below, generate uncompressed digest files. * tests/________: removed '-z', expect uncompressed digest files (More space required, but less dependencies (zlib)). * generic/registry.c: Bugfix in 'TrfInput' (-> Feb 14) caused the system to call read-flush twice. Noted due to doublesized results for message digests. New flag 'readIsFlushed' to prevent this. * doc/install.tex: Complete. * generic/registry.c (TrfInput): fixed bug regarding calculation of bytes to move down via 'memmove' (operands were in wrong order). Wed Feb 26 18:31:50 1997 Andreas Kupries * win/makefile.vc (LIBDES): new configuration variable. allows usage of win32 binary distribution of SSLeay. * tools/ldAout.tcl: integrated patch containing small bugfixes. Sent by Jan. * doc/install.tex: new installation manual, nearly complete now. * added directory 'zlib.vc'. Contains everything to compile zlib as shared library under windows (MSVC++ 4.2). * reorganized 'patches' directory. Every version of tcl got its own subdir. Tue Feb 25 22:38:18 1997 Andreas Kupries * generic/sha/sha.c: * generic/sha/sha.h: renamed typedef'd LONG to UINT32. Avoids collision with definition made by Windows. SHA finally ok under windows (see Feb 15 too). Sun Feb 23 18:46:33 1997 Andreas Kupries * generic/idea/idea.h: see below. * generic/sha/sha.h: Added check for compilation on DEC Alphas, define LONG accordingly. Thu Feb 20 21:27:32 1997 Andreas Kupries * generic/zlib.c (Z_LIB_NAME): Default is 'zlib.dll' now. * win/makefile.vc (install): protect 'md' with -@ against errors (directory maybe in existence already). * tests/binio.test: added 'fconfigure -translation binary' to 1.8 Sat Feb 15 22:58:32 1997 Andreas Kupries * tests/sha.test: don't execute 'sha-2.2' under windows. Uses 'cat' to beef up a 1000 character file to 1e6 characters. A more portable method is required to do this. * tests/binio.test: spots using '/dev/null' rewritten, removed dependency on un*x. * generic/b64code.c: see below, same thing. * generic/uucode.c: added explicit casts to all array initializers, MSVC was not unable to comprehend that they are 'char's or to convert them into such, at least silently. * generic/blowfish.c (BC_Schedule): added explicit casts from 'int' to 'short'. * generic/sha/sha.h: avoid 2nd definition of 'typedef unsigned long LONG' under windows. * generic/init.c: moved TRF_EXPORT definition and usage to 'transform.h'. * generic/unstack.c: same as below. * generic/binio.c: 'BinioCmd' static now, with proper declaration. * win/makefile.vc: integrated todays experiences with 'nmake'. * compat/tclLoadWin.c: added declaration to supress warning about unknown 'TclWinConvertError'. This procedure is internal to tcl. Fri Feb 14 19:15:46 1997 Andreas Kupries * win/makefile.vc: first stab at Makefile for windows. Constructed from 'ftp://ftp.sunlabs.com/pub/tcl/example.zip(makefile.vc)' and the makefile used by tcl itself. * generic/init.c: added prolog required for DLL generation under windows. * generic/registry.c (TrfInput, TrfOutput): Inserted usage of procedures for handling complete buffers, they are prefered over the single-character vectors. (TrfInput): corrected logical error causing the system to loose partial data at Eof on underlying channel. Thu Feb 13 21:40:03 1997 Andreas Kupries * -: The bunch of messages below resulted from my first try to compile trf under windoof. Some other messages, not recorded here, were due to the usage of an unpatched version of tcl. Note: The current stage of development in using the object interfaces compiles ok against 8.0a2, but NOT a1. The 'interp' arguments to the used functions were removed between these revisions. First thought at work: How the hell could gcc compile my code, containing such a grave error as supplying to few arguments to a function. Have to install 8.0a2 at work pronto. * compat/tclLoadWin.c: fixed some small problems in here. (dlopen): corrected declaration of 'intialized', added an 'i'. (UnloadLibraries): terminated 2nd declaration with ';'. (dlclose, UnloadLibraries): calls to 'ckfree' required casts. Had some more warnings, investigation defered to next try. * generic/digest.c (EncodeBuffer): signed/unsigned mismatch. * generic/util.c (TrfMerge4To3): The cpp's used so far don't understand an empty argument to a macro. Noop '>> 0' supplied now. * generic/binio.c (PackCmd, 'D', 'U'): Had wrong casts here. * generic/registry.c (TransformImmediate): signed/unsigned mismatch. * generic/rc4/rc4.c (rc4_prepare_key): see below. * generic/asc85code.c (Encode, FlushEncoder, Decode, FlushDecoder): see below. * generic/adler.c: * generic/crc.c: * generic/crc_zlib.c (MD_Final): added casts to stop MS VC++ 4.2 from complaining about conversion problems and loss of data. Tue Feb 11 18:46:01 1997 Andreas Kupries * 'binio', 'unstack' need conversion too. * -------------- tests ok. * generic/util.c (TrfGetChannel): Wrapper to 'Tcl_GetChannel'. Required by objectbased commands, copies the standard result into the 'objResult' of the interpreter. Automatically activated in 'transformInt.h', for tcl major >= 8. * generic/blockcipher.c: * generic/digest.c: * generic/rs_ecc.c: * generic/zip.c: * generic/b64code.c: * generic/octcode.c: * generic/hexcode.c: * generic/bincode.c: * generic/uucode.c: * generic/asc85code.c: changed result generation from 'Tcl_AppendResult' to 'ADD_RES'. * 2nd iteration through files named below, changed result generation from 'Tcl_AppendResult' to 'ADD_RES'. * generic/transformInt.h (ADD_RES): New macro. Used to build command results in a version independent manner. Its definition depends upon the tcl version! * generic/registry.c (Trf_Register): adapted validity checks to changed 'Trf_OptionVectors' structure. * generic/templates/opt_template.c: ok. * generic/bc_opt.c (SetOption): ok. (TrfBlockcipherOptions): ok. * generic/zip_opt.c (SetOption): ok. (TrfZIPOptions): ok. * generic/c_opt.c (SetOption): ok. (TrfCipherOptions): ok. * generic/dig_opt.c (SetOption): ok. (TrfMDOptions): ok. * generic/convert.c (SetOption): ok. (Trf_ConverterOptions): ok. * zipt_opt.c: * dig_opt.c: * bc_opt.c: * c_opt.c: * convert.c: adaption to object interfaces required here! * generic/transform.h (Trf_OptionVectors): added 'setObjProc' to structure. /* ********* POTENTIAL INCOMPATIBILITY at C-level ********* */ * generic/transform.h: New prototype 'Trf_SetObjOption'. Object equivalent to 'Trf_SetOption'. Use VOID for Tcl_Obj if compiled against tcl major version below 8. * generic/registry.c (Trf_Register): Uses 'TrfExecuteObjCmd' if possible. * generic/registry.c (TrfExecuteObjCmd): New function, equivalent to 'TrfExecuteCmd', uses the object interfaces of tcl 8. Conditional compilation removes functionality for Tcl below version 8.x Thu Feb 6 19:27:41 1997 Andreas Kupries * Reorg. complete, distribution running again (unix). * unix/Makefile: corrected MANIFEST check, removed target 'depend'. Removed tests for 'makedepend' from 'configure.in'. Wed Feb 5 23:35:17 1997 Andreas Kupries * : Reorganization for multiplatform development and use (unix, mac, win). Shuffled all files around. Adapted unix makefile to changes. Nothing for Mac and Windows yet. Rewrote generation of distribution (PREPARE, make-tape). 'DESCRIPTION' now central point for version information. The data obtained there is placed into all relevant files at distribution time (README, LSM, ...), especially 'generic/transform.h' and 'generic/patchlevel.h' (former names had '.in' suffixes). 'Configur'ing these files made it impossible to use them for Windows/Mac development. Note: 'PREPARE' is an file internal to the package. It contains tcl-code preparing the package for distribution (removing inofficial and/or internal files, manpage generation, ...). It is not part of the distribution however. Wed Feb 4 21:18:15 1997 Andreas Kupries * ======================= released 1.0b2 ======================= Fri Jan 31 18:43:29 1997 Andreas Kupries * libdes.c: * zlib.c: use library names without path, use OS facilities for searching (LD_LIBRARY_PATH, et.al). * tools/ldAout.tcl: search for symbols did not account for capitals. Found after building libz.a without zsymbols.c * digest.c: had unsigned <-> signed comparison. Thu Jan 30 22:32:45 1997 Andreas Kupries * compat/tclLoadShl.c (dlopen): improved error messaging for HP-UX upon failed loads. * Makefile.in: removed superfl. targets for 'zsymbols.o' and 'ld_sysmbols.o'. * configure.in: use default (/usr/local) for prefix instead of NONE. * got patch from Jan fixing some minor things. see above ^. Sun Jan 26 21:18:56 1997 Andreas Kupries * binio.c (FLIP (in ReorderBytes)): corrected wrong indexing in first assignment. (UnpackCmd): added format-length and 0-padding to hex conversions (%x -> %08x, %08lx, %04x). * tests/binio.test: added tests for 'binio'. Mon Jan 20 23:07:01 1997 Andreas Kupries * binio.c (PackCmd, UnpackCmd): use Tcl_GetChannelByteorder to determine wether swapping is required or not. See entry at Jan 13, -> binio.c too. * added *.byteorder patches. These introduce a new channel attribute, the associated byteorder. It can be retrieved directly and via 'fconfigure'. Setting is possible by 'fconfigure' only. This is used by 'binio' to swap word information if required. Wed Jan 15 19:07:12 1997 Andreas Kupries * -- all changes below by Jan Nijtmans. All of Monday, Jan 13 was covered by his patch too. * cipher.c: See Jan 5, (XX). Some remains of same thing. * digest.c (DecodeBuffer, l.674): See below, this time the first argument of 'memcpy'. Cause of (##) ? * registry.c (TrfInput, l. 683): Added () around 'trans->result + toRead', some compiler (which?) choked without. * configure.in (line 261): SHLIB_LD_ALL must be set in all cases. Without it "make libz" and "make libdes" will work on Ultrix, but not on other machines. * zip.c: See Jan 5, (XX). Some remains of same thing, forward declarations forgotten. Tue Jan 14 21:57:19 1997 Andreas Kupries * configure.in (line 259): don't bother with -ltclX.Y if not running under AIX. * INSTALL: updated to reflect new search order. * configure.in: changed search order: sibling directories before paths. But commandline options (-with-tcl...) overide all. * all digests fail on HP A.09.04 (Bus error). Seems to be something in general code (dig_opt / digest). Had no time to study it further, but must be done. (##) * zip.c: See Jan 5, (XX). Some remains of same thing. Mon Jan 13 21:41:33 1997 Andreas Kupries * haval/haval.c: Most of conversion was already done (See Jan 5), with the exception of a single place (haval_tailor). * blowfish/blowfish.c: * blowfish/blowfish.h: * idea/idea.c: * idea/idea.h: * md5/md5.c: * md5/md5.h: * rc4/rc4.c: * rc4/rc4.h: See below. Most files integrated from external sources have this problem. * sha/sha.c: * sha/sha.h: added , _ANSI_ARGS_ () generally to conform to JO's conventions for extension programming. Removed usage of ##-operator too (concatenates token processed by preprocessor). REASON: HP (uname -> 'A.09.04 B') choked on prototypes and the like. * configure.in (AC_PATH_PROG(MAKEDEPEND)): see below (-> depend). (sizeof int, long int): determine type sizes, required by 'binio'. * Makefile.in (BASE_SRC, BASE_OBJ): added 'binio'. (depend): changed 'makedepend' to '@MAKEDEPEND@', let configure determine its location. Use ':' if not found (as for the HP used by my employer). * binio.c: new file and command 'binio'. Based on Jacobs (Jacob.Levvy@eng.sun.com) proposal. Exception: reordering of bytes (see ### BYTEORDER ###). Need a flag to tell me the byteorder associated to the used channels. * ======================= released 1.0b1 ======================= Fri Jan 10 12:48:13 1997 Andreas Kupries * registry.c (TrfInput): fixed error preventing read/gets from stacked channels to work properly (set trans->used to 0, then! used it, argh). * configure.in: Added 8.0, 8.0a1 to search sequences. * doc/INSTALL: * doc/INSTALL.optional: * doc/man.tex: updated dependency information. Mon Jan 6 19:14:20 1997 Andreas Kupries * patches/core7.6.patch, patches/core8.0a1.patch: Added patch files for tcl-core to remove dependency on plus-patches. Sun Jan 5 22:26:46 1997 Andreas Kupries * --> Jan's patch integrated now. * Makefile.in: adapted to changes in 'configure.in'. * configure.in: streamlined handling of Ultrix 4.4 and other Aout systems. External libraries now must have extension '.a'. * compat/tclLoadNone.c: changed to include all global symbols exported by libz and libdes resp. This forces static linkage on systems not supporting dynamic loading. * haval/haval.h: * haval/haval.c: changed header prototypes to _ANSI_ARGS_-notation of Tcl. Changed prototypes to K&R style. * registry.c: * unstack.c: Removed superfluous '&'s. * transform.h.in: const -> CONST * asc85code.c: * b64code.c: * bincode.c: * hexcode.c: * octcode.c: (XX) * uucode.c: * rs_ecc.c: * blockcipher.c: * digest.c: I consistently used 'Trf_WriteProc fun' instead of 'Trf_WriteProc* fun' in declarations and definitions of 'Create(En/De)coder'. Severe case of cut/copy/paste disease. Found by an older compiler under Ultrix 4.1. Fixed now. * Back from christmas holiday. --> Integrate patch send by Jan at Dec 20, 1996. Wed Dec 18 18:46:58 1996 Andreas Kupries * ======================= released 1.0a3 ======================= * PREPARE: change title of MANIFEST. * Makefile.in (distclean): removed MANIFEST from list. Tue Dec 17 17:35:13 1996 Andreas Kupries * transform.h.in: * c_opt.c: * rc4.c: * templates/c_template.c: extended interface analogously to message digests, blockcipher to allow dynamic loading. RC4 does not require this, but later functionality might do. * Makefile.in (depend): added -D___MAKEDEPEND___, see below. * transformInt.h: use ___MAKEDEPEND__ to hide 'zlib.h', 'des.h' during makedepend runs. * tests/sha.test: see below, added expansion of file 'sha.test.vec'. * tests/sha.test.vec: reduced from 1e6 bytes to 1000 bytes. Will be blown up at test time! Should reduce distribution size about 100 K. * doc/INSTALL.optional: new file, instructions and comments related to building shared libraries for ZLIB and LIBDES. --==** Important **==--. * compat/ld_symbols.c: see below, copied and modified. valid for libdes 3.23. * compat/zsymbols.c: new file, contains functionality to enable dyn. loading for a.out (Ultrix). Got from Jan. Valid for zlib 1.0.4. * transformInt.h: HAVE_LIBDES_H -> HAVE_DES_H. * compat/tclLoadNone.c: * compat/_eprintf.c: new files, for systems without dyn. loading, and to avoid problems with gcc and assert. Send in by Jan. * compat/tclLoadAout.c: new version from Jan, had problems on Ultrix due to some unknown symbols. * sha/sha.c (sha_final): removed superfluous '&' (sha_info->data, lines 170, 175, 177). * registry.c (TrfWatch): removed 'return' in void-procedure. Why did 'gcc -Wall' did not complain? Mon Dec 16 18:29:27 1996 Andreas Kupries * des.c: * bc_opt.c: * transformInt.h: * libdes.c: LIBDES will be loaded on demand now. Removed from distribution. * ZLIB removed from distribution, will be loaded if required (commands: adler, crc-zlib, zip). * adler.c: * crc_zlib.c (MD_Check): checkProc searches and loads 'libz'. * sha.c: * md5.c: * crc.c: * haval.c: no checkProc required. * dig_opt.c (checkOptions): Calls 'checkProc' now. * transform.h.in: Extended interface to digests (Trf_MDCheck, checkProc). * zip_opt.c (checkOptions): load libz here. * Makefile.in (zlib): new target to make libz. * configure.in: added code to enable generation of libz as shared library. Sat Dec 14 19:17:56 1996 Andreas Kupries * configure.in: * Makefile.in: Integrated information from patch (*2). New directory 'compat' with dll-loading code for various OS (taken from tcl). * blowfish/blowfish.c (Blowfish_decipher): changed assignments 'Xl = *xl', 'Xr = *xr' to 'Xl.word = *xl', 'Xr.word = *xr'. The assigment to the union was accepted by gcc, but not Ultrix 4.4, cc3.0. * blowfish/bf_tab.h: The '\'s introduced by Jans patch (see *1) got through the Ultrix 4.4, cc3.0 preprocessor and let the compiler bark. Removed now. * blockcipher.c: * bc_util.c: * cipher.c: * blowfish.c * zip.c: see below. * md5.c: * haval.c: * sha.c (MD_Update(Buf), MD_Final): see below. * digest.c: all allocs now cast to the correct type (there were some casts missing, causing ULTRIX 4.4, cc3.0 to barf). * hexcode.c: * octcode.c: * bincode.c: encode uses table-lookup now, no more bitfiddling. Wed Dec 11 20:54:10 1996 Andreas Kupries * zip.c: * rs_ecc.c: Done too. * Got patch from Jan Nijtmans (*2) to load arbitrary dynamic libraries, enabling me to remove 'zlib' and 'libdes' from distribution. Integration defered until all and everything is updated to handle character buffers. * blockcipher.c: Updated to handle character buffers as well. Tue Dec 10 21:22:02 1996 Andreas Kupries * md5.c: * crc.c: * crc_zlib.c: * haval.c: All updated to handle buffers containing more than one character. For speedups see doc/speed/* * sha.c (MD_UpdateBuf): New procedure to handle a buffer of characters. Depending on input-size 'sha' is now ~2-3 times as fast. * digest.c (Encode-, Decodebuffer): New procedures to convert complete buffers. Use a procedure to convert a buffer of characters, if defined by the digest. * registry.c (TransformImmediate): read 4K chunks of characters now, instead one by one. Use a procedure to convert a buffer of characters, if defined by the transformation. Thu Dec 5 20:19:31 1996 Andreas Kupries * ======================= released 1.0a2 ======================= * The last changes reworked the package installation to conform to the new standard set by the core: library and package index go into a subdirectory of the library directory (making it a sibling to tclX.Y). * Makefile.in (EXTENSION): set to Trf, the official name of this extension. (LIB_RUNTIME_DIR): use EXTENSION, VERSION to determine complete path. (install): target 'install-package' removed. (install-lib): install package index too. * got a patch from Jan Nijtmans (*1): - Addition of LIB_RUNTIME_DIR (needed for Solaris, otherwise the custom tclsh cannot find libtrf1.0.so at run-time.) - Changed pkgIndex.tcl such that the library is only loaded when one of the commands are used for the first time (like memchan). - Add a Tcl_StaticPackage() call in tclAppInit.c - blowfish/bf_tab.h needs to be devided into 4 blocks with {}'s around it, otherwise a warning is given (gcc -Wall (aku)). Wed Dec 4 20:18:20 1996 Andreas Kupries * registry.c (TrfWatch): now forwards request to parent too. Tue Dec 3 22:38:05 1996 Andreas Kupries * digest.c: fixed problem regarding to 'XX->dest'. NULL's were not handled. Tripped by new 'TrfClose' in registry.c * tests: These were changed too, to use 'unstack $XX' instead of 'transform remove $XX head'. * registry.c: Twiddled with it the last 2 days to use the simpler Tcl_ReplaceChannel API, as propossed by J.Nijtmans. Now the package again compiles, links and passes all tests. // This is a branch // Wed Oct 16 21:59:39 1996 Andreas Kupries * tools/md: new example for generation and check of message digests. supersedes example 'md5sum'. independent of external script libraries. Tue Oct 15 00:06:20 1996 Andreas Kupries * init.c (Trf_Init): register new digests. * adler32.c: * crc32.c: added message digests algorithm contained in zlib as separate commands. * templates/cvt_template.c: see below. * templates/opt_template.c: fixed errors in template (clientData). * init.c (Trf_Init): register compressor. * doc/man.tex: added description of "zip"-command, extended chapter containing the references to external copyrights. * zip_opt.c: option processor for compressor. * zip.c: added compressor based on zlib library (authors: Jean-Loup Gailly (gzip@prep.ai.mit.edu) Mark Adler (madler@alumni.caltech.edu)). Mon Oct 7 22:55:44 1996 Andreas Kupries * Module ready for delivery. Starting official log now. trf2.1.4/win/0000755000175000017500000000000012034467745012363 5ustar sergeisergeitrf2.1.4/win/makefile.vc0000644000175000017500000003277111216343142014465 0ustar sergeisergei# ************************************************************************** # Visual C++ 2.x, 4.0, 5.0 and 6.0 makefile for Trf 2.1.4 (MAY-06-2009) # # See the file "doc/license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # CVS: $Id: makefile.vc,v 1.38 2009/05/07 05:30:36 andreas_kupries 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 and other directories. # # ************************************************************************** # # **** Configuration section **** # # ************************************************************************** VERSION = "2.1.4" SHORTVERSION = "21" # ======================================================================= # Specify the root directory of the source distribution of this extension # Don't modify this. ROOT = .. # ======================================================================= # Specify the directory to place the intermediate files into, for example # the object files. The default setting below generates them in place. TMPDIR = . # ======================================================================= # Information about the setup the MS Visual C++ IDE on your system. # If you did not change the default location during the installation the # default values should be right. # ======================================================================= # Name and placement of an important system DLL, the M$ Visual C RunTime MSVCRT = msvcrt.dll MSVCRT_SYS = c:\winnt\system32\msvcrt.dll # ======================================================================= # Paths to the binaries and libraries of the Visual C++ environment. # #TOOLS32 = c:\msdev # VC++ 2.x and 4.x #TOOLS32_rc = c:\msdev TOOLS32 = c:\progra~1\devstu~1\vc # VC++ 5.0 TOOLS32_rc = c:\progra~1\devstu~1\shared~1 #TOOLS32 = c:\progra~1\Microsoft Visual Studio\VC98 # VC++ 6.0 #TOOLS32_rc = c:\progra~1\Microsoft Visual Studio\Common\MSDev98 MS_LIBPATH = $(TOOLS32)\lib # For a german installation use # #TOOLS32 = c:\programme\devstudio\vc #TOOLS32_rc = c:\programme\devstudio\sharedIDE #MS_LIBPATH = c:\programme\devstudio\vc\lib # ======================================================================= # Name and path of a zip-compatible compressor application. Required for # the generation of binary distributions. Ignore it if you don't want to # generate that. PKZIP = pkzip.exe # ======================================================================= # The name of the SSLeay library changed from crypto32.dll to the value # given below. Relevant only for SSLeay 0.9 and opensll 0.9.2b. #SSL_LIBRARY = -DSSL_LIB_NAME=\"libeay32.dll\" # ======================================================================= # Ok, lets talk about TCL. If you did not change the default location # during its installation the default values should be right. The 2nd # definition is for a german installation. # ======================================================================= # Specify the version of tcl you are using, remove all dots from the # number (8.0.3 => 803) TCL_SHORTVERS = 82 # ======================================================================= # Path to the installed include files (or the part of the source # distribution containing them. TCL_INCLUDES = c:\progra~1\tcl\include #TCL_INCLUDES = c:\programme\tcl\include # ======================================================================= # Path to the installed libraries (*.dll and *.lib) or the part of the # source distribution containing them (*after* its compilation). # # *Note* If you installed tcl8.0.3 from the Tcl-Blast! CD you have to # rename tcl80vc.lib in the specified directory to tcl80.lib to get going. # # The installation path should differ from the above only if a source # distribution of tcl is used as the base of the compilation. TCL_LIBRARIES = c:\progra~1\tcl\lib #TCL_LIBRARIES = c:\programme\tcl\lib PKG_INSTALLBASEDIR = $(TCL_LIBRARIES) # ======================================================================= # Path to the installed interpreters or the part of the source # distribution containing them (*after* its compilation). TCL_BINARIES = c:\progra~1\tcl\bin #TCL_BINARIES = c:\programme\tcl\bin # ======================================================================= # Set this to the appropriate value of /MACHINE: for your platform MACHINE = IX86 # ======================================================================= # Comment the following line to compile with symbols NODEBUG=1 # ======================================================================= # uncomment the following line to include the command 'binio'. Not # required for tcl 8.x as the 'binary' command contains the official # functionality. Recommended for tcl 7.6 #BINIO=-DENABLE_BINIO # ======================================================================= # comment the following line if you want to # compile without stub support. STUBS_FLAG=-DUSE_TCL_STUBS # ======================================================================= # comment the following line if you want to # compile without threads support. THREADS_FLAG=-DTCL_THREADS # ======================================================================= # uncomment the following line if you want to link (b)zlib statically. #ZLIB_STATIC = -DZLIB_STATIC_BUILD #BZLIB_STATIC = -DBZLIB_STATIC_BUILD ###################################################################### # Do not modify below this line ###################################################################### # The interpreters. TCLSH = "$(TCL_BINARIES)\tclsh$(TCL_SHORTVERS).exe" TCLLIB = "$(TCL_LIBRARIES)\tclstub$(TCL_SHORTVERS).lib" # Base name of the generated library, full names for DLL and its stub, # and complete installation directory for the package. TRF = trf$(SHORTVERSION) TRFLIB = $(TRF).lib TRF_STUB_LIB_FILE= trfstub$(VERSION).lib TRFDLL = $(TRF).dll INSTALLDIR = $(PKG_INSTALLBASEDIR)\$(TRF) # List of the object files to generate and link. TRFSTUBOBJS = \ $(TMPDIR)\trfStubLib.obj TRFOBJS = \ $(TMPDIR)\dllEntry.obj \ $(TMPDIR)\adler.obj \ $(TMPDIR)\asc85code.obj \ $(TMPDIR)\b64code.obj \ $(TMPDIR)\bincode.obj \ $(TMPDIR)\binio.obj \ $(TMPDIR)\convert.obj \ $(TMPDIR)\crc.obj \ $(TMPDIR)\crc_zlib.obj \ $(TMPDIR)\dig_opt.obj \ $(TMPDIR)\digest.obj \ $(TMPDIR)\haval.obj \ $(TMPDIR)\hexcode.obj \ $(TMPDIR)\init.obj \ $(TMPDIR)\load.obj \ $(TMPDIR)\crypt.obj \ $(TMPDIR)\loadman.obj \ $(TMPDIR)\md5dig.obj \ $(TMPDIR)\md2.obj \ $(TMPDIR)\octcode.obj \ $(TMPDIR)\otpcode.obj \ $(TMPDIR)\otpmd5.obj \ $(TMPDIR)\otpsha1.obj \ $(TMPDIR)\registry.obj \ $(TMPDIR)\rs_ecc.obj \ $(TMPDIR)\sha.obj \ $(TMPDIR)\sha1.obj \ $(TMPDIR)\rmd160.obj \ $(TMPDIR)\rmd128.obj \ $(TMPDIR)\unstack.obj \ $(TMPDIR)\util.obj \ $(TMPDIR)\uucode.obj \ $(TMPDIR)\zip.obj \ $(TMPDIR)\zip_opt.obj \ $(TMPDIR)\zlib.obj \ $(TMPDIR)\bz2.obj \ $(TMPDIR)\bz2_opt.obj \ $(TMPDIR)\bz2lib.obj \ $(TMPDIR)\qpcode.obj \ $(TMPDIR)\reflect.obj \ $(TMPDIR)\ref_opt.obj \ $(TMPDIR)\trfStubInit.obj \ $(TMPDIR)\tclLoadWin.obj # -- possibly not required -- PATH=$(TOOLS32)\bin;$(PATH) # Shorthands for the tools we need from MSVC 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" CP = copy RM = del ###################################################################### # Compiler flags ###################################################################### # Important directories in the distribution WINDIR = $(ROOT)\win GENERICDIR = $(ROOT)\generic # ... and the compiler flags TRF_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(ROOT)" -I"$(TCL_INCLUDES)" TRF_DEFINES = -nologo -D__WIN32__ -DWIN32 -D_WINDOWS -DZLIB_DLL -DTRF_VERSION=\"$(VERSION)\" -DHAVE_STDLIB_H $(BINIO) $(STUBS_FLAG) $(SSL_LIBRARY) -DBUILD_Trf -DBUGS_ON_EXIT $(ZLIB_STATIC) $(BZLIB_STATIC) TRF_CFLAGS = $(cdebug) $(cflags) $(cvarsdll) $(include32) \ $(TRF_INCLUDES) $(TRF_DEFINES) CON_CFLAGS = $(cdebug) $(cflags) $(cvars) $(include32) -DCONSOLE DOS_CFLAGS = $(cdebug) $(cflags) $(include16) -AL ###################################################################### # 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 = "$(MS_LIBPATH)\msvcrt.lib" "$(MS_LIBPATH)\oldnames.lib" !ENDIF baselibs = "$(MS_LIBPATH)\kernel32.lib" $(optlibs) \ "$(MS_LIBPATH)\advapi32.lib" winlibs = $(baselibs) "$(MS_LIBPATH)\user32.lib" "$(MS_LIBPATH)\gdi32.lib" \ "$(MS_LIBPATH)\comdlg32.lib" "$(MS_LIBPATH)\winspool.lib" guilibs = $(libc) $(winlibs) conlibs = $(libc) $(baselibs) guilibsdll = $(libcdll) $(winlibs) conlibsdll = $(libcdll) $(baselibs) ###################################################################### # Compile flags ###################################################################### !IFDEF NODEBUG cdebug = -Ox !ELSE cdebug = -Z7 -Od -WX !ENDIF # declarations common to all compiler options ccommon = -c -W3 -nologo -YX !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 (finally :-) ###################################################################### release: $(TRFDLL) $(TRF_STUB_LIB_FILE) all: $(TRFDLL) $(TRF_STUB_LIB_FILE) test: $(TRFDLL) $(TCLSH) << load $(TRFDLL) cd ../tests source all << install: $(TRFDLL) -@md $(INSTALLDIR) $(CP) $(TRFDLL) $(INSTALLDIR)\$(TRFDLL) $(CP) $(WINDIR)\pkgIndex.tcl $(INSTALLDIR)\pkgIndex.tcl $(TRF_STUB_LIB_FILE): $(TRFSTUBOBJS) $(lib32) /out:$@ $(TRFSTUBOBJS) $(TRFDLL): $(TRFOBJS) $(TMPDIR)\trf.res $(link32) $(ldebug) $(dlllflags) \ $(TCLLIB) $(guilibsdll) \ $(TMPDIR)\trf.res \ -out:$(TRFDLL) \ $(TRFOBJS) bindist: $(TRFDLL) -@md $(TRF) -@md $(TRF)\patches -@md $(TRF)\patches\v7.6 -@md $(TRF)\patches\v8.0 -@md $(TRF)\patches\v8.1b1 -@$(CP) $(TRFDLL) $(TRF)\$(TRFDLL) -@$(CP) $(WINDIR)\pkgIndex.tcl $(TRF)\pkgIndex.tcl -@$(CP) $(WINDIR)\README.VC $(TRF)\README.VC -@$(CP) $(MSVCRT_SYS) $(TRF)\$(MSVCRT) -@$(CP) $(ROOT)\patches\v7.6\byteorder.patch $(TRF)\patches\v7.6 -@$(CP) $(ROOT)\patches\v7.6\standard.patch $(TRF)\patches\v7.6 -@$(CP) $(ROOT)\patches\v7.6\tcl.h $(TRF)\patches\v7.6 -@$(CP) $(ROOT)\patches\v7.6\tclIO.c $(TRF)\patches\v7.6 -@$(CP) $(ROOT)\patches\v7.6p2\byteorder.patch $(TRF)\patches\v7.6p2 -@$(CP) $(ROOT)\patches\v7.6p2\standard.patch $(TRF)\patches\v7.6p2 -@$(CP) $(ROOT)\patches\v7.6p2\tcl.h $(TRF)\patches\v7.6p2 -@$(CP) $(ROOT)\patches\v7.6p2\tclIO.c $(TRF)\patches\v7.6p2 -@$(CP) $(ROOT)\patches\v8.0\byteorder.patch $(TRF)\patches\v8.0 -@$(CP) $(ROOT)\patches\v8.0\standard.patch $(TRF)\patches\v8.0 -@$(CP) $(ROOT)\patches\v8.0\tcl.h $(TRF)\patches\v8.0 -@$(CP) $(ROOT)\patches\v8.0\tclIO.c $(TRF)\patches\v8.0 -@$(CP) $(ROOT)\patches\v8.1b1\byteorder.patch $(TRF)\patches\v8.1b1 -@$(CP) $(ROOT)\patches\v8.1b1\standard.patch $(TRF)\patches\v8.1b1 -@$(CP) $(ROOT)\patches\v8.1b1\tcl.h $(TRF)\patches\v8.1b1 -@$(CP) $(ROOT)\patches\v8.1b1\tclIO.c $(TRF)\patches\v8.1b1 $(PKZIP) -r $(TRF)-win32.zip $(TRF)\*.* -@$(RM) $(TRF)\$(TRFDLL) -@$(RM) $(TRF)\pkgIndex.tcl -@$(RM) $(TRF)\README.VC -@$(RM) $(TRF)\$(MSVCRT) -@$(RM) $(TRF)\patches\v7.6\byteorder.patch -@$(RM) $(TRF)\patches\v7.6\standard.patch -@$(RM) $(TRF)\patches\v7.6\tcl.h -@$(RM) $(TRF)\patches\v7.6\tclIO.c -@rd $(TRF)\patches\v7.6 -@$(RM) $(TRF)\patches\v7.6p2\byteorder.patch -@$(RM) $(TRF)\patches\v7.6p2\standard.patch -@$(RM) $(TRF)\patches\v7.6p2\tcl.h -@$(RM) $(TRF)\patches\v7.6p2\tclIO.c -@rd $(TRF)\patches\v7.6p2 -@$(RM) $(TRF)\patches\v8.0\byteorder.patch -@$(RM) $(TRF)\patches\v8.0\standard.patch -@$(RM) $(TRF)\patches\v8.0\tcl.h -@$(RM) $(TRF)\patches\v8.0\tclIO.c -@rd $(TRF)\patches\v8.0 -@$(RM) $(TRF)\patches\v8.1b1\byteorder.patch -@$(RM) $(TRF)\patches\v8.1b1\standard.patch -@$(RM) $(TRF)\patches\v8.1b1\tcl.h -@$(RM) $(TRF)\patches\v8.1b1\tclIO.c -@rd $(TRF)\patches\v8.1b1 -@rd $(TRF)\patches -@rd $(TRF) # # Implicit rules # {$(WINDIR)}.c{$(TMPDIR)}.obj: $(cc32) $(TRF_CFLAGS) -Fo$(TMPDIR)\ $< {$(GENERICDIR)}.c{$(TMPDIR)}.obj: $(cc32) $(TRF_CFLAGS) -Fo$(TMPDIR)\ $< {$(ROOT)\compat}.c{$(TMPDIR)}.obj: $(cc32) $(TRF_CFLAGS) -Fo$(TMPDIR)\ $< {$(WINDIR)}.rc{$(TMPDIR)}.res: $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(WINDIR)" -D__WIN32__ \ $< clean: -@del *.exp -@del *.lib -@del *.dll -@del *.pch -@del $(TMPDIR)\*.obj trf2.1.4/win/trf.ico0000644000175000017500000000256611216343142013644 0ustar sergeisergei è6( 0F( @€€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿ™—yvwfffgvw™™™•a—ffffgf™™™™™™™–fffqVfav ™™™•y—ff™™™—f`™™™™™vffi™™™‰vw™™™™™vf¹™“˜™¶fd™wwfg™™™˜™–a™)•vfa™™™˜™–gwR™!™™ve™™•wI–fe!‘ffg™™„†H–i‘" ‘wf™˜t„Evfv"!™ ™vfi™T„WfW"™™ –ævfD„ffq ™™ •™vfffffw™™ ™—ægffF ™™™ ™—yvxa† ‘!™™™ ™™™fx†q)™™™ ™™™™ŸD†E")™™™ ™™™™™TWDy— ™™™ ™™™™™TGD ™™™ ™™™™™tDDGa™™™ ™™™™™„DDEp!™™™ ™™™˜™†DE@a`™™™™™™™˜™˜DE™™ ‰™™™™™Ÿ™™„DI& ‰™™™™™˜‰™˜dD#‘` ™™™™™™ù™™ˆˆ™g ™™™™‰ˆ™™™‰™'‘f™™™™ù˜÷™™™™qf™™™™™™w™™™™™‘#™™™™™™™™™™™™™ ™™™™™™™Á€€€€€€€€€€€€øÿ( À€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿ™wffwy™—™ve‘vA™—•f9™—g™‘Wf™——a—f™wWa•vWFw!‘vgggr™—ffG™™™XGA™™™™EA™™™™dFr™™™ytA™™y—Å"™™x™‡‘2™™y‰™™"™™™™™( @€ÿÿÿ?ŸÁmÿ°=Wñîý'Î|ý?¾³}}_cÿ}XÛ>ù_NòŸO?jß|7ZXsª¿ËŸÀs»£ñû»·nÍ{¶þÿ{¸þþû¿þû¿ïþû¿ïþû¿ïÿ}¿ïÿ}¿oÿ}wÿ½{ÿÝ=ýå¾óùŸ+~ÏÜÿÿþßÿøøåtrf2.1.4/win/Makefile.cross0000644000175000017500000003116511216344446015152 0ustar sergeisergei #---------------------------------------------------------------- # This file is a Makefile for Trf 2.1.4 (as of MAY-06-2009), usable for CygWin B20.1 # Donated by Jan Nijtmans # And modified by myself (Andreas Kupries ) # for usage with a cross-compiler producing windows binaries on # unix. This required to change/touch some Windowisms. #---------------------------------------------------------------- EXTENSION = Trf VERSION = 2.1.4 TCL_VERSION = 84 TCL_SRC_TOP_DIR = ../../tcl TCL_INSTALL_TOP_DIR = `pwd`/../install DEL = rm -f CROSSPFX = /usr/local/cross-tools/bin/i386-mingw32msvc- TRF_DLL_FILE = ${EXTENSION}21.dll TRF_LIB_FILE = lib${EXTENSION}21.a TRF_STATIC_LIB_FILE = lib${EXTENSION}21s.a TRF_STUB_LIB_FILE = lib${EXTENSION}stub21.a SSL_LIBRARY = -DSSL_LIB_NAME=\"libeay32.dll\" BZ2_LIBRARY = -DBZ2_LIB_NAME=\"bz2.dll\" #ZLIB_STATIC = -DZLIB_STATIC_BUILD #BZLIB_STATIC = -DBZLIB_STATIC_BUILD # #---------------------------------------------------------------- # Things you can change to personalize the Makefile for your own # site (you can make these changes in either Makefile.in or # Makefile, but changes to Makefile will get lost if you re-run # the configuration script). #---------------------------------------------------------------- # Directory in which the source of this extension can be found srcdir = . TMPDIR = . # Directories in which the Tcl core can be found TCL_INC_DIR = $(TCL_SRC_TOP_DIR)/generic TCL_INCP_DIR = $(TCL_SRC_TOP_DIR)/win TCL_LIB_DIR = $(TCL_SRC_TOP_DIR)/win TCL_LIB_SPEC = $(TCL_SRC_TOP_DIR)/win/libtclstub$(TCL_VERSION).a # Libraries to be included with trf.dll TCL_SHARED_LIBS = # Default top-level directories in which to install architecture- # specific files (exec_prefix) and machine-independent files such # as scripts (prefix). The values specified here may be overridden # at configure-time with the --exec-prefix and --prefix options # to the "configure" script. prefix = $(TCL_INSTALL_TOP_DIR) exec_prefix = $(prefix) # Directory containing scripts supporting the work of this makefile tool = $(srcdir)/tools # The following definition can be set to non-null for special systems # like AFS with replication. It allows the pathnames used for installation # to be different than those used for actually reference files at # run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix # when installing files. INSTALL_ROOT = # Directory where trf.dll is at run-time: LIB_RUNTIME_DIR = $(exec_prefix)/lib/$(EXTENSION)$(VERSION) # Directory in which to install the archive trf.dll: LIB_INSTALL_DIR = $(INSTALL_ROOT)$(LIB_RUNTIME_DIR) # Directory in which to install the extended shell tclsh: BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin # Directory in which to install the include file transform.h: INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include # Top-level directory in which to install manual entries: MAN_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/man # To change the compiler switches, for example to change from -O # to -g, change the following line: CFLAGS = -O2 -fnative-struct -mno-cygwin -DNDEBUG -DUSE_TCL_STUBS -D__WIN32__ -DWIN32 -D_WINDOWS -DZLIB_DLL -DTCL_THREADS -DHAVE_STDLIB_H # To disable ANSI-C procedure prototypes reverse the comment characters # on the following lines: PROTO_FLAGS = #PROTO_FLAGS = -DNO_PROTOTYPE # 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 # 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 # "install" around; better to use the install-sh script that comes # with the distribution, which is slower but guaranteed to work. INSTALL = $(tool)/install-sh -c # The symbols below provide support for dynamic loading and shared # libraries. 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. The second definition should be used # in conjunction with Tcl 8.1. TRF_SHLIB_CFLAGS = #TRF_SHLIB_CFLAGS = -DTCL_USE_STUBS # The symbol below provides support for dynamic loading and shared # libraries. See configure.in for a description of what it means. # The values of the symbolis normally set by the configure script. SHLIB_LD = # Libraries to use when linking: must include at least the dynamic # loading library and the math library (in that order). This # definition is determined by the configure script. ALL_LIBS = $(TCL_LIB) LIBS = #---------------------------------------------------------------- # 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. #---------------------------------------------------------------- INSTALL_PROGRAM = $(INSTALL) -m 744 INSTALL_DATA = $(INSTALL) -m 644 INSTALL_SHLIB = $(INSTALL) -m 555 RANLIB = ranlib SHLIB_SUFFIX = .dll #---------------------------------------------------------------- # 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 = $(CROSSPFX)gcc AS = $(CROSSPFX)as LD = $(CROSSPFX)ld DLLTOOL = $(CROSSPFX)dlltool DLLWRAP = $(CROSSPFX)dllwrap -mnocygwin WINDRES = $(CROSSPFX)windres DLL_LDFLAGS = -mwindows -Wl,-e,_DllMain@12 DLL_LDLIBS = -L$(TCL_LIB_DIR) -ltclstub$(TCL_VERSION) baselibs = -lkernel32 $(optlibs) -ladvapi32 winlibs = $(baselibs) -luser32 -lgdi32 -lcomdlg32 -lwinspool guilibs = $(libc) $(winlibs) guilibsdll = $(libcdll) $(winlibs) TRF_DEFINES = -D__WIN32__ -DSTATIC_BUILD ${TRF_SHLIB_CFLAGS} -DTRF_VERSION="\"${VERSION}\"" ${SSL_LIBRARY} ${ZLIB_STATIC} ${BZLIB_STATIC} -DBUGS_ON_EXIT # $(TCL_CC_SWITCHES) INCLUDES = -I. -I$(srcdir) -I../generic -I$(TCL_INC_DIR) -I$(TCL_INCP_DIR) DEFINES = $(PROTO_FLAGS) $(MEM_DEBUG_FLAGS) $(TRF_SHLIB_CFLAGS) \ $(TRF_DEFINES) CC_SWITCHES = $(CFLAGS) $(DEFINES) $(INCLUDES) # fundamentals of this library SOURCES = ../generic/adler.c \ ../generic/asc85code.c \ ../generic/b64code.c \ ../generic/bincode.c \ ../generic/binio.c \ ../generic/convert.c \ ../generic/crc.c \ ../generic/crc_zlib.c \ ../generic/dig_opt.c \ ../generic/digest.c \ ../generic/haval.c \ ../generic/hexcode.c \ ../generic/init.c \ ../generic/load.c \ ../generic/crypt.c \ ../generic/loadman.c \ ../generic/md2.c \ ../generic/md5dig.c \ ../generic/octcode.c \ ../generic/otpcode.c \ ../generic/otpmd5.c \ ../generic/otpsha1.c \ ../generic/registry.c \ ../generic/rs_ecc.c \ ../generic/sha.c \ ../generic/sha1.c \ ../generic/rmd160.c \ ../generic/rmd128.c \ ../generic/unstack.c \ ../generic/util.c \ ../generic/uucode.c \ ../generic/zip.c \ ../generic/zip_opt.c \ ../generic/zlib.c \ ../generic/bz2.c \ ../generic/bz2_opt.c \ ../generic/bz2lib.c \ ../generic/qpcode.c \ ../generic/reflect.c \ ../generic/ref_opt.c \ ../generic/trfStubInit.c \ ../compat/tclLoadWin.c OBJECTS = adler.o \ asc85code.o \ b64code.o \ bincode.o \ binio.o \ convert.o \ crc.o \ crc_zlib.o \ dig_opt.o \ digest.o \ haval.o \ hexcode.o \ init.o \ load.o \ crypt.o \ loadman.o \ md2.o \ md5dig.o \ octcode.o \ otpcode.o \ otpmd5.o \ otpsha1.o \ registry.o \ rs_ecc.o \ sha.o \ sha1.o \ rmd160.o \ rmd128.o \ unstack.o \ util.o \ uucode.o \ zip.o \ zip_opt.o \ zlib.o \ bz2.o \ bz2_opt.o \ bz2lib.o \ qpcode.o \ reflect.o \ ref_opt.o \ trfStubInit.o \ tclLoadWin.o #-------------------------------------------------------# default: $(TRF_DLL_FILE) $(TRF_LIB_FILE) $(TRF_STUB_LIB_FILE) all: default test: $(TRF_DLL_FILE) wish${TK_VERSION} demo.tcl #-------------------------------------------------------# trfStubLib.o: ../generic/trfStubLib.c $(CC) -c $(CC_SWITCHES) ../generic/trfStubLib.c -o $@ trfStubInit.o: ../generic/trfStubInit.c $(CC) -c $(CC_SWITCHES) ../generic/trfStubInit.c -o $@ adler.o: ../generic/adler.c $(CC) -c $(CC_SWITCHES) ../generic/adler.c -o $@ asc85code.o: ../generic/asc85code.c $(CC) -c $(CC_SWITCHES) ../generic/asc85code.c -o $@ b64code.o: ../generic/b64code.c $(CC) -c $(CC_SWITCHES) ../generic/b64code.c -o $@ bincode.o: ../generic/bincode.c $(CC) -c $(CC_SWITCHES) ../generic/bincode.c -o $@ binio.o: ../generic/binio.c $(CC) -c $(CC_SWITCHES) ../generic/binio.c -o $@ convert.o: ../generic/convert.c $(CC) -c $(CC_SWITCHES) ../generic/convert.c -o $@ crc.o: ../generic/crc.c $(CC) -c $(CC_SWITCHES) ../generic/crc.c -o $@ crc_zlib.o: ../generic/crc_zlib.c $(CC) -c $(CC_SWITCHES) ../generic/crc_zlib.c -o $@ dig_opt.o: ../generic/dig_opt.c $(CC) -c $(CC_SWITCHES) ../generic/dig_opt.c -o $@ digest.o: ../generic/digest.c $(CC) -c $(CC_SWITCHES) ../generic/digest.c -o $@ haval.o: ../generic/haval.c $(CC) -c $(CC_SWITCHES) ../generic/haval.c -o $@ hexcode.o: ../generic/hexcode.c $(CC) -c $(CC_SWITCHES) ../generic/hexcode.c -o $@ init.o: ../generic/init.c $(CC) -c $(CC_SWITCHES) ../generic/init.c -o $@ load.o: ../generic/load.c $(CC) -c $(CC_SWITCHES) ../generic/load.c -o $@ crypt.o: ../generic/crypt.c $(CC) -c $(CC_SWITCHES) ../generic/crypt.c -o $@ loadman.o: ../generic/loadman.c $(CC) -c $(CC_SWITCHES) ../generic/loadman.c -o $@ md5dig.o: ../generic/md5dig.c $(CC) -c $(CC_SWITCHES) ../generic/md5dig.c -o $@ md2.o: ../generic/md2.c $(CC) -c $(CC_SWITCHES) ../generic/md2.c -o $@ octcode.o: ../generic/octcode.c $(CC) -c $(CC_SWITCHES) ../generic/octcode.c -o $@ otpcode.o: ../generic/otpcode.c $(CC) -c $(CC_SWITCHES) ../generic/otpcode.c -o $@ otpmd5.o: ../generic/otpmd5.c $(CC) -c $(CC_SWITCHES) ../generic/otpmd5.c -o $@ otpsha1.o: ../generic/otpsha1.c $(CC) -c $(CC_SWITCHES) ../generic/otpsha1.c -o $@ registry.o: ../generic/registry.c $(CC) -c $(CC_SWITCHES) ../generic/registry.c -o $@ rs_ecc.o: ../generic/rs_ecc.c $(CC) -c $(CC_SWITCHES) ../generic/rs_ecc.c -o $@ sha.o: ../generic/sha.c $(CC) -c $(CC_SWITCHES) ../generic/sha.c -o $@ sha1.o: ../generic/sha1.c $(CC) -c $(CC_SWITCHES) ../generic/sha1.c -o $@ rmd160.o: ../generic/rmd160.c $(CC) -c $(CC_SWITCHES) ../generic/rmd160.c -o $@ rmd128.o: ../generic/rmd128.c $(CC) -c $(CC_SWITCHES) ../generic/rmd128.c -o $@ unstack.o: ../generic/unstack.c $(CC) -c $(CC_SWITCHES) ../generic/unstack.c -o $@ util.o: ../generic/util.c $(CC) -c $(CC_SWITCHES) ../generic/util.c -o $@ uucode.o: ../generic/uucode.c $(CC) -c $(CC_SWITCHES) ../generic/uucode.c -o $@ zip.o: ../generic/zip.c $(CC) -c $(CC_SWITCHES) ../generic/zip.c -o $@ zip_opt.o: ../generic/zip_opt.c $(CC) -c $(CC_SWITCHES) ../generic/zip_opt.c -o $@ zlib.o: ../generic/zlib.c $(CC) -c $(CC_SWITCHES) ../generic/zlib.c -o $@ bz2.o: ../generic/zip.c $(CC) -c $(CC_SWITCHES) ../generic/bz2.c -o $@ bz2_opt.o: ../generic/zip_opt.c $(CC) -c $(CC_SWITCHES) ../generic/bz2_opt.c -o $@ bz2lib.o: ../generic/zlib.c $(CC) -c $(CC_SWITCHES) ../generic/bz2lib.c -o $@ qpcode.o: ../generic/qpcode.c $(CC) -c $(CC_SWITCHES) ../generic/qpcode.c -o $@ reflect.o: ../generic/reflect.c $(CC) -c $(CC_SWITCHES) ../generic/reflect.c -o $@ ref_opt.o: ../generic/ref_opt.c $(CC) -c $(CC_SWITCHES) ../generic/ref_opt.c -o $@ tclLoadWin.o: ../compat/tclLoadWin.c $(CC) -c $(CC_SWITCHES) ../compat/tclLoadWin.c -o $@ dllEntry.o: dllEntry.c $(CC) -c $(CC_SWITCHES) dllEntry.c -o $@ #-------------------------------------------------------# $(TRF_DLL_FILE): $(OBJECTS) trfres.o dllEntry.o trf.def $(DLLWRAP) -s $(DLL_LDFLAGS) -mno-cygwin -o $@ $(OBJECTS) \ trfres.o dllEntry.o --def trf.def \ $(DLL_LDLIBS) $(TRF_LIB_FILE): trf.def $(TRF_DLL_FILE) $(DLLTOOL) --as=$(AS) --dllname $(TRF_DLL_FILE) \ --def trf.def --output-lib $@ $(TRF_STATIC_LIB_FILE): $(OBJECTS) $(AR) cr $@ $(OBJECTS) $(TRF_STUB_LIB_FILE): trfStubLib.o $(AR) cr $@ trfStubLib.o trf.def: $(OBJECTS) $(DLLTOOL) --export-all --exclude-symbols DllMain@12 --output-def $@ $(OBJECTS) trfres.o: trf.rc $(WINDRES) --include . --define VS_VERSION_INFO=1 trf.rc trfres.o #-------------------------------------------------------# clean: $(DEL) $(OBJECTS) $(TRF_DLL_FILE) $(DEL) TAGS depend *~ */*~ core* tests/core* so_locations lib*.so* lib*.a trf.def distclean: clean $(DEL) config.* $(DEL) Makefile #-------------------------------------------------------# # DO NOT DELETE THIS LINE -- make depend depends on it. trf2.1.4/win/makefile.vc50000644000175000017500000003222111216343142014540 0ustar sergeisergei# ************************************************************************** # Visual C++ 2.x and 4.0 makefile for Trf 2.1.4 (MAY-06-2009) # # See the file "doc/license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # CVS: $Id: makefile.vc5,v 1.19 2009/05/07 05:30:36 andreas_kupries 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 and other directories. # # ************************************************************************** # # **** Configuration section **** # # ************************************************************************** VERSION = "2.1.4" SHORTVERSION = "21" # ======================================================================= # Specify the root directory of the source distribution of this extension # Don't modify this. ROOT = .. # ======================================================================= # Specify the directory to place the intermediate files into, for example # the object files. The default setting below generates them in place. TMPDIR = . # ======================================================================= # Information about the setup the MS Visual C++ IDE on your system. # If you did not change the default location during the installation the # default values should be right. # ======================================================================= # Name and placement of an important system DLL, the M$ Visual C RunTime MSVCRT = msvcrt.dll MSVCRT_SYS = c:\winnt\system32\msvcrt.dll # ======================================================================= # Paths to the binaries and libraries of the Visual C++ environment. Since # VC 5.x it is split over two directories :-(. # TOOLS32 = c:\progra~1\devstudio\vc TOOLS32_rc = c:\progra~1\devstudio\sharedIDE MS_LIBPATH = c:\progra~1\devstudio\vc\lib # For a german installation use # #TOOLS32 = c:\programme\devstudio\vc #TOOLS32_rc = c:\programme\devstudio\sharedIDE #MS_LIBPATH = c:\programme\devstudio\vc\lib # ======================================================================= # Name and path of a zip-compatible compressor application. Required for # the generation of binary distributions. Ignore it if you don't want to # generate that. PKZIP = pkzip.exe # ======================================================================= # The name of the SSLeay library changed from crypto32.dll to the value # given below. Relevant only for SSLeay 0.9 and opensll 0.9.2b. #SSL_LIBRARY = -DSSL_LIB_NAME=\"libeay32.dll\" # ======================================================================= # Ok, lets talk about TCL. If you did not change the default location # during its installation the default values should be right. The 2nd # definition is for a german installation. # ======================================================================= # Specify the version of tcl you are using, remove all dots from the # number (8.0.3 => 803) TCL_SHORTVERS = 82 # ======================================================================= # Path to the installed include files (or the part of the source # distribution containing them. TCL_INCLUDES = c:\progra~1\tcl\include #TCL_INCLUDES = c:\programme\tcl\include # ======================================================================= # Path to the installed libraries (*.dll and *.lib) or the part of the # source distribution containing them (*after* its compilation). # # *Note* If you installed tcl8.0.3 from the Tcl-Blast! CD you have to # rename tcl80vc.lib in the specified directory to tcl80.lib to get going. # # The installation path should differ from the above only if a source # distribution of tcl is used as the base of the compilation. TCL_LIBRARIES = c:\progra~1\tcl\lib #TCL_LIBRARIES = c:\programme\tcl\lib PKG_INSTALLBASEDIR = $(TCL_LIBRARIES) # ======================================================================= # Path to the installed interpreters or the part of the source # distribution containing them (*after* its compilation). TCL_BINARIES = c:\progra~1\tcl\bin #TCL_BINARIES = c:\programme\tcl\bin # ======================================================================= # Set this to the appropriate value of /MACHINE: for your platform MACHINE = IX86 # ======================================================================= # Comment the following line to compile with symbols NODEBUG=1 # ======================================================================= # uncomment the following line to include the command 'binio'. Not # required for tcl 8.x as the 'binary' command contains the official # functionality. Recommended for tcl 7.6 #BINIO=-DENABLE_BINIO # ======================================================================= # uncomment the following line if you want to # compile with stub support. STUBS_FLAG=-DUSE_TCL_STUBS # ======================================================================= # uncomment the following line if you want to link (b)zlib statically. #ZLIB_STATIC = -DZLIB_STATIC_BUILD #BZLIB_STATIC = -DBZLIB_STATIC_BUILD ###################################################################### # Do not modify below this line ###################################################################### # The interpreters. TCLSH = "$(TCL_BINARIES)\tclsh$(TCL_SHORTVERS).exe" TCLLIB = "$(TCL_LIBRARIES)\tclstub$(TCL_SHORTVERS).lib" # Base name of the generated library, full names for DLL and its stub, # and complete installation directory for the package. TRF = trf$(SHORTVERSION) TRFLIB = $(TRF)$(TCL_SHORTVERS).lib TRF_STUB_LIB_FILE= $(TRF)stub$(TCL_SHORTVERS).lib TRFDLL = $(TRF).dll INSTALLDIR = $(PKG_INSTALLBASEDIR)\$(TRF) # List of the object files to generate and link. TRFSTUBOBJS = \ $(TMPDIR)\trfStubLib.obj TRFOBJS = \ $(TMPDIR)\dllEntry.obj \ $(TMPDIR)\adler.obj \ $(TMPDIR)\asc85code.obj \ $(TMPDIR)\b64code.obj \ $(TMPDIR)\bincode.obj \ $(TMPDIR)\binio.obj \ $(TMPDIR)\convert.obj \ $(TMPDIR)\crc.obj \ $(TMPDIR)\crc_zlib.obj \ $(TMPDIR)\dig_opt.obj \ $(TMPDIR)\digest.obj \ $(TMPDIR)\haval.obj \ $(TMPDIR)\hexcode.obj \ $(TMPDIR)\init.obj \ $(TMPDIR)\load.obj \ $(TMPDIR)\crypt.obj \ $(TMPDIR)\loadman.obj \ $(TMPDIR)\md5dig.obj \ $(TMPDIR)\md2.obj \ $(TMPDIR)\octcode.obj \ $(TMPDIR)\otpcode.obj \ $(TMPDIR)\otpmd5.obj \ $(TMPDIR)\otpsha1.obj \ $(TMPDIR)\registry.obj \ $(TMPDIR)\rs_ecc.obj \ $(TMPDIR)\sha.obj \ $(TMPDIR)\sha1.obj \ $(TMPDIR)\rmd160.obj \ $(TMPDIR)\rmd128.obj \ $(TMPDIR)\unstack.obj \ $(TMPDIR)\util.obj \ $(TMPDIR)\uucode.obj \ $(TMPDIR)\zip.obj \ $(TMPDIR)\zip_opt.obj \ $(TMPDIR)\zlib.obj \ $(TMPDIR)\bz2.obj \ $(TMPDIR)\bz2_opt.obj \ $(TMPDIR)\bz2lib.obj \ $(TMPDIR)\qpcode.obj \ $(TMPDIR)\reflect.obj \ $(TMPDIR)\ref_opt.obj \ $(TMPDIR)\trfStubInit.obj \ $(TMPDIR)\tclLoadWin.obj # -- possibly not required -- PATH=$(TOOLS32)\bin;$(PATH) # Shorthands for the tools we need from MSVC 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" CP = copy RM = del ###################################################################### # Compiler flags ###################################################################### # Important directories in the distribution WINDIR = $(ROOT)\win GENERICDIR = $(ROOT)\generic # ... and the compiler flags TRF_INCLUDES = -I$(WINDIR) -I$(GENERICDIR) -I$(ROOT) -I$(TCL_INCLUDES) TRF_DEFINES = -nologo -D__WIN32__ -DWIN32 -D_WINDOWS -DZLIB_DLL -DTRF_VERSION=\"$(VERSION)\" -DHAVE_STDLIB_H $(BINIO) $(STUBS_FLAG) $(SSL_LIBRARY) -DBUILD_Trf -DBUGS_ON_EXIT $(ZLIB_STATIC) $(BZLIB_STATIC) TRF_CFLAGS = $(cdebug) $(cflags) $(cvarsdll) $(include32) \ $(TRF_INCLUDES) $(TRF_DEFINES) CON_CFLAGS = $(cdebug) $(cflags) $(cvars) $(include32) -DCONSOLE DOS_CFLAGS = $(cdebug) $(cflags) $(include16) -AL ###################################################################### # 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 = "$(MS_LIBPATH)\msvcrt.lib" "$(MS_LIBPATH)\oldnames.lib" !ENDIF baselibs = "$(MS_LIBPATH)\kernel32.lib" $(optlibs) \ "$(MS_LIBPATH)\advapi32.lib" winlibs = $(baselibs) "$(MS_LIBPATH)\user32.lib" "$(MS_LIBPATH)\gdi32.lib" \ "$(MS_LIBPATH)\comdlg32.lib" "$(MS_LIBPATH)\winspool.lib" guilibs = $(libc) $(winlibs) conlibs = $(libc) $(baselibs) guilibsdll = $(libcdll) $(winlibs) conlibsdll = $(libcdll) $(baselibs) ###################################################################### # Compile flags ###################################################################### !IFDEF NODEBUG cdebug = -Ox !ELSE cdebug = -Z7 -Od -WX !ENDIF # declarations common to all compiler options ccommon = -c -W3 -nologo -YX !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 (finally :-) ###################################################################### release: $(TRFDLL) $(TRF_STUB_LIB_FILE) all: $(TRFDLL) $(TRF_STUB_LIB_FILE) test: $(TRFDLL) $(TCLSH) << load $(TRFDLL) cd ../tests source all << install: $(TRFDLL) -@md $(INSTALLDIR) $(CP) $(TRFDLL) $(INSTALLDIR)\$(TRFDLL) $(CP) $(WINDIR)\pkgIndex.tcl $(INSTALLDIR)\pkgIndex.tcl $(TRF_STUB_LIB_FILE): $(TRFSTUBOBJS) $(lib32) /out:$@ $(TRFSTUBOBJS) $(TRFDLL): $(TRFOBJS) $(TMPDIR)\trf.res $(link32) $(ldebug) $(dlllflags) \ $(TCLLIB) $(guilibsdll) \ $(TMPDIR)\trf.res \ -out:$(TRFDLL) \ $(TRFOBJS) bindist: $(TRFDLL) -@md $(TRF) -@md $(TRF)\patches -@md $(TRF)\patches\v7.6 -@md $(TRF)\patches\v8.0 -@md $(TRF)\patches\v8.1b1 -@$(CP) $(TRFDLL) $(TRF)\$(TRFDLL) -@$(CP) $(WINDIR)\pkgIndex.tcl $(TRF)\pkgIndex.tcl -@$(CP) $(WINDIR)\README.VC $(TRF)\README.VC -@$(CP) $(MSVCRT_SYS) $(TRF)\$(MSVCRT) -@$(CP) $(ROOT)\patches\v7.6\byteorder.patch $(TRF)\patches\v7.6 -@$(CP) $(ROOT)\patches\v7.6\standard.patch $(TRF)\patches\v7.6 -@$(CP) $(ROOT)\patches\v7.6\tcl.h $(TRF)\patches\v7.6 -@$(CP) $(ROOT)\patches\v7.6\tclIO.c $(TRF)\patches\v7.6 -@$(CP) $(ROOT)\patches\v7.6p2\byteorder.patch $(TRF)\patches\v7.6p2 -@$(CP) $(ROOT)\patches\v7.6p2\standard.patch $(TRF)\patches\v7.6p2 -@$(CP) $(ROOT)\patches\v7.6p2\tcl.h $(TRF)\patches\v7.6p2 -@$(CP) $(ROOT)\patches\v7.6p2\tclIO.c $(TRF)\patches\v7.6p2 -@$(CP) $(ROOT)\patches\v8.0\byteorder.patch $(TRF)\patches\v8.0 -@$(CP) $(ROOT)\patches\v8.0\standard.patch $(TRF)\patches\v8.0 -@$(CP) $(ROOT)\patches\v8.0\tcl.h $(TRF)\patches\v8.0 -@$(CP) $(ROOT)\patches\v8.0\tclIO.c $(TRF)\patches\v8.0 -@$(CP) $(ROOT)\patches\v8.1b1\byteorder.patch $(TRF)\patches\v8.1b1 -@$(CP) $(ROOT)\patches\v8.1b1\standard.patch $(TRF)\patches\v8.1b1 -@$(CP) $(ROOT)\patches\v8.1b1\tcl.h $(TRF)\patches\v8.1b1 -@$(CP) $(ROOT)\patches\v8.1b1\tclIO.c $(TRF)\patches\v8.1b1 $(PKZIP) -r $(TRF)-win32.zip $(TRF)\*.* -@$(RM) $(TRF)\$(TRFDLL) -@$(RM) $(TRF)\pkgIndex.tcl -@$(RM) $(TRF)\README.VC -@$(RM) $(TRF)\$(MSVCRT) -@$(RM) $(TRF)\patches\v7.6\byteorder.patch -@$(RM) $(TRF)\patches\v7.6\standard.patch -@$(RM) $(TRF)\patches\v7.6\tcl.h -@$(RM) $(TRF)\patches\v7.6\tclIO.c -@rd $(TRF)\patches\v7.6 -@$(RM) $(TRF)\patches\v7.6p2\byteorder.patch -@$(RM) $(TRF)\patches\v7.6p2\standard.patch -@$(RM) $(TRF)\patches\v7.6p2\tcl.h -@$(RM) $(TRF)\patches\v7.6p2\tclIO.c -@rd $(TRF)\patches\v7.6p2 -@$(RM) $(TRF)\patches\v8.0\byteorder.patch -@$(RM) $(TRF)\patches\v8.0\standard.patch -@$(RM) $(TRF)\patches\v8.0\tcl.h -@$(RM) $(TRF)\patches\v8.0\tclIO.c -@rd $(TRF)\patches\v8.0 -@$(RM) $(TRF)\patches\v8.1b1\byteorder.patch -@$(RM) $(TRF)\patches\v8.1b1\standard.patch -@$(RM) $(TRF)\patches\v8.1b1\tcl.h -@$(RM) $(TRF)\patches\v8.1b1\tclIO.c -@rd $(TRF)\patches\v8.1b1 -@rd $(TRF)\patches -@rd $(TRF) # # Implicit rules # {$(WINDIR)}.c{$(TMPDIR)}.obj: $(cc32) $(TRF_CFLAGS) -Fo$(TMPDIR)\ $< {$(GENERICDIR)}.c{$(TMPDIR)}.obj: $(cc32) $(TRF_CFLAGS) -Fo$(TMPDIR)\ $< {$(ROOT)\compat}.c{$(TMPDIR)}.obj: $(cc32) $(TRF_CFLAGS) -Fo$(TMPDIR)\ $< {$(WINDIR)}.rc{$(TMPDIR)}.res: $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(WINDIR)" -D__WIN32__ \ $< clean: -@del *.exp -@del *.lib -@del *.dll -@del *.pch -@del $(TMPDIR)\*.obj trf2.1.4/win/README0000644000175000017500000000200711216343142013223 0ustar sergeisergei Tcl Data transformations (Tcl-Trf) (Version 2.1.4 / MAY-06-2009) Andreas Kupries (andreas_kupries@users.sourceforge.net) This is the README file for the Windows version of the 'Tcl-Trf' package. ----------------------------------------------------------------------- In order to compile Trf for Windows, you need the following items: Trf 2.1.4 Source Distribution Tcl 7.6, 8.0+ Source distribution A version of 'patch' running under Windows. Visual C++ 2.x/4.x/5.x First you have to patch and recompile your Tcl distribution. Please read paragraph 1 of 'doc/INSTALL' on how to do this. 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. trf2.1.4/win/README.VC0000644000175000017500000000141411216343142013533 0ustar sergeisergeiFrom the "Tcl on Windows" FAQ : M-5: Problems with Microsoft Visual C++ 4.2 and Tcl If you're using Visual C++ 4.2 and running under Windows 95, you may get an error that the msvcrt.dll cannot be found. You may also have problems with an invalid argument error. You can solve your problem one of two ways: *Back out of VC++ 4.2 to VC++ 4.1 * Install the msvcrt.dll that's missing (or on some Win95 systems, corrupted!) in your c:\windows\system directory. The problem is that VC++ 4.2 for some reason generates code that wants this DLL, and if it's not there, it won't work. And, some versions of Win95 are shipping without this DLL, or worse, with one that's incompatible with the code generated with VC++ 4.2 -Jacob Levy trf2.1.4/win/Makefile.gnu0000644000175000017500000003020411216343142014573 0ustar sergeisergei #---------------------------------------------------------------- # This file is a Makefile for Trf 2.1.4 (as of MAY-06-2009), usable for CygWin B20.1 # Donated by Jan Nijtmans #---------------------------------------------------------------- EXTENSION = Trf VERSION = 2.1.4 #TCL_VERSION = 81 TCL_VERSION = 82 TRF_DLL_FILE = ${EXTENSION}21.dll TRF_LIB_FILE = lib${EXTENSION}21.a TRF_STATIC_LIB_FILE = lib${EXTENSION}21s.a TRF_STUB_LIB_FILE = lib${EXTENSION}stub21.a SSL_LIBRARY = -DSSL_LIB_NAME=\"libeay32.dll\" BZ2_LIBRARY = -DBZ2_LIB_NAME=\"bz2.dll\" #ZLIB_STATIC = -DZLIB_STATIC_BUILD #BZLIB_STATIC = -DBZLIB_STATIC_BUILD # #---------------------------------------------------------------- # Things you can change to personalize the Makefile for your own # site (you can make these changes in either Makefile.in or # Makefile, but changes to Makefile will get lost if you re-run # the configuration script). #---------------------------------------------------------------- # Directory in which the source of this extension can be found srcdir = . TMPDIR = . # Directories in which the Tcl core can be found TCL_INC_DIR = /progra~1/tcl/include TCL_LIB_DIR = /progra~1/tcl/lib TCL_LIB_SPEC = /progra~1/tcl/lib/libtclstub$(TCL_VERSION).a # Libraries to be included with trf.dll TCL_SHARED_LIBS = # Default top-level directories in which to install architecture- # specific files (exec_prefix) and machine-independent files such # as scripts (prefix). The values specified here may be overridden # at configure-time with the --exec-prefix and --prefix options # to the "configure" script. prefix = /progra~1/Tcl exec_prefix = $(prefix) # Directory containing scripts supporting the work of this makefile tool = $(srcdir)/tools # The following definition can be set to non-null for special systems # like AFS with replication. It allows the pathnames used for installation # to be different than those used for actually reference files at # run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix # when installing files. INSTALL_ROOT = # Directory where trf.dll is at run-time: LIB_RUNTIME_DIR = $(exec_prefix)/lib/$(EXTENSION)$(VERSION) # Directory in which to install the archive trf.dll: LIB_INSTALL_DIR = $(INSTALL_ROOT)$(LIB_RUNTIME_DIR) # Directory in which to install the extended shell tclsh: BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin # Directory in which to install the include file transform.h: INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include # Top-level directory in which to install manual entries: MAN_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/man # To change the compiler switches, for example to change from -O # to -g, change the following line: CFLAGS = -O2 -fnative-struct -mno-cygwin -DNDEBUG -DUSE_TCL_STUBS -D__WIN32__ -DWIN32 -D_WINDOWS -DZLIB_DLL -DTCL_THREADS -DHAVE_STDLIB_H # To disable ANSI-C procedure prototypes reverse the comment characters # on the following lines: PROTO_FLAGS = #PROTO_FLAGS = -DNO_PROTOTYPE # 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 # 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 # "install" around; better to use the install-sh script that comes # with the distribution, which is slower but guaranteed to work. INSTALL = $(tool)/install-sh -c # The symbols below provide support for dynamic loading and shared # libraries. 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. The second definition should be used # in conjunction with Tcl 8.1. TRF_SHLIB_CFLAGS = #TRF_SHLIB_CFLAGS = -DTCL_USE_STUBS # The symbol below provides support for dynamic loading and shared # libraries. See configure.in for a description of what it means. # The values of the symbolis normally set by the configure script. SHLIB_LD = # Libraries to use when linking: must include at least the dynamic # loading library and the math library (in that order). This # definition is determined by the configure script. ALL_LIBS = $(TCL_LIB) LIBS = #---------------------------------------------------------------- # 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. #---------------------------------------------------------------- INSTALL_PROGRAM = $(INSTALL) -m 744 INSTALL_DATA = $(INSTALL) -m 644 INSTALL_SHLIB = $(INSTALL) -m 555 RANLIB = ranlib SHLIB_SUFFIX = .dll #---------------------------------------------------------------- # 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 = gcc AS = as LD = ld DLLTOOL = dlltool DLLWRAP = dllwrap -mnocygwin WINDRES = windres DLL_LDFLAGS = -mwindows -Wl,-e,_DllMain@12 DLL_LDLIBS = -L/progra~1/tcl/lib -ltclstub$(TCL_VERSION) baselibs = -lkernel32 $(optlibs) -ladvapi32 winlibs = $(baselibs) -luser32 -lgdi32 -lcomdlg32 -lwinspool guilibs = $(libc) $(winlibs) guilibsdll = $(libcdll) $(winlibs) TRF_DEFINES = -D__WIN32__ -DSTATIC_BUILD ${TRF_SHLIB_CFLAGS} -DTRF_VERSION="\"${VERSION}\"" ${SSL_LIBRARY} ${ZLIB_STATIC} ${BZLIB_STATIC} -DBUGS_ON_EXIT # $(TCL_CC_SWITCHES) INCLUDES = -I. -I$(srcdir) -I../generic -I$(TCL_INC_DIR) DEFINES = $(PROTO_FLAGS) $(MEM_DEBUG_FLAGS) $(TRF_SHLIB_CFLAGS) \ $(TRF_DEFINES) CC_SWITCHES = $(CFLAGS) $(DEFINES) $(INCLUDES) # fundamentals of this library SOURCES = ../generic/adler.c \ ../generic/asc85code.c \ ../generic/b64code.c \ ../generic/bincode.c \ ../generic/binio.c \ ../generic/convert.c \ ../generic/crc.c \ ../generic/crc_zlib.c \ ../generic/dig_opt.c \ ../generic/digest.c \ ../generic/haval.c \ ../generic/hexcode.c \ ../generic/init.c \ ../generic/load.c \ ../generic/crypt.c \ ../generic/loadman.c \ ../generic/md2.c \ ../generic/md5dig.c \ ../generic/octcode.c \ ../generic/otpcode.c \ ../generic/otpmd5.c \ ../generic/otpsha1.c \ ../generic/registry.c \ ../generic/rs_ecc.c \ ../generic/sha.c \ ../generic/sha1.c \ ../generic/rmd160.c \ ../generic/rmd128.c \ ../generic/unstack.c \ ../generic/util.c \ ../generic/uucode.c \ ../generic/zip.c \ ../generic/zip_opt.c \ ../generic/zlib.c \ ../generic/bz2.c \ ../generic/bz2_opt.c \ ../generic/bz2lib.c \ ../generic/qpcode.c \ ../generic/reflect.c \ ../generic/ref_opt.c \ ../generic/trfStubInit.c \ ../compat/tclLoadWin.c OBJECTS = adler.o \ asc85code.o \ b64code.o \ bincode.o \ binio.o \ convert.o \ crc.o \ crc_zlib.o \ dig_opt.o \ digest.o \ haval.o \ hexcode.o \ init.o \ load.o \ crypt.o \ loadman.o \ md2.o \ md5dig.o \ octcode.o \ otpcode.o \ otpmd5.o \ otpsha1.o \ registry.o \ rs_ecc.o \ sha.o \ sha1.o \ rmd160.o \ rmd128.o \ unstack.o \ util.o \ uucode.o \ zip.o \ zip_opt.o \ zlib.o \ bz2.o \ bz2_opt.o \ bz2lib.o \ qpcode.o \ reflect.o \ ref_opt.o \ trfStubInit.o \ tclLoadWin.o #-------------------------------------------------------# default: $(TRF_DLL_FILE) $(TRF_LIB_FILE) $(TRF_STUB_LIB_FILE) all: default test: $(TRF_DLL_FILE) wish${TK_VERSION} demo.tcl #-------------------------------------------------------# trfStubLib.o: ../generic/trfStubLib.c $(CC) -c $(CC_SWITCHES) ../generic/trfStubLib.c -o $@ trfStubInit.o: ../generic/trfStubInit.c $(CC) -c $(CC_SWITCHES) ../generic/trfStubInit.c -o $@ adler.o: ../generic/adler.c $(CC) -c $(CC_SWITCHES) ../generic/adler.c -o $@ asc85code.o: ../generic/asc85code.c $(CC) -c $(CC_SWITCHES) ../generic/asc85code.c -o $@ b64code.o: ../generic/b64code.c $(CC) -c $(CC_SWITCHES) ../generic/b64code.c -o $@ bincode.o: ../generic/bincode.c $(CC) -c $(CC_SWITCHES) ../generic/bincode.c -o $@ binio.o: ../generic/binio.c $(CC) -c $(CC_SWITCHES) ../generic/binio.c -o $@ convert.o: ../generic/convert.c $(CC) -c $(CC_SWITCHES) ../generic/convert.c -o $@ crc.o: ../generic/crc.c $(CC) -c $(CC_SWITCHES) ../generic/crc.c -o $@ crc_zlib.o: ../generic/crc_zlib.c $(CC) -c $(CC_SWITCHES) ../generic/crc_zlib.c -o $@ dig_opt.o: ../generic/dig_opt.c $(CC) -c $(CC_SWITCHES) ../generic/dig_opt.c -o $@ digest.o: ../generic/digest.c $(CC) -c $(CC_SWITCHES) ../generic/digest.c -o $@ haval.o: ../generic/haval.c $(CC) -c $(CC_SWITCHES) ../generic/haval.c -o $@ hexcode.o: ../generic/hexcode.c $(CC) -c $(CC_SWITCHES) ../generic/hexcode.c -o $@ init.o: ../generic/init.c $(CC) -c $(CC_SWITCHES) ../generic/init.c -o $@ load.o: ../generic/load.c $(CC) -c $(CC_SWITCHES) ../generic/load.c -o $@ crypt.o: ../generic/crypt.c $(CC) -c $(CC_SWITCHES) ../generic/crypt.c -o $@ loadman.o: ../generic/loadman.c $(CC) -c $(CC_SWITCHES) ../generic/loadman.c -o $@ md5dig.o: ../generic/md5dig.c $(CC) -c $(CC_SWITCHES) ../generic/md5dig.c -o $@ md2.o: ../generic/md2.c $(CC) -c $(CC_SWITCHES) ../generic/md2.c -o $@ octcode.o: ../generic/octcode.c $(CC) -c $(CC_SWITCHES) ../generic/octcode.c -o $@ otpcode.o: ../generic/otpcode.c $(CC) -c $(CC_SWITCHES) ../generic/otpcode.c -o $@ otpmd5.o: ../generic/otpmd5.c $(CC) -c $(CC_SWITCHES) ../generic/otpmd5.c -o $@ otpsha1.o: ../generic/otpsha1.c $(CC) -c $(CC_SWITCHES) ../generic/otpsha1.c -o $@ registry.o: ../generic/registry.c $(CC) -c $(CC_SWITCHES) ../generic/registry.c -o $@ rs_ecc.o: ../generic/rs_ecc.c $(CC) -c $(CC_SWITCHES) ../generic/rs_ecc.c -o $@ sha.o: ../generic/sha.c $(CC) -c $(CC_SWITCHES) ../generic/sha.c -o $@ sha1.o: ../generic/sha1.c $(CC) -c $(CC_SWITCHES) ../generic/sha1.c -o $@ rmd160.o: ../generic/rmd160.c $(CC) -c $(CC_SWITCHES) ../generic/rmd160.c -o $@ rmd128.o: ../generic/rmd128.c $(CC) -c $(CC_SWITCHES) ../generic/rmd128.c -o $@ unstack.o: ../generic/unstack.c $(CC) -c $(CC_SWITCHES) ../generic/unstack.c -o $@ util.o: ../generic/util.c $(CC) -c $(CC_SWITCHES) ../generic/util.c -o $@ uucode.o: ../generic/uucode.c $(CC) -c $(CC_SWITCHES) ../generic/uucode.c -o $@ zip.o: ../generic/zip.c $(CC) -c $(CC_SWITCHES) ../generic/zip.c -o $@ zip_opt.o: ../generic/zip_opt.c $(CC) -c $(CC_SWITCHES) ../generic/zip_opt.c -o $@ zlib.o: ../generic/zlib.c $(CC) -c $(CC_SWITCHES) ../generic/zlib.c -o $@ bz2.o: ../generic/zip.c $(CC) -c $(CC_SWITCHES) ../generic/bz2.c -o $@ bz2_opt.o: ../generic/zip_opt.c $(CC) -c $(CC_SWITCHES) ../generic/bz2_opt.c -o $@ bz2lib.o: ../generic/zlib.c $(CC) -c $(CC_SWITCHES) ../generic/bz2lib.c -o $@ qpcode.o: ../generic/qpcode.c $(CC) -c $(CC_SWITCHES) ../generic/qpcode.c -o $@ reflect.o: ../generic/reflect.c $(CC) -c $(CC_SWITCHES) ../generic/reflect.c -o $@ ref_opt.o: ../generic/ref_opt.c $(CC) -c $(CC_SWITCHES) ../generic/ref_opt.c -o $@ tclLoadWin.o: ../compat/tclLoadWin.c $(CC) -c $(CC_SWITCHES) ../compat/tclLoadWin.c -o $@ dllEntry.o: dllEntry.c $(CC) -c $(CC_SWITCHES) dllEntry.c -o $@ #-------------------------------------------------------# $(TRF_DLL_FILE): $(OBJECTS) trfres.o dllEntry.o trf.def $(DLLWRAP) -s $(DLL_LDFLAGS) -mno-cygwin -o $@ $(OBJECTS) \ trfres.o dllEntry.o --def trf.def \ $(DLL_LDLIBS) $(TRF_LIB_FILE): trf.def $(TRF_DLL_FILE) $(DLLTOOL) --as=$(AS) --dllname $(TRF_DLL_FILE) \ --def trf.def --output-lib $@ $(TRF_STATIC_LIB_FILE): $(OBJECTS) $(AR) cr $@ $(OBJECTS) $(TRF_STUB_LIB_FILE): trfStubLib.o $(AR) cr $@ trfStubLib.o trf.def: $(OBJECTS) $(DLLTOOL) --export-all --exclude-symbols DllMain@12 --output-def $@ $(OBJECTS) trfres.o: trf.rc $(WINDRES) --include . --define VS_VERSION_INFO=1 trf.rc trfres.o #-------------------------------------------------------# clean: del $(OBJECTS) $(TRF_DLL_FILE) del TAGS depend *~ */*~ core* tests/core* so_locations lib*.so* distclean: clean del config.* del Makefile #-------------------------------------------------------# # DO NOT DELETE THIS LINE -- make depend depends on it. trf2.1.4/win/dllEntry.c0000644000175000017500000000133411216343142014306 0ustar sergeisergei/* * dllEntry.c -- * * This procedure provides the entry point for the dll * */ #include #if defined(_MSC_VER) || defined(__GNUC__) #define DllEntryPoint DllMain #endif /* *---------------------------------------------------------------------- * * DllEntryPoint -- * * This routine is called by gcc, VC++ or Borland to invoke the * initialization code for Tcl. * * Results: * TRUE. * * Side effects: * None. * *---------------------------------------------------------------------- */ BOOL APIENTRY DllEntryPoint ( HINSTANCE hInst, /* Library instance handle. */ DWORD reason, /* Reason this function is being called. */ LPVOID reserved) /* Not used. */ { return TRUE; } trf2.1.4/win/pkgIndex.tcl0000644000175000017500000000060011216343142014615 0ustar sergeisergei# Tcl package index file, version 1.0 # # Window package index for Trf 2.1.4 (as of MAY-06-2009) # proc trfifneeded dir { rename trfifneeded {} if {[package vcompare [info tclversion] 8.1] >= 0} { set version {} } else { regsub {\.} [info tclversion] {} version } package ifneeded Trf 2.1 "load [list [file join $dir trf21$version.dll]] Trf" } trfifneeded $dir trf2.1.4/win/trf.rc0000644000175000017500000000152711216343142013472 0ustar sergeisergei// SCCS: @(#) trf.rc 1.0 96/04/12 18:08:09 // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION 1,2,2,0 PRODUCTVERSION 1,2,2,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x4L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "Trf Dll\0" VALUE "OriginalFilename", "trf2180.dll\0" VALUE "CompanyName", "Andreas Kupries\0" VALUE "FileVersion", "2.1" VALUE "LegalCopyright", "Copyright \251 1998\0" VALUE "ProductName", "Trf 2.1 for Windows\0" VALUE "ProductVersion", "2.1" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END // // Icon // trf ICON DISCARDABLE "trf.ico" trf2.1.4/doc/0000755000175000017500000000000012034467745012333 5ustar sergeisergeitrf2.1.4/doc/README.zlib0000644000175000017500000001110311216343142014127 0ustar sergeisergeizlib 1.0.4 is a general purpose data compression library. All the code is reentrant (thread safe). The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). These documents are also available in other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html All functions of the compression library are documented in the file zlib.h. A usage example of the library is given in the file example.c which also tests that the library is working correctly. Another example is given in the file minigzip.c. The compression library itself is composed of all source files except example.c and minigzip.c. To compile all files and run the test program, follow the instructions given at the top of Makefile. In short "make test; make install" should work for most machines. For MSDOS, use one of the special makefiles such as Makefile.msc; for VMS, use Make_vms.com or descrip.mms. Questions about zlib should be sent to or, if this fails, to the addresses given below in the Copyright section. The zlib home page is http://quest.jpl.nasa.gov/zlib/ The changes made in version 1.0.4 are documented in the file ChangeLog. The main changes since 1.0.3 are: - In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF bit, so the decompressor could decompress all the correct data but went on to attempt decompressing extra garbage data. This affected minigzip too. - zlibVersion and gzerror return const char* (needed for DLL) - port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) A Perl interface to zlib written by Paul Marquess is in the CPAN (Comprehensive Perl Archive Network) sites, such as: ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib* Notes for some targets: - For Turbo C the small model is supported only with reduced performance to avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 - For 64-bit Iris, deflate.c must be compiled without any optimization. With -O, one libpng test fails. The test works in 32 bit mode (with the -32 compiler flag). The compiler bug has been reported to SGI. - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works when compiled with cc. - zlib doesn't work on HP-UX 9.05 with one cc compiler (the one not accepting the -O option). It works with the other cc compiler. - To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL For help on building a zlib DLL, contact Alessandro Iacopetti http://lisa.unial.it/iaco , or contact Brad Clarke . - gzdopen is not supported on RISCOS Acknowledgments: The deflate format used by zlib was defined by Phil Katz. The deflate and zlib specifications were written by Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in zlib; they are too numerous to cite here. Copyright notice: (C) 1995-1996 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler gzip@prep.ai.mit.edu madler@alumni.caltech.edu If you use the zlib library in a product, we would appreciate *not* receiving lengthy legal documents to sign. The sources are provided for free but without warranty of any kind. The library has been entirely written by Jean-loup Gailly and Mark Adler; it does not include third-party code. If you redistribute modified sources, we would appreciate that you include in the file ChangeLog history information documenting your changes. trf2.1.4/doc/md5crypt.man0000644000175000017500000000133611216343142014563 0ustar sergeisergei[include common/trf_version.inc] [manpage_begin md5crypt n [vset trf_version]] [titledesc "Password hashing based on \"md5\""] [include common/trf_header.inc] [description] The command [cmd md5crypt] is for the encryption of passwords and uses [term md5] as hash algorithm. An alternative command for the same function, but based on the older [syscmd crypt(3)] hash function is [cmd crypt]. [para] [list_begin definitions] [call [cmd md5crypt] [arg password] [arg salt]] Encrypts the [arg password] using the specified [arg salt] and returns the generated hash value as the result of the command. [list_end] [see_also trf-intro crypt] [keywords crypt password md5 {message digest} mac hashing hash authentication] [manpage_end] trf2.1.4/doc/seek.handling.example0000644000175000017500000001166511216343142016414 0ustar sergeisergei Handling of seeking on a transformation. ______________________________________________________________________ Explained by example. Covers possible problems and solutions too. ______________________________________________________________________ The transformation: oct (conversion of bytes into octal encoding) Ratio: 1 real character encoded into 3 characters Assumptions: Attached to a seekable channel, Configured to encode written bytes and to decode read bytes Wording: Transform is 'up', the channel below 'down'. ______________________________________________________________________ Basics: Per up-character written, seek 3 characters in down. So: tell.up = tell.down / 3 Do: Create down-channel, seek 5 bytes bytes from start, stack up, tell. What is the position ? tell.down % 3 == 2, tel.down / 3 = 1 ? The problem is one of phases. The octal encoding may start at arbitrary positions and not aligned to 0-phase, so a simple division is not quite right. Solution: Use position in down current during stacking as zero-point, calculate positions relative to this place. So: tell.up = (tell.down - offset) / 3 In the example above: tell.up = 0 = (5-5)/3. Ok. Do: Create down channel, stack up, seek 2 characters, force seek policy 'transform identity', seek 1 byte back, restore old policy (*), seek 1 character forward, tell. What is the position ? Trace: Seek 2 chars up = 6 characters down. Seek 1 char up back, identity! = Place 5 down. Seek 1 char up, normal = Place 8 8 % 3 == 2, out of phase again, fractional position! The problem is that we forced the down-channel into a different phase relative to the one established by the first two actions. Solution: Use the position in down just before restoration of natural seek policy as *new* zero-point, again calculate positions relative to this place. More complications: * A transform reads many bytes ahead if the user requests more than it has buffered. It additionally remembers the data not yet consumed by the caller. This introduces an additional offset between up and down positions. Example: Create down channel, stack up. => up/down position == 0, empty buffers. Read 10 characters. => Transform reads 4K ahead, transforms them into 1365 decoded characters and 1 character untransformed. 10 decoded characters are delivered. => tell.down == 4096. => tell.up == 10 offset = 4096 - 10*3 = 4066 Conclusions for the code - Reading from the buffer has to decrement the offset. - Seeking within the limits of the buffer changes only the offset. Reading while within the limits of the buffer has to take the data from the up position, possibly from inside the buffers, and not from the start. Of course, it may cause a reload too, as usual. - Tell should not go to the down channel while within the limits of the buffers. Hm, this way it will almost never talk to the down channel, because the offsets generated from the read-aheads are sufficient. - Seeking behind or before the buffer discards it. And has to seek the down channel to its new position too. - Tell'ing could go down if there is no offset. But all of the above nearly amounts to keeping our own location, so we can use that. - A write has to restore the real down position associated with the up position, it can use the offset for this. Read buffers must be discarded to prevent the system from returning false data. The write *could* try to update the buffers too, but I don't think that this is worth the effort. * The above covered seeking from start and relative to the current position. Now how do the seek relative to the end ? Especially if the end in the down-channel is a fractional position upward. Round to nearest non-fractional below end of down as logical end ? Or the next non-fractional greater than the real 'end' ? 'oct' and similar transformations *are* able to handle incomplete blocks at the end. des in ecb and cbc mode on the other hand is not able to do this. Hm, ... (*) Oops, not yet possible with the defined interface! Question: * Any real life examples of non-linear functions between seek locations of up and down, still computable without effort ? If no, I might reduce the basic transform information from a function vector to two numbers simply specifying the ratio between them. 2 numbers to express things like 3:4, f.e. for base64. This should make it simpler for 'tcl level transforms' too. And I am able to handle basically *all* stuff in the generic level * And I haven't thought about 'encode on read'. Returns 3 characters per character below. So a seek position above is a fraction below! OTOH, from the texts above (send earlier) it seems that I have to keep separate up and down locations anyway so it shouldn't be that much of hassle. Especially if I only allow seeking in multiples of the ratio (3 here). trf2.1.4/doc/changes.final0000644000175000017500000001066711216343142014751 0ustar sergeisergeiChanges in the script api to Trf. ================================= * KISS (Keep it simple, stupid). General interface (registry.c) ------------------------------------ Current state ~~~~~~~~~~~~~ a) command ?-option value?... The so called 'immediate' mode. b) command ?-option value?... -attach '-attach' is an option, and may therefore be put everywhere. It was placed at the end for emphasis only. This form actually creates a 'filter' intercepting the read/writes on the specified . The filter takes over the role of the channel it is attached to, allowing to stack even more filters. Proposed changes ~~~~~~~~~~~~~~~~ * Use object facilities of 8.0 to allow strings with embedded '\0's. * '\0's restrict usage with 7.6, so channel based behaviour must be retained. This is no issue for 8.1 A) command ?-option value?... The transformation result is returned as result of the command! The given value is interpreted as binary data. B) command ?-option value?... -out The transformation result is written into the specified channel. C) command ?-option value?... -in The value is read from the specified channel, the result is returned. D) command ?-option value?... -in -out The value is read from the input channel, the result written to the output channel. This implements (a). In words: * Either use '-in ' or specify the value directly. * Either use '-out channel' or expect the transformed information as result of the command. (b) remains unchanged. Additional rule * Usage of '-attach' disallows '-in', '-out', no result will given, no value expected (#args %2 == 0). Interface to conversions, and similar transformations ----------------------------------------------------- Unchanged. Remark: Similar transformations are 'rs_ecc' and 'zip'. They can be seen as conversions too, only with a special set of options. Interface to ciphers (cipher.c, c_opt.c) ------------------------------------------- Current state ~~~~~~~~~~~~~ * Ciphers get key information via '-key channel'. Proposed changes ~~~~~~~~~~~~~~~~ * Interpret the value of '-key' in depencendance of the value of '-key-type'. This is either 'data' or 'channel', with 'data' as default. -key-type data -key : Interpret as binary data. -key-type channel -key : Interpret as channel handle. If the key is given as hexstring, or dual, octal, etc, the following lines will do the trick: 8.0: cipher -key [hex -mode decode ] ... (case A, see above) 7.6: create . | write the hexstring hex -attach -mode decode | into a channel, puts | decode to binary unstack | data too. seek 0 | cipher -key ... (This is the current way with 8.x too) Interface to blockciphers (blockcipher.c, bc_opt.c) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The relevant options are -key (key information) -iv (initialization vector for stream modes) I propose the same changes as with ciphers: -key, -key-type -iv, -iv-type Interface to message digests ---------------------------- Current state ~~~~~~~~~~~~~ * 2 submodes for a filter. absorb: identity with respect to user data. calculates a digest during write, attaches it after the last character written by the user. calculates a digest during read, compares it to the digest after the user data. result goes into an associated variable. write: /dev/null with respect to user data. calculates digests for read/write, writes them to destination channels after the primary channel is/was closed. Proposed changes ~~~~~~~~~~~~~~~~ * No changes to the immediate mode. * No changes of filter submode 'absorbtion'. * Change submode 'write' to allow writing into variables. Use ..-type options to determine the type of destination. Unsure: Continuously update variables, or write only after the primary channel was closed, as with channels ? KISS: Same as with channels. * Another submode: 'transparent'. Like 'write' with respect to digest calculation, but identity for user information, as in 'absorb'. * rename options -write-dest, -read-dest to -write-destination, -read-destination Compatible to existing scripts, and names are more clear. trf2.1.4/doc/crypt.man0000644000175000017500000000127611216343142014160 0ustar sergeisergei[include common/trf_version.inc] [manpage_begin crypt n [vset trf_version]] [titledesc "Password hashing based on \"crypt\""] [include common/trf_header.inc] [description] The command [cmd crypt] is an interface to the [syscmd crypt(3)] function for the encryption of passwords. An alternative command for the same, but based on [term md5] is [cmd md5crypt]. [para] [list_begin definitions] [call [cmd crypt] [arg password] [arg salt]] Encrypts the [arg password] using the specified [arg salt] and returns the generated hash value as the result of the command. [list_end] [see_also trf-intro md5crypt] [keywords crypt password md5 {message digest} mac hashing hash authentication] [manpage_end] trf2.1.4/doc/sha1_otp.man0000644000175000017500000000006411216343142014527 0ustar sergeisergei[vset digest sha1_otp] [include digest/main.inc] trf2.1.4/doc/otp_words.man0000644000175000017500000000071511216343142015034 0ustar sergeisergei[vset encoding otp_words] [include encoding/header.inc] [para] This encoding transforms every block of four bytes (64 bit) into six english words, as defined in RFC 2289 ([uri http://www.rfc-editor.org/rfc/rfc2289.txt]). This encoding is the sole one which is [emph {not able}] to handle an incomplete block at the end of the input. [include encoding/middle.inc] [keywords {rfc 2289} md5_otp] [see_also trf-intro md5_otp] [include encoding/footer.inc] trf2.1.4/doc/testvectors.otp0000644000175000017500000000463111216343142015431 0ustar sergeisergei MD5 ENCODINGS Pass Phrase Seed Cnt Hex Six Word Format ======================================================================== This is a test. TeSt 0 9E87 6134 D904 99DD INCH SEA ANNE LONG AHEM TOUR This is a test. TeSt 1 7965 E054 36F5 029F EASE OIL FUM CURE AWRY AVIS This is a test. TeSt 99 50FE 1962 C496 5880 BAIL TUFT BITS GANG CHEF THY AbCdEfGhIjK alpha1 0 8706 6DD9 644B F206 FULL PEW DOWN ONCE MORT ARC AbCdEfGhIjK alpha1 1 7CD3 4C10 40AD D14B FACT HOOF AT FIST SITE KENT AbCdEfGhIjK alpha1 99 5AA3 7A81 F212 146C BODE HOP JAKE STOW JUT RAP OTP's are good correct 0 F205 7539 43DE 4CF9 ULAN NEW ARMY FUSE SUIT EYED OTP's are good correct 1 DDCD AC95 6F23 4937 SKIM CULT LOB SLAM POE HOWL OTP's are good correct 99 B203 E28F A525 BE47 LONG IVY JULY AJAR BOND LEE SHA1 ENCODINGS Pass Phrase Seed Cnt Hex Six Word Format ======================================================================== This is a test. TeSt 0 BB9E 6AE1 979D 8FF4 MILT VARY MAST OK SEES WENT This is a test. TeSt 1 63D9 3663 9734 385B CART OTTO HIVE ODE VAT NUT This is a test. TeSt 99 87FE C776 8B73 CCF9 GAFF WAIT SKID GIG SKY EYED AbCdEfGhIjK alpha1 0 AD85 F658 EBE3 83C9 LEST OR HEEL SCOT ROB SUIT AbCdEfGhIjK alpha1 1 D07C E229 B5CF 119B RITE TAKE GELD COST TUNE RECK AbCdEfGhIjK alpha1 99 27BC 7103 5AAF 3DC6 MAY STAR TIN LYON VEDA STAN OTP's are good correct 0 D51F 3E99 BF8E 6F0B RUST WELT KICK FELL TAIL FRAU OTP's are good correct 1 82AE B52D 9437 74E4 FLIT DOSE ALSO MEW DRUM DEFY OTP's are good correct 99 4F29 6A74 FE15 67EC AURA ALOE HURL WING BERG WAIT trf2.1.4/doc/bin.man0000644000175000017500000000052511216343142013563 0ustar sergeisergei[vset encoding bin] [include encoding/header.inc] [para] This encoding transforms every byte in the input into a sequence of 8 characters containing the binary representation of the byte. For example [para] [example { % bin -mode encode Z 01011010 }] [include encoding/middle.inc] [keywords hex oct] [include encoding/footer.inc] trf2.1.4/doc/hex.man0000644000175000017500000000052511216343142013577 0ustar sergeisergei[vset encoding hex] [include encoding/header.inc] [para] This encoding transforms every byte in the input into a sequence of 2 characters containing the hexadecimal representation of the byte. For example [para] [example { % hex -mode encode Z 5A }] [include encoding/middle.inc] [keywords bin oct] [include encoding/footer.inc] trf2.1.4/doc/art/0000755000175000017500000000000011216343142013102 5ustar sergeisergeitrf2.1.4/doc/art/logo-64x64.gif0000644000175000017500000001623311216343142015327 0ustar sergeisergeiGIF89a@@÷þæèýôõþëóýÖÙüÞâüÈÉû¶¹ø±²ú¨«ø—šö’ù†ˆøtx÷fj÷[cõUX÷GKí8Bø59í4;ù*2ì+2ö#'ÿÿÿ’7G9åòøTŽ«1 GUGê"&êé è é éæèéê#(ë#(ì&+ø¤oktRgWÐÀ¾CIœøq¢ 0 cÆŒ3f̘1cÆŒ3f̘1cÆ /’èŒÂèž7oþþü tŠŒ©:u¨ørÄŠR ˜1cÆŒ3f̨"Ä€ PÀœp 'ÌPƒ Xxá…$l`1L1ÅcL´ãD¡<@K.]4È+sÜL& q`X¡Ã*WÌ€ ( € 'œ‚ !,pÁ0A(xQX„ƒ 3ÅãÍ7ؘSËW\1C ˆ2Ê+²,pAx¼2Ë9Þó 7JpÂEVDQcŒÑJ_\Ä 'œp ” À Àl°1Ë2Ë$à 6ß\CÎ4CXp 'œp (챇 &œÁëÈ"É (¤ÀÆ ºƒ 2íŒ3Ž:þܳƒIDÄ=´b„9T‘Á[<B ¹è¢ 3 Áà 1Ð@óL;DØPƒ ^ì±Ç{¤àÅ%8p á´ 6ßd’Eå\qÅ2 € 3Ì0à 3̀ ÔÀFLà 'œp 'œp 'œp )x1œpˆ0‚ xp 'œp 'œp 'œp 'œpB Hì„K M8ÄPD‘C G, B 3Ì0à 3Ì0à 3Ì0C )Lñ 0 Ì0à 'ˆ`‚ÜpàGzèðB\]dPŬ‘EHP€Äþ 'œÂ 0C 3œp 'œp 'œp 'ÌðÁ3œp‚ê‘|äc{˜‡;ä1€`(A ~0wèÃíðF6®Ñ5œ¸,… `8®€„Gø` /˜@ ƒÄ@'˜Á fp‚¤`˜ANP¤ )˜Á <0œ`3ˆh@Ì`¨A l`Ü9ÐÁlÀƒø ˜B p‚œà'8Á Np‚œ(H pà'˜ F@pÀ þð9Â6ØAr`ä€ Uè@XpD0À%8A N‚Ð (C J0ƒœà'8Á Np‚œà'ˆ >œ "°€(á‡?üáø * !è :°„%¾…: âTà€,ƒ)T {8Á Np”àÀBàœà'8Á Np‚œà'@ P€‚¤ÀŽðÄ'àˆ?üáøÃäðP"R¸@þh„ TH°À N€ '8Á Rð(à@Fðœà'8Á Np‚œà'@ Pp‚T`l€*!8H@ yøÃþˆB°¢"ÂÈ„V¬â @ P€ '8Á N‚\àÀh`‚œà'8Á Rp‚œà5¸.r¡ 삽PB|á $\@JÈ ‘ŠUhÂ9ðZ‘ äà H8 P€ '8A L‚\àFðÌ`'A ¨ fäËàÁ/ªq %LÈÆ5|`XèYHEþ@‘ m¬aŒ¨B‚Њ1TAL°€P€‚Ì`3˜A >\àÀBƒ\CºÐ.†± übßÀ6! r|}€EàP¨Áàð†7¾ sœãè@1€€†0Ôa[ðA+€„@'8Á N‚\àÀ xP6˜@ XàV0 lˆÃ µ0Å®pTàm@% áŠ\ xD àð† #Å  t#C¶*XA W@ RP‚ à0@ >` aX3°!h(’@ Np‚œ"pÄ(þQˆuØaqÀà €ì!ºÀF4”ÀM˜@`´@…$Xa u°Â¬PP¡T Q0 ¸ âP Ã0 ÅP â@ Ñp{°{°{ð{ðî ó`$0—0(ðï° íP Ç@ ôðWpW >@H€Hð¦U ðYP[Ð"à5À’@ Ñ  º ߀ âÐ û ü‰Pì€ï÷ )°'0ö $lPàÐÈD0 ðà×p€(€``€°>P0&à2`'àþ307°êÐÑР؀ J ™0 ñŒ€5€C0' œp ÃÀ ØÀ  Ë èp ,;@(€(€(€(€(€(p)401ð&ÀA@C0E`G1p'p'p'p'p'p'p@  )!àR`S'p'p'p'p'p'p'p3`30ÐT`JH08@-:PVðGð à30303030303`!p@ #`p&þ0 ð303030)3p€Z \pW@=ÀFPUA`Ð/°]]Ð"à3p'p'p'p'p'p4ð40€$p'p'p' 4P PeÀ% 3€@ÀU`AðHGGÐ`YY€g€iÀ#p'p'p'p'p'€' @p @1'p'p!0mpàoq s@lpH€guÐÐkp@Hà! "þ'p'p'p'p'p(p'°!ÀÐ"ð)€)#` oàpð‚AƒðX€`bpY@pp'ð'$Ѐ!ð'p'p'p'p'p'p'ð$0` P'€"аpðPŒÐŽ`Ð>`cðk#p€ ð'p?ð#`` `?p'p'p'p'p'€)4p10  ‘à€ðð€D QðZ0 0WðþNp/P{@600#0'p'P!p0 3030303030303à%p `)ð#Є pð€ P™Ðš0c`FPGEpH0'1€3033pð'p'p'p'p'p(€3à'p?`5€ððððð…àžˆ°A°€'€(€(p'p'p1@ p ''p'p'p'p'p(€(€'p^þðŽ £€ð€ðPz@ U ¥€;` Aðƒ°Hp'€(€(p'p'% p @1'p'p'p'p'p(€(p'€{’ ‘ €€¨à ‘€ y ª@c@«P[° >€H€(€(€(p'p'p `p@'p'p'p'p'p(€(p@ PÀ•Prà °qð€ ¯ 0W€Hð§fp€(€(€(p'p'p"pþ0&30303030302à^0ŽÀ  ´P M y Ð ©` `X: :``[ «°H€(030303àð"Ðp0'p'p(`5P2`’ð º º@»@Á NP®ðj0 ÄЀ˜À m! % A°UÀWp(€(€(p'p)` p@1'p^p^ Ê0 ð lÀÀÀ Í °PÎð Ð=ຠMà …ÒÐ ÓÀ%€þZð9ð`W€(€(€(p'p)!Ðp @1'p^à5pË  ÛÐ ¸° D Õ° Í ÅP Ü€ ÈÀ Ø ÄÐ   ½p :I¦ÀfÀ uPVpH€(€(p'p'p!0p @1 X° ¿ð ¿€<`ÍÀ ÚÐ Å ØP Ï á  Ç ×°È Ù€ ßð À lÀX ã `AA° (€3€(p'p'p!pp'P’ð æ`Å ¹ â ßð Óþ0 BPCÀ» y€²à¯p ÑÀ Å Ì à @Iu°>@€(p'030 ðp@2`0lÀÔРѰ Ø Í0 ŒpWp(Àl ¨ð ëÐr€ P ÀP ÅÀ –` ÀhÀ•P É`G0Jð2pp'p%pP<€ÅP À  ê  á ÑP ×p Ï@W€'p4€@±®Àpð€¬€¹À ßÀ ê€æ` °«àVN_€H€þ%@p`lÀC€ÔÃ`Åð Ø µP gp(p(p^ `Îð ~ Ð qðq@ ÀŒÀ Ì ß0 ’P`X€H`_0Uð° ™dðžp€!`P`5À<0 ÃP Ø€ È l`'p'p'p^Pl°€  pt€%à<° º€ Ûp J0 Ó0 ™ 6Ð 9Z`Q`[` \ЭG l° Û€ Ê€ê Ø€ Íà™P C`'p'p'p{îàï`7pìÀ^ þl° ¸À Í` ð 50’ð`_ H€;:@{ 9[°<C0Cp° æP ØÀ Ñ B`)PõP)°{ðî óp"`@3ðópøŸ ×ÀMpXP€X€`H°™_€HT0­Ð"p^à5Àl@ÅP ß ¾@ Âô°ó?P{0î ó0`#àïð À íÐñ°Â0 ¾p€(0Wð`W€{€k`à!P^° æ0èP É  æð Øþ@ РÓPõ{àPðìP)€(ð{@{À6À Ñ ;ÐùÐý)P((€300'pH­P¡a  Xj°RÛ!–aÃv [/`ÓaR£†Œ3,\©1äF”i¸°E‹† Ù­5YZABâ (P @ʼn^>Œ@paBŒ'Nœ˜ÁJ¸qºÂ­ÀU Û¶kJ¸Ýò¥ä°i™„ «5Œ¶ožMû2äÆ2uʺ=B (P @ʼn'bŒ°w¡‚…)RÔX‚ ݯ!7j°YÒ0`ÍŠaÆ­˜8mܾqÃö [³eâÌ+6l6CnÔð°ÅŒ3f¤H‘bF…Nˆx`F… 2²7F2‚©Ñ‰¸'~©5”¸’ºS_„6woSk%•½ …¯>7±7\@‡°Nc25eyÿÓ¼f[MnŒ–ÉE‘.KkH]­!0YxzÿµœH;«h›³~u¥œÖs–ONjŒà™¤ÛD<Âãàà‡:L§n˜XÓL9KÎ$Øž¬K šå1÷o5t­ s±‰ë§ÿNô†#•Ñy¦|Maí-ô_#Ur/]ƒÉ6ALY‚FMÑTYx‘ª!þ! Imported from GIF image: bg.gif, Çõ‘ù}†ôswõdhò\aõWXóILîGKõ=Cö88ï-2ô#)í#(ú¨«ÿçèûÛÝZa[›—’çÀÃHKEêé êç ê êé$êæÿ®Õý 9,þ l+WEí&+é',ê%*éê#(ÿ%þ.PM‘G5uE2²7F2‚©Ñ‰¸'~©5”¸’ºS_„6woSk%•½ …¯>7±7\@‡°Nc25eyÿÓ¼f[MnŒ–ÉE‘.KkH]­!0YxzÿµœH;«h›³~u¥œÖs–ONjŒà™¤ÛD<Âãàà‡:L§n˜XÓL9KÎ$Øž¬K šå1÷o5t­ s±‰ë§ÿNô†#•Ñy¦|Maí-ô_#Ur/]ƒÉ6ALY‚FMÑTYx‘ªþ0€@$P @Á 0`  @8x!‚„ Ä`@¡B… >6(©!É,WÈ”1cæ š4PÔHiP ƒÆP`€‚…§O @…µd©R¦4b¢eÅ8V¨PÁ@‡1ƒxS¦*×+h8*©Ð !É'ãÐtâk¹? ÂÁ°‘Ƶl`€BŠp@ƒÃ~ ’ ƒCˆ)QÂHˆ#1¸p0¡‚*¨Ð‚—B†ÜØ1r( ˆl P¡BƒH!/`¼d¥AçØ,dX’)[–‰Y fβPº±bƒœþØuCÊ;\òÜÍÇbÄŠ T`³FkÔ4,¨`°…#˜À' €‚ $p@ @@ (¨€ (0°À ,´à /Àƒ   0À€(T@0ðUXqWdƒ Zð Â8á\Ô@ *¨ ‚ *h`‚tÔ…náÅxä‘z¬À€*˜3ŒA*¨€ D0BÀq$‘`!É$PB +8¢‚ ˜À ƒ°ñ ¶Ü *—Ü‚K(ªä¢K,»ìÂK|ÒË0¬b*˜Àƒ€ƒ.ÖXÌ5Øt`g0‘6þV`QÊ6ÜЂHzT² 0¤¡&Ý(°†  B‹,£¨³Ž9å˜Ãΰ†:¡´ã4~ሠFà°ÂC0À@%ö\²ŠÊ£Ë+–sM(¹¼¢Œ;ºH!Ž8k\€`\,@A\€`€`€ 0À\Àxð!ˆ0 %(  0À€Ìp4Tð€T@EX\áÅ6¼ C`ÀpDþb¤ÀcP 0À€ >øk°ÑÆd¸ñqÈ1G :|`ƒ)0 ALA *¨ ‚    {ð…n¸Ñ‡ˆ‚Ø€(˜PÁƒ$ *¨ ‚ ,°g(rÇ"`ÁH#ŽŒ0+, * Àƒ(A*,PI Xr &KèB™h² 'zÑ BØ (0Àƒ ˆÀ "ªX+ZáŠWÀ"²˜-` †Cˆ@µXÁT p ƒ˜nŠTøâÀF&‘a C }P0ˆ±‹bhÁ”Ð"l pþƒ(À3Dñ‰UøâÐø R€ >DCn¸Â4¨±ŒLì¢`È °GHaƒƒ¤ Q¼âÞè T‚âà(Ĥ ŠeÈÁáG(#ACÀÄ/> U¼"Øè€’Ps˜Ã‰ÀÌqtèátX…V 8"‡P€Þ±Œ\C­àÁ:xÄÃbÀ”a9Ä#ž`aØ€œP :°z,ã´¸E=®†wìÀ`F(tƒ?¸£Ž@P€˜€‰`€pLˆá¾ >nq]Üâ·ðÅ\¡Š? `  P€à ;trf2.1.4/doc/art/logo-60x90.gif0000644000175000017500000002154311216343142015322 0ustar sergeisergeiGIF89a<Z÷ÿÿÿþúúüôöþéëýÖ×ýÌÑüÆÉûµ¸ù¬µø•˜ø‰‹ôvxôiuögkñYdñTXóLUí:Cí6;ì,4í#)îEKõññ]tfQWK¡£žGUHù¥§êêéé è ë"&).)=1ÝáÞk•©DIGÿ¡•K'Žw]¶Ìg“σº,6,$Î.E4J¯ŽP²²ç°K†w—Ün¤¿«Óâj‘o&f‡4q”Ug‡™Òæ.”ÆEW/&^qWpеƒ«†®w®é+XK(‰Mdж*wœ"RjÀÒÝ*}¥{¥!_{·ÎGm&ƒ«R#/{§'ˆ´3’¹SmîVZuš#d{1‰´ )6O-‚«0ƒ¬3Š©)Vq4Eé"(æGŒ²“ÇŠ8H•Å4$`}ù|„éÒÿSZp¢Ôp‰.<2ŸjH> Pȵ)ETig†ùmût£`î7#ÿÖÿïê +öX±œÿÈØ¥ÿ¯¢Yä_$zÂ5•Ÿÿ@¨eDhgmh!×–­¾!þ! Imported from GIF image: bg.gif,<ZÇÿÿÿþúúüôöþéëýÖ×ýÌÑüÆÉûµ¸ù¬µø•˜ø‰‹ôvxôiuögkñYdñTXóLUí:Cí6;ì,4í#)îEKõññ]tfQWK¡£žGUHù¥§êêéé è ë"&).)=1ÝáÞk•©DIGÿ¡•K'Žw]¶Ìg“σº,6,$Î.E4J¯ŽP²²ç°K†w—Ün¤¿«Óâj‘o&f‡4q”Ug‡™Òæ.”ÆEW/&^qWpеƒ«†®w®é+XK(‰Mdж*wœ"RjÀÒÝ*}¥{¥!_{·ÎGm&ƒ«R#/{§'ˆ´3’¹SmîVZuš#d{1‰´ )6O-‚«0ƒ¬3Š©)Vq4Eé"(æGŒ²“ÇŠ8H•Å4$`}ù|„éÒÿSZp¢Ôp‰.<2ŸjH> Pȵ)ETig†ùmût£`î7#ÿÖÿïê +öX±œÿÈØ¥ÿ¯¢Yä_$zÂ5•Ÿÿ@¨eDhgmh!×–­¾þ @€€0pA‚ 0hàà„&P PA°pƒ2hØB‡+V¬X±bÅŠ+V¬ð0@+T„À*V¬X±bÅŠ+V¬X±¢Å‘#+œì(‚#‹&L4Ð8'€X±bÅŠ+V¬X±b…Š <¤HÀ…Š+V¬XÑÁÅnÚ¼yóN+LŽ8qRÄˉ 86ä(R',Xx  €,V¬X±bÅŠ+V¬X¡BE€V¬Pña¡7wîܹƒg 2~pÀÄ ’8NþAãÄ.D¬X±B<øÀbÅŠ+V¬X±bÅŠ+¬°Â +¬ÐA!‚ÀqÇwÜqÇwà¡È"Š\;ÀÀƒg8A +¬°Â +¬°Â ,¤ €@ "¬°Â +¬°Â +¬°Â -ˆ  )$À)qø1Ç$ PòÆxHB„VÈ $,bMÁ +¬°Â +¬° H@ "¬°Â +0aÅ2ÄðR‹,:ÈrL/°0s /Í8ã…,Ç4.•<ƒL/Eü Ä F,‘ÃQtáÄ +¬°Â +¬° T ,¬„¬Ð 4þ¼HM3«T±HG¬ÐAlh¢À‘qCL4ÑãBЃ ?°D3 AD +¬°Â *€`à L¤a…,´M3«LQÅG¬°Â +¬ÐˆÇ$˜ò†oRˆºìÍ1Ãp ä8á„;x'€²D/„¡D$ Ci¤‘\ðò 4È4“Œ M€<ìܲÂ-ì´s P¡+¬†<ó”s 2ÔñÈð@BD e´pÄD‘NôpÃ"9@à Rˆ-”‘Æ7Ç4M/ƼrÌ9VÔÐà ,°À +¬ÐCVœ³Kþ4ÐDƒÌ*SLQŒNp±Â +¬°Â +¬°Â +¬BP B€B:èà5t 1ÀôÓ0¿DcÌ/Æ@Í/¼ð /¶„£À*Àðb‹,<ÁH0xà|𠀂 PР+¬À +¬À +¬°Â +¬°Â +¬°Â +¬°Â +¬°Â +¬°Â +¬°Â ,°°‚ ôЃ?Bz!À`@ BŒp‚€€,XÁ V°‚¬`+`Á¾t *R ‚¬`+XÁ V ‚„À.ø€Vp0ÜÀFÜ †)œþ0ÀÀnP„ Ac8ÀD°‚¬`+XÁ V°‚¬`,Aøà°`+Púà†7äáw¸Ãðà'Ô¡7 r!àEøÃÔð°`+`A P ,XÁ V°‚¬`+XÁ V ¨¡+X €@†9Èáw¸Ãîp‡;ÜayxD®à` t8ƒ(À‚¬`+XÁ VÀHÀBÀ‚¬`+XÁ V°‚¬`+XÁ V°ˆ z˜ÃðˆN8Bw¸4á‰|â[ (nЄ#´`+XÁ V°‚¬`*þø +XÁ V°‚¬`-XÁ Ò ‹]ð¢P€+lÑ‹ àB ¾ØE/4€M°_Hƒœà!,H` V°‚¬`+XÁ X‚@@°&X¡ÒÀ`ƒ¿ˆ4šÑŒcìÂ˰Å/hA hD#шF*²‘†4„âÚØFN€#€‚ GXÁ V°‚¬`è€Ô RÄ4¤! +È‚ÍX…3’&¬`˜úÐ Gh"ðƒ&îp‡7ØÁÀ€F3ˆq lì"âȱ„E,á2`ÂV°‚p8þ€ Ò. ã¬ 4¢Ñ npãeXÁ V°‚¬``CTÀX D` ÊZ#ǰÅ.vÁ tH!0€œÐ /€¶°€€"Bd±‹c@#Ñà2^ñŒyÀƒé`nv° ,A7´‚¤Á»hÆ1t1„zàØ`ÅD°‚´à-XÁVà„'TA€ (°‚¬V …6†a+ЂÆh†1¢ ôâ¯85ŽÁ‹d #ƈF4X±Œ_ô@€ Å,¸p„¬`+XÁ V°‚¬`+`A€ € !HAþ R‚„ð€:Ш@*PÁ VÀ‚°€+X(À‚´ -ABà $@0€À/€A Ì€€Z°‚¬`+XÁ V°‚¬`"PAD°‚¬@ AD°‚¬`+XÁ V°‚¬`+XÁ V°'< Qœð„)a?@ 6p‚x +XÁ V°‚¬`+X :¤@PP¸@+XÁ V°‚¬`+XÁ Vp.dÁL8‚žpÀ00 Nph AXXÀ‚¬`+XÁ þV°‚tà  \0-¤@,XÁ V°‚xÀ DÀ+pÂа!¼ 0ÂN€ƒ á hp<0€€`+XÁ V°‚¬`+XD €Á V°‚ˆ  €Þð9ÈáxÀà 0`üÀ LN€ƒ+ N` XÀ€À8€TÀ‚¬`+XÁ V°‚¬`"¬`è@ñ9Üáw¸Ãôˆ#°À hÂN°#l¡b°à€°`+A€¨ ,XÁ V°‚¬`+XÁ Vþ ‚B*XÁ BD¼w¸ÃDèA98ÁrƒE¼€[˜œÀ‚°@+°+°+Ð à,°+°+°+°+°+°+°+°+ÀPˆðwpwpwpwpwps0 u9p^€NÀ+°+°+°+°,T à,°+°+°+°+°+°+°+°+À"@  wpyÐw€‹[pK`KÀKPOà+°+°+°+°+°" +°+°þ+°+°+°+°+°+À!À  £0wj@ o wpxP NÐÀH8`=p+°+°+°+°+°à"°+°+°+°+°" «À ­Ð ) ® S0r€Zð °†à±00$€82@"°+°+°+°+À @ ,°+°+ÀV0 ÃÐ V@À Äð ©Ð ¾` ½ÅÆp ðx„€ Éð NÀ+ð‹€/pG°+°+°+°+À  þ ,°+°,ÀLÀÀ@ Æ ¼ ´ Ñ Ñ Ñ` Æ ÆÐ ¼0 Ì€ ÑàQ{ ¹@ 2@8hàÕ°+°+°+À0ð-P«@ ÄÀ ´P C  ´ ÑÐ ÇÀ <D€š0“Ð Þð«Ð Ò Ð° Ñ@ Ø ;ð0 °9 Np+°+°+°*ð à,ÀÐ@ÐÃ@ Æ Íð ËðMÐ" ‰0Á@r £àË ÐÐ 80]` ] µð #þÀ8]ÀG°+°"0 ©0 Ç Æ Æ Ñ` ´@i°+°+ð…@ o  s` Ðy€yàP¿@ Ðp Ãi {à¹p?@0°f2N p ,À+Ð@ð Ä` Æð ¿Ðe°+°+°+° ž0 ào€¥ P@ð ÇÐ Ì@ Ô@ USР0ð?[0a°8[Ù  Ú0 »p Ä Ð` ^Ð Äp=À+°+°+p ìÐ,! Œ,À+þ=ð Çp °àÐ"à2°apGàbð$DÀAK° °+°+ 6  »Ð «° Ôà öзÀê,p ìзÀ*ÐdÀï õ` ÆÐ Í€ «à A0`p+°GÐ/?pN U`1Ð PC° Ú° Ã0º@ ÆÐ °ðÌ ¡`@,·ð·À+ "€`¡° Ç€ ½PÅÐMÐLÀ-À+°+°+°-°-@;@"°,Àeû€ Çp Æ` Ñ@½@ «Ó V@þLV0^ ÇРр ½`­° Ç@AÀN@+°+°+°+°+°+À) 0-@+°=ð Ú0 DÀ"R° Ð Æ Ð ÑÐ ¿` Í Ñ ÑÐ Æ »@ ¿ð ¼ @P@P+À,À,°+°+°+°+À   ppÀ ° ð Ðààð ! ðàÐ" " "Ð#@%`p( " + " ,À,À,ÀþÀ,À"À,À+°+°+À,À,À+°+°+°+À*ð)Ðà56ð67€9`:°/@< *°+°+°+°+°+°+°+°+°+°+°,À+°+°+°+°+°+°+°+°+À+pHJpGpA°8pLÐE`*°+°+°+°+°+°+ ÀT°"° ,à+°+°+°+°+°+°+°+°+àOP Và;p8À09p<ð°þ+°+°+°+°+°"Zð+TÀ  +°+°+°+°+°+°À? GpNP3 0`V@8`8p'p[а+°+°+°+°+À@ °) ð) +°+°+°+°" "°+°NÐQ>àNpEà'pB°°7EPAÐ À+°+°+°+°+À@d* ð+°+°+°+Ð)P@P GPA<`>àV@8p'`þEPEph° °+°+°+°+°+°*  °+°+°+à.pkÀm°"pNpApB`[ '`EgàN@  +°+°+°+°+À*0_Ð.0+°+°+  °oðr r0t 2pLàu B[°APhàGÀ,ÀPÀ +°+°+°+°+°+°,ð_`Ð+°+° `owpwps O°8€0þV €KPb-À,À,À)°p +°+°+°+°+°+°+ )À+°" xðwpwpx0€N€Eð< [`'pEà|Ð+°+°)P +°+°+°+°+°+À*ðd@À+Ð! ƒðypwpw€~àD@= D€A°[€3pNPÐ+°, .`Р+°+°+°+°+°+À* d°*°,ð…Àpwpwpþ† €P0`?ÐaàWàG  °+°, À0Ð,°+°+°+°+°+°"ÐŒ "°"ðÐopwpwpx0Ž0S 8p'°8pFGà+°+°+°+°,Ð" à,°+°+°+°+°+°+°+°+À ‘rpwpwpwpwps Œ€E`€3ðN°+°+°+°+°,ð ð,°+°+°+°+°+°+°+°+ÀþP”ðwpwpwpw€x0•`  :À8@SpG°+°+°+°+°, ,°+°+°+°+°+°+°+°+À wpw †pw0Š€ 8$ð{ K@Hà+°+°+°+°+°+™ ,°+°+°+°+°+°+°+°+ -›€wpyÀ mw€yàEð08€9°]à+°+°+°+°+À*à ,°+°+°+þ°+°+°+°+°**‰0x¡pxpw€š LàH`[Gp+°+°+°+°+°*ð@‚,V¬X±bÅŠ+V¬X±bÅ )8h`iÎ= L½¹ƒgN¢@@˜8á‚*ެX±bÅŠ+V¬`ÑAH!bÅŠ+V¬X±bE‹#@Z¤I£ƒªTW4ÌuÀ”"UsB! 9–ð‚ÆÉŠ+V¬X±b . À+V¬X±bÅŠ+Z´"k­Z.2¹²+ˆª[^Á ‚g.¹>}þútæŽ]ˆ¬X±bÅŠ+V°`b ±bÅŠ+D0’H €jýúµj+`½‚S# ˜ wàpB”ê…#GH䈪I‹+V¬X±b !@‚,V¬X±ˆ’Y´jñâˆeŽá%• Ö†— >qà˜c4ÀeŽ„¬`+XÁZÐ PxA ”á.̲àlP`ü¢«è…3h±‹P,` ¸À¬@*ø‚ê@‹cD£«ÂŠá„#ˆ@+XÁ V°‚¬`+XA Z`ƒʰ´ @ØÇ1¢f4#ÔHF2†à 0¡ G8€Pƒ!$ƒÍh1~AŒWô"U(ÆZ°‚¬`+XÁ V°‚¬`)H" ¬`+A± þl£ÀˆF4šÑ X¼bSH7ŒáŒ^¤‚Ë F3  ^œã@Ð1°A 18a+XÁ V°‚¬`+XÁ X@*XÁ VÐ ´B­Òˆ_@#шF4Œh¬‚¼€†1šhƒ¿øÅ/j¡‹4 ºAV°‚¬`+XÁ V°‚¬€ P†(а€L…,˜Pt ­ØÅ1V± ^#ш4¢h@ÃÐXÅ*Р`ü‚µÈ†>ðxÀè€ : ¨@* D‚ €¨€2Ð p üñ‹_@œÂ¸4ŒÁ ^ðÂÆ`Å)® ^ðð…1x! _ À0€ ` PÀ8@;trf2.1.4/doc/art/logo-16x16.gif0000644000175000017500000000354411216343142015322 0ustar sergeisergeiGIF89a÷>/?.;)+#&?452#<50,,M;8EC/E7F0B1.Yw0Sp#cq1o~;k}RUJ4E5+H6%K1)U2%T4.s$x*`, b0.t,)t62r>9}.GRA4LM`V`i`F@fAOeDLfGXvHRjUltLkLdv\vep] ˜… Š £±;—;” '™/Ëk‘v–´/BŒ=F²6Y£4jŽ%x (}§?¤H‡O6–X@žFeˆGwšDx›|J—pRgb‚TiÅНг޹ ов ‚¤%€¨"‰³/‡´>ˆª‘Á‘Á%£Ë7ªÕD˜™U¼‚'%–*/š&'ž&'’:$’33“6:Ÿ98´º¿²(¢#!§1:²->ž7K’=Q€%}¥9K¹?L¦@0…NM˜KLƒNgˆ\rŠoj‘h|¥WP´N_¾JQ±P\ÜØÅ%É%/È+.Æ1?Ï5;Ó7>Ü8=ææèéëèï ïëèíííìðÿÿÿÿ ÿÿøÿ öÿÿÿûê$ë$í"ï%÷"ÿ"ÿ$ÿ%ÿ&ÿ'ÿ ÿ!ÿ"ÿ ÿ,ç#$à'.ê %ë &í"&î %ë#(é&+ë$)ë%)ë$*î#(ï#(í$)ï%*ï'+â*2ï,1î03í48ð %ð#'ò"&ö %ó#(ð$)ó$)ð*.ÿ1!ÿ3$ÿ2.ò07ð47ó46ð69ñ8=ñ9=÷:;ÿ<:ä=Cõ>CÍjÿCÿYØklðAEñFGòLMóRSô_`ÿ\aåbbîhn÷abõbeòdjôehñhlôilóx{“~˜•~µ´yž±€ªÞŸŸèƒŠö‚ˆô…ˆö”—ú¬®ø´µúº»ûÉÉûÊË!þ! Imported from GIF image: bg.gif,Ç>/?.;)+#&?452#<50,,M;8EC/E7F0B1.Yw0Sp#cq1o~;k}RUJ4E5+H6%K1)U2%T4.s$x*`, b0.t,)t62r>9}.GRA4LM`V`i`F@fAOeDLfGXvHRjUltLkLdv\vep] ˜… Š £±;—;” '™/Ëk‘v–´/BŒ=F²6Y£4jŽ%x (}§?¤H‡O6–X@žFeˆGwšDx›|J—pRgb‚TiÅНг޹ ов ‚¤%€¨"‰³/‡´>ˆª‘Á‘Á%£Ë7ªÕD˜™U¼‚'%–*/š&'ž&'’:$’33“6:Ÿ98´º¿²(¢#!§1:²->ž7K’=Q€%}¥9K¹?L¦@0…NM˜KLƒNgˆ\rŠoj‘h|¥WP´N_¾JQ±P\ÜØÅ%É%/È+.Æ1?Ï5;Ó7>Ü8=ææèéëèï ïëèíííìðÿÿÿÿ ÿÿøÿ öÿÿÿûê$ë$í"ï%÷"ÿ"ÿ$ÿ%ÿ&ÿ'ÿ ÿ!ÿ"ÿ ÿ,ç#$à'.ê %ë &í"&î %ë#(é&+ë$)ë%)ë$*î#(ï#(í$)ï%*ï'+â*2ï,1î03í48ð %ð#'ò"&ö %ó#(ð$)ó$)ð*.ÿ1!ÿ3$ÿ2.ò07ð47ó46ð69ñ8=ñ9=÷:;ÿ<:ä=Cõ>CÍjÿCÿYØklðAEñFGòLMóRSô_`ÿ\aåbbîhn÷abõbeòdjôehñhlôilóx{“~˜•~µ´yž±€ªÞŸŸèƒŠö‚ˆô…ˆö”—ú¬®ø´µúº»ûÉÉûÊËþ±= ö«X-R¼’í¢fŽÛ9%¾U ´ä‡–jœà@2Cø–ÒåèÜ&w4b| àŒ¸Dëà°¸â (mä0ái¢ÆKš võ’5 Ý ” ÚSÇJ S„Ésmš4aê;trf2.1.4/doc/art/logo-120x181.gif0000644000175000017500000007671111216343142015467 0ustar sergeisergeiGIF89axµ÷ÿÿÿûÖ×úÈÉøº¼ô‘“ñhkïZ^ê#(í8CöëøDJ;BB5  =>15UA00'CE;ó„†ì,62D402'BTFBC5xytduk7H815*lmj ]aNSTM3R=ë154:. inW9¡gÃíÙòdeaˆmâ#/ª X+E4%##!VeZM]S&*!*,#,H8·vÃ/80,-)§E•µ!RŒ0‡â_‡Î”Ñ·2mzsÐVŒ"#Ów°)g†*n+v›/€© !Ë3_+o‘ßHm-wœ-~¦!.x.¨)i‰Üy©.xœ/ª,v›.§5($,&`}/‚ª'f… )m-9(h‡.€¨1º'j‹¿!K*r–,7ÎG{\K'B2õkðDÿÜû¯ù“í6"ø†óXì*&ñNý½ !þ! Imported from GIF image: bg.gif,xµÇÿÿÿûÖ×úÈÉøº¼ô‘“ñhkïZ^ê#(í8CöëøDJ;BB5  =>15UA00'CE;ó„†ì,62D402'BTFBC5xytduk7H815*lmj ]aNSTM3R=ë154:. inW9¡gÃíÙòdeaˆmâ#/ª X+E4%##!VeZM]S&*!*,#,H8·vÃ/80,-)§E•µ!RŒ0‡â_‡Î”Ñ·2mzsÐVŒ"#Ów°)g†*n+v›/€© !Ë3_+o‘ßHm-wœ-~¦!.x.¨)i‰Üy©.xœ/ª,v›.§5($,&`}/‚ª'f… )m-9(h‡.€¨1º'j‹¿!K*r–,7ÎG{\K'B2õkðDÿÜû¯ù“í6"ø†óXì*&ñNý½ þ@€ @ € 8pàÀ ,0hàà„8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀDþüPQ¤ÃðP"Ä #8pàÀ8pàÀpÀpÀpÀpÀ|‘cpÀpÀ@@pÀpÀpÀpÀpÀpÀpÀpÀpÀpÀ0‚±ÂpÀ¤à PÄRXñ@SpPFTpÀpÀpÀpÀpÀpÀpÀÐ pÀpÀx^pÀpÀpÀpÀpÀpÀpÀþpÀpÀp€R8ð:dpÀpÀ$øàÄ0àì@pÀpÀpÀpÀpÀpÀpÀpÀpÀjpÀpÀpÀpÀpÀc"ˆ ~øá‡~øáÇ pÀpÀp€;ìÐDTÔ`ƒX˜ÁÁ t0P >0pÀpÀpÀ`@ÀpÀpÀpÀpÀpÀpÀpÀpÀþh€ÆpÀpÀpÀL…â‡~øá‡~øá‡~øá‡~0rÀPxÀ@?ü0Å BhÅ#ÄD?ô°€øàÁpÀpÀpÀpÀ ÀpÀpÀpÀpÀpÀpÀpÀp´qÀpÀpÀh&á?øÁ~ðƒüà?øÁ~ðƒü°ˆà8Àp€à8À  8á gÁ *Q"à8ÀÐá8Àp€àþ8Àpp€à8Àp€à8Àp€à8Àp€à8À¾Ð†à8Àp€€ „üà?øÁ~ðƒüà?øÁ~ðƒüà?øÁ H|àü ! ÃΠ…`áR¨&p€à8Àp€à8Àp€à8À`p€à8Àp€à8Àp€à8Àp€à8Àp€à8Àp€´~ðƒüà?øÁ~þðƒüà?øÁ~ðƒüà?øÁ~`D5à8B(1);8Àp€à8Àp€à8Àp€à8Àp€à8Àp€à8Àp€à8Àp€à8Àp€à8Àp€ ~ðƒüà?øÁ§@D!üà?øÁ~ðƒüà?øÁPhÀ|ÀPB (p ´€…!ˆâ8Àp€à8Àp€à8Àp€à8Àþp€à8Àp€à8Àp€à8Àp€à8Àp€à8àÁðƒüà?<âxÀƒüà?øÁ~ðƒq€à8Àp!\@ ZˆÃ( ˆâ8Àp€à8Àp€à8Àp€à8€`€à8Àp€à8Àp€à8Àp€à¹-v±‹]ì"8 ‹]Ђµ¨E-ná‡EØ-†AŒZÔÂ~ðƒþüð  8Àp€à€%„Ð8ˆá8Àp€à8Àp€à8Àp€à8€p€à8Àp€à8À ‹\ƒ»ØÅ.v±‹\àÈ…0„A Z c»Ø2°‹]Ђ´¨Å-jq‹ìb´ -ˆAŒZøÁ~ðƒxÁ‹_ж8À`Á B~°À€Ÿ`Åp€à8Àp€à8Àp€à8p€à8Àþp€à8Àp€à²ØE1Œa Z8£Å0Æ/hA Z(CÊP†2”¡ e(CÊP†2”¡ e(CÊP†2”¡ e(CÊP†2”Q [´á8Àp€Ђ´ …-°;ü@o%„p€à8Àp€à8Àp€à8À 0à8Àp€ä"»0†1ŒA‹]ìbÅÆ/~A ZЂʨ…-ˆa‹à8Àp€€Aˆðƒüðˆàxðƒüà?øAÂøÅ/~A ZЂ´ -hþa‹ \PÁ  ‚l`AGÀ~ †WØaN8Àp€à8Àp€àp@ppppppppp»° ¿ð ´@ ÊP Ä@ ¶@ ppppp]d0p­à~à~pÖà~à~à~à~à~àx ´@ ´@ ´@ ¿@ µ@ ´@ ´@ ´@ ´` àEP+ð u B @À¯pppppp`pppþp »° Å` Æ ´@ ´@ ´  ¿` ÆP µP ppppppppdÝà~à~à—à €~à~à~à~ð`€ppÂ` ¿@ ´@ ´` p°E€š@JpppàŸÀVÀv `€E0*° šppppppppp° »` ´@ ´ð ¿ µP ²ppppppppppppp –ðþxà~à‹ppppp° Æ@ ´  Ê  ´@ ¿ð ¿ð ¿ð Æ@ ´` pž`š  ppp>p‡ð š   â0U`ošpppppp° »° »` Æ` ´  Ê  ´` ư pppppppppå`èpppphppppPæp@ ´@ Ê  ´Äp ÄppppppBppppp> ãþ ðppà; b€gppppppp´@ ´@ Ê  Ê  Êp ·@ ´@ ´ ä`æpppípppå`çppppp pppPæ@ ´  Ê  Ê  »° » Â@ ´@ ´@ Æ ·pppppppš ppppPàX Xð pp° » ²ppppp° »° Æ` ´@ Ê@ ·P ´@ ´@ þ pppppppppppppp·@ Ê  Ê  Ê  ´@ ´p ·p ·P µppppppppppppppppp``ppppppppÅ` ´@ Ê  ¿p Â` Æ` Ð@ ´@ ·à Ê  ´@ µP µ Ï@ ¿ð ¿p ½à ±0 Ãp ·` ´@ Ê  Ê  Ê@ ´@ É€ ³0 pp° »° ¿` ·pþ ppppppppppppppppppppppp»pppppp° »` ´@ Êð   Â` Æ@ Ê  Êð ¿ð ¿ð ´@ Ê  Êð ¿ð ¿ð ´@ Ȱ ³Ð p»° Å` ư »° »0 pppppppppppppppppppppppppppþppppppppppppppppppppppppppppppppp  +À-À.0/p0`pppppppppppppppppppppppppppppppþpppppppppppppp>°CP @ppp ÀRpI@Tpp°T@`3@pppppppppppppp€cppppàpppppppppppppppppp°ppppPà@ W 0G°S€0#pJàþ?$àppppppppppppppmmpppÐippppppppppp8 cppppp>@> #vPEpp5°@°VP=À@°àà$pppppppppppppppppppppþppppppp†à~à~à~à~à~à~à~@[€\0!ðppppbpR [03p)°>àppppppppppppppppppppppppðppppppЂà~à~à~à~à~à~à~àppppp;à$° ‘à+pþ@Dàppjàpppppp`pppppppppppppppp€hpppppp}à~à~à~à~à~à~à~ðp‹0X€6° ZPJ€EpX J'P*°D@ppp€pppppppp`pppppppppþpppppppppppp„à~à~à~à~à~à~à~à~à~à~à~à~à–€p€5ÀJà0à•°ppppppppppppp@ppppppppppppppppppppp0 ~à~à~à~à~à~~à~à~à~àg€Xþ0U€ w  *àb LP* ¤ ppppppppppppp`8pàÀ8pàÀ8pàÀ8pàÀ8pà€š8àÇ?~üøY´h!?~üøñãÇ?~ü¨BpàÀ8 fA‡ °l:pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pÀ×þ8pà²vѪU«V-?~ZH@¯_·jõòãGЭU¥4Y¡°¡Nv¶Ôøt†Â”SBQÀtàÀ8pàÀ8pàÀ8pà"8pàÀ8à€8à€8à€8à€8àa„¡e—]vÙe—Æ`—]h¡å–Zn©¥•tÙeZh!†˜ZjñÃ?üðb~ùÅ[l9à€8àHÄXC-BC”8à€8à€8à€8à€8à€8à€$à€8à€8þà€8à€8à€rÉEcŒÙe—]v)&—„†Zh¡…e”QFe”QFe”QFe”QFehYŠZjñcZh¡E(ì @E(°£ !ÜÐbMÀB ,øX#Š,9à€8à€8à€8à€8à€8à€ à€8à€ˆ%–YfÙe—]vÙe–Yd9à€vÙ¥hŒ¡…e”QFej©Å˜Y8à¦ñÃ?üðc‘ð?¨¡…ZhQFeh¡åZŒ1æ€b~¡…Zh±å€ @ˆCVÐâ 'V"!þ8à€8à€8à€8à€8à€0à€8à€8à€8à€vÙ¥cŒ¡…Z”QFeŒá…—j8à€8à€8à€pÅ?üð£•`?üðÃ?þ8à€v†Z”QFe¨á‡C(P¡8à€°Å–fŠÐD›:` ê8à€8à€8à€8à€8à€d‘e–Yf¡…Z„F˜]vÙeZh¡…e~¡Åcª9à€8à€8à€8@Iüðƒüà?øá—Àþá?øÁ~ðƒüàn`Å(†1~A ZЂ´ -Œq€à ÀBÜ „"¨ p€" …O¬¡ ×4…à8Àp€ €à8Àp€à8Àv± cô¨-hñ cã8Àp€à8Àp€à8À&€†BÂÂ8@?øÁ~ðC8Òp€à8ÀvA Z(CÊxÆ2ˆa [há¶°…-la‹ZØâ8€N°‚C€€ €!@À Bˆ Q†7P¡@þ`€€Â0†1 A ZЂ´ …2h¡ e(CÊøE-jQ‹[ìâ8Àp€à8Àp€à(9ÌqŽà8À¼€4à8Àp€à8ÀvA Z(C´E-ÌaŽà8Àp€TB b(‚"¶p€à8À<0,C8Àp|âãЂp€à8Àp€à8Àv±‹]ô Å-nQ‹]ìB·8;Ìavàä0‡9p€à8@9ÌŽà8Àp5€á8Àpþ€ æ8Ç.hA e(CÊP-hq‹[Üâ·¸1ˆa‹à8Àp€àhø‡!à8Àp€DAp(p€à8À` cЂ´ -hA‹]ìbÆ0†1hA e(C·¨…0„‘‹à8Àp€à8Àp€°ã8Àp€ ^8Àp€`´P†2”¡ e(£µ8Àp€à8Àp€à8Àp€à8Àp€à8ÀpHŒãp€à8Àp€þà8Àp€ Æ -”¡ e(ƒ´ …2”¡Œ[ÜBÂè-„!Œà8Àp€à8Àp€ ¿0-h¡ e(CÊPÆ/v±‹]ÃÆ0Æ-nq‹[Üâ·8Àp€à8Àp€à8Àp€à8Àp€à p€à8Àp€àh4Œa Zà8Àp€ Р-h¡ eüâ´ -hA ZЂ´PÆ-n¡ ZÐBÊP†2”¡ e(CÊPÆ/~! aü´ØÅ.v1‹Yþà8Àp€à8Àp€à8Àp€à8Àp€à8Àp€àp€À $P cЂÆà`»0-h1‹]ìb»ØÅ.Œa Zìb³hv±‹]ó˜Å,fÅ.ŠaŒ]ì€ €þ€ @ `à8Àp€à8Àp€à8Àp€à8Àp€à8Àp€à8Àp€ € Ø@8Ð`€¸8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8þ€8€8€8€808€8€8€8€8€8€8€ð È8€8€8€ðè € 0€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€"H&h‚8€8€8€ð"À€P'x8€8€€p€$ˆ0€8€8€þ8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€ð€È-€8€8€8ð€-P,À‚&à€$à€È.(‚ €8€8€8€8€8€8€8€8€8€8€8€8€8€8€˜€ð‚8€8€8€8€@48€8€þ8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€ Ø!¨ à€8€8€X€ ÀH%ƒ*8ƒø($ ‚€8€8€8€8€8€8€8€8€8€8€8€8€8€8€6ƒ8€8€8€8€1Pƒ 8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8°-€3Ђ8€8€8€`pƒP€P7€ƒpþ€ ¸ à€)¨ ð ðð€8€8€8€8€8€8€8€8€8€8€8€8€8€8/€18€8€8€8€4è‚8€8€8€8€8€8€8€8€8€8€8€8€/ð/ð8€8€8€8€8€`P&(‚ p:à€8€8€È )8X*P"ð `hØ8€€8€8€8€8€8€8€8€8€8€8€8€8€8€8€€8€þ8€8€ Hƒ8€8€8€8€8€8€8€8€8€8€1À<È=ØH€8€8€8€8€ ð¸Ø€˜‚X€ àƒ X#X€"ð`ð8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€ð‚8€8€ø€/8€8€8€8€8€8€8€8€8€.€Bè?ð?ð?ð?ð?ð?ðˆ88€8€8€þ8€8ð 7ø-P'à ð`ð8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€/8€8€8€8€8€8€8€Cð?ð?ð?ð?ð?ð?ð?ðDH„€ Pƒ!øC8€0%+(À7H€‚8€8€8€8€8€8€8€8€8€8€8€8€8€8€8þ€8€8€8€8€8€8€8€8€8€8€˜€68€8€8€8€8€8€8€6p?ð?ð?ð?ð?ð?ð?ð?ðƒE8€8€8€ 1¨ ø!0*((Ø"8€ H€18€8€8€8€8€8€8€88€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€ð ƒ8€8€8€8€8€8€.€Ið?ð?ð?ð?ð?þð?ð?ð?x„8€8€8€8€8€8 x‚ ˆ„-° „`"8€8€8€/è‚8€8€8€8€8€8€(8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€@8€8€8€8€8€8€ €?ð?ð?ð?ð?ð?ð?ðA¸„8€Ø!81P28€8€8€+P&À(L8€8€8€84ø‚8€8€8€8€8€þ8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€ð/8€8€8€8€8€@0?ð?ð?ð?ð?ð?ð?ð?ð?ð?ð? (‚ ˆƒè€è„-8ƒ!È!Ø-˜ƒ8€8€8€8€8€8€8€8€8€8€8€8€8€0€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€ 8€8€8þ€8€8€H=ð?ð?ð?ð?ð?ð?ð?ð?ð?ð?ð?ð?ð?Hð`€5À‚N˜HXƒ(‚À„8€8€8€8€8€8€8€8€8€8€8€8€8€0€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€6H?ð?ð?ð?ð?ð?ð?ð?ð?ð?ð?ð?ð?ðƒK€48€-P-øÀ„8€þ8€8€8€8€8€8€8€8€8€8€8€8€8€ €8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8?ð?ð?ð?ð?ð?ð?ð?ð?ð?ð+¨‚3€)Ђ-X€"8 ‚M8P9…8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€þ8€8€8€8€8€8€8€8€8€8€8€8€8€0?ð?ð?ð?ð?ðI ?ð?ð?ð?ð" €'P‚(-à!À8‚€„3‚M…8€8€8€8€8€8€8€8€8€8€8€8€8€(pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀE~üøñãÇŸFFéñãÇ?~üøñãÇÏŸc8pàÀk6pÐâ„ʦ8þpàÀ8pàÀ8pàÀpàÀ8pàÀ8pàÀ8pàÀ8pàÀÐåÀ­üøñãÇÏŸ®øñãÇ?~üøñó'Ñ8pàÀpœpPA%«8pàÀ8pàÀ8pàÀ`àÀ8pàÀpÀpÀpÀpÀpÀpÀp -µØRË-~øáÇ%¸`ˆ~øá‡~øH"8A&þ6qb¡EXH!…ˆ‘Å&pÀpÀpÀpÀpÀpÀp@pÀpÀpÀpÀpÀpÀpÀ¹äâ‹/»ì²‹/pȲ -µÔRK-·øñÈaà‹/¿ÜRK-~øá‡~”ÂÇXlAhÅb@â€?&BpÀpÀpÀpÀpÀpÀp@pÀpÀpÀpÀpÀpÀpÀä" þ-´ì²Ë.»Èrì² -´ÔRK-µøq.ìB -´SK-~øá‡~ä@1ÅÔrÀpÀÄV€‚¬pÀpÀpÀpÀpÀpÀp€pÀpÀpÀpÀÄË.»ì²Ë.¾pÀ‹0´Ð²Ë.»ì"‹ì² -´ÜRË-·0r€¼C -·S‹~øá‡~ðÂË/´ØbËpÀü ‰[`±Å qÀpÀpÀpÀpÀpÀpþpÀpÀpÀpÀK.ÂвË.»ì²Ë.p€0ÂÐB -É$ƒÌ.ÅC -hA ZЂ´ -hA eЂĨ…üà^ã´    d¡ЍB4Q! A  Và8Àp€à8Àp€à8Àp€@8Àp€à8Àp€à8Àr! aûØÅ.v1‹bô -hA e(CÊP†2”¡ e(CÊP†2”¡ e(CÊP†2vA ZÐþB´°…B|¯ØÁ°‹_Ì¢Rp~ †°@8Àp€à8Àp€à8Àp€€8Àp€à»ØÅ.v±‹]ÌB8Àp€]ì¢Ð0-hA e(CÊP†2”¡ e(C¿0†%üà?øÁц0hA ZÐBÊP†2”¡ e(CÒ˜Åp€ ¿ -hA [àV0‚5ˆá›8Àp€à8Àp€à8Àp€€8Àp€àþ²È…0~a cìb»ØÅ,f1‹bÃÆ -hA e(ÏpF5p€à 6üà?øÁ‹8€?øÁ~-hA ZЂ´ -hA ZЂ´ …-p€&|âM!)¨À +Á'p€à8Àp€à8Àp€@À8Àp€à8À‹]ÃÆ0-hA Z(CÊP†2~ñ cc8Àp€à8@Lá?øÁ8À(€?øÁ~ðƒZц]ÿ -”¡ eÐâþšàƒ&° ‚hb š8Àp, áа°€+à8Àp€à8Àp€€À8Àp€à8Àp€à»Ø…0~ñ ZÐB²0Æ,fÑŒà8Àp€à8Àà?øÁˆ8€)?øÁ~ðƒü ?øÁ -h¡ eÐàp€Ø¢´ -hA ià|¨ƒ°ÀJü@n8Àp€à8Àp€Àà8ÀhA ZЂ´ -~ñ‹YÌb»þØÅ/~A ZÔâ¿0F1p€à8Àp€ `?øÁ~XÄ"BøÁ~ðƒüà?øáð‚0~ñ ZЂ´ -hA ZЂÆ8À  !@ CЄ„p†k`áEp@(€…à8Àp€àà8Àd‘‹\ìÂÆ0†1hA ZЂ´P†2”¡ `cËÅp€à8Àp€àPC!üà?øÁ~¸`€]Â~ðƒüà? i8À„a cü‚´ -Œq€à°þƒ„€1Ta8Àp€[XÀ (à†¨À BÂp€àà8Àp€à8Àv±‹]ã¿ø-hQ‹Z£Å8Àp€à8Àp€à8À&†BÂ~ðC&øÁ~ðƒüà‡o á8À cЂÊP-~ÑŒháGЄÞp€à8ÀÀ€*¼B'p€´€…`Až°ÃP€ Á@ÀÀÀÀÀÀÀìÂ.ƒ1-Ð-ÐÂ/þC5ÀÀÀÀÀÀÀÀÀÀÀ\*B\‚À(øøàÂÀÀÀÀì-Ð-(ƒ2Ð-Ð-Ð-Ð-ÐB-ÔB-Ô‚-À(‚¨ÀÀÀhA|hD‚LÁlÁü€&üÀÀÀ-ü-ÐÂ,Ð-Ð-Ђ2(ƒ2Ô‚1C1Ã-ÀÀÀÀÀÀÀÀÀÀÀÀÀÀ€LÀÀÀÀÀÀÀƒ1Ðþ-(ƒ2ÐÂ/ü‚1C1C1ÃÀÀTXÀÀÀøÀh¨Àp€ ¨€'X¸|‚€À.È‚,ÌÂ,ü‚14@4@4Ð-üÂ/ü-Ô-Ð-Ã.ÀÀÀÀÀÀÀÀÀ@9˜Ã9ÀÀÀ ÂÀÀÀÀÀÀì-Ђ2Ð-4ƒ-˜ƒ9ÀÀÀÀ€|ÂÀÀÀ€À%TÁÀÀ0@À` ÀþÀÀÀÀÀÀìÂ.ì‚1-Ђ2(-ÔB-ÜÂÀ@:¨Ã9œ:ÃÀÀÀ@9˜:ÀÀÀ@@ÀÀÀÀ:œƒ9˜Ã.Ð-(ƒ2(ƒ2ìÂ-ÜÂ-ÜÂ-ÔB-œ:¬ÃÀÀÀÀÀÀ€""@€ÀÀÀ0€@À ÀÀÀÀÀÀÀÀÀ.Ð-Ђ2(Ã/üÂ/ÔÂ-Ü‚09˜:ÀÀÀÀÀÀ@9˜Ã9ÀÀþÀÀt|ÁÀÀÀ”ƒ9 -Ђ2(ƒ2(ƒ2ü‚1-Ð-ÐÂ-ÜÂ-ÜÂ-ÀÀÀÀÀÀŒƒ`"ÀÀÀ€0X`ÀÀÀÀÀÀÐ-Ð-Ð-(ƒ2Ð-üÂ/Ђ2(ƒ2Ð-ÐB-¼ƒ9 ;;œÃ:ÀÀÀ”9˜Ã9”C:ÀÀÀ@ÀÀÀÀ”ƒ0Ђ2(ƒ2(ƒ2,ðC9˜ƒ9”ƒ0ƒ0C1;ÀÀÀÀÀÀÀþÀÀÀÀ@ PP hÀÀÀìÂ.ì‚1Ã,ƒ0ìÂÀÀ.ìÂ.ƒ1-ÐÂ-ÜÂ/Ã-Ü-ÃÀÀÀÀÀÀÀÀÀÀÀÀtÀÀ€2(ƒ2(ƒ2(ƒ2(C-ÔB-ÔB-ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ.-Ð-(ƒ2Ð-(ƒ2(þƒ2Ð-ÜÂ-ÈÂÀÀÀÀÀÀÀÀÀÀÀ€/Ô-Ђ2(ƒ2(ƒ2üÂ/ƒ1Ð-ÜÂ-ÜÂ-ÔB-ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀƒ1Ð-Ђ2(ƒ2Ã/ƒ1Ð-ÐÂ-Ð-ÜÂ-Ð-Ð-ÐÂ-ÜB.äÂÀÀÀ€3ø‚/Ü‚/8-Ђ2(ƒ2(ƒ2(ƒ2ì2ÀÀ.ìÂ.ƒ1Ã-þÜÂ-ÜÂÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ€ÀÀÀÀÀÀÀ@3Ì-Ð-ÐÂÀÀƒ0ƒ0-Ð-(ƒ2(-(ƒ2ÜÂ-Ð--Ð-(C-ÜÂ/-ÐÂ-Ð-Ђ2(ƒ2(ƒ2ÐÂ/üÂ/ÐB2ÌÂ.ÌÂ,ÀÀÀÈ‚,äB.ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ€ÀÀÀÀÀÀþÄÂ.ìÂ.ÃÀÀÀÀÀ.ƒ1Ð-(ƒ0ƒ1ƒ1üÂ/Ð-(ƒ2(ƒ2Ð-Ð-Ђ2(ƒ2(-Ð-Ð-(ƒ2øÂ.À.ìB1ƒ1Ã.ìÂ.ÌÂ,ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀì‚1Ð-Ì‚1€Ã.ƒ1Ђ2(Ã.ìÂ.ì‚1Ã/Ђ2ìÂ.ìÂ.ìÂ.ƒ1ÐþÂ,ÌÂ,ÌÃ.ì‚1Ã.ìÂ.쀀€€ÀÀÀÀÀÀÀÀÀÀÀÀ€$€€€€€€ ÀÀÀÀÀÀÀLÀÀÀÀÀÀ@ P@XÀþ4À`@hH€€€ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀlÀd@@ ”€ œ  ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀþÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ€Ä€€À¤€ Ì ¨€ÀÀ€”€Ô€ ÜÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀþÀÀÀÀÀÀÀ”€ü€¬€ÀÀÀødÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀA 8ÀÀÀÀx€ ô@ $ÁÀÀø€(@,pÂÀ8pàÀ8pàÀ8pþàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀRjL¡äÀ`…A‘NP\8pàÀ)"LQ±ÂÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ8pàÀ$Tá°Ã8ÐÀƒ•WžDXqKˆ$j䘡£À8pàÀþ8à€8à€8à€8à€8à€˜  /&8à€8à€8à 0#„8à€8à€8à€8à€8à€8à€8à€8à€8à€8à|˜"TPB‹8à€|hàPp@ %,°B)28b 8à€8à€8à€8à€8à€8à€8à€8à€/ 8à€8à€º€18à€8à€8à€8à€8à€8à€8à€8à€8à€8à€þð@ 36Á .8à€Ð" Ρ†,fТˆ¦*8à€8à€8à€8à€8à€8à€8à€8 8à€8à5€¼˜à€8à€8à€8à€8à€8à€8à€8à€8à,8à€8à€`€„¬¨Á‚8à€°¨‚’8"Š€¨8ã$8à€8à€8à€8à€8à€8à€8à€8á€8à€˜ c‚8à€8à€þ8à€8à€8à€8à€8à€8à€8 ƒ3¨˜á€8à€€‚Ö¡Š3 ÈA1¤`C +€@âjp‚|`À‡8à€8à€8à€8à€8à€8à€8à€hÒ8à€8à€Úp€à8Àp€à8Àp€à8Àp€à8Àp€àDˆƒj`†œà8Àp€#€V&˜aà ^°"ø  ðHàx@8Àp€à8þÀp€à8Àp€à8Àà¨á8Àp€L PÃp€à8Àp€à8Àp€à8Àp€à8Àp€à`À ðƒ8@*8Àp€¤ P žÐ`!€€<À€ø€ð<0 8Àp€à8Àp€à8Àp€à8Àtá8Àp€¨j8Àp€à8Àp€à8Àp€à^H€ 8Àþp€àðÀä€rˆCp€Ô7ˆ€Š0a$ð|@0À8Àp8Àp€à8Àp€à8Àp€à8ÀÐà8Àp€1 8Àp€à8Àp€à8Àp€.èÂp€à8€@‚˜b   ‚` ¸€Šp‚øÀ ð@ Hp€à8Àp8Àp€à8Àp€à8Àþp€à8Àp€à8ÀР 8Àp€à8Àp€à8ÀÆèCüà?øá€@p€à8À@4` 8AB pSxÀ°Àø`;ðÀp€à8À 8Àp€à8Àp€à8Àp€à8Àp2à8Àá8Àp€à8Àp€à€Â~ðƒüà?øÁ~ðCPp€à8Àþpø w(ªð€Ô`tp|@0à8Àp€à8À`8Àp€à8Àp€à8Àp€à8Àp€/à8ÀÈ€à8Àp€à8Àp€à ð ?øÁ~ðƒüà?øÁ~PÁœ„<à8Àp€ÀFP€j „3p`E€<àƒà8Àp€à8À@8Àp€à8Àp€à8Àp€à8Àpþ€à8À€4à8Àp€à8Àp€ €0„üà?øÁ~ðƒüà?øÁ~`€0ƒ7ÐÀ ?pÀp€€g˜B¨!lÁ>ðp€à8Àp€à8À& 8Àp€à8Àp€à8Àp€à8Àp€à8€€à8Àp€à8ÀðÀ~ðƒüà?øÁ~ðƒüà?øÁ‹8€|A°N0‚ð`Uˆ@þx )ØÁp€à8Ààààà@€àààààààààààààààà À ààààààà üÀüÀüÀüÀüÀüÀüÀü àà|Àv@`` F€„ ´ ( ŠÀ8à|À Úàààààààà€àààààààààààþàààààÚ`àààààà@ üÀüÀüÀüÀüÀüÀüÀüÀáààà| v:@ T ²@ †`TêÀ ÀàºÚàààààààD àààààààààààààààà¼ÐàààààààÔ$ÁüÀüÀüÀüÀüÀüÀüÀü`ààþààà<€J€Š~`  `<Ààà€ ¼ààààààà @ààààààààààààààààÈÒàààààà@ üÀüÀüÀüÀüÀüÀüÀüàààààààà€Ê@8~`N€ˆààà  &ààààààà@àþàààààààààààààààÐààààààÆ$ÁüÀüÀüÀüÀüÀüÀüÀ,áà„ (áà&`àà@Ä`6 ŠJ€ààà `àààààà`$ààààààààààààààààÐ ààààà  ÀüÀüþÀüÀüÀüÀüÀüÀü à`¬@4Ì€dÀŠàଠ †ÀŽ œ`ˆ`ààà€ ààààààààààààààààààààààààÆ€ ààààà &ÁüÀüÀüÀüÀüÀüÀüÀ¡üÀüÀÎÀ NÀÞ¶ a: ¶`h@ ´€ˆàààà&ààþàààààààààààààààààààààà༠ àààààÒÁüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀü <€ ¨@ ø  ´ l ~à žv àààààààààààà@pàààààààààààààààþààààààРüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀ€R€Ž€„` 6à @è0áààààààààààààÀ àààààààààààààààààààààà üÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüà J€:þx€°€  vààààààààààààà€ ààààààààààààààààààààà  ÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀü`Ò à(` À~@`ààààààààààààà&@$ààààþààààààààààààààààà  ðÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀüÀáà† N`œà @¡ààààààààààààà@ààààààààààààààààààààà  ôÀüÀüÀüÀüÀüÀüÀþüÀüÀüÀü €ŒÀ Òà >! °@€`DáàààààààààààààààààààààààààààààààààààFÁüÀüÀüÀüÀüÀüÀüÀüÀüÀüàªÀ"z`Ž 4Á Ü`¸ ° °ÎàààààààààààþàààDàààààààààààààààààààààà$ÁüÀüÀüÀüÀü@$ÁüÀüÀüÀ ! ~À °@Þ@ T@ª ኀ¶@T Dáààààààààààààà ààààààààààààààààààþààààLÁüÀüÀüÀüüÀüÀüÀüÀüÀüÀ€H€ˆà  œ@ °À , Tà ² vààààààààààààààààààààààààààààààààààààNÁüÀüÀüÀü`PüÀüÀüÀüÀüÀüÀR¾àH`À|@Šà ~ ´@àþàààààààààààà`$pàÀ8pàÀ8pàÀ8pàÀ8pàÀ& 8pàÀD~üøñãÇF‰ òãÇ?~üøñãÇO58pàÀkx¨€`¥J¤8pàÀ8pàÀ8pàÀpàÀ8pàÀ8pàÀ8pàÀ8pàÀðràÀˆüøñãÇŸK«òãÇþ?~üøñãUš 8pàÀ Ö„S¤«8pàÀ8pàÀ8pàÀpàÀ8pÀpÀpÀpÀpÀpÀpÀpÀ@‰Àˆ~øá‡­ ~øá‡~øá‡~ø±ÈpÀpÀ ‚o¨ðF›pÀpÀpÀpÀpÀpÀpÀ"`ÀpÀpÀpÀpÀpÀpÀpÀþpÀpÀ@,²Ì‚‡ ~øá‡‹\’~øá‡~øá‡pÀpGˆ¡…@  +À‘pÀpÀpÀpÀpÀpÀpÀ`ÀpÀpÀpÀpÀpÀpÀpÀpÀpÀK.´ÔRË-·øá"èÀ.»ðÒ‹~øáÇ"|á†hRk|¢Bˆ¡‰8±˜pÀpÀpÀpÀpÀpÀpÀþ`ÀpÀpÀpÀpÀpÀpÀK.¾øâ‹/¹pÀË.´ÔRK-½øá#€/¾üRK-·øá‡‚øq(šh¡`¡b Eœ°QˆrÀpÀpÀpÀpÀpÀpÀ`ÀpÀpÀpÀpÀpÀpÀ‹0´ì²Ë.»pÀ‹]Ђµ¨Å-ná‡E\ ðÅ/~Q‹ZÔÂ~ðƒüÀ@Pð€|Àþ€0  ÄVHA8Àp€à8Àp€à8Àp€à8€`€à8Àp€à8Àp€à8Àp€à¹-v±‹]ìb8°‹]Ђµ¨E-ná‡\»Ø-hAŒZÜÂ~ðƒü@  8Àp€à¨‚~ 1pá8Àp€à8Àp€à8Àp€à8€`€à8Àp€à8Àp€þà8Àp€à¹†0h±‹]ìb¹8°‹]Ђµ¸Å-jш´» -ˆAŒZÜÂ~ðƒü0 ÿ°…-p€àÀ‚"6 M!¯8Àp€à8Àp€à8Àp€à8€p€à8Àp€à8ÀpYìb»ØE.p€àÈ…0hA‹]ìb»…°‹]Ђ·¨Å-nш¤a» -ˆAŒZÜÂ~ðƒü€†]ã¶°Åp€àø„À1þPB Ç8Àp€à8Àp€à8Àp€à˜p€à8Àp€à8À Yìb»ØÅ.|‘‹àÈ…0hA Zìb»ØE°‹]Ђ´¨E-nq‹¢´ -ˆa‹ZøÁ~ðƒfaŒ_ü¶°Åp€¡ àƒ„€,(š8Àp€à8Àp€à8Àp€à8p€à8Àp€à8Àp€\È‚´ØÅ.v± _þà8€0„A Z »ØÅ,°‹]Ђ´ F-jQ‹ì‚´ -ˆAŒZøÁ~ðÃ.Œñ Z@Á¶8À °'¨€ ¸ƒ&†à,¸áN¨Ãp€à8Àp€à8Àp€à8@p€à8Àp€à8Àp€äB´0Æ.v±‹]#8€0„A ZЂÊP-hA ZЂ´ -hA ZÐB´P-f! YøÁ~(-h¡ ZØÁ…4… ˜AB°Ã´  A ˆÂ1p€àþ8Àp€à8Àp€à8€p€à8Àp€à8Àp€@ …1h±‹]ìbÅ8À.„! ZЂÊP†2”¡ e(CÊP†2”¡ e(CÊP-hA Yäâ» -hA [hbšx€& ! dA Ì€‚-p!ð¡ bhÂ+p€à8Àp€à8Àp€à8€p€à8Àp€à8Àp€à»Ø…1ŒA‹]ìbÅ(†1hA ZÐBþÊP†2”¡ e(CÊP†2”¡ e(CÊP†2”¡ e(C´ …2ha [ZPp€ ¿ -Š!†-8¡ Âàp€à8Àp€à8Àppppppppppppppp»° Æ` ´@ ´@ ´@ ´  Ê  Ê  Ê  Ê  Ê  Ê  Ê  ´@ ´@ Ê  Ê  Ê  Ê  Ê  Ê  Ïð Ípppp¿@ ´@ ¶` pbÐJpš€Bð pþpppppppppppppp± ²° »° »° ³° pp° »` Ð@ ´  Ê  Ê  Ê  ´` µP ¶Ð`ð~à~à~°€ Â@ ´@ Ê  Ê  Ê@ ¿À Æ` pP ¿@ ´@ ´` ppU ð pŠ ¯ppppppppppppppp± ¹0 Æ` »° »° ³0 ²pþP Å` Æ@ ´  Ê  Ê@ ¿` ÆP pp`` ~à~à~°€ ~à ´@ ´  ´@ ´@ ´@ ´P ¿@ ´@ ´` ¶p× B€|pG BPZ€ppppppppppppppp¹ »` Æ` ´° »° ³0 ÂP ¿` ´@ Ê  ´` Æ0 ³ppppm@~à~à~ € `~à~à~ Â@ ¿ð ´@ ´@ ´@ ´þ@ ´@ ¶p?€E`X g \p*Š bpppppppppppppppp²° »` Æ` ´@ Å ´@ ´@ ´  ´P µ` ¶0 pppp0­à~à~ð  €~à~à~à~° Æð ¿@ ´@ ´@ ´@ ¶` pw€‘0ZŸ@  š`'`ž Šð pppppppppþppppppp» Å` Æ` ´@ Ê  Ê  ´ð ¼À ÆP ppppp0£à~à~` 0 €~à~à~à‹0]P ´@ ´  Ê  Ê0 Yànð * *0nppp+ U ‘`?@ ¯ð pppppppppppppppp» Åð ¿@ ´@ Ê@ Àð ˰ Ípppppppºà~à~þ  €~à~à~` «p ~àÂ@ ´@ Ê  Ê@ ‘ b0 p` ¶@ ´@ Ò@B`@  *Ð Xpppppppppppppppp° »° ¿ð ´@ ´À Æ@ Ä@ ppppmpp€~à~à` ~à~à~à~à~à~ Â@ ´  ´@ ´ Vp¶` ´@ ´@ ´@ ´ð ÏpX  g@ G Špp Ûþppppppppppp·@ ´` Åpp° »ð ¿@ ´@ µ@ Ä` Åppppp0 @Öà}à~à‹ð‚à~à~à~à~à~° ´@ ´@ ´@ ´@ ´@ ´@ ´@ ¿P ÀbpQpQŸ@ S°b`ð Bpppppp8p Å` Æ@ ´@ ´@ ´@ »0 »° ¿ð ´@ ´ð ¿` ÆP þpppppp]€„à~à~à™° „à~à~à~à~à¦_° Æ` ¿@ ´@ ´@ ´@ ´ð Åpp”PXPB V°??à'P* B ÛppppppÏð Ï ³` Æ` ´@ ´@ ´@ ´@ ´  Ê@ ¿ð Æ` ÕpppppppÐ@~à~à~à­px£à~à~à~à~€hpÅ` ¿@ ´@ ´@ ´Pþ pp˜ðb X0bàp€N Z@g€V ?p bpppp ppp¹ »° Æ` Æ ´@ ´@ Ê  Ê@ Í` ³P ²ppppppppm’à~à~à‚pÁªà~à~à~à~à €pÅP Æð ´@ ´@ ÆppàŸ X C0pppPN`Ÿ`À*àC b  Vpp pppþpp»° ÂP ¿ð ´ð ´@ ´` µ@ ÄP µppppppppp`0 ‚à~à~0 m…à~à~à~àÞmppP Æ@ ´@ ´@ ÆÐ pBp? `pppp€V     XPB X \ÀX ppppppp° »` ¿@ ´P µð ÆP ppppppppp0`P‚à~À þ~à~à~€ €pp° ´@ Ê  Ê@ à ¶` *P¯ pppp@Xp|°? °@ŸBp`U v ¯ÀÛp@ppppppp»° Æ` Æ@ ´@ ´ð ÆP ppppppppppp ÜPˆð0à~à~àÝ0pppp»@ ´  Ê  ÔP µ@ Ä€PàµP µP µ` pD n€PpÀU` €þ€bÀZðš 0b`@ppppppp»° Æ` ´@ ´@ ´ð ÆP pppppppppppp à‹ð`~à~Ðppppp»@ ´  Ê  Ê@ ´@ ´@ ´@ ¿ð ¿ð ¿pÀ*€× Spp@”#àEXÐ Z  ?€@ppppP Æ` Æ` Â@ ´@ ´@ ÀP ÄP Å ppppþppppppppp‹pð™pppppp»` ´  Ê  ´@ ¿` Æ` Æ` ÅP  Åp%€àY pppkÀ!° *0?Jø”Y  E‹-Z´hÑ¢E‹–2eÊ”Ñ2fÌX­[·8pàÀ8pàÀL G޹8p €68pàÀ8p@-ZÊ”)£U¬X±b8pàÀ¢†ZqíÓ8pÀƒ@4AÀrà@Eþ@Ø9C€Âví2fl4Z´hÑ¢E‹-Z´hѪU«-c»8pàÀ8pàÀ8Pκ8p  /8pàÀ8p`-eÊhÑjFÌœ¹8pàÀšªHQðãÀ8àÇ›Uøh:pàÀJšˆ±£€±bÅ’%k×®]Š)Fa„ÙecŒù…e”¡…cvÙå€8à€8à€8à€8à€Ê1çœ8à€8 08à€8à€H‡rØ…e”¡…[d1Çœ8à€8à€þÐD18à€8à€q!Xà€8à€8à€8à€8`—]~¡EenùŘ]n¹å–Ú1Çœ8 sÔ9à€8à€Ê1çœ8à€8à€1˜à€8à€(Çœs~QFe”Q†Zh¡…Zn¹å–[n¹å–8à€8à€8àE è¤ >8à€8€ø8ã.ªà€8à€8à€8à€(†þZ”QFeh¹å–[h¡…aÈ1çœ8à€8à€à8@9ÌŽà8Àp€€ 8Àp€ æ-”¡ e(ƒ¿0†1hA ZЂ´ Å-nq‹à8Àp€àA@p†à8ÀÀf|”¸p€à8Àp€àÅ -h¡ e(CÊP-hA ZЂ´øE1Ìavà`‡;p€à8@9ÌŽà8Àp€8Àp€ æ …2”¡ e(CØÅ.v! aCþ†1Œà8Àp€à8Àp€à8ÀP h *Pp€à8Àp€Ђ´P-”A Züâ¿ø-h¡ eЂ´¨Å-n‘t˜çhÇp€à@Ç9ÐqŽsã8Àp€ ^8Àp€à´P†2”¡ e(#(:ÎŽs¬cè8‡,r‘Žà8Àp€à8Àp€à8Àp€-áUp€à8ÀŒa cЂ´€4v±‹ìb»0Æ/~A eÔâµþð…0„q‹à8Àp€à8Àp€à8Àp€` ^8Àp€€ÊP†2”¡ eÜ¢µ Æp€à8Àp€à8Àp€à8Àp€à8Àp€Œ`Bp€àØÅ.va YÈâ8Àp€`»Ø…1~ñ eÜ‚´¸Å-hA aã8Àp€à8Àp€à8Àp€`^8ÀpY(CÊP†2”¡ ZÔâ·¨E-jq€à8Àp€à8þÀp€à8Àp€à8Àp€Àp€àØÅp€à8Àp€`»Ø…1hA eÐâ· -hA ZÐB·8Àp€à8Àp€à8Àp€à8ÀvQ Z(CÊP†2hñ cЂ·¸Å-nQ‹Zà8Àp€à8Àp€à8Àp€à8Àp€@p€à8Àp€à8Àp€àÅ -”¡ e(ƒ´P†2”¡ ZÜâÂÆþ-p€à8Àp€à8Àp€àpF-hA e(CÊP-„Q cÃÆ Å-nq‹[Üâ8Àp€à8Àp€à8Àp€à8Àp€àp€à8Àp€à8Àp€Ã´ …2”¡ Z´ -nq‹[ÐB·¸-h! aã8Àp€à8Àp€[Üâ´ …2”¡ e(CÊø2°‹]ì¢Æ0†1nq‹[Üâ8Àp€à8Àp€à8Àþp€à8Àp€à p€à8Àp€à8Àp€bЂÊP†2”! aÃЀ-hA ZÜâ´ -hA‹[ÜB¸…3v± _ÜâÔpÆ/~q _ƒÊP†2”¡ e(C»@Æ,q€`»ØÅ.ŒaŒ[Üâ8Àp€à8Àp€à8Àp€8€8€8€8€8€8€8€8€8€8€8€8€8€b0Z eP†]8€aa0c€ZPZPZPeP†[¨…Z0þ†XZ Z¨…ZØ…X Z …[øZPePePe Z ZH†]˜…Yh†8€8€…]Øa …8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€hc0Z …8€8€8€a(c ePePZ Z Z Z` eP†Z¨…_` Z ZPePePe …_ø…_ø…_ …]Ø…Y˜…f8€8€8€8€\x†8€8€8€8€þ8€8€8€8€8€8€8€8€8€8€8€8€ 8€8€8€8€8€8€ˆ…]0c0†8€8€8€8€†b0Z e …_ø…_ø…_ Z ZPePePePePePePZ Z e …_Ø…]a0c0ZØ…]Ø…Yh†8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€ €8€8€8€8€8€8€Ø…]ˆ…8€8€8€þ8€8€(c ZPaaa0cøZPePe Z Z ZPePZ …_ø…_ ZØ…]Ø…8€]†b0cØ…]Ø…]˜…f8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€ €8€8€8€8€8€8€8€8€8€8€8€8€8€b0Z Z0c8€aØcøZPZø…_ø…_ø…_ ZPZø…_Ø…]0cøZ˜…Y˜Y8€8€]Øc0þ†]Ø…]Ø…]8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€8€0€8€8€8€8€8€8€80( €Øc0Z c˜€]ØcøZP†]Ø…]Ø…]ØcøZP†]Ø…]€]Øc0Z‡Y˜…Y…]ØcØ…]Ø…]   €€;trf2.1.4/doc/md5.man0000644000175000017500000000005711216343142013500 0ustar sergeisergei[vset digest md5] [include digest/main.inc] trf2.1.4/doc/transform.man0000644000175000017500000001501411216343142015025 0ustar sergeisergei[include common/trf_version.inc] [manpage_begin transform n [vset trf_version]] [titledesc "Tcl level transformations"] [include common/trf_header.inc] [description] The command [cmd transform] reflects the API for a stack channel transformation into the tcl level, thus enabling the writing of transformations in tcl. [para] [list_begin definitions] [call [cmd transform] [opt [arg options...]] [opt [arg data]]] [list_begin definitions] [lst_item "[option -mode] [const read]|[const write]"] This option is accepted by the command if and only if it is used in [term immediate] mode. See section [sectref {IMMEDIATE versus ATTACHED}] for an explanation of the term. [nl] The argument value specifies whether to run the read or the write part of the transformation specified via option [option -command] on the immediate data. [nl] Beyond the argument values listed above all unique abbreviations are recognized too. [lst_item "[option -command] [arg cmd]"] This option has to be present and is always understood. Its argument is a command prefix. This command prefix will be called by internally whenever some operation of the transformation has to be executed. An empty [arg cmd] is not allowed. [nl] The exact nature of the various possible calls and their expected results is described later, in section [sectref {CALLBACK API}]. [include common/options.inc] [list_end] [list_end] [include common/sections.inc] [section {CALLBACK API}] Here we describe the API of the callback command implementing the actual transformation. [para] [list_begin definitions] [call [cmd callback] [arg operation] [arg data]] The callback is always called with two arguments, first an operation code followed by data. The latter will be empty for some operations. [nl] The known operations are listed below, together with an explanation of the arguments, what is expected of them, and how their results are handled. [list_begin definitions] [lst_item [const create/write]] When called [arg data] is empty. The result of the call is ignored. [nl] This is the first operation executed for the write side of the transformation. It has to initialize the internals of this part of the transformation and ready it for future calls. [lst_item [const delete/write]] When called [arg data] is empty. The result of the call is ignored. [nl] This is the last operation executed for the write side of the transformation. It has to shutdown the internals of this part of the transformation and release any resources which were acquired over the lifetime of the transformation. [lst_item [const write]] The operation is called whenever data is written to the channel. [nl] At the time of the call the argument [arg data] will contain the bytes to transform. The result of the call is taken as the result of the transformation and handed to the next stage down in the stack of transformation associated with the channel. [nl] This operation has to transform the contents of [arg data], using whatever data was left over from the last call of the operation. The transformation is allowed to buffer incomplete data. [lst_item [const flush/write]] When called [arg data] is empty. The operation has to transform any incomplete data it has buffered internally on the write side. The result of the call is taken as the result of the transformation and handed to the next stage down in the stack of transformation associated with the channel. [lst_item [const clear/write]] When called [arg data] is empty. The result of the call is ignored. [nl] The write side of the transformation has to clear its internal buffers. This operation is called when the user seeks on the channel, thus invalidating any incomplete transformation. [lst_item [const create/read]] When called [arg data] is empty. The result of the call is ignored. [nl] This is the first operation executed for the read side of the transformation. It has to initialize the internals of this part of the transformation and ready it for future calls. [lst_item [const delete/read]] When called [arg data] is empty. The result of the call is ignored. [nl] This is the last operation executed for the write side of the transformation. It has to shutdown the internals of this part of the transformation and release any resources which were acquired over the lifetime of the transformation. [lst_item [const read]] The operation is called whenever data is read from the channel. [nl] At the time of the call the argument [arg data] will contain the bytes to transform. The result of the call is taken as the result of the transformation and posted to the next stage up in the stack of transformation associated with the channel. [nl] This operation has to transform the contents of [arg data], using whatever data was left over from the last call of the operation. The transformation is allowed to buffer incomplete data. [lst_item [const flush/read]] When called [arg data] is empty. The operation has to transform any incomplete data it has buffered internally on the read side. The result of the call is taken as the result of the transformation and posted to the next stage up in the stack of transformation associated with the channel. [lst_item [const clear/read]] When called [arg data] is empty. The result of the call is ignored. [nl] The read side of the transformation has to clear its internal buffers. This operation is called when the user seeks on the channel, thus invalidating any incomplete transformation. [lst_item [const query/maxRead]] When called [arg data] is empty. The result of the call is interpreted as integer number. This operation is used by the generic layer to determine if the transformation establishes a limit on the number of bytes it (the generic layer) is allowed read from the transformations lower in the stack. A negative result unsets any limit. [nl] This has to be used if a transformation employs some kind of end-of-data marker. We cannot allow the generic layer to overshoot this marker because any data read after it cannot be stuffed back into the core buffers, causing the I/O system to loose data if the transformation is unstacked after it recognized the end of its data. This is a limitation of the I/O system in the tcl core. [nl] Returning a positive value will cause the I/O system to slow down, but also ensures that no data is lost. [nl] Two examples for such transformations are the data decompressors for [cmd zip] and [cmd bz2]. They use the C-level equivalent of this operation to prevent the overshooting. [list_end] [list_end] [see_also trf-intro] [keywords {general transform}] [manpage_end] trf2.1.4/doc/rs_ecc.man0000644000175000017500000000251411216343142014251 0ustar sergeisergei[include common/trf_version.inc] [manpage_begin rs_ecc n [vset trf_version]] [titledesc "Reed-Solomon error correcting code"] [include common/trf_header.inc] [description] The command [cmd rs_ecc] provides a reed-solomon error correcting coder. The coder operates on blocks of 248 bytes each, therefore buffering 247 bytes. [para] [list_begin definitions] [call [cmd rs_ecc] [opt [arg options...]] [opt [arg data]]] [list_begin definitions] [lst_item "[option -mode] [const encode]|[const decode]"] This option has to be present and is always understood. [nl] For [term immediate] mode the argument value specifies the operation to use. For an [term attached] encoding it specifies the operation to use for [emph writing]. Reading will automatically use the reverse operation. See section [sectref {IMMEDIATE versus ATTACHED}] for explanations of these two terms. [nl] Beyond the argument values listed above all unique abbreviations are recognized too. [nl] [const Encode] converts from arbitrary (most likely binary) data into a representation containing additional error correcting information, [const decode] does the reverse, and performs the error correction if necessary. [include common/options.inc] [list_end] [list_end] [include common/sections.inc] [see_also trf-intro] [keywords {error correction} reed-solomon] [manpage_end] trf2.1.4/doc/oct.man0000644000175000017500000000051711216343142013601 0ustar sergeisergei[vset encoding oct] [include encoding/header.inc] [para] This encoding transforms every byte in the input into a sequence of 3 characters containing the octal representation of the byte. For example [para] [example { % oct -mode encode Z 132 }] [include encoding/middle.inc] [keywords bin hex] [include encoding/footer.inc] trf2.1.4/doc/adler.man0000644000175000017500000000034711216343142014104 0ustar sergeisergei[vset digest adler] [include digest/header.inc] [section NOTES] This command implements the ADLER digest used by the zlib compression library ([uri http://www.gzip.org/zlib/]). [keywords zlib zip] [include digest/footer.inc] trf2.1.4/doc/trf.man0000644000175000017500000000564511216343142013616 0ustar sergeisergei[comment {-*- tcl -*- doctools}] [include common/trf_version.inc] [manpage_begin trf-intro n [vset trf_version]] [titledesc {Introduction to Trf}] [include common/trf_header.inc] [description] The package [package Trf] provides a number of commands which take data and transform them in various ways. [section BACKGROUND] The implementation of Trf began as proof-of-concept of the validity and usefulness of the "stacked channel" patches to the core. These patches allow the writing of extensions to the generic I/O system of the core which are able to intercept all read/write operations on designated channels, thus giving it the ability to transform the data flowing through these channels as desired. [para] This allows things like transparent encryption, compression, charset recoding, etc. [para] Since version 8.2 of the tcl core the aforementioned patches are part of the tcl core itself, changing the status of [package trf] from "extension requiring core patches" to "normal extension". [para] Other packages built upon either the stackd channels directly, or Trf are: [list_begin enum] [enum] [package TrfCrypt], by myself, contains various encryption systems [enum] [package TLS], an SSL/TLS implementation by Matt Newman. [enum] [package {Tcl MIME}] by Marshall Rose. [list_end] [section API] The commands provide by [package trf] can be placed into the three categories listed below. Note that all commands are added to the global namespace. [list_begin definitions] [lst_item [term Encodings]] The encoding commands either take some data and return the same data in encoded form, or take encoded data and return a decoded result. [list_begin enum] [enum] [cmd oct] [enum] [cmd hex] [enum] [cmd oct] [enum] [cmd base64] [enum] [cmd uuencode] [enum] [cmd ascii85] [enum] [cmd otp_words] [enum] [cmd quoted-printable] [list_end] [nl] [lst_item [term {Message Digests}]] The second category are message digests in general, simple ones like [cmd crc], and cryptographically strong algorithms like [cmd md5]. [list_begin enum] [enum] [cmd crc-zlib] [enum] [cmd crc] [enum] [cmd adler] [enum] [cmd md2] [enum] [cmd md5] [enum] [cmd md5_otp] [enum] [cmd sha] [enum] [cmd sha1] [enum] [cmd sha1_otp] [enum] [cmd haval] [enum] [cmd ripemd-160] [enum] [cmd ripemd-128] [list_end] [nl] [lst_item Miscellaneous] At last a number of commands not readily placed into categories providing password crypting, general transformations, data compression, error correction and others. [list_begin enum] [enum] [cmd crypt] [enum] [cmd md5crypt] [enum] [cmd transform] [enum] [cmd rs_ecc] [enum] [cmd zip] [enum] [cmd bz2] [enum] [cmd unstack] [list_end] [list_end] [see_also oct hex oct base64 uuencode ascii85 otp_words quoted-printable crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 crypt md5crypt transform rs_ecc zip bz2] [keywords transformation encoding {message digest} compression {error correction}] [manpage_end] trf2.1.4/doc/html/0000755000175000017500000000000011216343254013264 5ustar sergeisergeitrf2.1.4/doc/html/sha1_otp.html0000644000175000017500000003066011216343254015675 0ustar sergeisergei sha1_otp - Trf transformer commands

sha1_otp(n) 2.1.3 "Trf transformer commands"

Name

sha1_otp - Message digest "sha1_otp"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command sha1_otp is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

sha1_otp ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, mac, message digest, sha1_otp

trf2.1.4/doc/html/ascii85.html0000644000175000017500000002031711216343254015422 0ustar sergeisergei ascii85 - Trf transformer commands

ascii85(n) 2.1.3 "Trf transformer commands"

Name

ascii85 - Encoding "ascii85"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command ascii85 is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every block of four bytes into the Ascii85 representation as defined in the 'Postscript Reference Manual' (2nd Edition, section 3.13, page 129).

ascii85 ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood by the encoding.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode

Keywords

ascii85, encoding, postscript

trf2.1.4/doc/html/crc-zlib.html0000644000175000017500000003136711216343254015671 0ustar sergeisergei crc-zlib - Trf transformer commands

crc-zlib(n) 2.1.3 "Trf transformer commands"

Name

crc-zlib - Message digest "crc-zlib"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command crc-zlib is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

crc-zlib ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

NOTES

This command uses the same CRC polynomial as the CRC algorithm used by the zlib compression library (http://www.gzip.org/zlib/).

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, crc, crc-zlib, hash, hashing, mac, message digest, zip, zlib

trf2.1.4/doc/html/crypt.html0000644000175000017500000001003711216343254015314 0ustar sergeisergei crypt - Trf transformer commands

crypt(n) 2.1.3 "Trf transformer commands"

Name

crypt - Password hashing based on "crypt"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command crypt is an interface to the crypt(3) function for the encryption of passwords. An alternative command for the same, but based on md5 is md5crypt.

crypt password salt

Encrypts the password using the specified salt and returns the generated hash value as the result of the command.

See Also

md5crypt, trf-intro

Keywords

authentication, crypt, hash, hashing, mac, md5, message digest, password

trf2.1.4/doc/html/adler.html0000644000175000017500000003127611216343254015252 0ustar sergeisergei adler - Trf transformer commands

adler(n) 2.1.3 "Trf transformer commands"

Name

adler - Message digest "adler"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command adler is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

adler ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

NOTES

This command implements the ADLER digest used by the zlib compression library (http://www.gzip.org/zlib/).

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

adler, authentication, hash, hashing, mac, message digest, zip, zlib

trf2.1.4/doc/html/otp_words.html0000644000175000017500000002061111216343254016172 0ustar sergeisergei otp_words - Trf transformer commands

otp_words(n) 2.1.3 "Trf transformer commands"

Name

otp_words - Encoding "otp_words"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command otp_words is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every block of four bytes (64 bit) into six english words, as defined in RFC 2289 (http://www.rfc-editor.org/rfc/rfc2289.txt). This encoding is the sole one which is not able to handle an incomplete block at the end of the input.

otp_words ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood by the encoding.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

ascii85, base64, bin, hex, md5_otp, oct, otp_words, quoted-printable, trf-intro, uuencode

Keywords

encoding, md5_otp, otp_words, rfc 2289

trf2.1.4/doc/html/unstack.html0000644000175000017500000001001011216343254015612 0ustar sergeisergei unstack - Trf transformer commands

unstack(n) 2.1.3 "Trf transformer commands"

Name

unstack - Unstacking channels

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command unstack is an interface to the public Tcl API function TclUnstackChannel. It unstacks the topmost transformation from the specified channel if there is any.

unstack channel

Removes the topmost transformation from the specified channel. If the channel has no transformation associated with it it will be closed. In other words, in this situation the command is equivalent to close.

See Also

trf-intro

Keywords

removal, transformation, unstacking

trf2.1.4/doc/html/oct.html0000644000175000017500000002030111216343254014733 0ustar sergeisergei oct - Trf transformer commands

oct(n) 2.1.3 "Trf transformer commands"

Name

oct - Encoding "oct"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command oct is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every byte in the input into a sequence of 3 characters containing the octal representation of the byte. For example

	% oct -mode encode Z
	132
oct ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood by the encoding.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode

Keywords

bin, encoding, hex, oct

trf2.1.4/doc/html/base64.html0000644000175000017500000002162211216343254015241 0ustar sergeisergei base64 - Trf transformer commands

base64(n) 2.1.3 "Trf transformer commands"

Name

base64 - Encoding "base64"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command base64 is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every block of three bytes into a block of four bytes, each of which is printable, i.e. 7bit ASCII. This implies that the result is valid UTF-8 too. The command uses essentially the same algorithm as for uuencode, except for a different mapping from 6-bit fragments to printable bytes.

base64 ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood by the encoding.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

NOTES

  1. The encoding is equivalent to PGP's ASCII armor and was also accepted as one of the MIME encodings for encapsulation of binary data. See RFC 2045 (http://www.rfc-editor.org/rfc/rfc2045.txt) for details and the specification of this encoding.

  2. The encoding buffers 2 bytes.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode

Keywords

ascii armor, base64, encoding, mime, pgp, rfc 2045, uuencode

trf2.1.4/doc/html/rs_ecc.html0000644000175000017500000001777411216343254015430 0ustar sergeisergei rs_ecc - Trf transformer commands

rs_ecc(n) 2.1.3 "Trf transformer commands"

Name

rs_ecc - Reed-Solomon error correcting code

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command rs_ecc provides a reed-solomon error correcting coder. The coder operates on blocks of 248 bytes each, therefore buffering 247 bytes.

rs_ecc ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into a representation containing additional error correcting information, decode does the reverse, and performs the error correction if necessary.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

trf-intro

Keywords

error correction, reed-solomon

trf2.1.4/doc/html/quoted-printable.html0000644000175000017500000002062511216343254017436 0ustar sergeisergei quoted-printable - Trf transformer commands

quoted-printable(n) 2.1.3 "Trf transformer commands"

Name

quoted-printable - Encoding "quoted-printable"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command quoted-printable is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

Printable ASCII characters are largely untouched. Otherwise a three-character encoding sequence is used. This is MIME's compromise encoding. See RFC 2045 (http://www.rfc-editor.org/rfc/rfc2045.txt) for its definition.

quoted-printable ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood by the encoding.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode

Keywords

encoding, mime, quoted-printable, rfc 2045

trf2.1.4/doc/html/sha.html0000644000175000017500000003057611216343254014740 0ustar sergeisergei sha - Trf transformer commands

sha(n) 2.1.3 "Trf transformer commands"

Name

sha - Message digest "sha"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command sha is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

sha ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, mac, message digest, sha

trf2.1.4/doc/html/md5.html0000644000175000017500000003057611216343254014652 0ustar sergeisergei md5 - Trf transformer commands

md5(n) 2.1.3 "Trf transformer commands"

Name

md5 - Message digest "md5"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command md5 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

md5 ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, mac, md5, message digest

trf2.1.4/doc/html/crc.html0000644000175000017500000003122311216343254014722 0ustar sergeisergei crc - Trf transformer commands

crc(n) 2.1.3 "Trf transformer commands"

Name

crc - Message digest "crc"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command crc is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

crc ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

NOTES

This command uses the same CRC polynomial as the CRC algorithm used by PGP (http://www.pgp.com).

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, crc, hash, hashing, mac, message digest, pgp

trf2.1.4/doc/html/md5crypt.html0000644000175000017500000001011611216343254015720 0ustar sergeisergei md5crypt - Trf transformer commands

md5crypt(n) 2.1.3 "Trf transformer commands"

Name

md5crypt - Password hashing based on "md5"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command md5crypt is for the encryption of passwords and uses md5 as hash algorithm. An alternative command for the same function, but based on the older crypt(3) hash function is crypt.

md5crypt password salt

Encrypts the password using the specified salt and returns the generated hash value as the result of the command.

See Also

crypt, trf-intro

Keywords

authentication, crypt, hash, hashing, mac, md5, message digest, password

trf2.1.4/doc/html/hex.html0000644000175000017500000002030611216343254014737 0ustar sergeisergei hex - Trf transformer commands

hex(n) 2.1.3 "Trf transformer commands"

Name

hex - Encoding "hex"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command hex is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every byte in the input into a sequence of 2 characters containing the hexadecimal representation of the byte. For example

	% hex -mode encode Z
	5A
hex ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood by the encoding.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode

Keywords

bin, encoding, hex, oct

trf2.1.4/doc/html/ripemd128.html0000644000175000017500000003137311216343254015674 0ustar sergeisergei ripemd-128 - Trf transformer commands

ripemd-128(n) 2.1.3 "Trf transformer commands"

Name

ripemd-128 - Message digest "ripemd-128"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command ripemd-128 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

ripemd-128 ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, mac, message digest, ripemd, ripemd-128

trf2.1.4/doc/html/haval.html0000644000175000017500000003062211216343254015250 0ustar sergeisergei haval - Trf transformer commands

haval(n) 2.1.3 "Trf transformer commands"

Name

haval - Message digest "haval"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command haval is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

haval ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, haval, mac, message digest

trf2.1.4/doc/html/trf.html0000644000175000017500000001576711216343254014765 0ustar sergeisergei trf-intro - Trf transformer commands

trf-intro(n) 2.1.3 "Trf transformer commands"

Name

trf-intro - Introduction to Trf

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The package Trf provides a number of commands which take data and transform them in various ways.

BACKGROUND

The implementation of Trf began as proof-of-concept of the validity and usefulness of the "stacked channel" patches to the core. These patches allow the writing of extensions to the generic I/O system of the core which are able to intercept all read/write operations on designated channels, thus giving it the ability to transform the data flowing through these channels as desired.

This allows things like transparent encryption, compression, charset recoding, etc.

Since version 8.2 of the tcl core the aforementioned patches are part of the tcl core itself, changing the status of trf from "extension requiring core patches" to "normal extension".

Other packages built upon either the stackd channels directly, or Trf are:

  1. TrfCrypt, by myself, contains various encryption systems

  2. TLS, an SSL/TLS implementation by Matt Newman.

  3. Tcl MIME by Marshall Rose.

API

The commands provide by trf can be placed into the three categories listed below. Note that all commands are added to the global namespace.

Encodings

The encoding commands either take some data and return the same data in encoded form, or take encoded data and return a decoded result.

  1. oct

  2. hex

  3. oct

  4. base64

  5. uuencode

  6. ascii85

  7. otp_words

  8. quoted-printable

Message Digests

The second category are message digests in general, simple ones like crc, and cryptographically strong algorithms like md5.

  1. crc-zlib

  2. crc

  3. adler

  4. md2

  5. md5

  6. md5_otp

  7. sha

  8. sha1

  9. sha1_otp

  10. haval

  11. ripemd-160

  12. ripemd-128

Miscellaneous

At last a number of commands not readily placed into categories providing password crypting, general transformations, data compression, error correction and others.

  1. crypt

  2. md5crypt

  3. transform

  4. rs_ecc

  5. zip

  6. bz2

  7. unstack

See Also

adler, ascii85, base64, bz2, crc, crc-zlib, crypt, haval, hex, md2, md5, md5_otp, md5crypt, oct, otp_words, quoted-printable, ripemd-128, ripemd-160, rs_ecc, sha, sha1, sha1_otp, transform, uuencode, zip

Keywords

compression, encoding, error correction, message digest, transformation

trf2.1.4/doc/html/transform.html0000644000175000017500000003376111216343254016177 0ustar sergeisergei transform - Trf transformer commands

transform(n) 2.1.3 "Trf transformer commands"

Name

transform - Tcl level transformations

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command transform reflects the API for a stack channel transformation into the tcl level, thus enabling the writing of transformations in tcl.

transform ?options...? ?data?
-mode read|write

This option is accepted by the command if and only if it is used in immediate mode. See section IMMEDIATE versus ATTACHED for an explanation of the term.

The argument value specifies whether to run the read or the write part of the transformation specified via option -command on the immediate data.

Beyond the argument values listed above all unique abbreviations are recognized too.

-command cmd

This option has to be present and is always understood. Its argument is a command prefix. This command prefix will be called by internally whenever some operation of the transformation has to be executed. An empty cmd is not allowed.

The exact nature of the various possible calls and their expected results is described later, in section CALLBACK API.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

CALLBACK API

Here we describe the API of the callback command implementing the actual transformation.

callback operation data

The callback is always called with two arguments, first an operation code followed by data. The latter will be empty for some operations.

The known operations are listed below, together with an explanation of the arguments, what is expected of them, and how their results are handled.

create/write

When called data is empty. The result of the call is ignored.

This is the first operation executed for the write side of the transformation. It has to initialize the internals of this part of the transformation and ready it for future calls.

delete/write

When called data is empty. The result of the call is ignored.

This is the last operation executed for the write side of the transformation. It has to shutdown the internals of this part of the transformation and release any resources which were acquired over the lifetime of the transformation.

write

The operation is called whenever data is written to the channel.

At the time of the call the argument data will contain the bytes to transform. The result of the call is taken as the result of the transformation and handed to the next stage down in the stack of transformation associated with the channel.

This operation has to transform the contents of data, using whatever data was left over from the last call of the operation. The transformation is allowed to buffer incomplete data.

flush/write

When called data is empty. The operation has to transform any incomplete data it has buffered internally on the write side. The result of the call is taken as the result of the transformation and handed to the next stage down in the stack of transformation associated with the channel.

clear/write

When called data is empty. The result of the call is ignored.

The write side of the transformation has to clear its internal buffers. This operation is called when the user seeks on the channel, thus invalidating any incomplete transformation.

create/read

When called data is empty. The result of the call is ignored.

This is the first operation executed for the read side of the transformation. It has to initialize the internals of this part of the transformation and ready it for future calls.

delete/read

When called data is empty. The result of the call is ignored.

This is the last operation executed for the write side of the transformation. It has to shutdown the internals of this part of the transformation and release any resources which were acquired over the lifetime of the transformation.

read

The operation is called whenever data is read from the channel.

At the time of the call the argument data will contain the bytes to transform. The result of the call is taken as the result of the transformation and posted to the next stage up in the stack of transformation associated with the channel.

This operation has to transform the contents of data, using whatever data was left over from the last call of the operation. The transformation is allowed to buffer incomplete data.

flush/read

When called data is empty. The operation has to transform any incomplete data it has buffered internally on the read side. The result of the call is taken as the result of the transformation and posted to the next stage up in the stack of transformation associated with the channel.

clear/read

When called data is empty. The result of the call is ignored.

The read side of the transformation has to clear its internal buffers. This operation is called when the user seeks on the channel, thus invalidating any incomplete transformation.

query/maxRead

When called data is empty. The result of the call is interpreted as integer number. This operation is used by the generic layer to determine if the transformation establishes a limit on the number of bytes it (the generic layer) is allowed read from the transformations lower in the stack. A negative result unsets any limit.

This has to be used if a transformation employs some kind of end-of-data marker. We cannot allow the generic layer to overshoot this marker because any data read after it cannot be stuffed back into the core buffers, causing the I/O system to loose data if the transformation is unstacked after it recognized the end of its data. This is a limitation of the I/O system in the tcl core.

Returning a positive value will cause the I/O system to slow down, but also ensures that no data is lost.

Two examples for such transformations are the data decompressors for zip and bz2. They use the C-level equivalent of this operation to prevent the overshooting.

See Also

trf-intro

Keywords

general transform

trf2.1.4/doc/html/uuencode.html0000644000175000017500000002110611216343254015761 0ustar sergeisergei uuencode - Trf transformer commands

uuencode(n) 2.1.3 "Trf transformer commands"

Name

uuencode - Encoding "uuencode"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command uuencode is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every block of three bytes into a block of four bytes, each of which is printable, i.e. 7bit ASCII. This implies that the result is valid UTF-8 too. The command uses essentially the same algorithm as for base64, except for a different mapping from 6-bit fragments to printable bytes.

uuencode ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood by the encoding.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

NOTES

  1. The encoding buffers 2 bytes.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode

Keywords

base64, encoding, uuencode

trf2.1.4/doc/html/bz2.html0000644000175000017500000002072611216343254014656 0ustar sergeisergei bz2 - Trf transformer commands

bz2(n) 2.1.3 "Trf transformer commands"

Name

bz2 - Data compression "bz2"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command bz2 is one of several data compressions provided by the package trf. See trf-intro for an overview of the whole package.

The command is based on the Burroughs-Wheeler transformation as implemented by the bzip2 compression library (http://sources.redhat.com/bzip2/).

bz2 ?options...? ?data?
-mode compress|decompress

This option has to be present and is always understood by the compression.

For immediate mode the argument value specifies the operation to use. For an attached compress it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Compress causes the compression of arbitrary (most likely binary) data. Decompression does the reverse .

-level integer

Specifies the compression level. Is either the string default or an integer number in the range 1 (minimal compression) to 9 (maximal compression).

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

bz2, trf-intro, zip

Keywords

Burroughs-Wheeler, bz2, compression, data compression, decompression

trf2.1.4/doc/html/md5_otp.html0000644000175000017500000003064611216343254015532 0ustar sergeisergei md5_otp - Trf transformer commands

md5_otp(n) 2.1.3 "Trf transformer commands"

Name

md5_otp - Message digest "md5_otp"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command md5_otp is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

md5_otp ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, mac, md5_otp, message digest

trf2.1.4/doc/html/bin.html0000644000175000017500000002030711216343254014724 0ustar sergeisergei bin - Trf transformer commands

bin(n) 2.1.3 "Trf transformer commands"

Name

bin - Encoding "bin"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command bin is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every byte in the input into a sequence of 8 characters containing the binary representation of the byte. For example

	% bin -mode encode Z
	01011010
bin ?options...? ?data?
-mode encode|decode

This option has to be present and is always understood by the encoding.

For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode

Keywords

bin, encoding, hex, oct

trf2.1.4/doc/html/md2.html0000644000175000017500000003057611216343254014647 0ustar sergeisergei md2 - Trf transformer commands

md2(n) 2.1.3 "Trf transformer commands"

Name

md2 - Message digest "md2"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command md2 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

md2 ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, mac, md2, message digest

trf2.1.4/doc/html/sha1.html0000644000175000017500000003061011216343254015006 0ustar sergeisergei sha1 - Trf transformer commands

sha1(n) 2.1.3 "Trf transformer commands"

Name

sha1 - Message digest "sha1"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command sha1 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

sha1 ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, mac, message digest, sha1

trf2.1.4/doc/html/zip.html0000644000175000017500000002212111216343254014752 0ustar sergeisergei zip - Trf transformer commands

zip(n) 2.1.3 "Trf transformer commands"

Name

zip - Data compression "zip"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command zip is one of several data compressions provided by the package trf. See trf-intro for an overview of the whole package.

The command is based on the deflate compression algorithm as specified in RFC 1951 (http://www.rfc-editor.org/rfc/rfc1951.txt) and as implemented by the zlib compression library (http://www.gzip.org/zlib/). See also RFC 1950 (http://www.rfc-editor.org/rfc/rfc1950.txt)

zip ?options...? ?data?
-mode compress|decompress

This option has to be present and is always understood by the compression.

For immediate mode the argument value specifies the operation to use. For an attached compress it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

Beyond the argument values listed above all unique abbreviations are recognized too.

Compress causes the compression of arbitrary (most likely binary) data. Decompression does the reverse .

-level integer

Specifies the compression level. Is either the string default or an integer number in the range 1 (minimal compression) to 9 (maximal compression).

-nowrap boolean

If set to true the command will not create the zip specific header (See RFC 1950) normally written before the compressed data. The options defaults to false. It has to be used when writing a gzip emulation in Tcl as gzip creates a different header.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

bz2, trf-intro, zip

Keywords

compression, data compression, decompression, rfc 1950, rfc 1951, rfc 1952, zip

trf2.1.4/doc/html/ripemd160.html0000644000175000017500000003137311216343254015670 0ustar sergeisergei ripemd-160 - Trf transformer commands

ripemd-160(n) 2.1.3 "Trf transformer commands"

Name

ripemd-160 - Message digest "ripemd-160"

Synopsis

  • package require Tcl ?8.2?
  • package require Trf ?2.1.3?

Description

The command ripemd-160 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

ripemd-160 ?options...? ?data?

The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.

-mode absorb|write|transparent

This option has to be present. The specified argument determines the behaviour of the digest in attached mode.

Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:

absorb

All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.

When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option -matchflag has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".

write

All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options -write-destination, -write-type, -read-destination, and -read-type.

transparent

This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

-matchflag varname

This option can be used if and only if the option "-mode absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.

-write-type variable|channel

This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option -write-destination. It defaults to variable.

-read-type variable|channel

Like option -write-type, but for option -read-destination.

-write-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -write-type. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

-read-destination data

This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option -read-type. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.

Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.

-attach channel

The presence/absence of this option determines the main operation mode of the transformation.

If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.

If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.

-in channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.

If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.

-out channel

This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.

If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.

IMMEDIATE versus ATTACHED

The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option -attach is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option -attach, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options -in and -out. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

See Also

adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro

Keywords

authentication, hash, hashing, mac, message digest, ripemd, ripemd-160

trf2.1.4/doc/digest/0000755000175000017500000000000011216344734013603 5ustar sergeisergeitrf2.1.4/doc/digest/header.inc0000644000175000017500000000205511216343142015520 0ustar sergeisergei[comment {-*- tcl -*- doctools = digest_header.inc}] [include common/trf_version.inc] [manpage_begin [vset digest] n [vset trf_version]] [titledesc "Message digest \"[vset digest]\""] [include common/trf_header.inc] [description] The command [cmd [vset digest]] is one of several message digests provided by the package [package trf]. See [syscmd trf-intro] for an overview of the whole package. [para] [list_begin definitions] [call [cmd [vset digest]] [opt [arg options...]] [opt [arg data]]] The options listed below are understood by the digest if and only if the digest is [term attached] to a channel. See section [sectref {IMMEDIATE versus ATTACHED}] for an explanation of the term [term attached]. [list_begin definitions] [include digest/options.inc] [list_end] [nl] The options listed below are always understood by the digest, [term attached] versus [term immediate] does not matter. See section [sectref {IMMEDIATE versus ATTACHED}] for explanations of these two terms. [list_begin definitions] [include common/options.inc] [list_end] [list_end] trf2.1.4/doc/digest/options.inc0000644000175000017500000000763011216343142015767 0ustar sergeisergei[comment {-*- tcl -*- doctools = digest_options.inc}] [lst_item "[option -mode] [const absorb]|[const write]|[const transparent]"] This option has to be present. The specified argument determines the behaviour of the digest in [term attached] mode. [nl] Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: [list_begin definitions] [lst_item [const absorb]] All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. [nl] When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option [option -matchflag] has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "[const ok]", or "[const failed]". [lst_item [const write]] All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options [option -write-destination], [option -write-type], [option -read-destination], and [option -read-type]. [lst_item [const transparent]] This mode is a mixture of both [const absorb] and [const write] modes. As for [const absorb] all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for [const write]. [list_end] [nl] [lst_item "[option -matchflag] [arg varname]"] This option can be used if and only if the option "[option -mode] [const absorb]" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. [lst_item "[option -write-type] [const variable]|[const channel]"] This option can be used for digests in mode [const write] or [const transparent]. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option [option -write-destination]. It defaults to [const variable]. [lst_item "[option -read-type] [const variable]|[const channel]"] Like option [option -write-type], but for option [option -read-destination]. [lst_item "[option -write-destination] [arg data]"] This option can be used for digests in mode [const write] or [const transparent]. The value [arg data] is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option [option -write-type]. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. [nl] [emph Note] that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's. [lst_item "[option -read-destination] [arg data]"] This option can be used for digests in mode [const write] or [const transparent]. The value [arg data] is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option [option -read-type]. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. [nl] [emph Note] that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's. trf2.1.4/doc/digest/main.inc0000644000175000017500000000014611216343142015213 0ustar sergeisergei[comment {-*- tcl -*- doctools = digest.inc}] [include digest/header.inc] [include digest/footer.inc] trf2.1.4/doc/digest/footer.inc0000644000175000017500000000042211216343142015562 0ustar sergeisergei[comment {-*- tcl -*- doctools = digest_footer.inc}] [include common/sections.inc] [see_also trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128] [keywords [vset digest] {message digest} mac hashing hash authentication] [manpage_end] trf2.1.4/doc/digest/ripemd.inc0000644000175000017500000000034011216343142015543 0ustar sergeisergei[vset digest ripemd-[vset digest]] [include digest/header.inc] [section NOTES] See [uri http://www.esat.kuleuven.ac.be/%7Ebosselae/ripemd160.html] for additional information. [keywords ripemd] [include digest/footer.inc] trf2.1.4/doc/uuencode.man0000644000175000017500000000104411216343142014617 0ustar sergeisergei[vset encoding uuencode] [include encoding/header.inc] [para] This encoding transforms every block of three bytes into a block of four bytes, each of which is printable, i.e. 7bit ASCII. This implies that the result is valid UTF-8 too. The command uses essentially the same algorithm as for [cmd base64], except for a different mapping from 6-bit fragments to printable bytes. [include encoding/middle.inc] [section NOTES] [list_begin enum] [enum] The encoding buffers 2 bytes. [list_end] [keywords base64] [include encoding/footer.inc] trf2.1.4/doc/seek.policies0000644000175000017500000000755711216343142015012 0ustar sergeisergei * Each base channel is either seekable or not * Each transformation can use one of several seek policies while attached to a channel. - 'transform position' Each seek/tell request is passed down to the channel below, and the specified/returned position is converted as necessary (one additional vector in the transformation driver). - 'pass' Is subsumed by the policy above, with position transformation = identity. - 'unseekable' The transformation does a running count of the current position as it sees the world. Returns the information upon request (tell). Real seeking is disallowed. * The actual seek policy used by a transformation is computed from several sources: - The 'natural seek policy' of the transformation. - The seekability of the base channel. - The seek policies used by the transformations below it. (how to determine ?) - Policy requests by the user. Rules: 1) An unseekable base channel enforces 'unseekable' in all transformations above it. 2) An unseekable transformation enforces 'unseekable' in all transformations above it. 3) The user is able to overide 'unseekable' with pass or transform, but only for the transformation currently at the top, and not if lower transformations or the base channel enforce unseekable. I.e. the rules (1) and (2) have precedence. In case of 'transform position' the user has to specify the conversion he wishes for the location in the form of a tcl command. An empty command causes the system to use 'identity'. This way the user is able to enforce the current behaviour of simply passing the position without changing it. The user has to know the effects of this on the various transformations in the stack. * The user specifies his requests by using the new standard options @ -seekpolicy transform|unseekable @ -seektransform command ('-seektransform' command implies '-seekpolicy tranform') * A transformation specifies its natural policy through a new attribute and a new function vector in its driver structure. One argument to the vector specifies the direction of the conversion (pass position down to channel, get position from channel below), the instance configuration provides additional context (mode encode/decode, etc.). * A position transformation returning an error causes the system to reject the seek. An error during up-conversion (tell) implies that an 'identity loc. transform' was in effect for some time allowing the fractional placement of the down-location with respect to up-location. Handling: ? * The general 'transform' command uses additional keywords while calling back into the tcl level to query and implement its natural seek policy. * Questions: - Is it possible to determine the seekability of a channel by simply using the public API's ? (Without destroying the state of the channel ?) Answer: Yes, by checking the channel type for a non-NULL pointer for the SeekProc. - Is it possible to determine the seekability of a transformation ? Yes, if the seekability of a channel is checkable via Tcl_Seek itself. But not necessarily without disturbing the state of the transformation and/or channel below (Because we will have to try to seek to get either success or error. On success the test seek has to be reversed immediately. But a transformation below may have already discarded its input buffer !). Answer: Not generally. As the notion of an unseekable transformation is slightly different from unseekable channel we have to provide a SeekProc at all times, rendering the check above for channels unusable. If we don't want to disturb the state of other transformations we are reduced to check for SeekProc == TrfSeek first, to filter out any non-Trf transforms and then to look directly into the instance structure. For non-Trf transforms we have to make conservative assumptions. trf2.1.4/doc/compress/0000755000175000017500000000000011216344734014157 5ustar sergeisergeitrf2.1.4/doc/compress/header.inc0000644000175000017500000000063111216343142016072 0ustar sergeisergei[comment {-*- tcl -*- doctools = compress/header.inc}] [include common/trf_version.inc] [manpage_begin [vset compress] n [vset trf_version]] [titledesc "Data compression \"[vset compress]\""] [include common/trf_header.inc] [description] The command [cmd [vset compress]] is one of several data compressions provided by the package [package trf]. See [syscmd trf-intro] for an overview of the whole package. trf2.1.4/doc/compress/options.inc0000644000175000017500000000166311216343142016343 0ustar sergeisergei[comment {-*- tcl -*- doctools = compress/options.inc}] [lst_item "[option -mode] [const compress]|[const decompress]"] This option has to be present and is always understood by the compression. [nl] For [term immediate] mode the argument value specifies the operation to use. For an [term attached] compress it specifies the operation to use for [emph writing]. Reading will automatically use the reverse operation. See section [sectref {IMMEDIATE versus ATTACHED}] for explanations of these two terms. [nl] Beyond the argument values listed above all unique abbreviations are recognized too. [nl] [const Compress] causes the compression of arbitrary (most likely binary) data. [const Decompression] does the reverse . [lst_item "[option -level] [arg integer]"] Specifies the compression level. Is either the string [const default] or an integer number in the range [const 1] (minimal compression) to [const 9] (maximal compression). trf2.1.4/doc/compress/middle.inc0000644000175000017500000000041111216343142016074 0ustar sergeisergei[comment {-*- tcl -*- doctools = compress/middle.inc}] [para] [list_begin definitions] [call [cmd [vset compress]] [opt [arg options...]] [opt [arg data]]] [list_begin definitions] [include compress/options.inc] [include common/options.inc] [list_end] [list_end] trf2.1.4/doc/compress/footer.inc0000644000175000017500000000031111216343142016133 0ustar sergeisergei[comment {-*- tcl -*- doctools = compress/footer.inc}] [include common/sections.inc] [see_also trf-intro bz2 zip] [keywords [vset compress] compression decompression {data compression}] [manpage_end] trf2.1.4/doc/encoding/0000755000175000017500000000000011216344734014112 5ustar sergeisergeitrf2.1.4/doc/encoding/header.inc0000644000175000017500000000061611216343142016030 0ustar sergeisergei[comment {-*- tcl -*- doctools = encoding_header.inc}] [include common/trf_version.inc] [manpage_begin [vset encoding] n [vset trf_version]] [titledesc "Encoding \"[vset encoding]\""] [include common/trf_header.inc] [description] The command [cmd [vset encoding]] is one of several data encodings provided by the package [package trf]. See [syscmd trf-intro] for an overview of the whole package. trf2.1.4/doc/encoding/options.inc0000644000175000017500000000133611216343142016273 0ustar sergeisergei[comment {-*- tcl -*- doctools = encoding_options.inc}] [lst_item "[option -mode] [const encode]|[const decode]"] This option has to be present and is always understood by the encoding. [nl] For [term immediate] mode the argument value specifies the operation to use. For an [term attached] encoding it specifies the operation to use for [emph writing]. Reading will automatically use the reverse operation. See section [sectref {IMMEDIATE versus ATTACHED}] for explanations of these two terms. [nl] Beyond the argument values listed above all unique abbreviations are recognized too. [nl] [const Encode] converts from arbitrary (most likely binary) data into the described representation, [const decode] does the reverse . trf2.1.4/doc/encoding/middle.inc0000644000175000017500000000041111216343142016027 0ustar sergeisergei[comment {-*- tcl -*- doctools = encoding_middle.inc}] [para] [list_begin definitions] [call [cmd [vset encoding]] [opt [arg options...]] [opt [arg data]]] [list_begin definitions] [include encoding/options.inc] [include common/options.inc] [list_end] [list_end] trf2.1.4/doc/encoding/footer.inc0000644000175000017500000000033511216343142016074 0ustar sergeisergei[comment {-*- tcl -*- doctools = encoding_footer.inc}] [include common/sections.inc] [see_also trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode] [keywords [vset encoding] encoding] [manpage_end] trf2.1.4/doc/tmml/0000755000175000017500000000000011216343254013271 5ustar sergeisergeitrf2.1.4/doc/tmml/bz2.tmml0000644000175000017500000001250011216343254014657 0ustar sergeisergei bz2 Data compression "bz2" package require Tcl 8.2 package require Trf 2.1.3 bz2 options... data
DESCRIPTION The command bz2 is one of several data compressions provided by the package trf. See trf-intro for an overview of the whole package.

The command is based on the Burroughs-Wheeler transformation as implemented by the bzip2 compression library (http://sources.redhat.com/bzip2/).

bz2 options... data
compress|decompress
This option has to be present and is always understood by the compression.
For immediate mode the argument value specifies the operation to use. For an attached compress it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Compress causes the compression of arbitrary (most likely binary) data. Decompression does the reverse .
integer
Specifies the compression level. Is either the string default or an integer number in the range 1 (minimal compression) to 9 (maximal compression).
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro bz2 zip Burroughs-Wheeler bz2 compression decompression data compression
trf2.1.4/doc/tmml/md2.tmml0000644000175000017500000002200211216343254014642 0ustar sergeisergei md2 Message digest "md2" package require Tcl 8.2 package require Trf 2.1.3 md2 options... data
DESCRIPTION The command md2 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

md2 options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 md2 message digest mac hashing hash authentication
trf2.1.4/doc/tmml/transform.tmml0000644000175000017500000002466211216343254016211 0ustar sergeisergei transform Tcl level transformations package require Tcl 8.2 package require Trf 2.1.3 transform options... data callback operation data
DESCRIPTION The command transform reflects the API for a stack channel transformation into the tcl level, thus enabling the writing of transformations in tcl.

transform options... data
read|write
This option is accepted by the command if and only if it is used in immediate mode. See section IMMEDIATE versus ATTACHED for an explanation of the term.
The argument value specifies whether to run the read or the write part of the transformation specified via option on the immediate data.
Beyond the argument values listed above all unique abbreviations are recognized too.
cmd
This option has to be present and is always understood. Its argument is a command prefix. This command prefix will be called by internally whenever some operation of the transformation has to be executed. An empty cmd is not allowed.
The exact nature of the various possible calls and their expected results is described later, in section CALLBACK API.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

CALLBACK API Here we describe the API of the callback command implementing the actual transformation.

callback operation data
The callback is always called with two arguments, first an operation code followed by data. The latter will be empty for some operations.
The known operations are listed below, together with an explanation of the arguments, what is expected of them, and how their results are handled.
create/write
When called data is empty. The result of the call is ignored.
This is the first operation executed for the write side of the transformation. It has to initialize the internals of this part of the transformation and ready it for future calls.
delete/write
When called data is empty. The result of the call is ignored.
This is the last operation executed for the write side of the transformation. It has to shutdown the internals of this part of the transformation and release any resources which were acquired over the lifetime of the transformation.
write
The operation is called whenever data is written to the channel.
At the time of the call the argument data will contain the bytes to transform. The result of the call is taken as the result of the transformation and handed to the next stage down in the stack of transformation associated with the channel.
This operation has to transform the contents of data, using whatever data was left over from the last call of the operation. The transformation is allowed to buffer incomplete data.
flush/write
When called data is empty. The operation has to transform any incomplete data it has buffered internally on the write side. The result of the call is taken as the result of the transformation and handed to the next stage down in the stack of transformation associated with the channel.
clear/write
When called data is empty. The result of the call is ignored.
The write side of the transformation has to clear its internal buffers. This operation is called when the user seeks on the channel, thus invalidating any incomplete transformation.
create/read
When called data is empty. The result of the call is ignored.
This is the first operation executed for the read side of the transformation. It has to initialize the internals of this part of the transformation and ready it for future calls.
delete/read
When called data is empty. The result of the call is ignored.
This is the last operation executed for the write side of the transformation. It has to shutdown the internals of this part of the transformation and release any resources which were acquired over the lifetime of the transformation.
read
The operation is called whenever data is read from the channel.
At the time of the call the argument data will contain the bytes to transform. The result of the call is taken as the result of the transformation and posted to the next stage up in the stack of transformation associated with the channel.
This operation has to transform the contents of data, using whatever data was left over from the last call of the operation. The transformation is allowed to buffer incomplete data.
flush/read
When called data is empty. The operation has to transform any incomplete data it has buffered internally on the read side. The result of the call is taken as the result of the transformation and posted to the next stage up in the stack of transformation associated with the channel.
clear/read
When called data is empty. The result of the call is ignored.
The read side of the transformation has to clear its internal buffers. This operation is called when the user seeks on the channel, thus invalidating any incomplete transformation.
query/maxRead
When called data is empty. The result of the call is interpreted as integer number. This operation is used by the generic layer to determine if the transformation establishes a limit on the number of bytes it (the generic layer) is allowed read from the transformations lower in the stack. A negative result unsets any limit.
This has to be used if a transformation employs some kind of end-of-data marker. We cannot allow the generic layer to overshoot this marker because any data read after it cannot be stuffed back into the core buffers, causing the I/O system to loose data if the transformation is unstacked after it recognized the end of its data. This is a limitation of the I/O system in the tcl core.
Returning a positive value will cause the I/O system to slow down, but also ensures that no data is lost.
Two examples for such transformations are the data decompressors for zip and bz2. They use the C-level equivalent of this operation to prevent the overshooting.
trf-intro general transform
trf2.1.4/doc/tmml/ripemd160.tmml0000644000175000017500000002237211216343254015701 0ustar sergeisergei ripemd-160 Message digest "ripemd-160" package require Tcl 8.2 package require Trf 2.1.3 ripemd-160 options... data
DESCRIPTION The command ripemd-160 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

ripemd-160 options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
NOTES See http://www.esat.kuleuven.ac.be/%7Ebosselae/ripemd160.html for additional information.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 ripemd ripemd-160 message digest mac hashing hash authentication
trf2.1.4/doc/tmml/sha1_otp.tmml0000644000175000017500000002205711216343254015710 0ustar sergeisergei sha1_otp Message digest "sha1_otp" package require Tcl 8.2 package require Trf 2.1.3 sha1_otp options... data
DESCRIPTION The command sha1_otp is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

sha1_otp options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 sha1_otp message digest mac hashing hash authentication
trf2.1.4/doc/tmml/otp_words.tmml0000644000175000017500000001254411216343254016212 0ustar sergeisergei otp_words Encoding "otp_words" package require Tcl 8.2 package require Trf 2.1.3 otp_words options... data
DESCRIPTION The command otp_words is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every block of four bytes (64 bit) into six english words, as defined in RFC 2289 (http://www.rfc-editor.org/rfc/rfc2289.txt). This encoding is the sole one which is not able to handle an incomplete block at the end of the input.

otp_words options... data
encode|decode
This option has to be present and is always understood by the encoding.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro md5_otp trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode rfc 2289 md5_otp otp_words encoding
trf2.1.4/doc/tmml/crc-zlib.tmml0000644000175000017500000002247311216343254015701 0ustar sergeisergei crc-zlib Message digest "crc-zlib" package require Tcl 8.2 package require Trf 2.1.3 crc-zlib options... data
DESCRIPTION The command crc-zlib is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

crc-zlib options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
NOTES This command uses the same CRC polynomial as the CRC algorithm used by the zlib compression library (http://www.gzip.org/zlib/).
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 zlib zip crc crc-zlib message digest mac hashing hash authentication
trf2.1.4/doc/tmml/crc.tmml0000644000175000017500000002227711216343254014745 0ustar sergeisergei crc Message digest "crc" package require Tcl 8.2 package require Trf 2.1.3 crc options... data
DESCRIPTION The command crc is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

crc options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
NOTES This command uses the same CRC polynomial as the CRC algorithm used by PGP (http://www.pgp.com).
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 pgp crc message digest mac hashing hash authentication
trf2.1.4/doc/tmml/sha.tmml0000644000175000017500000002200211216343254014733 0ustar sergeisergei sha Message digest "sha" package require Tcl 8.2 package require Trf 2.1.3 sha options... data
DESCRIPTION The command sha is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

sha options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 sha message digest mac hashing hash authentication
trf2.1.4/doc/tmml/md5crypt.tmml0000644000175000017500000000265211216343254015740 0ustar sergeisergei md5crypt Password hashing based on "md5" package require Tcl 8.2 package require Trf 2.1.3 md5crypt password salt
DESCRIPTION The command md5crypt is for the encryption of passwords and uses md5 as hash algorithm. An alternative command for the same function, but based on the older crypt(3) hash function is crypt.

md5crypt password salt
Encrypts the password using the specified salt and returns the generated hash value as the result of the command.
trf-intro crypt crypt password md5 message digest mac hashing hash authentication
trf2.1.4/doc/tmml/rs_ecc.tmml0000644000175000017500000001156311216343254015430 0ustar sergeisergei rs_ecc Reed-Solomon error correcting code package require Tcl 8.2 package require Trf 2.1.3 rs_ecc options... data
DESCRIPTION The command rs_ecc provides a reed-solomon error correcting coder. The coder operates on blocks of 248 bytes each, therefore buffering 247 bytes.

rs_ecc options... data
encode|decode
This option has to be present and is always understood.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into a representation containing additional error correcting information, decode does the reverse, and performs the error correction if necessary.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro error correction reed-solomon
trf2.1.4/doc/tmml/bin.tmml0000644000175000017500000001226411216343254014741 0ustar sergeisergei bin Encoding "bin" package require Tcl 8.2 package require Trf 2.1.3 bin options... data
DESCRIPTION The command bin is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every byte in the input into a sequence of 8 characters containing the binary representation of the byte. For example

% bin -mode encode Z 01011010

bin options... data
encode|decode
This option has to be present and is always understood by the encoding.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode hex oct bin encoding
trf2.1.4/doc/tmml/haval.tmml0000644000175000017500000002202411216343254015257 0ustar sergeisergei haval Message digest "haval" package require Tcl 8.2 package require Trf 2.1.3 haval options... data
DESCRIPTION The command haval is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

haval options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 haval message digest mac hashing hash authentication
trf2.1.4/doc/tmml/zip.tmml0000644000175000017500000001354411216343254014775 0ustar sergeisergei zip Data compression "zip" package require Tcl 8.2 package require Trf 2.1.3 zip options... data
DESCRIPTION The command zip is one of several data compressions provided by the package trf. See trf-intro for an overview of the whole package.

The command is based on the deflate compression algorithm as specified in RFC 1951 (http://www.rfc-editor.org/rfc/rfc1951.txt) and as implemented by the zlib compression library (http://www.gzip.org/zlib/). See also RFC 1950 (http://www.rfc-editor.org/rfc/rfc1950.txt)

zip options... data
compress|decompress
This option has to be present and is always understood by the compression.
For immediate mode the argument value specifies the operation to use. For an attached compress it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Compress causes the compression of arbitrary (most likely binary) data. Decompression does the reverse .
integer
Specifies the compression level. Is either the string default or an integer number in the range 1 (minimal compression) to 9 (maximal compression).
boolean
If set to true the command will not create the zip specific header (See RFC 1950) normally written before the compressed data. The options defaults to false. It has to be used when writing a gzip emulation in Tcl as gzip creates a different header.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro bz2 zip rfc 1950 rfc 1951 rfc 1952 zip compression decompression data compression
trf2.1.4/doc/tmml/md5.tmml0000644000175000017500000002200211216343254014645 0ustar sergeisergei md5 Message digest "md5" package require Tcl 8.2 package require Trf 2.1.3 md5 options... data
DESCRIPTION The command md5 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

md5 options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 md5 message digest mac hashing hash authentication
trf2.1.4/doc/tmml/crypt.tmml0000644000175000017500000000257611216343254015337 0ustar sergeisergei crypt Password hashing based on "crypt" package require Tcl 8.2 package require Trf 2.1.3 crypt password salt
DESCRIPTION The command crypt is an interface to the crypt(3) function for the encryption of passwords. An alternative command for the same, but based on md5 is md5crypt.

crypt password salt
Encrypts the password using the specified salt and returns the generated hash value as the result of the command.
trf-intro md5crypt crypt password md5 message digest mac hashing hash authentication
trf2.1.4/doc/tmml/trf.tmml0000644000175000017500000001011711216343254014757 0ustar sergeisergei trf-intro Introduction to Trf package require Tcl 8.2 package require Trf 2.1.3
DESCRIPTION The package Trf provides a number of commands which take data and transform them in various ways.
BACKGROUND The implementation of Trf began as proof-of-concept of the validity and usefulness of the "stacked channel" patches to the core. These patches allow the writing of extensions to the generic I/O system of the core which are able to intercept all read/write operations on designated channels, thus giving it the ability to transform the data flowing through these channels as desired.

This allows things like transparent encryption, compression, charset recoding, etc.

Since version 8.2 of the tcl core the aforementioned patches are part of the tcl core itself, changing the status of trf from "extension requiring core patches" to "normal extension".

Other packages built upon either the stackd channels directly, or Trf are:

  1. TrfCrypt, by myself, contains various encryption systems
  2. TLS, an SSL/TLS implementation by Matt Newman.
  3. Tcl MIME by Marshall Rose.
API The commands provide by trf can be placed into the three categories listed below. Note that all commands are added to the global namespace.
Encodings
The encoding commands either take some data and return the same data in encoded form, or take encoded data and return a decoded result.
  1. oct
  2. hex
  3. oct
  4. base64
  5. uuencode
  6. ascii85
  7. otp_words
  8. quoted-printable

Message Digests
The second category are message digests in general, simple ones like crc, and cryptographically strong algorithms like md5.
  1. crc-zlib
  2. crc
  3. adler
  4. md2
  5. md5
  6. md5_otp
  7. sha
  8. sha1
  9. sha1_otp
  10. haval
  11. ripemd-160
  12. ripemd-128

Miscellaneous
At last a number of commands not readily placed into categories providing password crypting, general transformations, data compression, error correction and others.
  1. crypt
  2. md5crypt
  3. transform
  4. rs_ecc
  5. zip
  6. bz2
  7. unstack
oct hex oct base64 uuencode ascii85 otp_words quoted-printable crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 crypt md5crypt transform rs_ecc zip bz2 transformation encoding message digest compression error correction
trf2.1.4/doc/tmml/quoted-printable.tmml0000644000175000017500000001250411216343254017445 0ustar sergeisergei quoted-printable Encoding "quoted-printable" package require Tcl 8.2 package require Trf 2.1.3 quoted-printable options... data
DESCRIPTION The command quoted-printable is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

Printable ASCII characters are largely untouched. Otherwise a three-character encoding sequence is used. This is MIME's compromise encoding. See RFC 2045 (http://www.rfc-editor.org/rfc/rfc2045.txt) for its definition.

quoted-printable options... data
encode|decode
This option has to be present and is always understood by the encoding.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode rfc 2045 mime quoted-printable encoding
trf2.1.4/doc/tmml/md5_otp.tmml0000644000175000017500000002204611216343254015537 0ustar sergeisergei md5_otp Message digest "md5_otp" package require Tcl 8.2 package require Trf 2.1.3 md5_otp options... data
DESCRIPTION The command md5_otp is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

md5_otp options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 md5_otp message digest mac hashing hash authentication
trf2.1.4/doc/tmml/base64.tmml0000644000175000017500000001342611216343254015256 0ustar sergeisergei base64 Encoding "base64" package require Tcl 8.2 package require Trf 2.1.3 base64 options... data
DESCRIPTION The command base64 is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every block of three bytes into a block of four bytes, each of which is printable, i.e. 7bit ASCII. This implies that the result is valid UTF-8 too. The command uses essentially the same algorithm as for uuencode, except for a different mapping from 6-bit fragments to printable bytes.

base64 options... data
encode|decode
This option has to be present and is always understood by the encoding.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
NOTES
  1. The encoding is equivalent to PGP's ASCII armor and was also accepted as one of the MIME encodings for encapsulation of binary data. See RFC 2045 (http://www.rfc-editor.org/rfc/rfc2045.txt) for details and the specification of this encoding.
  2. The encoding buffers 2 bytes.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode uuencode rfc 2045 mime pgp ascii armor base64 encoding
trf2.1.4/doc/tmml/ascii85.tmml0000644000175000017500000001224211216343254015432 0ustar sergeisergei ascii85 Encoding "ascii85" package require Tcl 8.2 package require Trf 2.1.3 ascii85 options... data
DESCRIPTION The command ascii85 is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every block of four bytes into the Ascii85 representation as defined in the 'Postscript Reference Manual' (2nd Edition, section 3.13, page 129).

ascii85 options... data
encode|decode
This option has to be present and is always understood by the encoding.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode postscript ascii85 encoding
trf2.1.4/doc/tmml/adler.tmml0000644000175000017500000002236311216343254015261 0ustar sergeisergei adler Message digest "adler" package require Tcl 8.2 package require Trf 2.1.3 adler options... data
DESCRIPTION The command adler is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

adler options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
NOTES This command implements the ADLER digest used by the zlib compression library (http://www.gzip.org/zlib/).
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 zlib zip adler message digest mac hashing hash authentication
trf2.1.4/doc/tmml/unstack.tmml0000644000175000017500000000245311216343254015640 0ustar sergeisergei unstack Unstacking channels package require Tcl 8.2 package require Trf 2.1.3 unstack channel
DESCRIPTION The command unstack is an interface to the public Tcl API function TclUnstackChannel. It unstacks the topmost transformation from the specified channel if there is any.

unstack channel
Removes the topmost transformation from the specified channel. If the channel has no transformation associated with it it will be closed. In other words, in this situation the command is equivalent to close.
trf-intro transformation unstacking removal
trf2.1.4/doc/tmml/oct.tmml0000644000175000017500000001225611216343254014757 0ustar sergeisergei oct Encoding "oct" package require Tcl 8.2 package require Trf 2.1.3 oct options... data
DESCRIPTION The command oct is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every byte in the input into a sequence of 3 characters containing the octal representation of the byte. For example

% oct -mode encode Z 132

oct options... data
encode|decode
This option has to be present and is always understood by the encoding.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode bin hex oct encoding
trf2.1.4/doc/tmml/uuencode.tmml0000644000175000017500000001265711216343254016006 0ustar sergeisergei uuencode Encoding "uuencode" package require Tcl 8.2 package require Trf 2.1.3 uuencode options... data
DESCRIPTION The command uuencode is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every block of three bytes into a block of four bytes, each of which is printable, i.e. 7bit ASCII. This implies that the result is valid UTF-8 too. The command uses essentially the same algorithm as for base64, except for a different mapping from 6-bit fragments to printable bytes.

uuencode options... data
encode|decode
This option has to be present and is always understood by the encoding.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
NOTES
  1. The encoding buffers 2 bytes.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode base64 uuencode encoding
trf2.1.4/doc/tmml/sha1.tmml0000644000175000017500000002201311216343254015016 0ustar sergeisergei sha1 Message digest "sha1" package require Tcl 8.2 package require Trf 2.1.3 sha1 options... data
DESCRIPTION The command sha1 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

sha1 options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 sha1 message digest mac hashing hash authentication
trf2.1.4/doc/tmml/hex.tmml0000644000175000017500000001226411216343254014755 0ustar sergeisergei hex Encoding "hex" package require Tcl 8.2 package require Trf 2.1.3 hex options... data
DESCRIPTION The command hex is one of several data encodings provided by the package trf. See trf-intro for an overview of the whole package.

This encoding transforms every byte in the input into a sequence of 2 characters containing the hexadecimal representation of the byte. For example

% hex -mode encode Z 5A

hex options... data
encode|decode
This option has to be present and is always understood by the encoding.
For immediate mode the argument value specifies the operation to use. For an attached encoding it specifies the operation to use for writing. Reading will automatically use the reverse operation. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
Beyond the argument values listed above all unique abbreviations are recognized too.
Encode converts from arbitrary (most likely binary) data into the described representation, decode does the reverse .
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro ascii85 base64 bin hex oct otp_words quoted-printable uuencode bin oct hex encoding
trf2.1.4/doc/tmml/ripemd128.tmml0000644000175000017500000002237211216343254015705 0ustar sergeisergei ripemd-128 Message digest "ripemd-128" package require Tcl 8.2 package require Trf 2.1.3 ripemd-128 options... data
DESCRIPTION The command ripemd-128 is one of several message digests provided by the package trf. See trf-intro for an overview of the whole package.

ripemd-128 options... data
The options listed below are understood by the digest if and only if the digest is attached to a channel. See section IMMEDIATE versus ATTACHED for an explanation of the term attached.
absorb|write|transparent
This option has to be present. The specified argument determines the behaviour of the digest in attached mode.
Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below:
absorb
All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel.
When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "ok", or "failed".
write
All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options , , , and .
transparent
This mode is a mixture of both absorb and write modes. As for absorb all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for write.

varname
This option can be used if and only if the option " absorb" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values.
variable|channel
This option can be used for digests in mode write or transparent. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option . It defaults to variable.
variable|channel
Like option , but for option .
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.
data
This option can be used for digests in mode write or transparent. The value data is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option . The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only.
Note that using a variable may yield incorrect results under tcl 7.6, due to embedded \0's.

The options listed below are always understood by the digest, attached versus immediate does not matter. See section IMMEDIATE versus ATTACHED for explanations of these two terms.
channel
The presence/absence of this option determines the main operation mode of the transformation.
If present the transformation will be stacked onto the channel whose handle was given to the option and run in attached mode. More about this in section IMMEDIATE versus ATTACHED.
If the option is absent the transformation is used in immediate mode and the options listed below are recognized. More about this in section IMMEDIATE versus ATTACHED.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the data to transform has to be read from.
If the transformation is in immediate mode and this option is absent the data to transform is expected as the last argument to the transformation.
channel
This options is legal if and only if the transformation is used in immediate mode. It provides the handle of the channel the generated transformation result is written to.
If the transformation is in immediate mode and this option is absent the generated data is returned as the result of the command itself.
NOTES See http://www.esat.kuleuven.ac.be/%7Ebosselae/ripemd160.html for additional information.
IMMEDIATE VERSUS ATTACHED The transformation distinguishes between two main ways of using it. These are the immediate and attached operation modes.

For the attached mode the option is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command unstack for the chosen channel. This is the only way to do this at the Tcl level.

In the second mode, which can be detected by the absence of option , the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution.

Where the data is taken from, and delivered to, is governed by the presence and absence of the options and . It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output.

trf-intro crc-zlib crc adler md2 md5 md5_otp sha sha1 sha1_otp haval ripemd-160 ripemd-128 ripemd ripemd-128 message digest mac hashing hash authentication
trf2.1.4/doc/zip.man0000644000175000017500000000167611216343142013625 0ustar sergeisergei[vset compress zip] [include compress/header.inc] [para] The command is based on the deflate compression algorithm as specified in RFC 1951 ([uri http://www.rfc-editor.org/rfc/rfc1951.txt]) and as implemented by the zlib compression library ([uri http://www.gzip.org/zlib/]). See also RFC 1950 ([uri http://www.rfc-editor.org/rfc/rfc1950.txt]) [para] [list_begin definitions] [call [cmd [vset compress]] [opt [arg options...]] [opt [arg data]]] [list_begin definitions] [include compress/options.inc] [lst_item "[option -nowrap] [arg boolean]"] If set to [const true] the command will not create the zip specific header (See RFC 1950) normally written before the compressed data. The options defaults to [const false]. It has to be used when writing a [syscmd gzip] emulation in Tcl as gzip creates a different header. [include common/options.inc] [list_end] [list_end] [keywords {rfc 1950} {rfc 1951} {rfc 1952}] [include compress/footer.inc] trf2.1.4/doc/crc-zlib.man0000644000175000017500000000040411216343142014514 0ustar sergeisergei[vset digest crc-zlib] [include digest/header.inc] [section NOTES] This command uses the same CRC polynomial as the CRC algorithm used by the zlib compression library ([uri http://www.gzip.org/zlib/]). [keywords zlib zip crc] [include digest/footer.inc] trf2.1.4/doc/INSTALL.configure0000644000175000017500000001365511216343142015337 0ustar sergeisergei This is a generic INSTALL file for utilities distributions. If this package does not come with, e.g., installable documentation or data files, please ignore the references to them below. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation, and creates the Makefile(s) (one in each subdirectory of the source directory). In some packages it creates a C header file containing system-dependent definitions. It also creates a file `config.status' that you can run in the future to recreate the current configuration. To compile this package: 1. Configure the package for your system. Normally, you just `cd' to the directory containing the package's source code and type `./configure'. If you're using `csh' on an old version of System V, you might need to type `sh configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While it is running, it prints some messages that tell what it is doing. If you don't want to see any messages, run `configure' with its standard output redirected to `/dev/null'; for example, `./configure >/dev/null'. To compile the package in a different directory from the one containing the source code, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If for some reason `configure' is not in the source code directory that you are configuring, then it will report that it can't find the source code. In that case, run `configure' with the option `--srcdir=DIR', where DIR is the directory that contains the source code. By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. Alternately, you can do so by consistently giving a value for the `prefix' variable when you run `make', e.g., make prefix=/usr/gnu make prefix=/usr/gnu install You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH' or set the `make' variable `exec_prefix' to PATH, the package will use PATH as the prefix for installing programs and libraries. Data files and documentation will still use the regular prefix. Normally, all files are installed using the same prefix. Some packages pay attention to `--with-PACKAGE' options to `configure', where PACKAGE is something like `gnu-as' or `x' (for the X Window System). They may also pay attention to `--enable-FEATURE' options, where FEATURE indicates an optional part of the package. The README should mention any `--with-' and `--enable-' options that the package recognizes. `configure' also recognizes the following options: `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' Do not print messages saying which checks are being made. `--verbose' Print the results of the checks. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `--x-includes=DIR' X include files are in DIR. `--x-libraries=DIR' X library files are in DIR. `configure' also accepts and ignores some other options. On systems that require unusual options for compilation or linking that the package's `configure' script does not know about, you can give `configure' initial values for variables by setting them in the environment. In Bourne-compatible shells, you can do that on the command line like this: CC='gcc -traditional' LIBS=-lposix ./configure On systems that have the `env' program, you can do it like this: env CC='gcc -traditional' LIBS=-lposix ./configure Here are the `make' variables that you might want to override with environment variables when running `configure'. For these variables, any value given in the environment overrides the value that `configure' would choose: - Variable: CC C compiler program. The default is `cc'. - Variable: INSTALL Program to use to install files. The default is `install' if you have it, `cp' otherwise. For these variables, any value given in the environment is added to the value that `configure' chooses: - Variable: DEFS Configuration options, in the form `-Dfoo -Dbar...'. Do not use this variable in packages that create a configuration header file. - Variable: LIBS Libraries to link with, in the form `-lfoo -lbar...'. If you need to do unusual things to compile the package, we encourage you to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the README so we can include them in the next release. 2. Type `make' to compile the package. If you want, you can override the `make' variables CFLAGS and LDFLAGS like this: make CFLAGS=-O2 LDFLAGS=-s 3. If the package comes with self-tests and you want to run them, type `make check'. If you're not sure whether there are any, try it; if `make' responds with something like make: *** No way to make target `check'. Stop. then the package does not come with self-tests. 4. Type `make install' to install programs, data files, and documentation. 5. You can remove the program binaries and object files from the source directory by typing `make clean'. To also remove the Makefile(s), the header file containing system-dependent definitions (if the package uses one), and `config.status' (all the files that `configure' created), type `make distclean'. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need it if you want to regenerate `configure' using a newer version of `autoconf'. trf2.1.4/doc/crc.man0000644000175000017500000000032611216343142013561 0ustar sergeisergei[vset digest crc] [include digest/header.inc] [section NOTES] This command uses the same CRC polynomial as the CRC algorithm used by PGP ([uri http://www.pgp.com]). [keywords pgp] [include digest/footer.inc] trf2.1.4/doc/defines0000644000175000017500000000531511216343142013660 0ustar sergeisergeiDefines used during the compilation of Trf to guide the process. ================================================================ ENABLE_BINIO (init.c, binio.c) If set enables the compilation of the 'binio' command. This command is deprecated, use 'binary' instead, which is the official way. Default: Not set. BZLIB_STATIC_BUILD (bz2lib.c) If set the code will assume that the 'bzip2'-library is linked statically into the trf library. If not set the code will try to locate and load the library dynamically, on demand. Default: Not set. BZ2_LIB_NAME (bz2lib.c) Defines the name of the 'bzip2'-library. Relevant only if BZLIB_STATIC_BUILD is *not* set. Default (Win): "libbz2.dll" Impossible to overide from the Makefile! Default: "libbz2.so" The Makefile can overide this definition. ZLIB_STATIC_BUILD (zlib.c) See BZLIB_STATIC_BUILD, this time for 'zlib'. Default: Not set. Z_LIB_NAME (zlib.c) See BZ2_LIB_NAME, this time for 'zlib'. Default (Win): "zlib.dll" Impossible to overide from the Makefile! Default: "libz.so" The Makefile can overide this definition. MD5_STATIC_BUILD See foo_LIB_NAME, this time for 'MD5'. Default: Not set. SSL_LIB_NAME (loadman.c) Trf searches for the SSL-library to get at some the hash functionality (md2, ...). This definition specifies the name of the library we are looking for. Default (Win): "crypto32.dll" Default: "libcrypto.so" The defaults can be overidden from the Makefile. CRYPT_LIB_NAME (loadman.c) The name of the library containing MD5. This value is usually set by 'configure' depending on the existence of -lcrypt and the functionality it contains. Default (Win): "crypt.dll" Default: "libcrypt.so" The defaults can and usually will be overidden from the Makefile, via 'configure'. WORDS_BIGENDIAN (rmd*.c, sha.c) Set by the 'configure' script. If set the code assumes that it will run on a bigendian system. Defult: None, computed by 'configure'. USE_TCL_STUBS (init.c, registry.c, unstack.c, trfStubLib.c) If set the code will use the stub-mechanism to call functions from the core. Default: Not set if compiled against Tcl < 8.1 Set if compiled against Tcl >= 8.1 TCL_THREADS (init.c) Lifted by 'configure' from 'tclConfig.sh'. If set Trf is compiled for thread-safe operation, i.e. some places are protected with mutexes. TRF_DEBUG TRF_STREAM_DEBUG Developer definitions. If set code is compiled into the extension providing extensive! logs of its operation. Especially TRF_STREAM_DEBUG is able to generate logs in the multi-megabyte range as it exactly logs the stream of bytes flowing throw a transformation (r and w paths). Default: Not set. ================================================================ trf2.1.4/doc/ripemd160.man0000644000175000017500000000006111216343142014515 0ustar sergeisergei[vset digest 160] [include digest/ripemd.inc] trf2.1.4/doc/bz2.man0000644000175000017500000000046111216343142013507 0ustar sergeisergei[vset compress bz2] [include compress/header.inc] [para] The command is based on the Burroughs-Wheeler transformation as implemented by the bzip2 compression library ([uri http://sources.redhat.com/bzip2/]). [include compress/middle.inc] [keywords Burroughs-Wheeler] [include compress/footer.inc] trf2.1.4/doc/quoted-printable.man0000644000175000017500000000060511216343142016271 0ustar sergeisergei[vset encoding quoted-printable] [include encoding/header.inc] [para] Printable ASCII characters are largely untouched. Otherwise a three-character encoding sequence is used. This is MIME's compromise encoding. See RFC 2045 ([uri http://www.rfc-editor.org/rfc/rfc2045.txt]) for its definition. [include encoding/middle.inc] [keywords {rfc 2045} mime] [include encoding/footer.inc] trf2.1.4/doc/license.terms0000644000175000017500000000260711216343142015017 0ustar sergeisergeiThis software is copyrighted by Andreas Kupries. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The author 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 AUTHOR 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 AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR 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 AUTHOR AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. trf2.1.4/doc/sha1.man0000644000175000017500000000006011216343142013641 0ustar sergeisergei[vset digest sha1] [include digest/main.inc] trf2.1.4/doc/man/0000755000175000017500000000000011216343254013073 5ustar sergeisergeitrf2.1.4/doc/man/ripemd160.n0000644000175000017500000001730511216343254014767 0ustar sergeisergei'\" '\" Generated from file 'ripemd160.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "ripemd-160" n 2.1.3 "Trf transformer commands" .BS .SH NAME ripemd-160 \- Message digest "ripemd-160" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBripemd-160\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBripemd-160\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBripemd-160\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH NOTES See \fIhttp://www.esat.kuleuven.ac.be/%7Ebosselae/ripemd160.html\fR for additional information. .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, mac, message digest, ripemd, ripemd-160 .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/sha1.n0000644000175000017500000001704411216343254014114 0ustar sergeisergei'\" '\" Generated from file 'sha1.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "sha1" n 2.1.3 "Trf transformer commands" .BS .SH NAME sha1 \- Message digest "sha1" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBsha1\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBsha1\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBsha1\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, mac, message digest, sha1 .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/otp_words.n0000644000175000017500000001065111216343254015275 0ustar sergeisergei'\" '\" Generated from file 'otp_words.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "otp_words" n 2.1.3 "Trf transformer commands" .BS .SH NAME otp_words \- Encoding "otp_words" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBotp_words\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBotp_words\fR is one of several data encodings provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP This encoding transforms every block of four bytes (64 bit) into six english words, as defined in RFC 2289 (\fIhttp://www.rfc-editor.org/rfc/rfc2289.txt\fR). This encoding is the sole one which is \fInot able\fR to handle an incomplete block at the end of the input. .PP .TP \fBotp_words\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood by the encoding. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into the described representation, \fBdecode\fR does the reverse . .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" ascii85, base64, bin, hex, md5_otp, oct, otp_words, quoted-printable, trf-intro, uuencode .SH KEYWORDS encoding, md5_otp, otp_words, rfc 2289 .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/adler.n0000644000175000017500000001726211216343254014351 0ustar sergeisergei'\" '\" Generated from file 'adler.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "adler" n 2.1.3 "Trf transformer commands" .BS .SH NAME adler \- Message digest "adler" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBadler\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBadler\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBadler\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH NOTES This command implements the ADLER digest used by the zlib compression library (\fIhttp://www.gzip.org/zlib/\fR). .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS adler, authentication, hash, hashing, mac, message digest, zip, zlib .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/rs_ecc.n0000644000175000017500000001020511216343254014506 0ustar sergeisergei'\" '\" Generated from file 'rs_ecc.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "rs_ecc" n 2.1.3 "Trf transformer commands" .BS .SH NAME rs_ecc \- Reed-Solomon error correcting code .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBrs_ecc\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBrs_ecc\fR provides a reed-solomon error correcting coder. The coder operates on blocks of 248 bytes each, therefore buffering 247 bytes. .PP .TP \fBrs_ecc\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into a representation containing additional error correcting information, \fBdecode\fR does the reverse, and performs the error correction if necessary. .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" trf-intro .SH KEYWORDS error correction, reed-solomon .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/bz2.n0000644000175000017500000001065711216343254013760 0ustar sergeisergei'\" '\" Generated from file 'bz2.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "bz2" n 2.1.3 "Trf transformer commands" .BS .SH NAME bz2 \- Data compression "bz2" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBbz2\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBbz2\fR is one of several data compressions provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP The command is based on the Burroughs-Wheeler transformation as implemented by the bzip2 compression library (\fIhttp://sources.redhat.com/bzip2/\fR). .PP .TP \fBbz2\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBcompress\fR|\fBdecompress\fR This option has to be present and is always understood by the compression. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR compress it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBCompress\fR causes the compression of arbitrary (most likely binary) data. \fBDecompression\fR does the reverse . .TP \fB-level\fR \fIinteger\fR Specifies the compression level. Is either the string \fBdefault\fR or an integer number in the range \fB1\fR (minimal compression) to \fB9\fR (maximal compression). .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" bz2, trf-intro, zip .SH KEYWORDS Burroughs-Wheeler, bz2, compression, data compression, decompression .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/oct.n0000644000175000017500000001042311216343254014037 0ustar sergeisergei'\" '\" Generated from file 'oct.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "oct" n 2.1.3 "Trf transformer commands" .BS .SH NAME oct \- Encoding "oct" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBoct\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBoct\fR is one of several data encodings provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP This encoding transforms every byte in the input into a sequence of 3 characters containing the octal representation of the byte. For example .PP .nf % oct -mode encode Z 132 .fi .PP .TP \fBoct\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood by the encoding. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into the described representation, \fBdecode\fR does the reverse . .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode .SH KEYWORDS bin, encoding, hex, oct .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/md2.n0000644000175000017500000001703411216343254013741 0ustar sergeisergei'\" '\" Generated from file 'md2.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "md2" n 2.1.3 "Trf transformer commands" .BS .SH NAME md2 \- Message digest "md2" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBmd2\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBmd2\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBmd2\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, mac, md2, message digest .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/crc-zlib.n0000644000175000017500000001734511216343254014771 0ustar sergeisergei'\" '\" Generated from file 'crc-zlib.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "crc-zlib" n 2.1.3 "Trf transformer commands" .BS .SH NAME crc-zlib \- Message digest "crc-zlib" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBcrc-zlib\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBcrc-zlib\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBcrc-zlib\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH NOTES This command uses the same CRC polynomial as the CRC algorithm used by the zlib compression library (\fIhttp://www.gzip.org/zlib/\fR). .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, crc, crc-zlib, hash, hashing, mac, message digest, zip, zlib .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/transform.n0000644000175000017500000002215411216343254015271 0ustar sergeisergei'\" '\" Generated from file 'transform.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "transform" n 2.1.3 "Trf transformer commands" .BS .SH NAME transform \- Tcl level transformations .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBtransform\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp \fBcallback\fR \fIoperation\fR \fIdata\fR .sp .BE .SH DESCRIPTION The command \fBtransform\fR reflects the API for a stack channel transformation into the tcl level, thus enabling the writing of transformations in tcl. .PP .TP \fBtransform\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBread\fR|\fBwrite\fR This option is accepted by the command if and only if it is used in \fIimmediate\fR mode. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term. .sp The argument value specifies whether to run the read or the write part of the transformation specified via option \fB-command\fR on the immediate data. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .TP \fB-command\fR \fIcmd\fR This option has to be present and is always understood. Its argument is a command prefix. This command prefix will be called by internally whenever some operation of the transformation has to be executed. An empty \fIcmd\fR is not allowed. .sp The exact nature of the various possible calls and their expected results is described later, in section \fBCALLBACK API\fR. .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "CALLBACK API" Here we describe the API of the callback command implementing the actual transformation. .PP .TP \fBcallback\fR \fIoperation\fR \fIdata\fR The callback is always called with two arguments, first an operation code followed by data. The latter will be empty for some operations. .sp The known operations are listed below, together with an explanation of the arguments, what is expected of them, and how their results are handled. .RS .TP \fBcreate/write\fR When called \fIdata\fR is empty. The result of the call is ignored. .sp This is the first operation executed for the write side of the transformation. It has to initialize the internals of this part of the transformation and ready it for future calls. .TP \fBdelete/write\fR When called \fIdata\fR is empty. The result of the call is ignored. .sp This is the last operation executed for the write side of the transformation. It has to shutdown the internals of this part of the transformation and release any resources which were acquired over the lifetime of the transformation. .TP \fBwrite\fR The operation is called whenever data is written to the channel. .sp At the time of the call the argument \fIdata\fR will contain the bytes to transform. The result of the call is taken as the result of the transformation and handed to the next stage down in the stack of transformation associated with the channel. .sp This operation has to transform the contents of \fIdata\fR, using whatever data was left over from the last call of the operation. The transformation is allowed to buffer incomplete data. .TP \fBflush/write\fR When called \fIdata\fR is empty. The operation has to transform any incomplete data it has buffered internally on the write side. The result of the call is taken as the result of the transformation and handed to the next stage down in the stack of transformation associated with the channel. .TP \fBclear/write\fR When called \fIdata\fR is empty. The result of the call is ignored. .sp The write side of the transformation has to clear its internal buffers. This operation is called when the user seeks on the channel, thus invalidating any incomplete transformation. .TP \fBcreate/read\fR When called \fIdata\fR is empty. The result of the call is ignored. .sp This is the first operation executed for the read side of the transformation. It has to initialize the internals of this part of the transformation and ready it for future calls. .TP \fBdelete/read\fR When called \fIdata\fR is empty. The result of the call is ignored. .sp This is the last operation executed for the write side of the transformation. It has to shutdown the internals of this part of the transformation and release any resources which were acquired over the lifetime of the transformation. .TP \fBread\fR The operation is called whenever data is read from the channel. .sp At the time of the call the argument \fIdata\fR will contain the bytes to transform. The result of the call is taken as the result of the transformation and posted to the next stage up in the stack of transformation associated with the channel. .sp This operation has to transform the contents of \fIdata\fR, using whatever data was left over from the last call of the operation. The transformation is allowed to buffer incomplete data. .TP \fBflush/read\fR When called \fIdata\fR is empty. The operation has to transform any incomplete data it has buffered internally on the read side. The result of the call is taken as the result of the transformation and posted to the next stage up in the stack of transformation associated with the channel. .TP \fBclear/read\fR When called \fIdata\fR is empty. The result of the call is ignored. .sp The read side of the transformation has to clear its internal buffers. This operation is called when the user seeks on the channel, thus invalidating any incomplete transformation. .TP \fBquery/maxRead\fR When called \fIdata\fR is empty. The result of the call is interpreted as integer number. This operation is used by the generic layer to determine if the transformation establishes a limit on the number of bytes it (the generic layer) is allowed read from the transformations lower in the stack. A negative result unsets any limit. .sp This has to be used if a transformation employs some kind of end-of-data marker. We cannot allow the generic layer to overshoot this marker because any data read after it cannot be stuffed back into the core buffers, causing the I/O system to loose data if the transformation is unstacked after it recognized the end of its data. This is a limitation of the I/O system in the tcl core. .sp Returning a positive value will cause the I/O system to slow down, but also ensures that no data is lost. .sp Two examples for such transformations are the data decompressors for \fBzip\fR and \fBbz2\fR. They use the C-level equivalent of this operation to prevent the overshooting. .RE .PP .SH "SEE ALSO" trf-intro .SH KEYWORDS general transform .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/haval.n0000644000175000017500000001705411216343254014354 0ustar sergeisergei'\" '\" Generated from file 'haval.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "haval" n 2.1.3 "Trf transformer commands" .BS .SH NAME haval \- Message digest "haval" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBhaval\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBhaval\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBhaval\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, haval, mac, message digest .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/bin.n0000644000175000017500000001043111216343254014021 0ustar sergeisergei'\" '\" Generated from file 'bin.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "bin" n 2.1.3 "Trf transformer commands" .BS .SH NAME bin \- Encoding "bin" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBbin\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBbin\fR is one of several data encodings provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP This encoding transforms every byte in the input into a sequence of 8 characters containing the binary representation of the byte. For example .PP .nf % bin -mode encode Z 01011010 .fi .PP .TP \fBbin\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood by the encoding. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into the described representation, \fBdecode\fR does the reverse . .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode .SH KEYWORDS bin, encoding, hex, oct .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/base64.n0000644000175000017500000001140711216343254014341 0ustar sergeisergei'\" '\" Generated from file 'base64.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "base64" n 2.1.3 "Trf transformer commands" .BS .SH NAME base64 \- Encoding "base64" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBbase64\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBbase64\fR is one of several data encodings provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP This encoding transforms every block of three bytes into a block of four bytes, each of which is printable, i.e. 7bit ASCII. This implies that the result is valid UTF-8 too. The command uses essentially the same algorithm as for \fBuuencode\fR, except for a different mapping from 6-bit fragments to printable bytes. .PP .TP \fBbase64\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood by the encoding. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into the described representation, \fBdecode\fR does the reverse . .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH NOTES .IP [1] The encoding is equivalent to PGP's ASCII armor and was also accepted as one of the MIME encodings for encapsulation of binary data. See RFC 2045 (\fIhttp://www.rfc-editor.org/rfc/rfc2045.txt\fR) for details and the specification of this encoding. .IP [2] The encoding buffers 2 bytes. .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode .SH KEYWORDS ascii armor, base64, encoding, mime, pgp, rfc 2045, uuencode .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/sha.n0000644000175000017500000001703411216343254014032 0ustar sergeisergei'\" '\" Generated from file 'sha.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "sha" n 2.1.3 "Trf transformer commands" .BS .SH NAME sha \- Message digest "sha" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBsha\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBsha\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBsha\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, mac, message digest, sha .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/hex.n0000644000175000017500000001043011216343254014034 0ustar sergeisergei'\" '\" Generated from file 'hex.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "hex" n 2.1.3 "Trf transformer commands" .BS .SH NAME hex \- Encoding "hex" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBhex\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBhex\fR is one of several data encodings provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP This encoding transforms every byte in the input into a sequence of 2 characters containing the hexadecimal representation of the byte. For example .PP .nf % hex -mode encode Z 5A .fi .PP .TP \fBhex\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood by the encoding. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into the described representation, \fBdecode\fR does the reverse . .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode .SH KEYWORDS bin, encoding, hex, oct .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/quoted-printable.n0000644000175000017500000001065211216343254016535 0ustar sergeisergei'\" '\" Generated from file 'quoted-printable.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "quoted-printable" n 2.1.3 "Trf transformer commands" .BS .SH NAME quoted-printable \- Encoding "quoted-printable" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBquoted-printable\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBquoted-printable\fR is one of several data encodings provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP Printable ASCII characters are largely untouched. Otherwise a three-character encoding sequence is used. This is MIME's compromise encoding. See RFC 2045 (\fIhttp://www.rfc-editor.org/rfc/rfc2045.txt\fR) for its definition. .PP .TP \fBquoted-printable\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood by the encoding. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into the described representation, \fBdecode\fR does the reverse . .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode .SH KEYWORDS encoding, mime, quoted-printable, rfc 2045 .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/unstack.n0000644000175000017500000000202411216343254014720 0ustar sergeisergei'\" '\" Generated from file 'unstack.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "unstack" n 2.1.3 "Trf transformer commands" .BS .SH NAME unstack \- Unstacking channels .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBunstack\fR \fIchannel\fR .sp .BE .SH DESCRIPTION The command \fBunstack\fR is an interface to the public Tcl API function \fBTclUnstackChannel\fR. It unstacks the topmost transformation from the specified channel if there is any. .PP .TP \fBunstack\fR \fIchannel\fR Removes the topmost transformation from the specified \fIchannel\fR. If the \fIchannel\fR has no transformation associated with it it will be closed. In other words, in this situation the command is equivalent to \fBclose\fR. .PP .SH "SEE ALSO" trf-intro .SH KEYWORDS removal, transformation, unstacking .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/md5_otp.n0000644000175000017500000001707411216343254014632 0ustar sergeisergei'\" '\" Generated from file 'md5_otp.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "md5_otp" n 2.1.3 "Trf transformer commands" .BS .SH NAME md5_otp \- Message digest "md5_otp" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBmd5_otp\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBmd5_otp\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBmd5_otp\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, mac, md5_otp, message digest .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/uuencode.n0000644000175000017500000001076111216343254015066 0ustar sergeisergei'\" '\" Generated from file 'uuencode.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "uuencode" n 2.1.3 "Trf transformer commands" .BS .SH NAME uuencode \- Encoding "uuencode" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBuuencode\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBuuencode\fR is one of several data encodings provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP This encoding transforms every block of three bytes into a block of four bytes, each of which is printable, i.e. 7bit ASCII. This implies that the result is valid UTF-8 too. The command uses essentially the same algorithm as for \fBbase64\fR, except for a different mapping from 6-bit fragments to printable bytes. .PP .TP \fBuuencode\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood by the encoding. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into the described representation, \fBdecode\fR does the reverse . .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH NOTES .IP [1] The encoding buffers 2 bytes. .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode .SH KEYWORDS base64, encoding, uuencode .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/crypt.n0000644000175000017500000000177511216343254014425 0ustar sergeisergei'\" '\" Generated from file 'crypt.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "crypt" n 2.1.3 "Trf transformer commands" .BS .SH NAME crypt \- Password hashing based on "crypt" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBcrypt\fR \fIpassword\fR \fIsalt\fR .sp .BE .SH DESCRIPTION The command \fBcrypt\fR is an interface to the \fBcrypt(3)\fR function for the encryption of passwords. An alternative command for the same, but based on \fImd5\fR is \fBmd5crypt\fR. .PP .TP \fBcrypt\fR \fIpassword\fR \fIsalt\fR Encrypts the \fIpassword\fR using the specified \fIsalt\fR and returns the generated hash value as the result of the command. .PP .SH "SEE ALSO" md5crypt, trf-intro .SH KEYWORDS authentication, crypt, hash, hashing, mac, md5, message digest, password .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/ascii85.n0000644000175000017500000001045011216343254014517 0ustar sergeisergei'\" '\" Generated from file 'ascii85.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "ascii85" n 2.1.3 "Trf transformer commands" .BS .SH NAME ascii85 \- Encoding "ascii85" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBascii85\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBascii85\fR is one of several data encodings provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP This encoding transforms every block of four bytes into the Ascii85 representation as defined in the 'Postscript Reference Manual' (2nd Edition, section 3.13, page 129). .PP .TP \fBascii85\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBencode\fR|\fBdecode\fR This option has to be present and is always understood by the encoding. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR encoding it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBEncode\fR converts from arbitrary (most likely binary) data into the described representation, \fBdecode\fR does the reverse . .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" ascii85, base64, bin, hex, oct, otp_words, quoted-printable, trf-intro, uuencode .SH KEYWORDS ascii85, encoding, postscript .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/ripemd128.n0000644000175000017500000001730511216343254014773 0ustar sergeisergei'\" '\" Generated from file 'ripemd128.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "ripemd-128" n 2.1.3 "Trf transformer commands" .BS .SH NAME ripemd-128 \- Message digest "ripemd-128" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBripemd-128\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBripemd-128\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBripemd-128\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH NOTES See \fIhttp://www.esat.kuleuven.ac.be/%7Ebosselae/ripemd160.html\fR for additional information. .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, mac, message digest, ripemd, ripemd-128 .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/trf.n0000644000175000017500000000603311216343254014047 0ustar sergeisergei'\" '\" Generated from file 'trf.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "trf-intro" n 2.1.3 "Trf transformer commands" .BS .SH NAME trf-intro \- Introduction to Trf .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp .BE .SH DESCRIPTION The package \fBTrf\fR provides a number of commands which take data and transform them in various ways. .SH BACKGROUND The implementation of Trf began as proof-of-concept of the validity and usefulness of the "stacked channel" patches to the core. These patches allow the writing of extensions to the generic I/O system of the core which are able to intercept all read/write operations on designated channels, thus giving it the ability to transform the data flowing through these channels as desired. .PP This allows things like transparent encryption, compression, charset recoding, etc. .PP Since version 8.2 of the tcl core the aforementioned patches are part of the tcl core itself, changing the status of \fBtrf\fR from "extension requiring core patches" to "normal extension". .PP Other packages built upon either the stackd channels directly, or Trf are: .IP [1] \fBTrfCrypt\fR, by myself, contains various encryption systems .IP [2] \fBTLS\fR, an SSL/TLS implementation by Matt Newman. .IP [3] \fBTcl MIME\fR by Marshall Rose. .PP .SH API The commands provide by \fBtrf\fR can be placed into the three categories listed below. Note that all commands are added to the global namespace. .TP \fIEncodings\fR The encoding commands either take some data and return the same data in encoded form, or take encoded data and return a decoded result. .RS .IP [1] \fBoct\fR .IP [2] \fBhex\fR .IP [3] \fBoct\fR .IP [4] \fBbase64\fR .IP [5] \fBuuencode\fR .IP [6] \fBascii85\fR .IP [7] \fBotp_words\fR .IP [8] \fBquoted-printable\fR .RE .sp .TP \fIMessage Digests\fR The second category are message digests in general, simple ones like \fBcrc\fR, and cryptographically strong algorithms like \fBmd5\fR. .RS .IP [1] \fBcrc-zlib\fR .IP [2] \fBcrc\fR .IP [3] \fBadler\fR .IP [4] \fBmd2\fR .IP [5] \fBmd5\fR .IP [6] \fBmd5_otp\fR .IP [7] \fBsha\fR .IP [8] \fBsha1\fR .IP [9] \fBsha1_otp\fR .IP [10] \fBhaval\fR .IP [11] \fBripemd-160\fR .IP [12] \fBripemd-128\fR .RE .sp .TP Miscellaneous At last a number of commands not readily placed into categories providing password crypting, general transformations, data compression, error correction and others. .RS .IP [1] \fBcrypt\fR .IP [2] \fBmd5crypt\fR .IP [3] \fBtransform\fR .IP [4] \fBrs_ecc\fR .IP [5] \fBzip\fR .IP [6] \fBbz2\fR .IP [7] \fBunstack\fR .RE .PP .SH "SEE ALSO" adler, ascii85, base64, bz2, crc, crc-zlib, crypt, haval, hex, md2, md5, md5_otp, md5crypt, oct, otp_words, quoted-printable, ripemd-128, ripemd-160, rs_ecc, sha, sha1, sha1_otp, transform, uuencode, zip .SH KEYWORDS compression, encoding, error correction, message digest, transformation .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/sha1_otp.n0000644000175000017500000001710411216343254014773 0ustar sergeisergei'\" '\" Generated from file 'sha1_otp.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "sha1_otp" n 2.1.3 "Trf transformer commands" .BS .SH NAME sha1_otp \- Message digest "sha1_otp" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBsha1_otp\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBsha1_otp\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBsha1_otp\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, mac, message digest, sha1_otp .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/crc.n0000644000175000017500000001722211216343254014025 0ustar sergeisergei'\" '\" Generated from file 'crc.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "crc" n 2.1.3 "Trf transformer commands" .BS .SH NAME crc \- Message digest "crc" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBcrc\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBcrc\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBcrc\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH NOTES This command uses the same CRC polynomial as the CRC algorithm used by PGP (\fIhttp://www.pgp.com\fR). .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, crc, hash, hashing, mac, message digest, pgp .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/zip.n0000644000175000017500000001155511216343254014063 0ustar sergeisergei'\" '\" Generated from file 'zip.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "zip" n 2.1.3 "Trf transformer commands" .BS .SH NAME zip \- Data compression "zip" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBzip\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBzip\fR is one of several data compressions provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP The command is based on the deflate compression algorithm as specified in RFC 1951 (\fIhttp://www.rfc-editor.org/rfc/rfc1951.txt\fR) and as implemented by the zlib compression library (\fIhttp://www.gzip.org/zlib/\fR). See also RFC 1950 (\fIhttp://www.rfc-editor.org/rfc/rfc1950.txt\fR) .PP .TP \fBzip\fR ?\fIoptions...\fR? ?\fIdata\fR? .RS .TP \fB-mode\fR \fBcompress\fR|\fBdecompress\fR This option has to be present and is always understood by the compression. .sp For \fIimmediate\fR mode the argument value specifies the operation to use. For an \fIattached\fR compress it specifies the operation to use for \fIwriting\fR. Reading will automatically use the reverse operation. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .sp Beyond the argument values listed above all unique abbreviations are recognized too. .sp \fBCompress\fR causes the compression of arbitrary (most likely binary) data. \fBDecompression\fR does the reverse . .TP \fB-level\fR \fIinteger\fR Specifies the compression level. Is either the string \fBdefault\fR or an integer number in the range \fB1\fR (minimal compression) to \fB9\fR (maximal compression). .TP \fB-nowrap\fR \fIboolean\fR If set to \fBtrue\fR the command will not create the zip specific header (See RFC 1950) normally written before the compressed data. The options defaults to \fBfalse\fR. It has to be used when writing a \fBgzip\fR emulation in Tcl as gzip creates a different header. .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" bz2, trf-intro, zip .SH KEYWORDS compression, data compression, decompression, rfc 1950, rfc 1951, rfc 1952, zip .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/md5crypt.n0000644000175000017500000000204611216343254015023 0ustar sergeisergei'\" '\" Generated from file 'md5crypt.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "md5crypt" n 2.1.3 "Trf transformer commands" .BS .SH NAME md5crypt \- Password hashing based on "md5" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBmd5crypt\fR \fIpassword\fR \fIsalt\fR .sp .BE .SH DESCRIPTION The command \fBmd5crypt\fR is for the encryption of passwords and uses \fImd5\fR as hash algorithm. An alternative command for the same function, but based on the older \fBcrypt(3)\fR hash function is \fBcrypt\fR. .PP .TP \fBmd5crypt\fR \fIpassword\fR \fIsalt\fR Encrypts the \fIpassword\fR using the specified \fIsalt\fR and returns the generated hash value as the result of the command. .PP .SH "SEE ALSO" crypt, trf-intro .SH KEYWORDS authentication, crypt, hash, hashing, mac, md5, message digest, password .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/man/md5.n0000644000175000017500000001703411216343254013744 0ustar sergeisergei'\" '\" Generated from file 'md5.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 1996-2003, Andreas Kupries '\" .so man.macros .TH "md5" n 2.1.3 "Trf transformer commands" .BS .SH NAME md5 \- Message digest "md5" .SH SYNOPSIS package require \fBTcl ?8.2?\fR .sp package require \fBTrf ?2.1.3?\fR .sp \fBmd5\fR ?\fIoptions...\fR? ?\fIdata\fR? .sp .BE .SH DESCRIPTION The command \fBmd5\fR is one of several message digests provided by the package \fBtrf\fR. See \fBtrf-intro\fR for an overview of the whole package. .PP .TP \fBmd5\fR ?\fIoptions...\fR? ?\fIdata\fR? The options listed below are understood by the digest if and only if the digest is \fIattached\fR to a channel. See section \fBIMMEDIATE versus ATTACHED\fR for an explanation of the term \fIattached\fR. .RS .TP \fB-mode\fR \fBabsorb\fR|\fBwrite\fR|\fBtransparent\fR This option has to be present. The specified argument determines the behaviour of the digest in \fIattached\fR mode. .sp Beyond the argument values listed above all unique abbreviations are recognized too. Their meaning is explained below: .RS .TP \fBabsorb\fR All data written to the channel is used to calculate the value of the message digest and then passed unchanged to the next level in the stack of transformations for the channel the digest is attached to. When the channel is closed the completed digest is written out too, essentially attaching the vlaue of the diggest after the information actually written to the channel. .sp When reading from the channel a value for the digest is computed too, and after closing of the channel compared to the digest which was attached, i.e. came behind the actual data. The option \fB-matchflag\fR has to be specified so that the digest knows where to store the result of said comparison. This result is a string and either "\fBok\fR", or "\fBfailed\fR". .TP \fBwrite\fR All data read from or written to the channel the digest is attached to is ignored and thrown away. Only a value for the digest of the data is computed. When the channel is closed the computed values are stored as ordered through the options \fB-write-destination\fR, \fB-write-type\fR, \fB-read-destination\fR, and \fB-read-type\fR. .TP \fBtransparent\fR This mode is a mixture of both \fBabsorb\fR and \fBwrite\fR modes. As for \fBabsorb\fR all data, read or written, passes through the digest unchanged. The generated values for the digest however are handled in the same way as for \fBwrite\fR. .RE .sp .TP \fB-matchflag\fR \fIvarname\fR This option can be used if and only if the option "\fB-mode\fR \fBabsorb\fR" is present. In that situation the argument is the name of a global or namespaced variable. The digest will write the result of comparing two digest values into this variable. The option will be ignored if the channel is write-only, because in that case there will be no comparison of digest values. .TP \fB-write-type\fR \fBvariable\fR|\fBchannel\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. Beyond the values listed above all their unique abbreviations are also allowed as argument values. The option determines the type of the argument to option \fB-write-destination\fR. It defaults to \fBvariable\fR. .TP \fB-read-type\fR \fBvariable\fR|\fBchannel\fR Like option \fB-write-type\fR, but for option \fB-read-destination\fR. .TP \fB-write-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-write-type\fR. The message digest computed for data written to the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is read-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .TP \fB-read-destination\fR \fIdata\fR This option can be used for digests in mode \fBwrite\fR or \fBtransparent\fR. The value \fIdata\fR is either the name of a global (or namespaced) variable or the handle of a writable channel, dependent on the value of option \fB-read-type\fR. The message digest computed for data read from the attached channel is written into it after the attached channel was closed. The option is ignored if the channel is write-only. .sp \fINote\fR that using a variable may yield incorrect results under tcl 7.6, due to embedded \\0's. .RE .sp The options listed below are always understood by the digest, \fIattached\fR versus \fIimmediate\fR does not matter. See section \fBIMMEDIATE versus ATTACHED\fR for explanations of these two terms. .RS .TP \fB-attach\fR \fIchannel\fR The presence/absence of this option determines the main operation mode of the transformation. .sp If present the transformation will be stacked onto the \fIchannel\fR whose handle was given to the option and run in \fIattached\fR mode. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .sp If the option is absent the transformation is used in \fIimmediate\fR mode and the options listed below are recognized. More about this in section \fBIMMEDIATE versus ATTACHED\fR. .TP \fB-in\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the data to transform has to be read from. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the data to transform is expected as the last argument to the transformation. .TP \fB-out\fR \fIchannel\fR This options is legal if and only if the transformation is used in \fIimmediate\fR mode. It provides the handle of the channel the generated transformation result is written to. .sp If the transformation is in \fIimmediate\fR mode and this option is absent the generated data is returned as the result of the command itself. .RE .PP .SH "IMMEDIATE VERSUS ATTACHED" The transformation distinguishes between two main ways of using it. These are the \fIimmediate\fR and \fIattached\fR operation modes. .PP For the \fIattached\fR mode the option \fB-attach\fR is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command \fBunstack\fR for the chosen channel. This is the only way to do this at the Tcl level. .PP In the second mode, which can be detected by the absence of option \fB-attach\fR, the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. .PP Where the data is taken from, and delivered to, is governed by the presence and absence of the options \fB-in\fR and \fB-out\fR. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \\0 characters embedded into either input or output. .SH "SEE ALSO" adler, crc, crc-zlib, haval, md2, md5, md5_otp, ripemd-128, ripemd-160, sha, sha1, sha1_otp, trf-intro .SH KEYWORDS authentication, hash, hashing, mac, md5, message digest .SH COPYRIGHT .nf Copyright (c) 1996-2003, Andreas Kupries .fitrf2.1.4/doc/unstack.man0000644000175000017500000000133511216343142014463 0ustar sergeisergei[include common/trf_version.inc] [manpage_begin unstack n [vset trf_version]] [titledesc "Unstacking channels"] [include common/trf_header.inc] [description] The command [cmd unstack] is an interface to the public Tcl API function [syscmd TclUnstackChannel]. It unstacks the topmost transformation from the specified channel if there is any. [para] [list_begin definitions] [call [cmd unstack] [arg channel]] Removes the topmost transformation from the specified [arg channel]. If the [arg channel] has no transformation associated with it it will be closed. In other words, in this situation the command is equivalent to [cmd close]. [list_end] [see_also trf-intro] [keywords transformation unstacking removal] [manpage_end] trf2.1.4/doc/haval.man0000644000175000017500000000006111216343142014101 0ustar sergeisergei[vset digest haval] [include digest/main.inc] trf2.1.4/doc/common/0000755000175000017500000000000011216344734013614 5ustar sergeisergeitrf2.1.4/doc/common/trf_version.inc0000644000175000017500000000010411216343142016632 0ustar sergeisergei[comment {-*- tcl -*- doctools = trf.inc}] [vset trf_version 2.1.4] trf2.1.4/doc/common/options.inc0000644000175000017500000000250511216343142015774 0ustar sergeisergei[comment {-*- tcl -*- doctools = common_options.inc}] [lst_item "[option -attach] [arg channel]"] The presence/absence of this option determines the main operation mode of the transformation. [nl] If present the transformation will be stacked onto the [arg channel] whose handle was given to the option and run in [term attached] mode. More about this in section [sectref {IMMEDIATE versus ATTACHED}]. [nl] If the option is absent the transformation is used in [term immediate] mode and the options listed below are recognized. More about this in section [sectref {IMMEDIATE versus ATTACHED}]. [lst_item "[option -in] [arg channel]"] This options is legal if and only if the transformation is used in [term immediate] mode. It provides the handle of the channel the data to transform has to be read from. [nl] If the transformation is in [term immediate] mode and this option is absent the data to transform is expected as the last argument to the transformation. [lst_item "[option -out] [arg channel]"] This options is legal if and only if the transformation is used in [term immediate] mode. It provides the handle of the channel the generated transformation result is written to. [nl] If the transformation is in [term immediate] mode and this option is absent the generated data is returned as the result of the command itself. trf2.1.4/doc/common/sections.inc0000644000175000017500000000302611216343142016127 0ustar sergeisergei[comment {-*- tcl -*- doctools = common_sections.inc}] [section {IMMEDIATE versus ATTACHED}] The transformation distinguishes between two main ways of using it. These are the [term immediate] and [term attached] operation modes. [para] For the [term attached] mode the option [option -attach] is used to associate the transformation with an existing channel. During the execution of the command no transformation is performed, instead the channel is changed in such a way, that from then on all data written to or read from it passes through the transformation and is modified by it according to the definition above. This attachment can be revoked by executing the command [cmd unstack] for the chosen channel. This is the only way to do this at the Tcl level. [para] In the second mode, which can be detected by the absence of option [option -attach], the transformation immediately takes data from either its commandline or a channel, transforms it, and returns the result either as result of the command, or writes it into a channel. The mode is named after the immediate nature of its execution. [para] Where the data is taken from, and delivered to, is governed by the presence and absence of the options [option -in] and [option -out]. It should be noted that this ability to immediately read from and/or write to a channel is an historic artifact which was introduced at the beginning of Trf's life when Tcl version 7.6 was current as this and earlier versions have trouble to deal with \0 characters embedded into either input or output. trf2.1.4/doc/common/trf_header.inc0000644000175000017500000000034711216343142016406 0ustar sergeisergei[comment {-*- tcl -*- doctools = trf_header.inc}] [moddesc {Trf transformer commands}] [copyright {1996-2003, Andreas Kupries }] [require Tcl [opt 8.2]] [require Trf [opt [vset trf_version]]] trf2.1.4/doc/ascii85.man0000644000175000017500000000050111216343142014252 0ustar sergeisergei[vset encoding ascii85] [include encoding/header.inc] [para] This encoding transforms every block of four bytes into the Ascii85 representation as defined in the 'Postscript Reference Manual' (2nd Edition, section 3.13, page 129). [include encoding/middle.inc] [keywords postscript] [include encoding/footer.inc] trf2.1.4/doc/sha.man0000644000175000017500000000005711216343142013566 0ustar sergeisergei[vset digest sha] [include digest/main.inc] trf2.1.4/doc/binio.proposal0000644000175000017500000003113211216343142015175 0ustar sergeisergeiReturn-Path: aku@kisters.de Return-Path: Received: from mercury.Sun.COM by mailhost.kisters.de with smtp (Smail3.1.29.1 #3) id m0uyISF-000BhGC; Wed, 4 Sep 96 15:57 MET DST Received: by mercury.Sun.COM (Sun.COM) id GAA29259; Wed, 4 Sep 1996 06:56:57 -0700 Received: from bisque.Eng.Sun.COM by Eng.Sun.COM (SMI-8.6/SMI-5.3) id GAA15069; Wed, 4 Sep 1996 06:56:56 -0700 Received: from noam.Eng.Sun.COM by bisque.Eng.Sun.COM (5.x/SMI-SVR4) id AA23111; Wed, 4 Sep 1996 06:56:53 -0700 Received: by noam.Eng.Sun.COM (5.x/SMI-SVR4) id AA00104; Wed, 4 Sep 1996 06:56:52 -0700 Date: Wed, 4 Sep 1996 06:56:52 -0700 From: jyl@bisque.Eng.Sun.COM (Jacob Levy) Message-Id: <9609041356.AA00104@noam.Eng.Sun.COM> To: Andreas Kupries In-Reply-To: Subject: (Re: transformation procedures, patch for tcl7.6b1) / Feedback Reply-To: jyl@Eng.Sun.COM Status: RO X-Status: Here is the proposal. Comments most welcome! --JYL =========================================================================== Proposal: Adding binary I/O facilities to Tcl -===========================================- Abstract: This note outlines the "why" and "how" of adding binary I/O capabilities to Tcl. Introduction ------------ Tcl 7.5 introduces a new mechanism for portable I/O programming, based on channels and channel drivers. The channel facility was written in C, with attention paid to making it possible to transfer either text or binary data via the APIs. However, the Tcl level procedures that provide access to the channel mechanism only allow transporting text (NULL terminated strings). Furthermore, Tcl datums are always NULL terminated strings. Because Tcl is unable to represent data containing NULL characters directly, many interesting algorithms are not expressible in Tcl directly, e.g. image or video data manipulation, compression, encryption etc. Furthermore, there is no mechanism for translating such data into a form that Tcl can manipulate directly, i.e. data that does not contain NULLs. This note proposes to add to Tcl: - A mechanism for transporting binary data between channels. - A mechanism for translating between binary data and representation of that data as Tcl strings. - A mechanism for constructing in-memory representations of binary data from Tcl programs. With these facilities, it is possible to: - transmit binary data between channels, through Tcl programs. - obtain binary input from channels and send binary out from Tcl programs. - build binary data structures from inside Tcl programs. This enables Tcl to be used for the areas mentioned above, e.g. direct image and video data manipulation, and for many other applications that require direct manipulation, input and output of binary data. Acknowledgments --------------- Several packages that implement various aspects of binary I/O in Tcl are already available. This proposal benefits from examining these packages: Tclbin by Laurent Demaille, TclBlob by Andreas Kupries, Binary by ???, and the Perl pack and unpack commands written by Larry Wall (???). Details ------- The rest of this note provides an overview of one possible implementation approach. In this approach, I propose: - One new Tcl command to effect data transfer, input and output: "binio". This command has sub commands to transfer data directly between any two channels, and to translate between binary representation of data in a channel and string representation for Tcl datums. - A new channel type for in-memory representation of data, including binary data. - A new fconfigure option is added to all channels: the byte order in effect for the channel. The default value for sockets is network order, and for other channels it is the byte order of the architecture on which the Tcl program is currently executing. I think it should be an error to copy binary data between channels that have different byte order settings, since it causes the data to become scrambled. With these additions, all channels are able to participate in binary data transfer, and binary I/O, and all existing channel commands can be applied to the new in-memory channel type. Binary I/O (Tcl APIs) --------------------- The new "binio" command has three sub commands: - binio copy inChannel outChannel ?count? Copies from inChannel to outChannel, up to the number of bytes indicated by the optional count argument or up to end of file on inChannel. inChannel must have been opened for reading and outChannel must have been opened for writing. It is an error to copy binary data between channels that have different byte orders. This operation returns the number of bytes copied, or -1 on error. - binio pack outChannel format ?data1 data2 ...? Packs binary data onto outChannel, a channel that must have been opened for writing. The format argument determines how the optional data1 through datan arguments are interpreted. This operation returns the number of data items successfully packed on outChannel or -1 if an error occurred. If an error occurred, it is possible that some output has already occurred. The various specifications that can appear in the format string are explained below. This operation reorders the bytes of each datum to match the order expected on outChannel if its byte order is different from that of the architecture on which the Tcl command is being executed. - binio unpack inChannel format ?var1 var2 ...? Unpacks binary data from inChannel into the named variables. The inChannel argument must denote a channel opened for reading. The format argument determines how the data obtained from the channel is translated into string representation and stored in the var1 through varn variables. If any of the variables are not initialized then the command creates them as local variables. This operation returns the number of data items successfully unpacked from inChannel or -1 if an error occurred. If -1 is returned, it is possible that some input may already have occurred. The various format specifications that can appear in the format string are explained below. This operation reorders the bytes of each datum to match the byte order expected on the architecture on which the command is executed if it is different from the byte order that is in effect on inChannel. Format Specifications --------------------- The new "binio pack" and "binio unpack" commands take a format specification to control how they operate. A format string consists of one or more "%" specifiers, as follows (unless otherwise specified, all values are in base ten): - %d specifies that the corresponding value is a four byte signed int. - %u specifies that the corresponding value is a four byte unsigned int. - %o specifies that the corresponding value is a four byte octal signed int. - %x specifies that the corresponding value is a four byte hexadecimal signed int. - %l specifies that the corresponding value is an eight byte signed int. - %L specifies that the corresponding value is an eight byte unsigned int. - %D specifies that the corresponding value is a two byte signed int. - %U specifies that the corresponding value is a two byte unsigned int. - %O specifies that the corresponding value is a two byte octal signed int. - %X specifies that the corresponding value is a two byte hexadecimal signed int. - %c specifies that the corresponding value is a one byte signed int (char). - %C specifies that the corresponding value is a one byte unsigned int. - %f specifies that the corresponding value is a four byte floating point number. - %F specifies that the corresponding value is an eight byte floating point number. - %s specifies that the corresponding value is a NULL terminated string. In-memory Channels (Tcl APIs) ----------------------------- In-memory channels represent transient data stores for data to be read or written by a Tcl program. Each in-memory channel provides an infinite (up to the limitations of virtual memory) indexed byte space (starting at zero) for data storage, and has a notion of a current access point for reading and writing. In-memory channels are always opened for both reading and writing. In-memory channels are able to seek at random between position 0 and the current length of the channel; seeking beyond the end of the current data is not possible -- you must explicitly write data on the channel to extend its length. Telling on the channel obtains the current access point. Writing and reading is possible from any point in the channel; writing into the middle of the channel overwrites the current content for the length of the data newly written, possibly extending the length of the channel. Reading and writing moves the current access point to the next byte to be read or written. Flushing has no effect; the channel is always completely up to date. It is possible to save or duplicate the contents of an in-memory channel using "binio copy". In-memory channels are always writable (fileevent writable will fire continuously) and they are readable when the current access point is before the last byte contained in the channel. In-memory channels provide a channel type specific, read-only, fconfigure option, "length", that obtains the current number of bytes of data stored in the channel. In-memory channels are created by the new command "memchan" which takes no arguments and returns the name of a newly created in-memory channel. The usual operations, e.g. "read", "gets", "puts", and so forth can be applied to the in-memory channel, and it can be shared or transferred between Tcl interpreters using "interp share" and "interp transfer", and closed with the Tcl "close" command. Closing the last reference to an in-memory channel removes the data from memory; it is lost unless you saved a persistent copy of the data on another (e.g. file based) channel with "binio copy". New Fconfigure Option --------------------- The "fconfigure" command is enhanced to provide a new option to set the byte order for a channel, and to query the current setting: - "fconfigure $chan -byteorder ?setting?" sets or gets the current setting. The valid values for the optional setting argument are "network", "bigendian" and "smallendian", which indicate network byte order, bigendian and smallendian respectively. The "bigendian" and "network" values are synonyms. Binary I/O (C APIs) ------------------- Do we need any? We can simply prepare a buffer (by copying the binary values into it) and then give the buffer to Tcl_Write. Similarly, we can get data out of the channel using Tcl_Read and then copy the binary data out of the returned buffer. On the other hand, we may want to provide a formatted I/O capability which also takes into account byte order issues. Note also that this functionality is already implemented to handle the pack and unpack sub commands. In-memory Channels (C APIs) --------------------------- I don't think we need any special C level APIs. Examples -------- I show below two examples of how the new facilities might be used; the first example shows how to compute a hash of data read from a channel, and the second shows how to build a C structure containing a short and a long in a Tcl program. Computing a hash: A hash may be computed from a channel by xor-ing each 4 byte value with a seed. The following procedure implements this: proc hash {chan seed} { set hash 0 while {[expr {[binio unpack $chan "%d" l] > 0}]} { set hash [expr {$hash + ($l ^ $seed)}] } return $hash } Creating an in-memory representation of a C structure: A C structure defined by the following C statement is needed as an argument to a function provided by a C extension: typedef struct mystruct { short myshort; long mylong; } mystruct; In Tcl, using the new in-memory channel, the structure can be built up in Tcl as follows (assume the Tcl variables "shortval" and "longval" contain the values to be stored in the structure): set m [memchan] binio pack $m "%s%l" $shortval $longval seek $m 0 start set result [some_primitive $m] The command procedure for "some_primitive" can obtain the structure from the in-memory channel using Tcl_Read: int SomePrimitiveCommand(clientData, interp, argc, argv) .... { .... Tcl_Channel chan = Tcl_GetChannel(interp, argv[1], NULL); mystruct *msPtr = ckalloc((unsigned) sizeof(mystruct)); int count = Tcl_Read(chan, (char *) msPtr, sizeof(mystruct)); .... ckfree((char *) msPtr; return TCL_OK; } Note that this does not do byte-order conversions, which is a neccessary step if the channel has a different byte order from that of the architecture on which the program is executing. For memory channels this is not an issue, but it will be an issue for external channels. trf2.1.4/doc/md2.man0000644000175000017500000000005711216343142013475 0ustar sergeisergei[vset digest md2] [include digest/main.inc] trf2.1.4/doc/ripemd128.man0000644000175000017500000000006111216343142014521 0ustar sergeisergei[vset digest 128] [include digest/ripemd.inc] trf2.1.4/doc/seek.notes0000644000175000017500000000761211216343142014323 0ustar sergeisergei Configuration ------------- Natural ratio between input and output: n:m Unseekable <=== (n == 0 || m == 0) Configurational state --------------------- Chosen ratio, without user intervention Flag, possible to overide ratio above or not ? Chosen ratio, after possible intervention by user State ----- Stream location of transformation. UpLoc Stream location of start and end of the read buffer. UpLocBS, UpLocBE Stream location of downstream channel. DwLoc "End" = Location of the character behind the last character in the buffer. !Integrity condition: (1) DwLoc "equivalent to" UpLocBE (2) UpLocBS = UpLocBE = UpLoc for an empty buffer. (3) UpLoc* % n == 0, i.e. a multiple of n. Derived state ------------- (up * m) / n = down (Position relative to starting point) Zero = Position downstream "equivalent to" Zero position upward. (1) DwLoc "equivalent to" UpLocBE ===> (UpLocBE * m) / n + Zero = DwLoc ===> Zero = (UpLocBE * m) / n - DwLoc Actions ------- Tell /done/ .... Report stream location of transformation. Seek, general /done/ ............. [Tell] Unseekable ===> Error STOP_____________________________ Identity ===> discard read/write buffers, pass request set flag "changed" STOP_____________________________ Seek, relative to start of stream (as seen by the transformation) /done/ ................................................................. Delta = NewPos - UpLoc Seek (Delta, relative to current position) STOP_____________________________ Seek, relative to current position (as seen by the transformation) /done/ .................................................................. (Delta % n) != 0 ===> Error NewUpLoc := UpLoc + Delta NewUpLoc < 0 ===> Error NewUpLoc < UpLocBS || NewUpLoc >= UpLocBE ===> Discard read buffer DeltaDown := ((NewUpLoc - UpLocBE) * m) / n DeltaDown != 0 ===> Seek down, relative to current: DeltaDown. DwLoc := DwLoc + DeltaDown UpLoc,UpLocBS,UpLocBE := NewUpLoc STOP_____________________________ UpLoc := NewUpLoc STOP_____________________________ Seek, relative to end of stream ............................... ??? not yet STOP_____________________________ Write /done/ ..... // Partial writes (incomplete tuple?, seek effect) // no seek!, no change of location // next read discards incomplete information. // next seek discards incomplete information! too. UpLoc != UpLocBE ===> Get Zero Discard read buffer. DeltaDown := ((UpLocBE - UpLoc) * m) / n Seek down, relative: DeltaDown. DwLoc := DwLoc + DeltaDown -- Now UpLoc "equivalent to" DwLoc -- IOW Positions up and down are now in sync. -- Phase == 0 now! UpLoc,UpLocBS,UpLocBE := UpLoc += toWrite DwLoc += (toWrite * m)/n Write complete transformation results. STOP_____________________________ // Handle only complete writes, in writer proc, do the above. // Automatic handling of incomplete tuples as described //above UpLoc == UpLocBE -- No read buffer existing, positions are in sync. Write complete transformation results. STOP_____________________________ Read .... Discard incomplete tuples in write buffer! Repeat Data in read buffer ===> Copy x from read buffer UpLoc += x Remove x from buffer LOOP Satisified ===> STOP (Integrity: UpLoc == UpLocBE) got := Read from down transform // got % m == 0 not assertable, can be fract // maintain phase! value as last ditch correction value DwLoc += got UpLocBS := UpLocBE UpLocBE += (got-phase) / m * n endrepeat STOP_____________________________ Stack /done/ ..... UpLoc,UpLocBS,UpLocBE := 0 DwLoc := Tell down. Phase == 0. Empty read/write buffers. STOP_____________________________ Force identity .............. Set flag "identity" Unset flag "changed" STOP_____________________________ Unforce identity ................ Changed ===> See "Stack" STOP_____________________________ ... handling force unseekable ? for seekable transforms. trf2.1.4/doc/md5_otp.man0000644000175000017500000000006311216343142014357 0ustar sergeisergei[vset digest md5_otp] [include digest/main.inc] trf2.1.4/doc/base64.man0000644000175000017500000000151211216343142014074 0ustar sergeisergei[vset encoding base64] [include encoding/header.inc] [para] This encoding transforms every block of three bytes into a block of four bytes, each of which is printable, i.e. 7bit ASCII. This implies that the result is valid UTF-8 too. The command uses essentially the same algorithm as for [cmd uuencode], except for a different mapping from 6-bit fragments to printable bytes. [include encoding/middle.inc] [section NOTES] [list_begin enum] [enum] The encoding is equivalent to PGP's ASCII armor and was also accepted as one of the MIME encodings for encapsulation of binary data. See RFC 2045 ([uri http://www.rfc-editor.org/rfc/rfc2045.txt]) for details and the specification of this encoding. [enum] The encoding buffers 2 bytes. [list_end] [keywords uuencode {rfc 2045} mime pgp {ascii armor}] [include encoding/footer.inc] trf2.1.4/tclconfig/0000755000175000017500000000000011216344734013527 5ustar sergeisergeitrf2.1.4/tclconfig/README.txt0000644000175000017500000000145311216343142015220 0ustar sergeisergeiThese files comprise the basic building blocks for a Tcl Extension Architecture (TEA) extension. For more information on TEA see: http://www.tcl.tk/doc/tea/ This package is part of the Tcl project at SourceForge, and latest sources should be available there: http://tcl.sourceforge.net/ This package 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. CONTENTS ======== The following is a short description of the files you will find in the sample extension. README.txt This file install-sh Program used for copying binaries and script files to their install locations. tcl.m4 Collection of Tcl autoconf macros. Included by a package's aclocal.m4 to define SC_* macros. trf2.1.4/tclconfig/install-sh0000755000175000017500000000421211216343142015522 0ustar sergeisergei#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 trf2.1.4/tclconfig/tcl.m40000644000175000017500000040055511216343142014554 0ustar sergeisergei# tcl.m4 -- # # This file provides a set of autoconf macros to help TEA-enable # a Tcl extension. # # Copyright (c) 1999-2000 Ajuba Solutions. # Copyright (c) 2002-2005 ActiveState 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.m4,v 1.12 2009/05/07 05:30:35 andreas_kupries Exp $ AC_PREREQ(2.57) dnl TEA extensions pass us the version of TEA they think they dnl are compatible with (must be set in TEA_INIT below) dnl TEA_VERSION="3.7" # Possible values for key variables defined: # # TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem') # TEA_PLATFORM - windows unix # #------------------------------------------------------------------------ # TEA_PATH_TCLCONFIG -- # # Locate the tclConfig.sh file and perform a sanity check on # the Tcl compile flags # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tcl=... # # Defines the following vars: # TCL_BIN_DIR Full path to the directory containing # the tclConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_TCLCONFIG], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_INIT]) # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tcl, AC_HELP_STRING([--with-tcl], [directory containing tcl configuration (tclConfig.sh)]), with_tclconfig=${withval}) AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case ${with_tclconfig} in */tclConfig.sh ) if test -f ${with_tclconfig}; then AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'` fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi ]) if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" AC_MSG_ERROR([Can't find Tcl configuration definitions]) else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_PATH_TKCONFIG -- # # Locate the tkConfig.sh file # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tk=... # # Defines the following vars: # TK_BIN_DIR Full path to the directory containing # the tkConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_TKCONFIG], [ # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true AC_ARG_WITH(tk, AC_HELP_STRING([--with-tk], [directory containing tk configuration (tkConfig.sh)]), with_tkconfig=${withval}) AC_MSG_CHECKING([for Tk configuration]) AC_CACHE_VAL(ac_cv_c_tkconfig,[ # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case ${with_tkconfig} in */tkConfig.sh ) if test -f ${with_tkconfig}; then AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'` fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi ]) if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" AC_MSG_ERROR([Can't find Tk configuration definitions]) else no_tk= TK_BIN_DIR=${ac_cv_c_tkconfig} AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_TCLCONFIG -- # # Load the tclConfig.sh file # # Arguments: # # Requires the following vars to be set: # TCL_BIN_DIR # # Results: # # Subst the following vars: # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE # #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TCLCONFIG], [ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh]) if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TCL_BIN_DIR}/tclConfig.sh" else AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh]) fi # eval is required to do the TCL_DBGX substitution eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TCL_BIN_DIR}/Makefile" ; then TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} elif test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tcl.framework installed in an arbitary location. case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then for i in "`cd ${TCL_BIN_DIR}; pwd`" \ "`cd ${TCL_BIN_DIR}/../..; pwd`"; do if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}" break fi done fi if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}" TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" fi ;; esac fi # eval is required to do the TCL_DBGX substitution eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" AC_SUBST(TCL_VERSION) AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) # TEA specific: AC_SUBST(TCL_LIBS) AC_SUBST(TCL_DEFS) AC_SUBST(TCL_EXTRA_CFLAGS) AC_SUBST(TCL_LD_FLAGS) AC_SUBST(TCL_SHLIB_LD_LIBS) ]) #------------------------------------------------------------------------ # TEA_LOAD_TKCONFIG -- # # Load the tkConfig.sh file # # Arguments: # # Requires the following vars to be set: # TK_BIN_DIR # # Results: # # Sets the following vars that should be in tkConfig.sh: # TK_BIN_DIR #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TKCONFIG], [ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TK_BIN_DIR}/tkConfig.sh" else AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) fi # eval is required to do the TK_DBGX substitution eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TK_BIN_DIR}/Makefile" ; then TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} elif test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tk.framework installed in an arbitary location. case ${TK_DEFS} in *TK_FRAMEWORK*) if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then for i in "`cd ${TK_BIN_DIR}; pwd`" \ "`cd ${TK_BIN_DIR}/../..; pwd`"; do if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}" break fi done fi if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}" TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" fi ;; esac fi # eval is required to do the TK_DBGX substitution eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" # TEA specific: Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?]) TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi AC_SUBST(TK_VERSION) AC_SUBST(TK_BIN_DIR) AC_SUBST(TK_SRC_DIR) AC_SUBST(TK_LIB_FILE) AC_SUBST(TK_LIB_FLAG) AC_SUBST(TK_LIB_SPEC) AC_SUBST(TK_STUB_LIB_FILE) AC_SUBST(TK_STUB_LIB_FLAG) AC_SUBST(TK_STUB_LIB_SPEC) # TEA specific: AC_SUBST(TK_LIBS) AC_SUBST(TK_XINCLUDES) ]) #------------------------------------------------------------------------ # TEA_PROG_TCLSH # Determine the fully qualified path name of the tclsh executable # in the Tcl build directory or the tclsh installed in a bin # directory. This macro will correctly determine the name # of the tclsh executable even if tclsh has not yet been # built in the build directory. The tclsh found is always # associated with a tclConfig.sh file. This tclsh should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments # none # # Results # Subst's the following values: # TCLSH_PROG #------------------------------------------------------------------------ AC_DEFUN([TEA_PROG_TCLSH], [ AC_MSG_CHECKING([for tclsh]) if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" fi list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TCL_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`/" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}" fi AC_MSG_RESULT([${TCLSH_PROG}]) AC_SUBST(TCLSH_PROG) ]) #------------------------------------------------------------------------ # TEA_PROG_WISH # Determine the fully qualified path name of the wish executable # in the Tk build directory or the wish installed in a bin # directory. This macro will correctly determine the name # of the wish executable even if wish has not yet been # built in the build directory. The wish found is always # associated with a tkConfig.sh file. This wish should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments # none # # Results # Subst's the following values: # WISH_PROG #------------------------------------------------------------------------ AC_DEFUN([TEA_PROG_WISH], [ AC_MSG_CHECKING([for wish]) if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" fi list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TK_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`/" break fi done WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}" fi AC_MSG_RESULT([${WISH_PROG}]) AC_SUBST(WISH_PROG) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SHARED -- # # Allows the building of shared libraries # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-shared=yes|no # # Defines the following vars: # STATIC_BUILD Used for building import/export libraries # on Windows. # # Sets the following vars: # SHARED_BUILD Value of 1 or 0 #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SHARED], [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build and link with shared libraries (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then AC_MSG_RESULT([shared]) SHARED_BUILD=1 else AC_MSG_RESULT([static]) SHARED_BUILD=0 AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) fi AC_SUBST(SHARED_BUILD) ]) #------------------------------------------------------------------------ # TEA_ENABLE_THREADS -- # # Specify if thread support should be enabled. If "yes" is specified # as an arg (optional), threads are enabled by default, "no" means # threads are disabled. "yes" is the default. # # TCL_THREADS is checked so that if you are compiling an extension # against a threaded core, your extension must be compiled threaded # as well. # # Note that it is legal to have a thread enabled extension run in a # threaded or non-threaded Tcl core, but a non-threaded extension may # only run in a non-threaded Tcl core. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-threads # # Sets the following vars: # THREADS_LIBS Thread library(s) # # Defines the following vars: # TCL_THREADS # _REENTRANT # _THREAD_SAFE # #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_THREADS], [ AC_ARG_ENABLE(threads, AC_HELP_STRING([--enable-threads], [build with threads]), [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants: # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention AC_DEFINE(USE_THREAD_ALLOC, 1, [Do we want to use the threaded memory allocator?]) AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) if test "`uname -s`" = "SunOS" ; then AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) fi AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?]) AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the same # library, as some systems hide it there until pthread.h is # defined. We could alternatively do an AC_TRY_COMPILE with # pthread.h, but that will work with libpthread really doesn't # exist, like AIX 4.2. [Bug: 4359] AC_CHECK_LIB(pthread, __pthread_mutex_init, tcl_ok=yes, tcl_ok=no) fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else AC_CHECK_LIB(pthreads, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else AC_CHECK_LIB(c, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "no"; then AC_CHECK_LIB(c_r, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled]) fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output AC_MSG_CHECKING([for building with threads]) if test "${TCL_THREADS}" = 1; then AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?]) AC_MSG_RESULT([yes (default)]) else AC_MSG_RESULT([no]) fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then AC_MSG_WARN([ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads.]) fi ;; *) if test "${TCL_THREADS}" = "1"; then AC_MSG_WARN([ --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core.]) fi ;; esac AC_SUBST(TCL_THREADS) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SYMBOLS -- # # Specify if debugging symbols should be used. # Memory (TCL_MEM_DEBUG) debugging can also be enabled. # # Arguments: # none # # TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives # the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted. # Requires the following vars to be set in the Makefile: # CFLAGS_DEFAULT # LDFLAGS_DEFAULT # # Results: # # Adds the following arguments to configure: # --enable-symbols # # Defines the following vars: # CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true # Sets to $(CFLAGS_OPTIMIZE) if false # LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true # Sets to $(LDFLAGS_OPTIMIZE) if false # DBGX Formerly used as debug library extension; # always blank now. # #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SYMBOLS], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_CONFIG_CFLAGS]) AC_MSG_CHECKING([for build with symbols]) AC_ARG_ENABLE(symbols, AC_HELP_STRING([--enable-symbols], [build with debugging symbols (default: off)]), [tcl_ok=$enableval], [tcl_ok=no]) DBGX="" if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" AC_MSG_RESULT([no]) else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then AC_MSG_RESULT([yes (standard debugging)]) fi fi # TEA specific: if test "${TEA_PLATFORM}" != "windows" ; then LDFLAGS_DEFAULT="${LDFLAGS}" fi AC_SUBST(CFLAGS_DEFAULT) AC_SUBST(LDFLAGS_DEFAULT) AC_SUBST(TCL_DBGX) if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?]) fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then AC_MSG_RESULT([enabled symbols mem debugging]) else AC_MSG_RESULT([enabled $tcl_ok debugging]) fi fi ]) #------------------------------------------------------------------------ # TEA_ENABLE_LANGINFO -- # # Allows use of modern nl_langinfo check for better l10n. # This is only relevant for Unix. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-langinfo=yes|no (default is yes) # # Defines the following vars: # HAVE_LANGINFO Triggers use of nl_langinfo if defined. # #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_LANGINFO], [ AC_ARG_ENABLE(langinfo, AC_HELP_STRING([--enable-langinfo], [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]), [langinfo_ok=$enableval], [langinfo_ok=yes]) HAVE_LANGINFO=0 if test "$langinfo_ok" = "yes"; then AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no]) fi AC_MSG_CHECKING([whether to use nl_langinfo]) if test "$langinfo_ok" = "yes"; then AC_CACHE_VAL(tcl_cv_langinfo_h, [ AC_TRY_COMPILE([#include ], [nl_langinfo(CODESET);], [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])]) AC_MSG_RESULT([$tcl_cv_langinfo_h]) if test $tcl_cv_langinfo_h = yes; then AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?]) fi else AC_MSG_RESULT([$langinfo_ok]) fi ]) #-------------------------------------------------------------------- # TEA_CONFIG_SYSTEM # # Determine what the system is (some things cannot be easily checked # on a feature-driven basis, alas). This can usually be done via the # "uname" command, but there are a few systems, like Next, where # this doesn't work. # # Arguments: # none # # Results: # Defines the following var: # # system - System/platform/version identification code. # #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_SYSTEM], [ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [ # TEA specific: if test "${TEA_PLATFORM}" = "windows" ; then tcl_cv_sys_version=windows elif test -f /usr/lib/NextStep/software_version; then tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then AC_MSG_WARN([can't find uname command]) tcl_cv_sys_version=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid` fi if test "`uname -s`" = "AIX" ; then tcl_cv_sys_version=AIX-`uname -v`.`uname -r` fi fi fi ]) system=$tcl_cv_sys_version ]) #-------------------------------------------------------------------- # TEA_CONFIG_CFLAGS # # Try to determine the proper flags to pass to the compiler # for building shared libraries and other such nonsense. # # Arguments: # none # # Results: # # Defines and substitutes the following vars: # # DL_OBJS - Name of the object file that implements dynamic # loading for Tcl on this system. # DL_LIBS - Library file(s) to include in tclsh and other base # applications in order for the "load" command to work. # LDFLAGS - Flags to pass to the compiler when linking object # files into an executable application binary such # as tclsh. # LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. Could # be the same as CC_SEARCH_FLAGS if ${CC} is used to link. # CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. # SHLIB_CFLAGS - Flags to pass to cc when compiling the components # of a shared library (may request position-independent # code, among other things). # SHLIB_LD - Base command to use for combining object files # into a shared library. # SHLIB_LD_LIBS - Dependent libraries for the linker to scan when # creating shared libraries. This symbol typically # goes at the end of the "ld" commands that build # shared libraries. The value of the symbol is # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If # dependent libraries should not be specified (as on # SunOS 4.x, where they cause the link to fail, or in # general if Tcl and Tk aren't themselves shared # libraries), then this symbol has an empty string # as its value. # SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable # extensions. An empty string means we don't know how # to use shared libraries on this platform. # LIB_SUFFIX - Specifies everything that comes after the "libfoo" # in a static or shared library name, using the $VERSION variable # to put the version in the right place. This is used # 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 a 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. # CFLAGS_DEBUG - # Flags used when running the compiler in debug mode # CFLAGS_OPTIMIZE - # Flags used when running the compiler in optimize mode # CFLAGS - Additional CFLAGS added as necessary (usually 64-bit) # #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_CFLAGS], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_INIT]) # Step 0.a: Enable 64 bit support? AC_MSG_CHECKING([if 64bit support is requested]) AC_ARG_ENABLE(64bit, AC_HELP_STRING([--enable-64bit], [enable 64bit support (default: off)]), [do64bit=$enableval], [do64bit=no]) AC_MSG_RESULT([$do64bit]) # Step 0.b: Enable Solaris 64 bit VIS support? AC_MSG_CHECKING([if 64bit Sparc VIS support is requested]) AC_ARG_ENABLE(64bit-vis, AC_HELP_STRING([--enable-64bit-vis], [enable 64bit Sparc VIS support (default: off)]), [do64bitVIS=$enableval], [do64bitVIS=no]) AC_MSG_RESULT([$do64bitVIS]) # Force 64bit on with VIS AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes]) # Step 0.c: Check if visibility support is available. Do this here so # that platform specific alternatives can be used below if this fails. AC_CACHE_CHECK([if compiler supports visibility "hidden"], tcl_cv_cc_visibility_hidden, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" AC_TRY_LINK([ extern __attribute__((__visibility__("hidden"))) void f(void); void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes, tcl_cv_cc_visibility_hidden=no) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [ AC_DEFINE(MODULE_SCOPE, [extern __attribute__((__visibility__("hidden")))], [Compiler support for module scope symbols]) ]) # Step 0.d: Disable -rpath support? AC_MSG_CHECKING([if rpath support is requested]) AC_ARG_ENABLE(rpath, AC_HELP_STRING([--disable-rpath], [disable rpath support (default: on)]), [doRpath=$enableval], [doRpath=yes]) AC_MSG_RESULT([$doRpath]) # TEA specific: Cross-compiling options for Windows/CE builds? AS_IF([test "${TEA_PLATFORM}" = windows], [ AC_MSG_CHECKING([if Windows/CE build is requested]) AC_ARG_ENABLE(wince, AC_HELP_STRING([--enable-wince], [enable Win/CE support (where applicable)]), [doWince=$enableval], [doWince=no]) AC_MSG_RESULT([$doWince]) ]) # Step 1: set the variable "system" to hold the name and version number # for the system. TEA_CONFIG_SYSTEM # 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) # Require ranlib early so we can override it in special cases below. AC_REQUIRE([AC_PROG_RANLIB]) # Step 3: set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case. do64bit_ok=no LDFLAGS_ORIG="$LDFLAGS" # When ld needs options to work in 64-bit mode, put them in # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load] # is disabled by the user. [Bug 1016796] LDFLAGS_ARCH="" TCL_EXPORT_FILE_SUFFIX="" UNSHARED_LIB_SUFFIX="" # TEA specific: use PACKAGE_VERSION instead of VERSION TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g CFLAGS_OPTIMIZE=-O AS_IF([test "$GCC" = yes], [ # TEA specific: CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall -Wno-implicit-int" ], [CFLAGS_WARNING=""]) TCL_NEEDS_EXP_FILE=0 TCL_BUILD_EXP_FILE="" TCL_EXP_FILE="" dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed. dnl AC_CHECK_TOOL(AR, ar) AC_CHECK_PROG(AR, ar, ar) STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" case $system in # TEA specific: windows) # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs # MACHINE is IX86 for LINK, but this is used by the manifest, # which requires x86|amd64|ia64. MACHINE="X86" if test "$do64bit" != "no" ; then if test "x${MSSDK}x" = "xx" ; then MSSDK="C:/Progra~1/Microsoft Platform SDK" fi MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` PATH64="" case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build PATH64="${MSSDK}/Bin/Win64/x86/AMD64" ;; ia64) MACHINE="IA64" PATH64="${MSSDK}/Bin/Win64" ;; esac if test ! -d "${PATH64}" ; then AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode]) AC_MSG_WARN([Ensure latest Platform SDK is installed]) do64bit="no" else AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) do64bit_ok="yes" fi fi if test "$doWince" != "no" ; then if test "$do64bit" != "no" ; then AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible]) fi if test "$GCC" = "yes" ; then AC_MSG_ERROR([Windows/CE and GCC builds incompatible]) fi TEA_PATH_CELIB # Set defaults for common evc4/PPC2003 setup # Currently Tcl requires 300+, possibly 420+ for sockets CEVERSION=420; # could be 211 300 301 400 420 ... TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... ARCH=ARM; # could be ARM MIPS X86EM ... PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" if test "$doWince" != "yes"; then # If !yes then the user specified something # Reset ARCH to allow user to skip specifying it ARCH= eval `echo $doWince | awk -F, '{ \ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \ }'` if test "x${ARCH}" = "x" ; then ARCH=$TARGETCPU; fi fi OSVERSION=WCE$CEVERSION; if test "x${WCEROOT}" = "x" ; then WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" if test ! -d "${WCEROOT}" ; then WCEROOT="C:/Program Files/Microsoft eMbedded Tools" fi fi if test "x${SDKROOT}" = "x" ; then SDKROOT="C:/Program Files/Windows CE Tools" if test ! -d "${SDKROOT}" ; then SDKROOT="C:/Windows CE Tools" fi fi WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]]) doWince="no" else # We could PATH_NOSPACE these, but that's not important, # as long as we quote them when used. CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" fi CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" fi fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi if test "$do64bit" != "no" ; then # All this magic is necessary for the Win64 SDK RC1 - hobbs CC="\"${PATH64}/cl.exe\"" CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" RC="\"${MSSDK}/bin/rc.exe\"" lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 TEA_ADD_LIBS([bufferoverflowU.lib]) elif test "$doWince" != "no" ; then CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" if test "${TARGETCPU}" = "X86"; then CC="\"${CEBINROOT}/cl.exe\"" else CC="\"${CEBINROOT}/cl${ARCH}.exe\"" fi CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" arch=`echo ${ARCH} | awk '{print tolower([$]0)}'` defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" if test "${SHARED_BUILD}" = "1" ; then # Static CE builds require static celib as well defs="${defs} _DLL" fi for i in $defs ; do AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i) done AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version]) AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version]) CFLAGS_DEBUG="-nologo -Zi -Od" CFLAGS_OPTIMIZE="-nologo -Ox" lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" LINKBIN="\"${CEBINROOT}/link.exe\"" AC_SUBST(CELIB_DIR) else RC="rc" lflags="-nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode RC="windres" CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" SHLIB_LD="$CC -shared" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # and also # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx # This essentially turns it all on. LDFLAGS_DEBUG="-debug -debugtype:cv" LDFLAGS_OPTIMIZE="-release" if test "$doWince" != "no" ; then LDFLAGS_CONSOLE="-link ${lflags}" LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} else LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots # Bogus to avoid getting this turned off DL_OBJS="tclLoadNone.obj" ;; AIX-*) AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [ # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r) # ok ... ;; *) CC=${CC}_r ;; esac AC_MSG_RESULT([Using $CC for compiling with threads]) ]) LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" LD_LIBRARY_PATH_VAR="LIBPATH" # Check to enable 64-bit flags for compiler/linker on AIX 4+ AS_IF([test "$do64bit" = yes -a "`uname -v`" -gt 3], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported with GCC on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS_ARCH="-q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" ]) ]) AS_IF([test "`uname -m`" = ia64], [ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" AS_IF([test "$GCC" = yes], [ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' ], [ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' ]) LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' ], [ AS_IF([test "$GCC" = yes], [SHLIB_LD='${CC} -shared'], [ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry" ]) SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} TCL_NEEDS_EXP_FILE=1 # TEA specific: use PACKAGE_VERSION instead of VERSION TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp' ]) # AIX v<=4.1 has some different flags than 4.2+ AS_IF([test "$system" = "AIX-4.1" -o "`uname -v`" -lt 4], [ AC_LIBOBJ([tclLoadAix]) DL_LIBS="-lld" ]) # On AIX <=v4 systems, libbsd.a has to be linked in to support # non-blocking file IO. This library has to be linked in after # the MATH_LIBS or it breaks the pow() function. The way to # insure proper sequencing, is to add it to the tail of MATH_LIBS. # This library also supplies gettimeofday. # # AIX does not have a timezone field in struct tm. When the AIX # bsd library is used, the timezone global and the gettimeofday # methods are to be avoided for timezone deduction instead, we # deduce the timezone by comparing the localtime result on a # known GMT value. AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no) AS_IF([test $libbsd = yes], [ MATH_LIBS="$MATH_LIBS -lbsd" AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?]) ]) ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -nostart' SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" #----------------------------------------------------------- # Check for inet_ntoa in -lbind, for BeOS (which also needs # -lsocket, even if the network functions are in -lnet which # is always linked to, for compatibility. #----------------------------------------------------------- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"]) ;; 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" CC_SEARCH_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" LDFLAGS="$LDFLAGS -export-dynamic" CC_SEARCH_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" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; HP-UX-*.11.*) # Use updated header definitions where possible AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?]) # TEA specific: Needed by Tcl, but not most extensions #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?]) #LIBS="$LIBS -lxnet" # Use the XOPEN network library AS_IF([test "`uname -m`" = ia64], [ SHLIB_SUFFIX=".so" # Use newer C++ library for C++ extensions #if test "$GCC" != "yes" ; then # CPPFLAGS="-AA" #fi ], [ SHLIB_SUFFIX=".sl" ]) AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' SHLIB_LD_LIBS='${LIBS}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = "yes"], [ AS_IF([test "$GCC" = yes], [ case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' SHLIB_LD_LIBS='${LIBS}' AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]) ;; esac ], [ do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS_ARCH="+DD64" ]) ]) ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) ;; IRIX-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [ CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" ], [ case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" ]) ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported by gcc]) ], [ do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS_ARCH="-64" ]) ]) ;; Linux*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" # TEA specific: CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings # when you inline the string and math operations. Turn this off to # get rid of the warnings. #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}' DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) AS_IF([test $do64bit = yes], [ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_m64 = yes], [ CFLAGS="$CFLAGS -m64" do64bit_ok=yes ]) ]) # The combo of gcc + glibc has a bug related to inlining of # functions like strtod(). The -fno-builtin flag should address # this problem but it does not work. The -fno-inline flag is kind # of overkill but it works. Disable inlining only when one of the # files in compat/*.c is being linked in. AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"]) ;; GNU*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" SHLIB_LD='${CC} -shared' DL_OBJS="" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) ;; Lynx*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; MP-RAS-*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,-Bexport" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; NetBSD-1.*|FreeBSD-[[1-2]].*) SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [ AC_EGREP_CPP(yes, [ #ifdef __ELF__ yes #endif ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)]) AS_IF([test $tcl_cv_ld_elf = yes], [ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' ], [ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' ]) # Ancient FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [ AC_EGREP_CPP(yes, [ #ifdef __ELF__ yes #endif ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)]) AS_IF([test $tcl_cv_ld_elf = yes], [ LDFLAGS=-Wl,-export-dynamic ], [LDFLAGS=""]) # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; NetBSD-*|FreeBSD-*) # FreeBSD 3.* and greater have ELF. # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) case $system in FreeBSD-3.*) # FreeBSD-3 doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' TCL_LIB_VERSIONS_OK=nodots ;; esac ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" # To avoid discrepancies between what headers configure sees during # preprocessing tests and compiling tests, move any -isysroot and # -mmacosx-version-min flags from CFLAGS to CPPFLAGS: CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`" CFLAGS="`echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`" AS_IF([test $do64bit = yes], [ case `arch` in ppc) AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag], tcl_cv_cc_arch_ppc64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes, tcl_cv_cc_arch_ppc64=no) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" do64bit_ok=yes ]);; i386) AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag], tcl_cv_cc_arch_x86_64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch x86_64" AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes, tcl_cv_cc_arch_x86_64=no) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [ CFLAGS="$CFLAGS -arch x86_64" do64bit_ok=yes ]);; *) AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);; esac ], [ # Check for combined 32-bit and 64-bit fat build AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [ fat_32_64=yes]) ]) # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}' AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_single_module = yes], [ SHLIB_LD="${SHLIB_LD} -Wl,-single_module" ]) # TEA specific: link shlib with current and compatiblity version flags vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d` SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [ LDFLAGS="$LDFLAGS -prebind"]) LDFLAGS="$LDFLAGS -headerpad_max_install_names" AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_search_paths_first = yes], [ LDFLAGS="$LDFLAGS -Wl,-search_paths_first" ]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [__private_extern__], [Compiler support for module scope symbols]) ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" # TEA specific: for combined 32 & 64 bit fat builds of Tk # extensions, verify that 64-bit build is possible. AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include" LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11" AC_TRY_LINK([#include ], [XrmInitialize();], tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) ]) # remove 64-bit arch flags from CFLAGS et al. if configuration # does not support 64-bit. AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua -o "$tcl_cv_lib_x11_64" = no], [ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' done]) ]) ;; NEXTSTEP-*) SHLIB_CFLAGS="" SHLIB_LD='${CC} -nostdlib -r' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadNext.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h [Should OS/390 do the right thing with sockets?]) ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SHLIB_CFLAGS="" # Hack: make package name same as library name SHLIB_LD='ld -R -export $@:' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadOSF.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" AS_IF([test "$SHARED_BUILD" = 1], [SHLIB_LD="ld -shared"], [ SHLIB_LD="ld -non_shared" ]) SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" AS_IF([test "$SHARED_BUILD" = 1], [ SHLIB_LD='ld -shared -expect_unresolved "*"' ], [ SHLIB_LD='ld -non_shared -expect_unresolved "*"' ]) SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"]) # see pthread_intro(3) for pthread support on osf1, k.furukawa AS_IF([test "${TCL_THREADS}" = 1], [ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` AS_IF([test "$GCC" = yes], [ LIBS="$LIBS -lpthread -lmach -lexc" ], [ CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) ]) ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" # dlopen is in -lc on QNX DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. AS_IF([test "$GCC" = yes], [ SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" ], [ SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" ]) SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SINIX*5.4*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SunOS-4*) SHLIB_CFLAGS="-PIC" SHLIB_LD="ld" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} # 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 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; SunOS-5.[[0-6]]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" # 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" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ SHLIB_LD="/usr/ccs/bin/ld -G -z text" CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ arch=`isainfo` AS_IF([test "$arch" = "sparcv9 sparc"], [ AS_IF([test "$GCC" = yes], [ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" SHLIB_CFLAGS="-fPIC" ]) ], [ do64bit_ok=yes AS_IF([test "$do64bitVIS" = yes], [ CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS_ARCH="-xarch=v9a" ], [ CFLAGS="$CFLAGS -xarch=v9" LDFLAGS_ARCH="-xarch=v9" ]) # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" ]) ], [AS_IF([test "$arch" = "amd64 i386"], [ AS_IF([test "$GCC" = yes], [ case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) do64bit_ok=yes CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]);; esac ], [ do64bit_ok=yes case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64";; esac ]) ], [AC_MSG_WARN([64bit mode not supported for $arch])])]) ]) # 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" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "$do64bit_ok" = yes], [ AS_IF([test "$arch" = "sparcv9 sparc"], [ # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" ], [AS_IF([test "$arch" = "amd64 i386"], [ # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" ])]) ]) ], [ case $system in SunOS-5.[[1-9]][[0-9]]*) SHLIB_LD='${CC} -G -z text ${LDFLAGS}';; *) SHLIB_LD='/usr/ccs/bin/ld -G -z text';; esac CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-R ${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 # that don't grok the -Bexport option. Test that it does. AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-Bexport" AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_Bexport = yes], [ LDFLAGS="$LDFLAGS -Wl,-Bexport" ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; esac AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform]) ]) dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so dnl # until the end of configure, as configure's compile and link tests use dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's dnl # preprocessing tests use only CPPFLAGS. AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""]) # Step 4: disable dynamic loading if requested via a command-line switch. AC_ARG_ENABLE(load, AC_HELP_STRING([--enable-load], [allow dynamic loading and "load" command (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) AS_IF([test "$tcl_ok" = no], [DL_OBJS=""]) AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [ AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.]) SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" DL_OBJS="tclLoadNone.o" DL_LIBS="" LDFLAGS="$LDFLAGS_ORIG" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" BUILD_DLTEST="" ]) LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [ case $system in AIX-*) ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; SCO_SV-3.2*) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac]) AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [ # TEA specific: use PACKAGE_VERSION instead of VERSION SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}']) AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [ # TEA specific: use PACKAGE_VERSION instead of VERSION UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a']) AC_SUBST(DL_LIBS) AC_SUBST(CFLAGS_DEBUG) AC_SUBST(CFLAGS_OPTIMIZE) AC_SUBST(CFLAGS_WARNING) AC_SUBST(STLIB_LD) AC_SUBST(SHLIB_LD) AC_SUBST(SHLIB_LD_LIBS) AC_SUBST(SHLIB_CFLAGS) AC_SUBST(LD_LIBRARY_PATH_VAR) # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary TEA_TCL_EARLY_FLAGS TEA_TCL_64BIT_FLAGS ]) #-------------------------------------------------------------------- # TEA_SERIAL_PORT # # 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, # and some build environments have stdin not pointing at a # pseudo-terminal (usually /dev/null instead.) # # Arguments: # none # # Results: # # Defines only one of the following vars: # HAVE_SYS_MODEM_H # USE_TERMIOS # USE_TERMIO # USE_SGTTY # #-------------------------------------------------------------------- AC_DEFUN([TEA_SERIAL_PORT], [ AC_CHECK_HEADERS(sys/modem.h) AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [ AC_TRY_RUN([ #include int main() { struct termios t; if (tcgetattr(0, &t) == 0) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include #include int main() { struct termios t; if (tcgetattr(0, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no; then AC_TRY_RUN([ #include #include int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no; then AC_TRY_RUN([ #include #include int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none) fi]) case $tcl_cv_api_serial in termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);; termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);; sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);; esac ]) #-------------------------------------------------------------------- # TEA_MISSING_POSIX_HEADERS # # Supply substitutes for missing POSIX header files. Special # notes: # - stdlib.h doesn't define strtol, strtoul, or # strtod insome versions of SunOS # - some versions of string.h don't declare procedures such # as strstr # # Arguments: # none # # Results: # # Defines some of the following vars: # NO_DIRENT_H # NO_ERRNO_H # NO_VALUES_H # HAVE_LIMITS_H or NO_LIMITS_H # NO_STDLIB_H # NO_STRING_H # NO_SYS_WAIT_H # NO_DLFCN_H # HAVE_SYS_PARAM_H # # HAVE_STRING_H ? # # tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and # CHECK on limits.h #-------------------------------------------------------------------- AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [ AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [ AC_TRY_LINK([#include #include ], [ #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)]) if test $tcl_cv_dirent_h = no; then AC_DEFINE(NO_DIRENT_H, 1, [Do we have ?]) fi # TEA specific: AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have ?])]) AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have ?])]) AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have ?])]) AC_CHECK_HEADER(limits.h, [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have ?])], [AC_DEFINE(NO_LIMITS_H, 1, [Do we have ?])]) AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0) AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0) if test $tcl_ok = 0; then AC_DEFINE(NO_STDLIB_H, 1, [Do we have ?]) 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, 1, [Do we have ?]) fi AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have ?])]) AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have ?])]) # OS/390 lacks sys/param.h (and doesn't need it, by chance). AC_HAVE_HEADERS(sys/param.h) ]) #-------------------------------------------------------------------- # TEA_PATH_X # # Locate the X11 header files and the X11 library archive. Try # the ac_path_x macro first, but if it doesn't find the X stuff # (e.g. because there's no xmkmf program) then check through # a list of possible directories. Under some conditions the # autoconf macro will return an include directory that contains # no include files, so double-check its result just to be safe. # # This should be called after TEA_CONFIG_CFLAGS as setting the # LIBS line can confuse some configure macro magic. # # Arguments: # none # # Results: # # Sets the following vars: # XINCLUDES # XLIBSW # PKG_LIBS (appends to) # #-------------------------------------------------------------------- AC_DEFUN([TEA_PATH_X], [ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then TEA_PATH_UNIX_X fi ]) AC_DEFUN([TEA_PATH_UNIX_X], [ AC_PATH_X not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then AC_TRY_CPP([#include ], , not_really_there="yes") else if test ! -r $x_includes/X11/Intrinsic.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then AC_MSG_CHECKING([for X11 header files]) found_xincludes="no" AC_TRY_CPP([#include ], found_xincludes="yes", found_xincludes="no") if test "$found_xincludes" = "no"; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Intrinsic.h; then AC_MSG_RESULT([$i]) XINCLUDES=" -I$i" found_xincludes="yes" break fi done fi else if test "$x_includes" != ""; then XINCLUDES="-I$x_includes" found_xincludes="yes" fi fi if test found_xincludes = "no"; then AC_MSG_RESULT([couldn't find any!]) fi if test "$no_x" = yes; then AC_MSG_CHECKING([for X11 libraries]) XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then AC_MSG_RESULT([$i]) XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) fi if test "$XLIBSW" = nope ; then AC_MSG_RESULT([could not find any! Using -lX11.]) XLIBSW=-lX11 fi # TEA specific: if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi ]) #-------------------------------------------------------------------- # TEA_BLOCKING_STYLE # # 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. # # Arguments: # none # # Results: # # Defines some of the following vars: # HAVE_SYS_IOCTL_H # HAVE_SYS_FILIO_H # USE_FIONBIO # O_NONBLOCK # #-------------------------------------------------------------------- AC_DEFUN([TEA_BLOCKING_STYLE], [ AC_CHECK_HEADERS(sys/ioctl.h) AC_CHECK_HEADERS(sys/filio.h) TEA_CONFIG_SYSTEM AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O]) case $system in # There used to be code here to use FIONBIO under AIX. However, it # was reported that FIONBIO doesn't work under AIX 3.2.5. Since # using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO # code (JO, 5/31/97). OSF*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; SunOS-4*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; *) AC_MSG_RESULT([O_NONBLOCK]) ;; esac ]) #-------------------------------------------------------------------- # TEA_TIME_HANLDER # # Checks how the system deals with time.h, what time structures # are used on the system, and what fields the structures have. # # Arguments: # none # # Results: # # Defines some of the following vars: # USE_DELTA_FOR_TZ # HAVE_TM_GMTOFF # HAVE_TM_TZADJ # HAVE_TIMEZONE_VAR # #-------------------------------------------------------------------- AC_DEFUN([TEA_TIME_HANDLER], [ AC_CHECK_HEADERS(sys/time.h) AC_HEADER_TIME AC_STRUCT_TIMEZONE AC_CHECK_FUNCS(gmtime_r localtime_r) AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [ AC_TRY_COMPILE([#include ], [struct tm tm; tm.tm_tzadj;], tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)]) if test $tcl_cv_member_tm_tzadj = yes ; then AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?]) fi AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [ AC_TRY_COMPILE([#include ], [struct tm tm; tm.tm_gmtoff;], tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)]) if test $tcl_cv_member_tm_gmtoff = yes ; then AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?]) fi # # Its important to include time.h in this check, as some systems # (like convex) have timezone functions, etc. # AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [ AC_TRY_COMPILE([#include ], [extern long timezone; timezone += 1; exit (0);], tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)]) if test $tcl_cv_timezone_long = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) else # # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. # AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [ AC_TRY_COMPILE([#include ], [extern time_t timezone; timezone += 1; exit (0);], tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)]) if test $tcl_cv_timezone_time = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) fi fi ]) #-------------------------------------------------------------------- # TEA_BUGGY_STRTOD # # Under Solaris 2.4, strtod returns the wrong value for the # terminating character under some conditions. Check for this # and if the problem exists use a substitute procedure # "fixstrtod" (provided by Tcl) that corrects the error. # Also, on Compaq's Tru64 Unix 5.0, # strtod(" ") returns 0.0 instead of a failure to convert. # # Arguments: # none # # Results: # # Might defines some of the following vars: # strtod (=fixstrtod) # #-------------------------------------------------------------------- AC_DEFUN([TEA_BUGGY_STRTOD], [ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0) if test "$tcl_strtod" = 1; then AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[ AC_TRY_RUN([ extern double strtod(); int main() { char *infString="Inf", *nanString="NaN", *spaceString=" "; char *term; double value; value = strtod(infString, &term); if ((term != infString) && (term[-1] == 0)) { exit(1); } value = strtod(nanString, &term); if ((term != nanString) && (term[-1] == 0)) { exit(1); } value = strtod(spaceString, &term); if (term == (spaceString+1)) { exit(1); } exit(0); }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy, tcl_cv_strtod_buggy=buggy)]) if test "$tcl_cv_strtod_buggy" = buggy; then AC_LIBOBJ([fixstrtod]) USE_COMPAT=1 AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?]) fi fi ]) #-------------------------------------------------------------------- # TEA_TCL_LINK_LIBS # # Search for the libraries needed to link the Tcl shell. # Things like the math library (-lm) and socket stuff (-lsocket vs. # -lnsl) are dealt with here. # # Arguments: # Requires the following vars to be set in the Makefile: # DL_LIBS # LIBS # MATH_LIBS # # Results: # # Subst's the following var: # TCL_LIBS # MATH_LIBS # # Might append to the following vars: # LIBS # # Might define the following vars: # HAVE_NET_ERRNO_H # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_LINK_LIBS], [ #-------------------------------------------------------------------- # 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"). #-------------------------------------------------------------------- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm") AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"]) #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"]) AC_CHECK_HEADER(net/errno.h, [ AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have ?])]) #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1) if test "$tcl_checkSocket" = 1; then AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt, LIBS="$LIBS -lsocket", tcl_checkBoth=1)]) 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, gethostbyname, [LIBS="$LIBS -lnsl"])]) # TEA specific: Don't perform the eval of the libraries here because # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' AC_SUBST(TCL_LIBS) AC_SUBST(MATH_LIBS) ]) #-------------------------------------------------------------------- # TEA_TCL_EARLY_FLAGS # # Check for what flags are needed to be passed so the correct OS # features are available. # # Arguments: # None # # Results: # # Might define the following vars: # _ISOC99_SOURCE # _LARGEFILE64_SOURCE # _LARGEFILE_SOURCE64 # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_EARLY_FLAG],[ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no, AC_TRY_COMPILE([[#define ]$1[ 1 ]$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no))) if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then AC_DEFINE($1, 1, [Add the ]$1[ flag when building]) tcl_flags="$tcl_flags $1" fi ]) AC_DEFUN([TEA_TCL_EARLY_FLAGS],[ AC_MSG_CHECKING([for required early compiler flags]) tcl_flags="" TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include ], [char *p = (char *)strtoll; char *q = (char *)strtoull;]) TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include ], [struct stat64 buf; int i = stat64("/", &buf);]) TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include ], [char *p = (char *)open64;]) if test "x${tcl_flags}" = "x" ; then AC_MSG_RESULT([none]) else AC_MSG_RESULT([${tcl_flags}]) fi ]) #-------------------------------------------------------------------- # TEA_TCL_64BIT_FLAGS # # Check for what is defined in the way of 64-bit features. # # Arguments: # None # # Results: # # Might define the following vars: # TCL_WIDE_INT_IS_LONG # TCL_WIDE_INT_TYPE # HAVE_STRUCT_DIRENT64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_64BIT_FLAGS], [ AC_MSG_CHECKING([for 64-bit integer type]) AC_CACHE_VAL(tcl_cv_type_64bit,[ tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 AC_TRY_COMPILE(,[__int64 value = (__int64) 0;], tcl_type_64bit=__int64, tcl_type_64bit="long long") # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... AC_TRY_COMPILE(,[switch (0) { case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; }],tcl_cv_type_64bit=${tcl_type_64bit})]) if test "${tcl_cv_type_64bit}" = none ; then AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?]) AC_MSG_RESULT([using long]) elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # TEA specific: We actually want to use the default tcl.h checks in # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* AC_MSG_RESULT([using Tcl header defaults]) else AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit}, [What type should be used to define wide integers?]) AC_MSG_RESULT([${tcl_cv_type_64bit}]) # Now check for auxiliary declarations AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[ AC_TRY_COMPILE([#include #include ],[struct dirent64 p;], tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)]) if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?]) fi AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[ AC_TRY_COMPILE([#include ],[struct stat64 p; ], tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)]) if test "x${tcl_cv_struct_stat64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in ?]) fi AC_CHECK_FUNCS(open64 lseek64) AC_MSG_CHECKING([for off64_t]) AC_CACHE_VAL(tcl_cv_type_off64_t,[ AC_TRY_COMPILE([#include ],[off64_t offset; ], tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)]) dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the dnl functions lseek64 and open64 are defined. if test "x${tcl_cv_type_off64_t}" = "xyes" && \ test "x${ac_cv_func_lseek64}" = "xyes" && \ test "x${ac_cv_func_open64}" = "xyes" ; then AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in ?]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi fi ]) ## ## Here ends the standard Tcl configuration bits and starts the ## TEA specific functions ## #------------------------------------------------------------------------ # TEA_INIT -- # # Init various Tcl Extension Architecture (TEA) variables. # This should be the first called TEA_* macro. # # Arguments: # none # # Results: # # Defines and substs the following vars: # CYGPATH # EXEEXT # Defines only: # TEA_VERSION # TEA_INITED # TEA_PLATFORM (windows or unix) # # "cygpath" is used on windows to generate native path names for include # files. These variables should only be used with the compiler and linker # since they generate native path names. # # EXEEXT # Select the executable extension based on the host type. This # is a lightweight replacement for AC_EXEEXT that doesn't require # a compiler. #------------------------------------------------------------------------ AC_DEFUN([TEA_INIT], [ # TEA extensions pass this us the version of TEA they think they # are compatible with. TEA_VERSION="3.7" AC_MSG_CHECKING([for correct TEA configuration]) if test x"${PACKAGE_NAME}" = x ; then AC_MSG_ERROR([ The PACKAGE_NAME variable must be defined by your TEA configure.in]) fi if test x"$1" = x ; then AC_MSG_ERROR([ TEA version not specified.]) elif test "$1" != "${TEA_VERSION}" ; then AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"]) else AC_MSG_RESULT([ok (TEA ${TEA_VERSION})]) fi case "`uname -s`" in *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo) EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) CYGPATH=echo EXEEXT="" TEA_PLATFORM="unix" ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi AC_SUBST(EXEEXT) AC_SUBST(CYGPATH) # This package name must be replaced statically for AC_SUBST to work AC_SUBST(PKG_LIB_FILE) # Substitute STUB_LIB_FILE in case package creates a stub library too. AC_SUBST(PKG_STUB_LIB_FILE) # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) AC_SUBST(PKG_TCL_SOURCES) AC_SUBST(PKG_HEADERS) AC_SUBST(PKG_INCLUDES) AC_SUBST(PKG_LIBS) AC_SUBST(PKG_CFLAGS) ]) #------------------------------------------------------------------------ # TEA_ADD_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_SOURCES # PKG_OBJECTS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_SOURCES], [ vars="$@" for i in $vars; do case $i in [\$]*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then AC_MSG_ERROR([could not find source file '$i']) fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done AC_SUBST(PKG_SOURCES) AC_SUBST(PKG_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_STUB_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_STUB_SOURCES # PKG_STUB_OBJECTS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_STUB_SOURCES], [ vars="$@" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then AC_MSG_ERROR([could not find stub source file '$i']) fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_TCL_SOURCES -- # # Specify one or more Tcl source files. These should be platform # independent runtime files. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_TCL_SOURCES #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_TCL_SOURCES], [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i']) fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done AC_SUBST(PKG_TCL_SOURCES) ]) #------------------------------------------------------------------------ # TEA_ADD_HEADERS -- # # Specify one or more source headers. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_HEADERS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_HEADERS], [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find header file '${srcdir}/$i']) fi PKG_HEADERS="$PKG_HEADERS $i" done AC_SUBST(PKG_HEADERS) ]) #------------------------------------------------------------------------ # TEA_ADD_INCLUDES -- # # Specify one or more include dirs. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_INCLUDES], [ vars="$@" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done AC_SUBST(PKG_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_ADD_LIBS -- # # Specify one or more libraries. Users should check for # the right platform before adding to their list. For Windows, # libraries provided in "foo.lib" format will be converted to # "-lfoo" when using GCC (mingw). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_LIBS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_LIBS], [ vars="$@" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done AC_SUBST(PKG_LIBS) ]) #------------------------------------------------------------------------ # TEA_ADD_CFLAGS -- # # Specify one or more CFLAGS. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_CFLAGS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_CFLAGS], [ PKG_CFLAGS="$PKG_CFLAGS $@" AC_SUBST(PKG_CFLAGS) ]) #------------------------------------------------------------------------ # TEA_PREFIX -- # # Handle the --prefix=... option by defaulting to what Tcl gave # # Arguments: # none # # Results: # # If --prefix or --exec-prefix was not specified, $prefix and # $exec_prefix will be set to the values given to Tcl when it was # configured. #------------------------------------------------------------------------ AC_DEFUN([TEA_PREFIX], [ if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}]) prefix=${TCL_PREFIX} else AC_MSG_NOTICE([--prefix defaulting to /usr/local]) prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then if test x"${TCL_EXEC_PREFIX}" != x; then AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) exec_prefix=${TCL_EXEC_PREFIX} else AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}]) exec_prefix=$prefix fi fi ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER_CC -- # # Do compiler checks the way we want. This is just a replacement # for AC_PROG_CC in TEA configure.in files to make them cleaner. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN([TEA_SETUP_COMPILER_CC], [ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. # If the user did not set CFLAGS, set it now to keep # the AC_PROG_CC macro from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- AC_PROG_MAKE_SET #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- AC_PROG_RANLIB #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- AC_OBJEXT AC_EXEEXT ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER -- # # Do compiler checks that use the compiler. This must go after # TEA_SETUP_COMPILER_CC, which does the actual compiler check. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN([TEA_SETUP_COMPILER], [ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. AC_REQUIRE([TEA_SETUP_COMPILER_CC]) #------------------------------------------------------------------------ # 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" -a -n "$GCC"; then AC_CACHE_CHECK([if the compiler understands -pipe], tcl_cv_cc_pipe, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no) CFLAGS=$hold_cflags]) if test $tcl_cv_cc_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- AC_C_BIGENDIAN if test "${TEA_PLATFORM}" = "unix" ; then TEA_TCL_LINK_LIBS TEA_MISSING_POSIX_HEADERS # Let the user call this, because if it triggers, they will # need a compat/strtod.c that is correct. Users can also # use Tcl_GetDouble(FromObj) instead. #TEA_BUGGY_STRTOD fi ]) #------------------------------------------------------------------------ # TEA_MAKE_LIB -- # # Generate a line that can be used to build a shared/unshared library # in a platform independent manner. # # Arguments: # none # # Requires: # # Results: # # Defines the following vars: # CFLAGS - Done late here to note disturb other AC macros # MAKE_LIB - Command to execute to build the Tcl library; # differs depending on whether or not Tcl is being # compiled as a shared library. # MAKE_SHARED_LIB Makefile rule for building a shared library # MAKE_STATIC_LIB Makefile rule for building a static library # MAKE_STUB_LIB Makefile rule for building a stub library #------------------------------------------------------------------------ AC_DEFUN([TEA_MAKE_LIB], [ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)" MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\"" fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" if test "$GCC" = "yes"; then PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE} fi # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}" fi eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi AC_SUBST(MAKE_LIB) AC_SUBST(MAKE_SHARED_LIB) AC_SUBST(MAKE_STATIC_LIB) AC_SUBST(MAKE_STUB_LIB) AC_SUBST(RANLIB_STUB) ]) #------------------------------------------------------------------------ # TEA_LIB_SPEC -- # # Compute the name of an existing object library located in libdir # from the given base name and produce the appropriate linker flags. # # Arguments: # basename The base name of the library without version # numbers, extensions, or "lib" prefixes. # extra_dir Extra directory in which to search for the # library. This location is used first, then # $prefix/$exec-prefix, then some defaults. # # Requires: # TEA_INIT and TEA_PREFIX must be called first. # # Results: # # Defines the following vars: # ${basename}_LIB_NAME The computed library name. # ${basename}_LIB_SPEC The computed linker flags. #------------------------------------------------------------------------ AC_DEFUN([TEA_LIB_SPEC], [ AC_MSG_CHECKING([for $1 library]) # Look in exec-prefix for the library (defined by TEA_PREFIX). tea_lib_name_dir="${exec_prefix}/lib" # Or in a user-specified location. if test x"$2" != x ; then tea_extra_lib_dir=$2 else tea_extra_lib_dir=NONE fi for i in \ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do if test -f "$i" ; then tea_lib_name_dir=`dirname $i` $1_LIB_NAME=`basename $i` $1_LIB_PATH_NAME=$i break fi done if test "${TEA_PLATFORM}" = "windows"; then $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\" else # Strip off the leading "lib" and trailing ".a" or ".so" tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'` $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}" fi if test "x${$1_LIB_NAME}" = x ; then AC_MSG_ERROR([not found]) else AC_MSG_RESULT([${$1_LIB_SPEC}]) fi ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TCL_HEADERS -- # # Locate the private Tcl include files # # Arguments: # # Requires: # TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has # already been called. # # Results: # # Substs the following vars: # TCL_TOP_DIR_NATIVE # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh} AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS]) AC_MSG_CHECKING([for Tcl private include files]) TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}` TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\" # Check to see if tclPort.h isn't already with the public headers # Don't look for tclInt.h because that resides with tcl.h in the core # sources, but the Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tclh}/tclWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then result="private headers found with public headers" else TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\" if test "${TEA_PLATFORM}" = "windows"; then TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\" else TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TCL_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -d "${TCL_BIN_DIR}/Headers" -a \ -d "${TCL_BIN_DIR}/PrivateHeaders"; then TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}" else TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TCL_INCLUDES}" else if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}]) fi result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}" fi fi AC_SUBST(TCL_TOP_DIR_NATIVE) AC_SUBST(TCL_INCLUDES) AC_MSG_RESULT([${result}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TCL_HEADERS -- # # Locate the installed public Tcl header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tclinclude switch to configure. # Result is cached. # # Substs the following vars: # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [ AC_MSG_CHECKING([for Tcl public headers]) AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tclh, [ # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h]) fi else if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "${TCL_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude]) else AC_MSG_RESULT([${ac_cv_c_tclh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TCL_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TK_HEADERS -- # # Locate the private Tk include files # # Arguments: # # Requires: # TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has # already been called. # # Results: # # Substs the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh} AC_REQUIRE([TEA_PUBLIC_TK_HEADERS]) AC_MSG_CHECKING([for Tk private include files]) TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}` TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\" # Check to see if tkPort.h isn't already with the public headers # Don't look for tkInt.h because that resides with tk.h in the core # sources, but the Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tkh}/tkWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then result="private headers found with public headers" else TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\" TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\" if test "${TEA_PLATFORM}" = "windows"; then TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\" else TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TK_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}" # Detect and add ttk subdir if test -d "${TK_SRC_DIR}/generic/ttk"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\"" fi if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\"" fi if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\"" fi if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TK_DEFS} in *TK_FRAMEWORK*) if test -d "${TK_BIN_DIR}/Headers" -a \ -d "${TK_BIN_DIR}/PrivateHeaders"; then TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}" else TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TK_INCLUDES}" else if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}]) fi result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}" fi fi AC_SUBST(TK_TOP_DIR_NATIVE) AC_SUBST(TK_XLIB_DIR_NATIVE) AC_SUBST(TK_INCLUDES) AC_MSG_RESULT([${result}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TK_HEADERS -- # # Locate the installed public Tk header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tkinclude switch to configure. # Result is cached. # # Substs the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [ AC_MSG_CHECKING([for Tk public headers]) AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tkh, [ # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h]) fi else if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "${TK_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude]) else AC_MSG_RESULT([${ac_cv_c_tkh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_INCLUDES) if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then # On Windows and Aqua, we need the X compat headers AC_MSG_CHECKING([for X11 header files]) if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_XINCLUDES) fi AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}]) fi ]) #------------------------------------------------------------------------ # TEA_PATH_CONFIG -- # # Locate the ${1}Config.sh file and perform a sanity check on # the ${1} compile flags. These are used by packages like # [incr Tk] that load *Config.sh files from more than Tcl and Tk. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-$1=... # # Defines the following vars: # $1_BIN_DIR Full path to the directory containing # the $1Config.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_CONFIG], [ # # Ok, lets find the $1 configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-$1 # if test x"${no_$1}" = x ; then # we reset no_$1 in case something fails here no_$1=true AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval}) AC_MSG_CHECKING([for $1 configuration]) AC_CACHE_VAL(ac_cv_c_$1config,[ # First check to see if --with-$1 was specified. if test x"${with_$1config}" != x ; then case ${with_$1config} in */$1Config.sh ) if test -f ${with_$1config}; then AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself]) with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'` fi;; esac if test -f "${with_$1config}/$1Config.sh" ; then ac_cv_c_$1config=`(cd ${with_$1config}; pwd)` else AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh]) fi fi # then check for a private $1 installation if test x"${ac_cv_c_$1config}" = x ; then for i in \ ../$1 \ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../$1 \ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../../$1 \ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ${srcdir}/../$1 \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi if test -f "$i/unix/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_$1config}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_$1config}" = x ; then $1_BIN_DIR="# no $1 configs found" AC_MSG_WARN([Cannot find $1 configuration definitions]) exit 0 else no_$1= $1_BIN_DIR=${ac_cv_c_$1config} AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_CONFIG -- # # Load the $1Config.sh file # # Arguments: # # Requires the following vars to be set: # $1_BIN_DIR # # Results: # # Subst the following vars: # $1_SRC_DIR # $1_LIB_FILE # $1_LIB_SPEC # #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG], [ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh]) if test -f "${$1_BIN_DIR}/$1Config.sh" ; then AC_MSG_RESULT([loading]) . "${$1_BIN_DIR}/$1Config.sh" else AC_MSG_RESULT([file not found]) fi # # If the $1_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable $1_LIB_SPEC will be set to the value # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC # instead of $1_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f "${$1_BIN_DIR}/Makefile" ; then AC_MSG_WARN([Found Makefile - using build library specs for $1]) $1_LIB_SPEC=${$1_BUILD_LIB_SPEC} $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC} $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH} fi AC_SUBST($1_VERSION) AC_SUBST($1_BIN_DIR) AC_SUBST($1_SRC_DIR) AC_SUBST($1_LIB_FILE) AC_SUBST($1_LIB_SPEC) AC_SUBST($1_STUB_LIB_FILE) AC_SUBST($1_STUB_LIB_SPEC) AC_SUBST($1_STUB_LIB_PATH) ]) #------------------------------------------------------------------------ # TEA_PATH_CELIB -- # # Locate Keuchel's celib emulation layer for targeting Win/CE # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-celib=... # # Defines the following vars: # CELIB_DIR Full path to the directory containing # the include and platform lib files #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_CELIB], [ # First, look for one uninstalled. # the alternative search directory is invoked by --with-celib if test x"${no_celib}" = x ; then # we reset no_celib in case something fails here no_celib=true AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval}) AC_MSG_CHECKING([for Windows/CE celib directory]) AC_CACHE_VAL(ac_cv_c_celibconfig,[ # First check to see if --with-celibconfig was specified. if test x"${with_celibconfig}" != x ; then if test -d "${with_celibconfig}/inc" ; then ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` else AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory]) fi fi # then check for a celib library if test x"${ac_cv_c_celibconfig}" = x ; then for i in \ ../celib-palm-3.0 \ ../celib \ ../../celib-palm-3.0 \ ../../celib \ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \ ${srcdir}/../celib-palm-3.0 \ ${srcdir}/../celib \ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \ ; do if test -d "$i/inc" ; then ac_cv_c_celibconfig=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_celibconfig}" = x ; then AC_MSG_ERROR([Cannot find celib support library directory]) else no_celib= CELIB_DIR=${ac_cv_c_celibconfig} CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` AC_MSG_RESULT([found $CELIB_DIR]) fi fi ]) # Local Variables: # mode: autoconf # End: trf2.1.4/BUILDINFO0000644000175000017500000000020611216343142013003 0ustar sergeisergei# -*- tcl -*- depends.on tcl memchan testsuite tests configure.with \ {} "--with-tcl=[file join %bld:tcl% %arch%] --enable-shared" trf2.1.4/PORTING0000644000175000017500000000027111216343142012614 0ustar sergeisergeiPorting notes for Tcl-Trf, the transformers package, as of 2.1.4, MAY-06-2009 ---------------------------------------------------- * Currently I have no report about porting problems. trf2.1.4/CHANGES0000644000175000017500000002044511216343142012547 0ustar sergeisergeiChanges from 2.1p1 to 2.1.3 * Corrected inconsistency BUILD_Trf / BUILD_trf. Changes from 2.1 to 2.1p1 * Fixes in some tools used during installation (findinpath, fixhbline). * [zip] is now able to handle additional data behind the compressed stream. By not reading it. No infinite loop for that case anymore. This also means that a pure-tcl version of gzip should be possible. Any takers ? * Merged patch from Dave Bodenstab to make the error messages better. * Uptodate binaries for Windows, via crosscompiling mingw gcc. Changes from 2.0p7 to 2.1 * Adapted to the rewrite of the stacked channel functionality in 8.3.2. A single binary should now support all stubbed cores (8.1 upward) by switching its behaviour at runtime. Some voodoo is used to make sure that it is not relevant which version of the core was used to create that all-purpose binary. Only the 8.0.x series requires a separate binary because it is not stubbed. Changes from 2.0p6 to 2.0p7 * Bugfixes for - usage of wrong strings in the script 'transform'. - wrong variable in makefile - a buffer overun in the quoted-printable encoding. - static library support. * Patch from Jan Nijtmans for usage of TEA build chain with mingw32. * Added a link to the TclAH extension (Authentication Hashes) to the documentation. Changes from 2.0p5 to 2.0p6 * Bugfixes - in the TEA configure related to md5-crypt (Sigh). - A memory leak. * Better/more support for building Trf as static library. Changes from 2.0p4 to 2.0p5 * Bugfix in the TEA configure related to md5-crypt. Changes from 2.0p3 to 2.0p4 * Bugfix in the TEA makefile. Changes from 2.0 to 2.0p3 * Fixed several small bugs. * Fixed some annoying bugs related to the changes made to MD5. Changes from 1.8 to 2.0 * Dropped support for Tcl 7.6. * Added support for TEA compliant building of this extension, see the subdirectory 'tea'. This requires at least Tcl/Tk 8.2. The old built facilities (unix, win) still exist and are still usable. Nevertheless TEA is the prefered way for Unix and Windows. * Added stubs, i.e. Trf now exports its own stub table. Thanks to Jan Nijtmans for providing the basic changes to get me started. * Revamped the way Trf is handling seek requests for transforms. **BEHAVIOURAL INCOMPATIBILITY** **BINARY INCOMPATIBILITY** (Trf_TypeDefinition's extended) See doc/html/trf_seek.html * Added vector for querying the max number of bytes to read. **BINARY INCOMPATIBILITY** (Trf_TypeDefinition's extended) * Squashed the bug in the 'bzip' (de)compressor. Squashed other bugs reported by Matt Newman * Added compile time options to link zlib / bzlib statically. --enable-static-zlib, -DZLIB_STATIC_BUILD --enable-static-bzlib, -DBZLIB_STATIC_BUILD * MD5 functionality is now loaded on demand. The source of the necessary shared library is part of the distribution and compiled if required (glibc2 Linux systems already have it). * New commands: md5crypt, crypt, use in password authentication. New option: -nowrap for 'zip' transformation. See documentation. * 'transform': Added operations 'query/maxRead' and 'query/ratio'. Changes from 1.7 to 1.8 * Marshall Rose made the 'base64' encoding MIME compliant and additionally donated his 'quoted-printable' converter. * Jan Nijtmans donated the 'bzip2' (de)compressor transform. It is unfortunately not yet complete, the decompressor is not working. * Rewrote the base code to handle the inclusion of the patch into the Tcl core (since 8.2) and the associated changes to the semantics of some of the functions. It now especially automagically distinguishes between unpatched 8.0, patched 8.0, unpatched 8.1, patched 8.1, 8.2 and beyond, and adapts itself accordingly, either at compile time (8.0.x) or runtime (8.1 and beyond). Changes from 1.6 to 1.7 * Headers now usable with a C++ compiler. * Marshall Rose donated code to implement the otp variants of md5 and sha1, according to RFC 2289. * The option processor now understands '--', it will stop the treatment of the following arguments as options. Again from Marshall Rose. * The patchkit for Tcl 8.1 is usable for Tcl 8.1.1 too. No new patchkit was made. * Made **thread-safe** if compiled against a thread-enabled 8.1. (Mutex used to serialize access to all written global variables) Changes from 1.6 to 1.6 * Added the patch kit for tcl 8.1 final Changes from 1.5 to 1.6 * The following information is valid only if Trf is used in conjunction with a 8.1 interpreter, as that is currently the only one implementing stubs. It is known that trf requires a patch to the core for full functionality (stacked channels). The core had to be patched to allow compilation of Trf, and its execution. Taking advantage of the new stub-mechanism Trf is now able to check for the existence of its patches at runtime. If loaded by an unpatched interpreter it will disable the features relying on the patch (-attach option of transforms, unstack), but run unimpeded otherwise. Due to some magic with #define and #ifdef it is now even possible to compile Trf against unpatched core without causing harm, the resulting library will have the complete functionality. Changes from 1.4 to 1.5 * Better handling of 'fileevent' and blocking-mode for transforms. Initial patch by Matt Newman (). * Fixed a nasty problem with my patch to the tcl core. Caused a crash if one tried to attach a transform to a new socket inside its accept script. Reason: Unwanted interaction between my handling of the refCount for the channel and tcl itself. Found by Matt Newman. Reworked all patchkits, except for 8.0[ab]*. Changes from 1.3 to 1.4 * Upgraded core patches for 8.1b2 and 8.0.4/5. * Added detection and usage of stubs. Changes from 1.2 to 1.3 * *No* functional changes. * Fixed several char / unsigned char mismatches and other nits reported by Larry Virden and his UltraSparc compiler. * Added technical explanation of the inner workings to the documentation, + images. * Upgraded core patches for 8.1b1 * Extended configure with options for the explicit definition of the location of the zlib and crypto libraries. Added intelligence to all pairs of location-options to derive their values from each other if only one of them is specified. Suggested by Larry Virden . * Added windows binary distribution. Changes from 1.1 to 1.2 * Moved all encryption aware code and definitions into a separate package, TrfCrypt. This allows the inclusion of the base package into the consortium CD ROM (and the upload to Neosoft). Changes from 1.0 to 1.1 * Adapted to C-API changes between 8.0 and 8.1 Added patches for Tcl 8.1a2 * Compiles now with Tcl 7.6, 8.0 and 8.1a2 * binio is more reclusive, it and its support (byteorder patch) will be removed in the next release. Please use the official 'binary' command of Tcl 8.x instead. Changes from b3 to final: * **** WARNING to all users of earlier versions **** The script API was rewritten to take advantage of the Tcl 8.x object API. The ability to operate on channels was retained, albeit under a different syntax. Please reread the manual, at least chapter 5 (Available commands). *a Extended C-level API allows for (block)cipher specific option processing. * A general transformation was added, under the name 'transform'. It reflects the underlying functionality up into the script level. * Added ciphers: <> ROT, for the fun of it. <> SAFER, by the author of IDEA. (uses *a) Changes from b2 to b3: * 'binio' command supported, but not included by default, because of equivalent functionality in 8.0b1, see 'binary' and 'fcopy'. Configure option '--enable-binio'. * Reorganized code into generic and os dependent parts. * Added Windows port. * Some bug fixes. * More algorithms: RC2, MD2, SHA-1 (SSLeay required) RIPEMD-160 * Commands created use the object-interface of tcl8.0b1 now. Runs with 7.6 nevertheless, BUT NOT with 8.0a1 or a2. Changes from b1 to b2: * The patches to the core are enhanced to associate channels with byteorder information. * A new command 'binio' to pack and/or unpack binary information and to copy between channels (the latter is essentially 'unsupported0'). (Un)packing will reorder bytes as needed, using the information mentioned above. trf2.1.4/README.tea0000644000175000017500000000102211216344223013173 0ustar sergeisergei Tcl Data transformations (Tcl-Trf) (Version 2.1.4 / MAY-06-2009) Andreas Kupries (andreas_kupries@users.sourceforge.net) This is the README file for the TEA compliant building of the Trf extension. Please follow the instructions in the HTML file doc/html/trf_ctea.html for compilation and installation of this package, independent of wether you are on a Unix or Windows machine. Beware that in case of Windows TEA uses the Cygwin tools from Cygnus (www.cygnus.com) for compilation and linking. After that, enjoy it. trf2.1.4/README0000644000175000017500000000535311216343142012435 0ustar sergeisergei Tcl Data transformations (Tcl-Trf) (Version 2.1.4 / MAY-06-2009) Andreas Kupries (andreas_kupries@users.sourceforge.net) This directory contains a freely distributable extension to Tcl/Tk called Tcl Data transformations (Tcl-Trf). The collection of provided transformation procedures includes: * Generation of message digests (hash values, checksums) MD2, MD5, SHA/SHS, SHA-1, HAVAL, RIPEMD-128, -160 CRC (polynomial used by PGP) ADLER (based upon zlib) * Conversion from and to various data encodings: dual, octal, hexadecimal representation uuencoding, base64-encoding, ASCII85-encoding * A reed-solomon error correcting coder. * (De)Compression based on zlib 1.0.4 or higher (1.1.3 is current) (if available as shared library) * Data encryption: Was removed from the base package, but is available separately (TrfCrypt). Example applications distributed with the package are: * 'tools/md', a message digest generator. Upwardly compatible to 'md5sum'. Tcl-Trf is developed for Tcl 7.6 or higher. It is a pure Tcl extension, Tk is not required. The extension requires a patched core. Patch files for 7.6, 8.0 and 8.0a2 are part of the distribution. The plus-patches maintained by Jan Nijtmans (nijtmans@nici.kun.nl) contain this patch too . Supporting (optional) packages are: * memchan 1.0 or higher (required by testsuite, by same author) See http://www.oche.de/~akupries/soft/memchan/ * zlib-1.0.4 or higher (1.1.3 is current!) See http://www.cdrom.com/pub/infozip/zlib/ * SSLeay or OpenSSL See http://www.ssleay.org/ or http://www.openssl.org/ Packages built upon the fundament provided by Trf are * TrfCrypt, contains various encryption systems, by myself. See http://www.oche.de/~akupries/soft/trfcrypt/ * TLS, an SSL/TLS implementation for all valid Tcl channels, by Matt Newman See http://www.sensus.org/tcl/tls.htm http://www.sensus.org/tcl/tls11.tgz This distribution contains the source code for Tcl-Trf + documentation describing commands (-> latex) and c-level interfaces (-> man-pages). COMPILING/USING Tcl-Trf To compile Tcl-Trf please follow the instructions in the HTML documentation (file: doc/html/trf_compile.html). To report bugs, bug fixes, descriptions of interesting Tcl-Trf applications, and suggested improvements: +) Send email to andreas_kupries@users.sourceforge.net or +) Post an article to the newsgroup comp.lang.tcl PLATFORMS tested: Linux 2.0.29 (gcc 2.7.2.3) Development system IRIX 6.2 (cc only) ULTRIX 4.1 (both cc and gcc) ULTRIX 4.4 (cc 3.0) HP-UX-9 (both cc and gcc) HP-UX-10.2 Solaris 2.5 (gcc only) Other machines and OS's should work too. Feedback about other OS's and compilers is appreciated. Please help me in making this package better. trf2.1.4/md5-crypt/0000755000175000017500000000000011216344734013403 5ustar sergeisergeitrf2.1.4/md5-crypt/crypt-entry.c0000644000175000017500000000522211216343142016040 0ustar sergeisergei/* Wrapper around MD5 sum replacement for crypt function. Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "trf_crypt.h" #include #include #ifndef EOPNOTSUPP #define EOPNOTSUPP 122 #endif #ifndef __set_errno # define __set_errno(val) errno = (val) #endif # define __crypt_r crypt_r # define __md5_crypt_r md5_crypt_r # define __md5_crypt md5_crypt /* Define our magic string to mark salt for MD5 encryption replacement. This is meant to be the same as for other MD5 based encryption implementations. */ static const char md5_salt_prefix[] = "$1$"; /* Prototypes for the MD5 encryption replacement functions. */ extern char *__md5_crypt_r (const char *key, const char *salt, char *buffer, int buflen); extern char *__md5_crypt (const char *key, const char *salt); extern char *__crypt_r (const char *key, const char *salt, struct crypt_data * data); /* We recognize an intended call of the MD5 crypt replacement function by the first 3 characters of the salt string. If they match the MD5 magic string we want MD5 encryption replacement. */ char * __crypt_r (key, salt, data) const char *key; const char *salt; struct crypt_data * data; { if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0) return __md5_crypt_r (key, salt, (char *) data, sizeof (struct crypt_data)); /* We don't have DES encryption. */ __set_errno (EOPNOTSUPP); return NULL; } /* The same here, only we call the non-reentrant version. */ char * crypt (key, salt) const char *key; const char *salt; { if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0) return __md5_crypt (key, salt); /* We don't have DES encryption. */ __set_errno (EOPNOTSUPP); return NULL; } trf2.1.4/md5-crypt/md5.c0000644000175000017500000003334111216343142014230 0ustar sergeisergei/* md5.c - Functions to compute MD5 message digest of files or memory blocks according to the definition of MD5 in RFC 1321 from April 1992. Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Written by Ulrich Drepper , 1995. */ #include #ifdef HAVE_CONFIG_H # include #endif #include #if STDC_HEADERS || defined _LIBC # include # include #else #ifdef WIN32 #define HAVE_MEMCPY #endif # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # endif #endif #include "transformInt.h" #include "md5.h" #ifdef _LIBC # include # if __BYTE_ORDER == __BIG_ENDIAN # define WORDS_BIGENDIAN 1 # endif /* We need to keep the namespace clean so define the MD5 function protected using leading __ and use weak aliases. */ # define md5_init_ctx __md5_init_ctx # define md5_process_block __md5_process_block # define md5_process_bytes __md5_process_bytes # define md5_finish_ctx __md5_finish_ctx # define md5_read_ctx __md5_read_ctx # define md5_stream __md5_stream # define md5_buffer __md5_buffer #endif #ifdef WORDS_BIGENDIAN # define SWAP(n) \ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #else # define SWAP(n) (n) #endif /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (RFC 1321, 3.1: Step 1) */ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; /* Initialize structure containing state of computation. (RFC 1321, 3.3: Step 3) */ void md5_init_ctx (ctx) struct md5_ctx *ctx; { ctx->A = 0x67452301; ctx->B = 0xefcdab89; ctx->C = 0x98badcfe; ctx->D = 0x10325476; ctx->total[0] = ctx->total[1] = 0; ctx->buflen = 0; } /* Put result from CTX in first 16 bytes following RESBUF. The result must be in little endian byte order. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ void * md5_read_ctx (ctx, resbuf) const struct md5_ctx *ctx; void *resbuf; { ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); return resbuf; } /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ void * md5_finish_ctx (ctx, resbuf) struct md5_ctx *ctx; void *resbuf; { /* Take yet unprocessed bytes into account. */ md5_uint32 bytes = ctx->buflen; size_t pad; /* Now count remaining bytes. */ ctx->total[0] += bytes; if (ctx->total[0] < bytes) ++ctx->total[1]; pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; memcpy (&ctx->buffer[bytes], fillbuf, pad); /* Put the 64-bit file length in *bits* at the end of the buffer. */ *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); /* Process last bytes. */ md5_process_block (ctx->buffer, bytes + pad + 8, ctx); return md5_read_ctx (ctx, resbuf); } /* Compute MD5 message digest for bytes read from STREAM. The resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. */ int md5_stream (stream, resblock) FILE *stream; void *resblock; { /* Important: BLOCKSIZE must be a multiple of 64. */ #define BLOCKSIZE 4096 struct md5_ctx ctx; char buffer[BLOCKSIZE + 72]; size_t sum; /* Initialize the computation context. */ md5_init_ctx (&ctx); /* Iterate over full file contents. */ while (1) { /* We read the file in blocks of BLOCKSIZE bytes. One call of the computation function processes the whole buffer so that with the next round of the loop another block can be read. */ size_t n; sum = 0; /* Read block. Take care for partial reads. */ do { n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); sum += n; } while (sum < BLOCKSIZE && n != 0); if (n == 0 && ferror (stream)) return 1; /* If end of file is reached, end the loop. */ if (n == 0) break; /* Process buffer with BLOCKSIZE bytes. Note that BLOCKSIZE % 64 == 0 */ md5_process_block (buffer, BLOCKSIZE, &ctx); } /* Add the last bytes if necessary. */ if (sum > 0) md5_process_bytes (buffer, sum, &ctx); /* Construct result in desired memory. */ md5_finish_ctx (&ctx, resblock); return 0; } /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ void * md5_buffer (buffer, len, resblock) const char *buffer; size_t len; void *resblock; { struct md5_ctx ctx; /* Initialize the computation context. */ md5_init_ctx (&ctx); /* Process whole buffer but last len % 64 bytes. */ md5_process_bytes (buffer, len, &ctx); /* Put result in desired memory area. */ return md5_finish_ctx (&ctx, resblock); } void md5_process_bytes (buffer, len, ctx) const void *buffer; size_t len; struct md5_ctx *ctx; { /* When we already have some bits in our internal buffer concatenate both inputs first. */ if (ctx->buflen != 0) { size_t left_over = ctx->buflen; size_t add = 128 - left_over > len ? len : 128 - left_over; memcpy (&ctx->buffer[left_over], buffer, add); ctx->buflen += add; if (left_over + add > 64) { md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); /* The regions in the following copy operation cannot overlap. */ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], (left_over + add) & 63); ctx->buflen = (left_over + add) & 63; } buffer = (const char *) buffer + add; len -= add; } /* Process misaligned blocks. */ while ((len > 64) && ((((unsigned int) buffer) & 3) != 0)) { memcpy(ctx->buffer, buffer, 64); md5_process_block(ctx->buffer, 64, ctx); buffer = (const char *) buffer + 64; len -= 64; } /* Process available complete blocks. */ if (len > 64) { md5_process_block (buffer, len & ~63, ctx); buffer = (const char *) buffer + (len & ~63); len &= 63; } /* Move remaining bytes in internal buffer. */ if (len > 0) { memcpy (ctx->buffer, buffer, len); ctx->buflen = len; } } /* These are the four functions used in the four steps of the MD5 algorithm and defined in the RFC 1321. The first function is a little bit optimized (as found in Colin Plumbs public domain implementation). */ /* #define FF(b, c, d) ((b & c) | (~b & d)) */ #define FF(b, c, d) (d ^ (b & (c ^ d))) #define FG(b, c, d) FF (d, b, c) #define FH(b, c, d) (b ^ c ^ d) #define FI(b, c, d) (c ^ (b | ~d)) /* Process LEN bytes of BUFFER, accumulating context into CTX. It is assumed that LEN % 64 == 0. */ void md5_process_block (buffer, len, ctx) const void *buffer; size_t len; struct md5_ctx *ctx; { md5_uint32 correct_words[16]; const md5_uint32 *words = buffer; size_t nwords = len / sizeof (md5_uint32); const md5_uint32 *endp = words + nwords; md5_uint32 A = ctx->A; md5_uint32 B = ctx->B; md5_uint32 C = ctx->C; md5_uint32 D = ctx->D; /* First increment the byte count. RFC 1321 specifies the possible length of the file up to 2^64 bits. Here we only compute the number of bytes. Do a double word increment. */ ctx->total[0] += len; if (ctx->total[0] < len) ++ctx->total[1]; /* Process all bytes in the buffer with 64 bytes in each round of the loop. */ while (words < endp) { md5_uint32 *cwp = correct_words; md5_uint32 A_save = A; md5_uint32 B_save = B; md5_uint32 C_save = C; md5_uint32 D_save = D; /* First round: using the given function, the context and a constant the next context is computed. Because the algorithms processing unit is a 32-bit word and it is determined to work on words in little endian byte order we perhaps have to change the byte order before the computation. To reduce the work for the next steps we store the swapped words in the array CORRECT_WORDS. */ #define OP(a, b, c, d, s, T) \ do \ { \ a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ ++words; \ CYCLIC (a, s); \ a += b; \ } \ while (0) /* It is unfortunate that C does not provide an operator for cyclic rotation. Hope the C compiler is smart enough. */ #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) /* Before we start, one word to the strange constants. They are defined in RFC 1321 as T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 */ /* Round 1. */ OP (A, B, C, D, 7, 0xd76aa478); OP (D, A, B, C, 12, 0xe8c7b756); OP (C, D, A, B, 17, 0x242070db); OP (B, C, D, A, 22, 0xc1bdceee); OP (A, B, C, D, 7, 0xf57c0faf); OP (D, A, B, C, 12, 0x4787c62a); OP (C, D, A, B, 17, 0xa8304613); OP (B, C, D, A, 22, 0xfd469501); OP (A, B, C, D, 7, 0x698098d8); OP (D, A, B, C, 12, 0x8b44f7af); OP (C, D, A, B, 17, 0xffff5bb1); OP (B, C, D, A, 22, 0x895cd7be); OP (A, B, C, D, 7, 0x6b901122); OP (D, A, B, C, 12, 0xfd987193); OP (C, D, A, B, 17, 0xa679438e); OP (B, C, D, A, 22, 0x49b40821); /* For the second to fourth round we have the possibly swapped words in CORRECT_WORDS. Redefine the macro to take an additional first argument specifying the function to use. */ #undef OP #define OP(f, a, b, c, d, k, s, T) \ do \ { \ a += f (b, c, d) + correct_words[k] + T; \ CYCLIC (a, s); \ a += b; \ } \ while (0) /* Round 2. */ OP (FG, A, B, C, D, 1, 5, 0xf61e2562); OP (FG, D, A, B, C, 6, 9, 0xc040b340); OP (FG, C, D, A, B, 11, 14, 0x265e5a51); OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); OP (FG, A, B, C, D, 5, 5, 0xd62f105d); OP (FG, D, A, B, C, 10, 9, 0x02441453); OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); OP (FG, D, A, B, C, 14, 9, 0xc33707d6); OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); OP (FG, B, C, D, A, 8, 20, 0x455a14ed); OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); OP (FG, C, D, A, B, 7, 14, 0x676f02d9); OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); /* Round 3. */ OP (FH, A, B, C, D, 5, 4, 0xfffa3942); OP (FH, D, A, B, C, 8, 11, 0x8771f681); OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); OP (FH, B, C, D, A, 14, 23, 0xfde5380c); OP (FH, A, B, C, D, 1, 4, 0xa4beea44); OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); OP (FH, B, C, D, A, 6, 23, 0x04881d05); OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); /* Round 4. */ OP (FI, A, B, C, D, 0, 6, 0xf4292244); OP (FI, D, A, B, C, 7, 10, 0x432aff97); OP (FI, C, D, A, B, 14, 15, 0xab9423a7); OP (FI, B, C, D, A, 5, 21, 0xfc93a039); OP (FI, A, B, C, D, 12, 6, 0x655b59c3); OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); OP (FI, C, D, A, B, 10, 15, 0xffeff47d); OP (FI, B, C, D, A, 1, 21, 0x85845dd1); OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); OP (FI, C, D, A, B, 6, 15, 0xa3014314); OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); OP (FI, A, B, C, D, 4, 6, 0xf7537e82); OP (FI, D, A, B, C, 11, 10, 0xbd3af235); OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); OP (FI, B, C, D, A, 9, 21, 0xeb86d391); /* Add the starting values of the context. */ A += A_save; B += B_save; C += C_save; D += D_save; } /* Put checksum in context given as argument. */ ctx->A = A; ctx->B = B; ctx->C = C; ctx->D = D; } #ifdef _LIBC /* Define weak aliases. */ # undef md5_init_ctx weak_alias (__md5_init_ctx, md5_init_ctx) # undef md5_process_block weak_alias (__md5_process_block, md5_process_block) # undef md5_process_bytes weak_alias (__md5_process_bytes, md5_process_bytes) # undef md5_finish_ctx weak_alias (__md5_finish_ctx, md5_finish_ctx) # undef md5_read_ctx weak_alias (__md5_read_ctx, md5_read_ctx) # undef md5_stream weak_alias (__md5_stream, md5_stream) # undef md5_buffer weak_alias (__md5_buffer, md5_buffer) #endif trf2.1.4/md5-crypt/trf_crypt.h0000644000175000017500000000334611216343142015566 0ustar sergeisergei/* * UFC-crypt: ultra fast crypt(3) implementation * * Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the GNU C Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * @(#)crypt.h 1.3 16 Sep 1996 * */ #ifndef _CRYPT_H #define _CRYPT_H 1 #include /* Encrypt at most 8 characters from KEY using salt to perturb DES. */ extern char *crypt _ANSI_ARGS_ ((CONST char *__key, CONST char *__salt)); /* Reentrant versions of the functions above. The additional argument points to a structure where the results are placed in. */ struct crypt_data { char keysched[16 * 8]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; /* end-of-alignment-critical-data */ char crypt_3_buf[14]; char current_salt[2]; long int current_saltbits; int direction; int initialized; }; #ifdef __USE_GNU extern char *crypt_r _ANSI_ARGS_ ((CONST char *__key, CONST char *__salt, struct crypt_data * __data)); #endif #endif /* crypt.h */ trf2.1.4/md5-crypt/md5c-test.c0000644000175000017500000000050311216343142015342 0ustar sergeisergei#include "trf_crypt.h" #include int main (int argc, char *argv[]) { const char salt[] = "$1$saltstring"; char *cp; int result = 0; cp = crypt ("Hello world!", salt); result |= strcmp ("$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1", cp); printf("md5c-test %s\n", result?"failed":"passed"); return result; } trf2.1.4/md5-crypt/COPYING.LIB0000644000175000017500000006427111216343142015045 0ustar sergeisergeiGNU LIBRARY GENERAL PUBLIC LICENSE ********************************** Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble ======== The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a. The modified work must itself be a software library. b. You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c. You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d. If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a. Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b. Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c. If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d. Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a. Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b. Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries ============================================== If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES. Copyright (C) YEAR NAME OF AUTHOR This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. SIGNATURE OF TY COON, 1 April 1990 Ty Coon, President of Vice That's all there is to it! trf2.1.4/md5-crypt/md5test.c0000644000175000017500000000254011216343142015125 0ustar sergeisergei#include #include "md5.h" static const struct { const char *input; const char result[16]; } tests[] = { { "", "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e" }, { "a", "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61" }, { "abc", "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72" }, { "message digest", "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0" }, { "abcdefghijklmnopqrstuvwxyz", "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00\x7d\xfb\x49\x6c\xca\x67\xe1\x3b" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f" }, { "123456789012345678901234567890123456789012345678901234567890" "12345678901234567890", "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6\x7a" } }; int main (int argc, char *argv[]) { struct md5_ctx ctx; char sum[16]; int result = 0; int cnt; for (cnt = 0; cnt < (int) (sizeof (tests) / sizeof (tests[0])); ++cnt) { md5_init_ctx (&ctx); md5_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx); md5_finish_ctx (&ctx, sum); result |= memcmp (tests[cnt].result, sum, 16); } printf("md5test %s\n", result?"failed":"passed"); return result; } trf2.1.4/md5-crypt/md5-crypt.c0000644000175000017500000001662011216343142015370 0ustar sergeisergei/* One way encryption based on MD5 sum. Copyright (C) 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #ifndef WIN32 #include #endif #include "md5.h" #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef __set_errno # define __set_errno(val) errno = (val) #endif # define __md5_crypt_r md5_crypt_r # define __md5_crypt md5_crypt # define __stpncpy stpncpy # define __set_errno(val) errno = (val) char * __stpncpy _ANSI_ARGS_((char *dest, const char *src, size_t n)); /* Define our magic string to mark salt for MD5 "encryption" replacement. This is meant to be the same as for other MD5 based encryption implementations. */ static const char md5_salt_prefix[] = "$1$"; /* Table with characters for base64 transformation. */ static const char b64t[64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; /* Prototypes for local functions. */ extern char *__md5_crypt_r _ANSI_ARGS_ ((const char *key, const char *salt, char *buffer, int buflen)); extern char *__md5_crypt _ANSI_ARGS_ ((const char *key, const char *salt)); /* This entry point is equivalent to the `crypt' function in Unix libcs. */ char * __md5_crypt_r (key, salt, buffer, buflen) const char *key; const char *salt; char *buffer; int buflen; { unsigned char alt_result[16]; struct md5_ctx ctx; struct md5_ctx alt_ctx; size_t salt_len; size_t key_len; size_t cnt; char *cp; /* Find beginning of salt string. The prefix should normally always be present. Just in case it is not. */ if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0) /* Skip salt prefix. */ salt += sizeof (md5_salt_prefix) - 1; salt_len = MIN (strcspn (salt, "$"), 8); key_len = strlen (key); /* Prepare for the real work. */ md5_init_ctx (&ctx); /* Add the key string. */ md5_process_bytes (key, key_len, &ctx); /* Because the SALT argument need not always have the salt prefix we add it separately. */ md5_process_bytes (md5_salt_prefix, sizeof (md5_salt_prefix) - 1, &ctx); /* The last part is the salt string. This must be at most 8 characters and it ends at the first `$' character (for compatibility which existing solutions). */ md5_process_bytes (salt, salt_len, &ctx); /* Compute alternate MD5 sum with input KEY, SALT, and KEY. The final result will be added to the first context. */ md5_init_ctx (&alt_ctx); /* Add key. */ md5_process_bytes (key, key_len, &alt_ctx); /* Add salt. */ md5_process_bytes (salt, salt_len, &alt_ctx); /* Add key again. */ md5_process_bytes (key, key_len, &alt_ctx); /* Now get result of this (16 bytes) and add it to the other context. */ md5_finish_ctx (&alt_ctx, alt_result); /* Add for any character in the key one byte of the alternate sum. */ for (cnt = key_len; cnt > 16; cnt -= 16) md5_process_bytes (alt_result, 16, &ctx); md5_process_bytes (alt_result, cnt, &ctx); /* For the following code we need a NUL byte. */ *alt_result = '\0'; /* The original implementation now does something weird: for every 1 bit in the key the first 0 is added to the buffer, for every 0 bit the first character of the key. This does not seem to be what was intended but we have to follow this to be compatible. */ for (cnt = key_len; cnt > 0; cnt >>= 1) md5_process_bytes ((cnt & 1) != 0 ? (const char *) alt_result : key, 1, &ctx); /* Create intermediate result. */ md5_finish_ctx (&ctx, alt_result); /* Now comes another weirdness. In fear of password crackers here comes a quite long loop which just processes the output of the previous round again. We cannot ignore this here. */ for (cnt = 0; cnt < 1000; ++cnt) { /* New context. */ md5_init_ctx (&ctx); /* Add key or last result. */ if ((cnt & 1) != 0) md5_process_bytes (key, key_len, &ctx); else md5_process_bytes (alt_result, 16, &ctx); /* Add salt for numbers not divisible by 3. */ if (cnt % 3 != 0) md5_process_bytes (salt, salt_len, &ctx); /* Add key for numbers not divisible by 7. */ if (cnt % 7 != 0) md5_process_bytes (key, key_len, &ctx); /* Add key or last result. */ if ((cnt & 1) != 0) md5_process_bytes (alt_result, 16, &ctx); else md5_process_bytes (key, key_len, &ctx); /* Create intermediate result. */ md5_finish_ctx (&ctx, alt_result); } /* Now we can construct the result string. It consists of three parts. */ cp = __stpncpy (buffer, md5_salt_prefix, MAX (0, buflen)); buflen -= sizeof (md5_salt_prefix); cp = __stpncpy (cp, salt, MIN ((size_t) buflen, salt_len)); buflen -= MIN ((size_t) buflen, salt_len); if (buflen > 0) { *cp++ = '$'; --buflen; } #define b64_from_24bit(B2, B1, B0, N) \ do { \ unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \ int n = (N); \ while (n-- > 0 && buflen > 0) \ { \ *cp++ = b64t[w & 0x3f]; \ --buflen; \ w >>= 6; \ } \ } while (0) b64_from_24bit (alt_result[0], alt_result[6], alt_result[12], 4); b64_from_24bit (alt_result[1], alt_result[7], alt_result[13], 4); b64_from_24bit (alt_result[2], alt_result[8], alt_result[14], 4); b64_from_24bit (alt_result[3], alt_result[9], alt_result[15], 4); b64_from_24bit (alt_result[4], alt_result[10], alt_result[5], 4); b64_from_24bit (0, 0, alt_result[11], 2); if (buflen <= 0) { __set_errno (ERANGE); buffer = NULL; } else *cp = '\0'; /* Terminate the string. */ /* Clear the buffer for the intermediate result so that people attaching to processes or reading core dumps cannot get any information. */ memset (alt_result, '\0', sizeof (alt_result)); return buffer; } char * __md5_crypt (key, salt) const char *key; const char *salt; { /* We don't want to have an arbitrary limit in the size of the password. We can compute the size of the result in advance and so we can prepare the buffer we pass to `md5_crypt_r'. */ static char *buffer = NULL; static int buflen = 0; int needed = 3 + strlen (salt) + 1 + 26 + 1; if (buflen < needed) { buflen = needed; if ((buffer = realloc (buffer, buflen)) == NULL) return NULL; } return __md5_crypt_r (key, salt, buffer, buflen); } trf2.1.4/md5-crypt/md5.h0000644000175000017500000001265211216343142014237 0ustar sergeisergei/* Declaration of functions and data types used for MD5 sum computing library functions. Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _MD5_H #define _MD5_H 1 #include #if defined HAVE_LIMITS_H || _LIBC # include #endif /* The following contortions are an attempt to use the C preprocessor to determine an unsigned integral type that is 32 bits wide. An alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but doing that would require that the configure script compile and *run* the resulting executable. Locally running cross-compiled executables is usually not possible. */ #ifdef _LIBC # include typedef u_int32_t md5_uint32; #else # if defined __STDC__ && __STDC__ # define UINT_MAX_32_BITS 4294967295U # else # define UINT_MAX_32_BITS 0xFFFFFFFF # endif /* If UINT_MAX isn't defined, assume it's a 32-bit type. This should be valid for all systems GNU cares about because that doesn't include 16-bit systems, and only modern systems (that certainly have ) have 64+-bit integral types. */ # ifndef UINT_MAX # define UINT_MAX UINT_MAX_32_BITS # endif # if UINT_MAX == UINT_MAX_32_BITS typedef unsigned int md5_uint32; # else # if USHRT_MAX == UINT_MAX_32_BITS typedef unsigned short md5_uint32; # else # if ULONG_MAX == UINT_MAX_32_BITS typedef unsigned long md5_uint32; # else /* The following line is intended to evoke an error. Using #error is not portable enough. */ "Cannot determine unsigned 32-bit data type." # endif # endif # endif #endif #undef __P #if defined (__STDC__) && __STDC__ # define __P(x) x #else # define __P(x) () #endif /* Structure to save state of computation between the single steps. */ struct md5_ctx { md5_uint32 A; md5_uint32 B; md5_uint32 C; md5_uint32 D; md5_uint32 total[2]; md5_uint32 buflen; char buffer[128]; }; /* * The following three functions are build up the low level used in * the functions `md5_stream' and `md5_buffer'. */ /* Initialize structure containing state of computation. (RFC 1321, 3.3: Step 3) */ extern void __md5_init_ctx __P ((struct md5_ctx *ctx)); extern void md5_init_ctx __P ((struct md5_ctx *ctx)); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 64!!! */ extern void __md5_process_block __P ((const void *buffer, size_t len, struct md5_ctx *ctx)); extern void md5_process_block __P ((const void *buffer, size_t len, struct md5_ctx *ctx)); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 64. */ extern void __md5_process_bytes __P ((const void *buffer, size_t len, struct md5_ctx *ctx)); extern void md5_process_bytes __P ((const void *buffer, size_t len, struct md5_ctx *ctx)); /* Process the remaining bytes in the buffer and put result from CTX in first 16 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ extern void *__md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); /* Put result from CTX in first 16 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ extern void *__md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf)); extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf)); /* Compute MD5 message digest for bytes read from STREAM. The resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. */ extern int __md5_stream __P ((FILE *stream, void *resblock)); /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ extern void *__md5_buffer __P ((const char *buffer, size_t len, void *resblock)); extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); #endif /* md5.h */ trf2.1.4/mac/0000755000175000017500000000000011216344734012317 5ustar sergeisergeitrf2.1.4/mac/README0000644000175000017500000000074711216344223013200 0ustar sergeisergei Tcl Data transformations (Tcl-Trf) (Version 2.1.4 / MAY-06-2009) Andreas Kupries (andreas_kupries@users.sourceforge.net) This is the README file for the Macintosh version of the Tcl-Trf package. I don't have a Mac, nor do I have access one. Because of this I am unable to provide a Mac port of this extension. I will most happily integrate any required changes, makefiles, et cetera into the distribution, if they are send to me (andreas_kupries@users.sourceforge.net). trf2.1.4/teapot.txt0000644000175000017500000000127111216343142013605 0ustar sergeisergeiPackage Trf 2.1.4 Meta platform source Meta summary Channel transformations Meta description This package provides a number of channel Meta description transformations, mainly various encodings, and Meta description cryptographic hashes. Beyond that it also provides Meta description (de_compression and error-correcting coding. It does Meta description not provide any type of encryption however. Meta subject channel encoding compression hashes transformation Meta subject error-correction ecc reed-solomon Meta category Channel Meta require {Tcl -require 8.4} Meta as::origin http://sourceforge.net/projects/tcltrf Meta as::author {Andreas Kupries} Meta license BSD trf2.1.4/generic/0000755000175000017500000000000012034467745013202 5ustar sergeisergeitrf2.1.4/generic/qpcode.c0000644000175000017500000005161311216344223014611 0ustar sergeisergei/* * qpcode.c -- * * Implements and registers conversion from and to quoted-printable representation. * * * Copyright (c) 1999 Marshall Rose (mrose@dbc.mtview.ca.us) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: qpcode.c,v 1.7 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include #include "transformInt.h" /* * Converter description * --------------------- * * Reference: * RFC 2045 * * Encoding: * Printable characters (other than "=") are passed through; otherwise a * character is represented by "=" followed by the two-digit hexadecimal * representation of the character's value. Ditto for trailing whitespace * at the end of a line. * * Decoding: * Invert the above. */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "quoted-printable", NULL, /* clientData not used by conversions. */ NULL, /* set later by TrfInit_QP */ /* THREADING: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_UNSEEKABLE }; /* * Definition of the control blocks for en- and decoder. */ #define CPERLIN 76 /* according to RFC 2045 */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (qp encode) */ int charCount; unsigned char buf[CPERLIN + 8]; /* DNew@Invisible.Net added the +8 or FlushEncoder runs off the end when called from the first call point in Encode with a too-long line. */ } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (qp decode) */ int quoted; unsigned char mask; } DecoderControl; static char hex2nib[0x80] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* *------------------------------------------------------* * * TrfInit_QP -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_QP (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (qp encode) */ ClearEncoder ((Trf_ControlBlock) c, clientData); return ((ClientData) c); } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (qp encode) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (qp encode) */ int i; char x = character & 0xff; /*in case we need to indicate trailing whitespace... */ if ((c -> charCount >= CPERLIN - 1) && ((x != '\n') || (c -> buf[c -> charCount -1] != '\r')) && ((i = FlushEncoder (ctrlBlock, interp, clientData)) != TCL_OK)) return i; /* avoid common problems in old software... */ switch (c -> charCount) { case 1: if (c -> buf[0] == '.') { (void) sprintf ((char*) c -> buf, "=%02X", '.'); c -> charCount = 3; } break; case 5: if (!strcmp ((char*) c -> buf, "From ")) { (void) sprintf ((char*) c -> buf, "=%02Xrom ", 'F'); c -> charCount = 7; } break; } switch (x) { case '\n': if ((c -> charCount > 0) && (c -> buf[c -> charCount - 1] == '\r')) c -> charCount--; /* and fall... */ case ' ': case '\t': case '\r': c -> buf[c -> charCount++] = character; break; default: if (('!' <= x) && (x <= '~')) { c -> buf[c -> charCount++] = character; break; } /* else fall... */ case '=': (void) sprintf ((char*) c -> buf + c -> charCount, "=%02X", (unsigned char) x); c -> charCount += 3; break; } if ((x == '\n') && ((i = FlushEncoder (ctrlBlock, interp, clientData)) != TCL_OK)) return i; return TCL_OK; } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { /* EncoderControl* c = (EncoderControl*) ctrlBlock; unused */ /* execute conversion specific code here (qp encode) */ int i = TCL_OK; while (bufLen-- > 0) { if ((i = Encode (ctrlBlock, *buffer++ & 0xff, interp, clientData)) != TCL_OK) break; } return i; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (qp encode) */ int i; if (c -> charCount == 0) return TCL_OK; if (c -> buf[c -> charCount - 1] == '\n') { if (c -> charCount > 1) switch (c -> buf[c -> charCount - 2]) { case ' ': case '\t': (void) strcpy ((char*) c -> buf + c -> charCount - 1, "=\n\n"); c -> charCount += 2; break; default: break; } } else { (void) strcpy ((char*) c -> buf + c -> charCount, "=\n"); c -> charCount += 2; } if ((i = c -> write (c -> writeClientData, c -> buf, c -> charCount, interp)) != TCL_OK) return i; ClearEncoder (ctrlBlock, clientData); return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (qp encode) */ c -> charCount = 0; memset (c -> buf, '\0', sizeof c -> buf); } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (qp decode) */ ClearDecoder ((Trf_ControlBlock) c, clientData); return ((ClientData) c); } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (qp decode) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (qp decode) */ int i; char x = character & 0xff; switch (c -> quoted) { case 0: switch (x) { default: if ((x < '!') || ('~' < x)) goto invalid_encoding; /* else fall... */ case ' ': case '\t': case '\n': i = c -> write (c -> writeClientData, (unsigned char*) &x, 1, interp); break; case '\r': i = TCL_OK; break; case '=': c -> quoted = 1; i = TCL_OK; break; } break; case 1: switch (x) { case '\n': c -> quoted = 0; i = TCL_OK; break; case '\r': i = TCL_OK; break; default: if (!isxdigit (x)) goto invalid_hex; c -> mask = hex2nib[x & 0x7f]; c -> quoted = 2; i = TCL_OK; break; } break; default: if (!isxdigit (x)) goto invalid_hex; c -> mask <<= 4; c -> mask |= hex2nib[x & 0x7f]; c -> quoted = 0; i = c -> write (c -> writeClientData, &c -> mask, 1, interp); break; } return i; invalid_hex: ; if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "expecting hexadecimal digit", (char *) NULL); } return TCL_ERROR; invalid_encoding: ; if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "expecting character in range [!..~]", (char *) NULL); } return TCL_ERROR; } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { /* DecoderControl* c = (DecoderControl*) ctrlBlock; unused */ /* execute conversion specific code here (qp decode) */ int i = TCL_OK; while (bufLen-- > 0) { if ((i = Decode (ctrlBlock, *buffer++ & 0xff, interp, clientData)) != TCL_OK) break; } return i; } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (qp decode) */ if (c -> quoted) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, c -> quoted > 1 ? "expecting another hexadecimal digit" : "expecting addition characters", (char *) NULL); } return TCL_ERROR; } ClearDecoder (ctrlBlock, clientData); return TCL_OK; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (qp decode) */ c -> quoted = 0; c -> mask = 0; } trf2.1.4/generic/md5dig.c0000644000175000017500000001574311216344223014513 0ustar sergeisergei/* * md5.c -- * * Implements and registers message digest generator MD5. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: md5dig.c,v 1.5 2008/12/11 19:04:25 andreas_kupries Exp $ */ #include "loadman.h" /* * Generator description * --------------------- * * The MD5 alogrithm is used to compute a cryptographically strong * message digest. */ #define MD5_CTXP (MD5_CTX*) #ifndef OTP #define DIGEST_SIZE (16) #else #define DIGEST_SIZE (8) #endif #define CTX_TYPE MD5_CTX /* * Declarations of internal procedures. */ static void MDmd5_Start _ANSI_ARGS_ ((VOID* context)); static void MDmd5_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDmd5_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDmd5_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); static int MDmd5_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ #ifndef OTP "md5", #else "otp_md5", #endif sizeof (CTX_TYPE), DIGEST_SIZE, MDmd5_Start, MDmd5_Update, MDmd5_UpdateBuf, MDmd5_Final, MDmd5_Check }; /* *------------------------------------------------------* * * TrfInit_MD5 -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int #ifndef OTP TrfInit_MD5 (interp) #else TrfInit_OTP_MD5 (interp) #endif Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDmd5_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDmd5_Start (context) VOID* context; { /* MD5Init ((MD5_CTX*) context);*/ md5f.init (MD5_CTXP context); #ifdef TRF_DEBUG { MD5_CTX* c = MD5_CTXP context; PRINT ("Init ABCD = %d %d %d %d\n", c->A, c->B, c->C, c->D); FL; } #endif } /* *------------------------------------------------------* * * MDmd5_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDmd5_Update (context, character) VOID* context; unsigned int character; { unsigned char buf = character; /* MD5Update ((MD5_CTX*) context, &buf, 1); */ md5f.update (MD5_CTXP context, &buf, 1); } /* *------------------------------------------------------* * * MDmd5_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDmd5_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { /* MD5Update ((MD5_CTX*) context, (unsigned char*) buffer, bufLen);*/ PRTSTR ("update by %d (%s)\n", bufLen, buffer); #ifdef TRF_DEBUG { MD5_CTX* c = MD5_CTXP context; PRINT ("Upd1 ABCD = %d %d %d %d\n", c->A, c->B, c->C, c->D); FL; } #endif md5f.update (MD5_CTXP context, (unsigned char*) buffer, bufLen); #ifdef TRF_DEBUG { MD5_CTX* c = MD5_CTXP context; PRINT ("Upd2 ABCD = %d %d %d %d\n", c->A, c->B, c->C, c->D); FL; } #endif } /* *------------------------------------------------------* * * MDmd5_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDmd5_Final (context, digest) VOID* context; VOID* digest; { #ifndef OTP /* MD5Final ((unsigned char*) digest, (MD5_CTX*) context); */ md5f.final ((unsigned char*) digest, MD5_CTXP context); #else int i; unsigned char result[16]; /* MD5Final ((unsigned char*) result, (MD5_CTX*) context);*/ md5f.final ((unsigned char*) result, MD5_CTXP context); for (i = 0; i < 8; i++) result[i] ^= result[i + 8]; memcpy ((VOID *) digest, (VOID *) result, DIGEST_SIZE); #endif #ifdef TRF_DEBUG { MD5_CTX* c = MD5_CTXP context; PRINT ("Flsh ABCD = %d %d %d %d\n", c->A, c->B, c->C, c->D); FL; } #endif } /* *------------------------------------------------------* * * MDmd5_Check -- * * ------------------------------------------------* * Do global one-time initializations of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * Loads the shared library containing the * SHA1 functionality * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int MDmd5_Check (interp) Tcl_Interp* interp; { return TrfLoadMD5 (interp); #ifdef MD5_STATIC_BUILD /*return TCL_OK;*/ #else #endif } #if 0 /* Import the MD5 code in case of static linkage. */ #ifdef MD5_STATIC_BUILD /* * External code from here on. */ #ifndef OTP #include "../md5-crypt/md5.c" /* THREADING: import of one constant var, read-only => safe */ #endif md5Functions md5f = { 0, md5_init_ctx, md5_process_bytes, md5_finish_ctx, 0, /* no crypt code! */ }; #endif #endif trf2.1.4/generic/transformInt.h0000644000175000017500000005234511216344305016035 0ustar sergeisergei#ifndef TRF_INT_H #define TRF_INT_H /* -*- c -*- * transformInt.h - internal definitions * * Copyright (C) 1996, 1997 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: transformInt.h,v 1.45 2008/12/11 19:04:25 andreas_kupries Exp $ */ #ifdef __cplusplus extern "C" { #endif #include "transform.h" #include #include #include #ifndef ___MAKEDEPEND___ /* * Hide external references during runs of 'makedepend'. * It may fail on some systems, if the files are not installed. */ #ifdef MAC_TCL #include "compat:dlfcn.h" #include "compat:zlib.h" #include "compat:bzlib.h" #else #ifdef HAVE_DLFCN_H # include #else # include "../compat/dlfcn.h" #endif #ifdef HAVE_zlibtcl_PACKAGE # include "zlibtcl.h" #else # ifdef HAVE_ZLIB_H # include # else # include "../compat/zlib.h" # endif #endif #endif #ifdef HAVE_BZ2_H # include #else # include "../compat/bzlib.h" #endif #ifdef HAVE_STDLIB_H # include #else # include "../compat/stdlib.h" #endif #endif /* * Ensure WORDS_BIGENDIAN is defined correcly: * Needs to happen here in addition to configure to work with fat compiles on * Darwin (where configure runs only once for multiple architectures). */ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef BYTE_ORDER # ifdef BIG_ENDIAN # if BYTE_ORDER == BIG_ENDIAN # undef WORDS_BIGENDIAN # define WORDS_BIGENDIAN 1 # endif # endif # ifdef LITTLE_ENDIAN # if BYTE_ORDER == LITTLE_ENDIAN # undef WORDS_BIGENDIAN # endif # endif #endif #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_Trf # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #endif /* 04/13/1999 Fileevent patch from Matt Newman * Normally defined in tcl*Port.h */ #ifndef EWOULDBLOCK #define EWOULDBLOCK EAGAIN #endif /* Debugging definitions. */ #ifdef _WIN32 #undef TRF_DEBUG #endif #ifdef TRF_DEBUG extern int n; #define BLNKS {int i; for (i=0;i= 8.1 * Required as there are incompatibilities between 8.0 and 8.1 */ #define GT81 ((TCL_MAJOR_VERSION > 8) || \ ((TCL_MAJOR_VERSION == 8) && \ (TCL_MINOR_VERSION >= 1))) /* Define macro which is TRUE for tcl versions >= 8.3.2 */ #define GT832 ((TCL_MAJOR_VERSION > 8) || \ ((TCL_MAJOR_VERSION == 8) && \ ((TCL_MINOR_VERSION > 3) || \ ((TCL_MINOR_VERSION == 3) && \ (TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE) && \ (TCL_RELEASE_SERIAL >= 2))))) #if ! (GT81) /* * Tcl version 8.0.x don't export their 'panic' procedure. Here we * define the necessary interface and map it to the name exported and * used by the higher versions. */ EXTERN void panic _ANSI_ARGS_ (TCL_VARARGS(CONST char*, format)); #undef Tcl_Panic #define Tcl_Panic panic #endif /* * A single structure of the type below is created and maintained for * every interpreter. Beyond the table of registered transformers it * contains version information about the interpreter used to switch * runtime behaviour. */ typedef struct _Trf_Registry_ { Tcl_HashTable* registry; /* Table containing all registered * transformers. */ #ifdef USE_TCL_STUBS int patchVariant; /* Defined only for versions of Tcl * supporting stubs, and thus enable * the extension to switch its * runtime behaviour depending on the * version of the core loading * it. The possible values are * defined below. This information is * propagated into the state of * running transformers as well. */ #endif } Trf_Registry; #ifdef USE_TCL_STUBS #define PATCH_ORIG (0) /* Patch as used in 8.0.x and 8.1.x */ #define PATCH_82 (1) /* Patch as included into 8.2. Valid till 8.3.1 */ #define PATCH_832 (2) /* Patch as rewritten for 8.3.2 and beyond */ #endif /* * A structure of the type below is created and maintained * for every registered transformer (and every interpreter). */ typedef struct _Trf_RegistryEntry_ { Trf_Registry* registry; /* Backpointer to the registry */ Trf_TypeDefinition* trfType; /* reference to transformer specification */ Tcl_ChannelType* transType; /* reference to derived channel type * specification */ Tcl_Command trfCommand; /* command associated to the transformer */ Tcl_Interp* interp; /* interpreter the command is registered * in. */ } Trf_RegistryEntry; /* * Procedures to access the registry of transformers for a specified * interpreter. The registry is a hashtable mapping from transformer * names to structures of type 'Trf_RegistryEntry' (see above). */ EXTERN Trf_Registry* TrfGetRegistry _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN Trf_Registry* TrfPeekForRegistry _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int Trf_Unregister _ANSI_ARGS_ ((Tcl_Interp* interp, Trf_RegistryEntry* entry)); /* * Procedures used by 3->4 encoders (uu, base64). */ EXTERN void TrfSplit3to4 _ANSI_ARGS_ ((CONST unsigned char* in, unsigned char* out, int length)); EXTERN void TrfMerge4to3 _ANSI_ARGS_ ((CONST unsigned char* in, unsigned char* out)); EXTERN void TrfApplyEncoding _ANSI_ARGS_ ((unsigned char* buf, int length, CONST char* map)); EXTERN int TrfReverseEncoding _ANSI_ARGS_ ((unsigned char* buf, int length, CONST char* reverseMap, unsigned int padChar, int* hasPadding)); /* * Definition of option information for message digests and accessor * to set of vectors processing these. */ typedef struct _TrfMDOptionBlock { int behaviour; /* IMMEDIATE vs. ATTACH, got from checkProc */ int mode; /* what to to with the generated hashvalue */ char* readDestination; /* Name of channel (or global variable) * to write the hash of read data to * (mode = TRF_WRITE_HASH / ..TRANSPARENT) */ char* writeDestination; /* Name of channel (or global variable) * to write the hash of written data to * (mode = TRF_WRITE_HASH / ..TRANSPARENT) */ int rdIsChannel; /* typeflag for 'readDestination', true for a channel */ int wdIsChannel; /* typeflag for 'writeDestination', true for a channel */ char* matchFlag; /* Name of global variable to write the match- * result into (TRF_ABSORB_HASH) */ Tcl_Interp* vInterp; /* Interpreter containing the variable named in * 'matchFlag', or '*Destination'. */ /* derived information */ Tcl_Channel rdChannel; /* Channel associated to 'readDestination' */ Tcl_Channel wdChannel; /* Channel associated to 'writeDestination' */ } TrfMDOptionBlock; #define TRF_IMMEDIATE (1) #define TRF_ATTACH (2) #define TRF_ABSORB_HASH (1) #define TRF_WRITE_HASH (2) #define TRF_TRANSPARENT (3) EXTERN Trf_OptionVectors* TrfMDOptions _ANSI_ARGS_ ((void)); /* * Definition of option information for general transformation (reflect.c, ref_opt.c) * to set of vectors processing these. */ typedef struct _TrfTransformOptionBlock { int mode; /* operation to execute (transform for read or write) */ #if (TCL_MAJOR_VERSION >= 8) Tcl_Obj* command; /* tcl code to execute for a buffer */ #else unsigned char* command; /* tcl code to execute for a buffer */ #endif } TrfTransformOptionBlock; /*#define TRF_UNKNOWN_MODE (0) -- transform.h */ #define TRF_WRITE_MODE (1) #define TRF_READ_MODE (2) EXTERN Trf_OptionVectors* TrfTransformOptions _ANSI_ARGS_ ((void)); /* * Definition of option information for ZIP compressor * + accessor to set of vectors processing them */ typedef struct _TrfZipOptionBlock { int mode; /* compressor mode: compress/decompress */ int level; /* compression level (1..9, -1 = default) */ int nowrap; /* pkzip-compatibility (0..1, 0 = default) */ } TrfZipOptionBlock; EXTERN Trf_OptionVectors* TrfZIPOptions _ANSI_ARGS_ ((void)); /* * Definition of option information for BZ2 compressor * + accessor to set of vectors processing them */ typedef struct _TrfBz2OptionBlock { int mode; /* compressor mode: compress/decompress */ int level; /* compression level (1..9, 9 = default) */ } TrfBz2OptionBlock; EXTERN Trf_OptionVectors* TrfBZ2Options _ANSI_ARGS_ ((void)); #define TRF_COMPRESS (1) #define TRF_DECOMPRESS (2) #define TRF_MIN_LEVEL (1) #define TRF_MAX_LEVEL (9) #define TRF_DEFAULT_LEVEL (-1) #define TRF_MIN_LEVEL_STR "1" #define TRF_MAX_LEVEL_STR "9" #ifndef WINAPI #define WINAPI #endif #ifdef ZLIB_STATIC_BUILD #undef ZEXPORT #define ZEXPORT #else #undef ZEXPORT #define ZEXPORT WINAPI #endif #ifdef HAVE_zlibtcl_PACKAGE #undef ZEXPORT #define ZEXPORT #endif /* * 'zlib' will be dynamically loaded. Following a structure to * contain the addresses of all functions required by this extension. * * Affected commands are: zip, adler, crc-zlib. * They will fail, if the library could not be loaded. */ typedef struct ZFunctions { VOID *handle; int (ZEXPORT * zdeflate) _ANSI_ARGS_ ((z_streamp strm, int flush)); int (ZEXPORT * zdeflateEnd) _ANSI_ARGS_ ((z_streamp strm)); int (ZEXPORT * zdeflateInit2_) _ANSI_ARGS_ ((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, CONST char *version, int stream_size)); int (ZEXPORT * zdeflateReset) _ANSI_ARGS_ ((z_streamp strm)); int (ZEXPORT * zinflate) _ANSI_ARGS_ ((z_streamp strm, int flush)); int (ZEXPORT * zinflateEnd) _ANSI_ARGS_ ((z_streamp strm)); int (ZEXPORT * zinflateInit2_) _ANSI_ARGS_ ((z_streamp strm, int windowBits, CONST char *version, int stream_size)); int (ZEXPORT * zinflateReset) _ANSI_ARGS_ ((z_streamp strm)); unsigned long (ZEXPORT * zadler32) _ANSI_ARGS_ ((unsigned long adler, CONST unsigned char *buf, unsigned int len)); unsigned long (ZEXPORT * zcrc32) _ANSI_ARGS_ ((unsigned long crc, CONST unsigned char *buf, unsigned int len)); } zFunctions; EXTERN zFunctions zf; /* THREADING: serialize initialization */ EXTERN int TrfLoadZlib _ANSI_ARGS_ ((Tcl_Interp *interp)); /* * 'libbz2' will be dynamically loaded. Following a structure to * contain the addresses of all functions required by this extension. * * Affected commands are: bzip. * They will fail, if the library could not be loaded. */ #ifdef BZLIB_STATIC_BUILD #undef BZEXPORT #define BZEXPORT #else #undef BZEXPORT #define BZEXPORT WINAPI #endif typedef struct BZFunctions { VOID *handle; int (BZEXPORT * bcompress) _ANSI_ARGS_ ((bz_stream* strm, int action)); int (BZEXPORT * bcompressEnd) _ANSI_ARGS_ ((bz_stream* strm)); int (BZEXPORT * bcompressInit) _ANSI_ARGS_ ((bz_stream* strm, int blockSize100k, int verbosity, int workFactor)); int (BZEXPORT * bdecompress) _ANSI_ARGS_ ((bz_stream* strm)); int (BZEXPORT * bdecompressEnd) _ANSI_ARGS_ ((bz_stream* strm)); int (BZEXPORT * bdecompressInit) _ANSI_ARGS_ ((bz_stream* strm, int verbosity, int small)); } bzFunctions; EXTERN bzFunctions bz; /* THREADING: serialize initialization */ EXTERN int TrfLoadBZ2lib _ANSI_ARGS_ ((Tcl_Interp *interp)); /* * The following definitions have to be usable for 8.0.x, 8.1.x, 8.2.x, * 8.3.[01], 8.3.2 and beyond. The differences between these versions: * * 8.0.x: Trf usable only if core is patched, to check at compile time * (Check = Fails to compile, for now). * * 8.1: Trf usable with unpatched core, but restricted, check at * compile time for missing definitions, check at runtime to * disable the missing features. * * 8.2.x: Changed semantics for Tcl_StackChannel (Tcl_ReplaceChannel). * 8.3.[01]: Check at runtime to switch the behaviour. The patch is part * of the core from now on. * * 8.3.2+: Stacked channels rewritten for better behaviour in some * situations (closing). Some new API's, semantic changes. */ #ifdef USE_TCL_STUBS #ifndef Tcl_StackChannel /* The core we are compiling against is not patched, so supply the * necesssary definitions here by ourselves. The form chosen for * the procedure macros (reservedXXX) will notify us if the core * does not have these reserved locations anymore. * * !! Synchronize the procedure indices in their definitions with * the patch to tcl.decls, as they have to be the same. */ /* 281 */ typedef Tcl_Channel (trf_StackChannel) _ANSI_ARGS_((Tcl_Interp* interp, Tcl_ChannelType* typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 282 */ typedef void (trf_UnstackChannel) _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Channel chan)); #define Tcl_StackChannel ((trf_StackChannel*) tclStubsPtr->reserved281) #define Tcl_UnstackChannel ((trf_UnstackChannel*) tclStubsPtr->reserved282) #endif /* Tcl_StackChannel */ #ifndef Tcl_GetStackedChannel /* * Separate definition, available in 8.2, but not 8.1 and before ! */ /* 283 */ typedef Tcl_Channel (trf_GetStackedChannel) _ANSI_ARGS_((Tcl_Channel chan)); #define Tcl_GetStackedChannel ((trf_GetStackedChannel*) tclStubsPtr->reserved283) #endif /* Tcl_GetStackedChannel */ #ifndef Tcl_WriteRaw /* Core is older than 8.3.2., so supply the missing definitions for * the new API's in 8.3.2. */ /* 394 */ typedef int (trf_ReadRaw) _ANSI_ARGS_((Tcl_Channel chan, char* dst, int bytesToRead)); /* 395 */ typedef int (trf_WriteRaw) _ANSI_ARGS_((Tcl_Channel chan, char* src, int srcLen)); /* 396 */ typedef int (trf_GetTopChannel) _ANSI_ARGS_((Tcl_Channel chan)); /* 397 */ typedef int (trf_ChannelBuffered) _ANSI_ARGS_((Tcl_Channel chan)); /* * Generating code for accessing these parts of the stub table when * compiling against a core older than 8.3.2 is a hassle because even * the 'reservedXXX' fields of the structure are not defined yet. So * we have to write up some macros hiding some very hackish pointer * arithmetics to get at these fields. We assume that pointer to * functions are always of the same size. */ #define STUB_BASE ((char*)(&(tclStubsPtr->tcl_UtfNcasecmp))) /* field 370 */ #define procPtrSize (sizeof (Tcl_DriverBlockModeProc *)) #define IDX(n) (((n)-370) * procPtrSize) #define SLOT(n) (STUB_BASE + IDX (n)) #define Tcl_ReadRaw (*((trf_ReadRaw**) (SLOT (394)))) #define Tcl_WriteRaw (*((trf_WriteRaw**) (SLOT (395)))) #define Tcl_GetTopChannel (*((trf_GetTopChannel**) (SLOT (396)))) #define Tcl_ChannelBuffered (*((trf_ChannelBuffered**) (SLOT (397)))) /* #define Tcl_ReadRaw ((trf_ReadRaw*) tclStubsPtr->reserved394) #define Tcl_WriteRaw ((trf_WriteRaw*) tclStubsPtr->reserved395) #define Tcl_GetTopChannel ((trf_GetTopChannel*) tclStubsPtr->reserved396) #define Tcl_ChannelBuffered ((trf_ChannelBuffered*) tclStubsPtr->reserved397) */ /* Always required, easy emulation. */ #define Tcl_ChannelWatchProc(chanDriver) ((chanDriver)->watchProc) #define Tcl_ChannelSetOptionProc(chanDriver) ((chanDriver)->setOptionProc) #define Tcl_ChannelGetOptionProc(chanDriver) ((chanDriver)->getOptionProc) #define Tcl_ChannelSeekProc(chanDriver) ((chanDriver)->seekProc) #endif /* Tcl_WriteRaw */ #endif /* USE_TCL_STUBS */ /* * Internal initialization procedures for all transformers implemented here. */ EXTERN int TrfInit_Bin _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_Oct _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_Hex _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_UU _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_B64 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_Ascii85 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_OTP_WORDS _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_QP _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_CRC _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_MD5 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_MD2 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_HAVAL _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_SHA _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_SHA1 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_OTP_SHA1 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_ADLER _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_CRC_ZLIB _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_RIPEMD128 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_RIPEMD160 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_OTP_MD5 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_RS_ECC _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_ZIP _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_BZ2 _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_Info _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_Unstack _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_Binio _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_Transform _ANSI_ARGS_ ((Tcl_Interp* interp)); EXTERN int TrfInit_Crypt _ANSI_ARGS_ ((Tcl_Interp* interp)); /* Compile time distinctions between various versions of Tcl. */ /* Do we support locking ? Has to be a version of 8.1 or * beyond with threading enabled. */ #if GT81 && defined (TCL_THREADS) /* THREADING: Lock procedures */ EXTERN void TrfLockIt _ANSI_ARGS_ ((void)); EXTERN void TrfUnlockIt _ANSI_ARGS_ ((void)); #define TrfLock TrfLockIt () #define TrfUnlock TrfUnlockIt () #else /* Either older version of Tcl, or non-threaded 8.1.x. * Whatever, locking is not required, undefine the calls. */ #define TrfLock #define TrfUnlock #endif /* Tcl 8.1 and beyond have better support for binary data. We have to * use that to avoid mangling information going through the * transformations. */ #if GT81 #define GET_DATA(in,len) (unsigned char*) Tcl_GetByteArrayFromObj ((in), (len)) #define NEW_DATA(r) Tcl_NewByteArrayObj ((r).buf, (r).used); #else #define GET_DATA(in,len) (unsigned char*) Tcl_GetStringFromObj ((in), (len)) #define NEW_DATA(r) Tcl_NewStringObj ((char*) (r).buf, (r).used) #endif /* Map the names of some procedures from the stubs-variant to their * pre-stubs names. */ #ifndef USE_TCL_STUBS #define Tcl_UnstackChannel Tcl_UndoReplaceChannel #define Tcl_StackChannel Tcl_ReplaceChannel #endif /* Define the code to 'provide' this package to the loading interpreter. */ #if !(GT81) #define PROVIDE(interp,stubs) Tcl_PkgProvide ((interp), PACKAGE_NAME, PACKAGE_VERSION); #else #ifndef __WIN32__ #define PROVIDE(interp,stubs) \ Tcl_PkgProvideEx ((interp), PACKAGE_NAME, PACKAGE_VERSION, (ClientData) &(stubs)); \ Trf_InitStubs ((interp), PACKAGE_VERSION, 0); #else #define PROVIDE(interp,stubs) Tcl_PkgProvideEx ((interp), PACKAGE_NAME, PACKAGE_VERSION, (ClientData) &(stubs)); #endif #endif #include "trfIntDecls.h" #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #ifdef __cplusplus } #endif /* C++ */ #endif /* TRF_INT_H */ trf2.1.4/generic/hexcode.c0000644000175000017500000004220311216344223014750 0ustar sergeisergei/* * hexcode.c -- * * Implements and registers conversion from and to hexadecimal representation. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: hexcode.c,v 1.12 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Converter description * --------------------- * * Encoding: * Every byte is converted into 2 characters, using elements * in the set {0-9,a-z} only. Thus a hexadecimal representation is * generated. The MSBit is output first. * * Decoding: * Only characters in the set {0-9a-zA-Z} are allowed as input. * Each 2-tuple is converted into a single byte. A single character * at the end of input is converted as if padded with "0". */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "hex", NULL, /* clientData not sed by converters */ NULL, /* set by 'TrfInit_Hex'. THREAD: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_RATIO (1, 2) }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; unsigned char charCount; /* number of characters assembled so far (0..1) */ unsigned char bench; /* buffer for assembled byte */ } DecoderControl; /* * Use table lookup */ static const char* code [] = { /* THREADING: constant, read-only => safe */ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF", }; /* *------------------------------------------------------* * * TrfInit_Hex -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Hex (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; #if 0 unsigned char buffer [2]; char high = (character >> 4) & 0x0F; char low = character & 0x0F; high += ((high < 10) ? '0' : 'A'-10); low += ((low < 10) ? '0' : 'A'-10); buffer [0] = high; buffer [1] = low; return c->write (c->writeClientData, buffer, 2, interp); #endif return c->write (c->writeClientData, (unsigned char*) code [character & 0x00ff], 2, interp); } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; char* out = (char*) ckalloc (2*bufLen+1); int res, i, j; CONST char* ch; for (i=0, j=0; i < bufLen; i++) { ch = code [buffer [i] & 0x00ff]; out [j] = ch [0]; j++; out [j] = ch [1]; j++; } out [j] = '\0'; res = c->write (c->writeClientData, (unsigned char*) out, 2*bufLen, interp); ckfree ((char*) out); return res; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { /* nothing to to */ return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { /* nothing to do */ } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; c->charCount = 0; c->bench = '\0'; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; unsigned char nibble = character; #define IN_RANGE(low,x,high) (((low) <= (x)) && ((x) <= (high))) if (IN_RANGE ('0', nibble, '9')) nibble -= '0'; else if (IN_RANGE ('a', nibble, 'f')) nibble -= 'a'-10; else if (IN_RANGE ('A', nibble, 'F')) nibble -= 'A'-10; else { if (interp) { char buf [10]; if (character < ' ' || character > 127) { sprintf (buf, "0x%02x", character); } else { buf [0] = '\''; buf [1] = character; buf [2] = '\''; buf [3] = '\0'; } Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character ", buf, " found in input", (char*) NULL); } return TCL_ERROR; } c->bench |= (nibble << (4 * (1- c->charCount))); c->charCount ++; if (c->charCount >= 2) { int res = c->write (c->writeClientData, &c->bench, 1, interp); c->bench = '\0'; c->charCount = 0; return res; } return TCL_OK; #undef IN_RANGE } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { #define IN_RANGE(low,x,high) (((low) <= (x)) && ((x) <= (high))) DecoderControl* c = (DecoderControl*) ctrlBlock; char* out = (char*) ckalloc (1+bufLen/2); int res, i, j; unsigned char nibble; for (i=0, j=0; i < bufLen; i++) { nibble = buffer [i]; if (IN_RANGE ('0', nibble, '9')) nibble -= '0'; else if (IN_RANGE ('a', nibble, 'f')) nibble -= 'a' - 10; else if (IN_RANGE ('A', nibble, 'F')) nibble -= 'A' - 10; else { if (interp) { char buf [10]; if (nibble < ' ' || nibble > 127) { sprintf (buf, "0x%02x", nibble); } else { buf [0] = '\''; buf [1] = nibble; buf [2] = '\''; buf [3] = '\0'; } Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character ", buf, " found in input", (char*) NULL); } ckfree (out); return TCL_ERROR; } c->bench |= (nibble << (4 * (1 - c->charCount))); c->charCount ++; if (c->charCount >= 2) { out [j] = c->bench; c->bench = '\0'; c->charCount = 0; j ++; } } res = c->write (c->writeClientData, (unsigned char*) out, j, interp); return res; #undef IN_RANGE } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; int res = TCL_OK; if (c->charCount > 0) { res = c->write (c->writeClientData, &c->bench, 1, interp); c->bench = '\0'; c->charCount = 0; } return res; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; c->bench = '\0'; c->charCount = 0; } trf2.1.4/generic/md2.c0000644000175000017500000001240611216344223014015 0ustar sergeisergei/* * md2.c -- * * Implements and registers message digest generator MD2. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: md2.c,v 1.3 2000/08/09 19:13:17 aku Exp $ */ #include "loadman.h" /* * Generator description * --------------------- * * The MD2 alogrithm is used to compute a cryptographically strong * message digest. */ #define DIGEST_SIZE (MD2_DIGEST_LENGTH) #define CTX_TYPE MD2_CTX /* * Declarations of internal procedures. */ static void MDmd2_Start _ANSI_ARGS_ ((VOID* context)); static void MDmd2_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDmd2_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDmd2_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); static int MDmd2_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ "md2", sizeof (CTX_TYPE), DIGEST_SIZE, MDmd2_Start, MDmd2_Update, MDmd2_UpdateBuf, MDmd2_Final, MDmd2_Check }; /* *------------------------------------------------------* * * TrfInit_MD2 -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_MD2 (interp) Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDmd2_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDmd2_Start (context) VOID* context; { md2f.init ((MD2_CTX*) context); } /* *------------------------------------------------------* * * MDmd2_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDmd2_Update (context, character) VOID* context; unsigned int character; { unsigned char buf = character; md2f.update ((MD2_CTX*) context, &buf, 1); } /* *------------------------------------------------------* * * MDmd2_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDmd2_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { md2f.update ((MD2_CTX*) context, (unsigned char*) buffer, bufLen); } /* *------------------------------------------------------* * * MDmd2_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDmd2_Final (context, digest) VOID* context; VOID* digest; { md2f.final ((unsigned char*) digest, (MD2_CTX*) context); } /* *------------------------------------------------------* * * MDmd2_Check -- * * ------------------------------------------------* * Do global one-time initializations of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * Loads the shared library containing the * MD2 functionality * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int MDmd2_Check (interp) Tcl_Interp* interp; { return TrfLoadMD2 (interp); } trf2.1.4/generic/ref_opt.c0000644000175000017500000002454711216344224015003 0ustar sergeisergei/* * convert.c -- * * Implements the C level procedures handling option processing * of transformation reflecting the work to the tcl level. * * * Copyright (c) 1997 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: ref_opt.c,v 1.9 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "reflect.h" /* * forward declarations of all internally used procedures. */ static Trf_Options CreateOptions _ANSI_ARGS_ ((ClientData clientData)); static void DeleteOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static int CheckOptions _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST Trf_BaseOptions* baseOptions, ClientData clientData)); static int SetOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST Tcl_Obj* optvalue, ClientData clientData)); static int QueryOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static void SeekQueryOptions _ANSI_ARGS_ ((Tcl_Interp* interp, Trf_Options options, Trf_SeekInformation* seekInfo, ClientData clientData)); /* *------------------------------------------------------* * * TrfTransformOptions -- * * ------------------------------------------------* * Accessor to the set of vectors realizing option * processing for reflecting transformation. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * See above. * *------------------------------------------------------* */ Trf_OptionVectors* TrfTransformOptions () { static Trf_OptionVectors optVec = /* THREADING: const, read-only => safe */ { CreateOptions, DeleteOptions, CheckOptions, NULL, /* no string procedure for 'SetOption' */ SetOption, QueryOptions, SeekQueryOptions /* Tcl level can change/define the ratio */ }; return &optVec; } /* *------------------------------------------------------* * * CreateOptions -- * * ------------------------------------------------* * Create option structure for reflecting transformation. * ------------------------------------------------* * * Sideeffects: * Allocates memory and initializes it as * option structure for reflecting * transformations. * * Result: * A reference to the allocated block of * memory. * *------------------------------------------------------* */ static Trf_Options CreateOptions (clientData) ClientData clientData; { TrfTransformOptionBlock* o; o = (TrfTransformOptionBlock*) ckalloc (sizeof (TrfTransformOptionBlock)); o->mode = TRF_UNKNOWN_MODE; o->command = (Tcl_Obj*) NULL; return (Trf_Options) o; } /* *------------------------------------------------------* * * DeleteOptions -- * * ------------------------------------------------* * Delete option structure of a reflecting transformation * ------------------------------------------------* * * Sideeffects: * A memory block allocated by 'CreateOptions' * is released. * * Result: * None. * *------------------------------------------------------* */ static void DeleteOptions (options, clientData) Trf_Options options; ClientData clientData; { TrfTransformOptionBlock* o = (TrfTransformOptionBlock*) options; if (o->command != NULL) { Tcl_DecrRefCount (o->command); } ckfree ((VOID*) o); } /* *------------------------------------------------------* * * CheckOptions -- * * ------------------------------------------------* * Check the given option structure for errors. * ------------------------------------------------* * * Sideeffects: * May modify the given structure to set * default values into uninitialized parts. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int CheckOptions (options, interp, baseOptions, clientData) Trf_Options options; Tcl_Interp* interp; CONST Trf_BaseOptions* baseOptions; ClientData clientData; { TrfTransformOptionBlock* o = (TrfTransformOptionBlock*) options; if (o->command == NULL) { Tcl_AppendResult (interp, "command not specified", (char*) NULL); return TCL_ERROR; } if ((o->command->bytes == 0) && (o->command->typePtr == NULL)) { /* object defined, but empty, reject this too */ Tcl_AppendResult (interp, "command specified, but empty", (char*) NULL); return TCL_ERROR; } if (baseOptions->attach == (Tcl_Channel) NULL) /* IMMEDIATE? */ { if (o->mode == TRF_UNKNOWN_MODE) { Tcl_AppendResult (interp, "-mode option not set", (char*) NULL); return TCL_ERROR; } } else /* ATTACH */ { if (o->mode != TRF_UNKNOWN_MODE) { /* operation mode irrelevant for attached transformation, * and specification therefore ruled as illegal. */ Tcl_AppendResult (interp, "mode illegal for attached transformation", (char*) NULL); return TCL_ERROR; } o->mode = TRF_WRITE_MODE; } return TCL_OK; } /* *------------------------------------------------------* * * SetOption -- * * ------------------------------------------------* * Define value of given option. * ------------------------------------------------* * * Sideeffects: * Sets the given value into the option * structure * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int SetOption (options, interp, optname, optvalue, clientData) Trf_Options options; Tcl_Interp* interp; CONST char* optname; CONST Tcl_Obj* optvalue; ClientData clientData; { TrfTransformOptionBlock* o = (TrfTransformOptionBlock*) options; int len; CONST char* value; len = strlen (optname+1); switch (optname [1]) { case 'm': if (0 != strncmp (optname, "-mode", len)) goto unknown_option; value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); len = strlen (value); switch (value [0]) { case 'r': if (0 != strncmp (value, "read", len)) goto unknown_mode; o->mode = TRF_READ_MODE; break; case 'w': if (0 != strncmp (value, "write", len)) goto unknown_mode; o->mode = TRF_WRITE_MODE; break; default: unknown_mode: Tcl_AppendResult (interp, "unknown mode '", (char*) NULL); Tcl_AppendResult (interp, value, (char*) NULL); Tcl_AppendResult (interp, "', should be 'read' or 'write'", (char*) NULL); return TCL_ERROR; break; } /* switch optvalue */ break; case 'c': if (0 != strncmp (optname, "-command", len)) goto unknown_option; /* 'optvalue' contains the command to execute for a buffer */ /* * Store reference, tell the interpreter about it. * We have to unCONST it explicitly to allow modification * of its reference counter */ o->command = (Tcl_Obj*) optvalue; Tcl_IncrRefCount (o->command); break; default: goto unknown_option; break; } return TCL_OK; unknown_option: Tcl_AppendResult (interp, "unknown option '", (char*) NULL); Tcl_AppendResult (interp, optname, (char*) NULL); Tcl_AppendResult (interp, "', should be '-mode' or '-command'", (char*) NULL); return TCL_ERROR; } /* *------------------------------------------------------* * * QueryOptions -- * * ------------------------------------------------* * Returns a value indicating wether the encoder or * decoder set of vectors is to be used by immediate * execution. * ------------------------------------------------* * * Sideeffects: * None * * Result: * 1 - use encoder vectors. * 0 - use decoder vectors. * *------------------------------------------------------* */ static int QueryOptions (options, clientData) Trf_Options options; ClientData clientData; { TrfTransformOptionBlock* o = (TrfTransformOptionBlock*) options; return (o->mode == TRF_WRITE_MODE ? 1 : 0); } /* *------------------------------------------------------* * * SeekQueryOptions -- * * ------------------------------------------------* * Modifies the natural seek policy according to the * configuration of the transformation (queries the * tcl level). * ------------------------------------------------* * * Sideeffects: * May modify 'seekInfo'. * * Result: * None. * *------------------------------------------------------* */ static void SeekQueryOptions (interp, options, seekInfo, clientData) Tcl_Interp* interp; Trf_Options options; Trf_SeekInformation* seekInfo; ClientData clientData; { TrfTransformOptionBlock* o = (TrfTransformOptionBlock*) options; ReflectControl rc; START (SeekQueryOptions); rc.interp = interp; rc.naturalRatio.numBytesTransform = seekInfo->numBytesTransform; rc.naturalRatio.numBytesDown = seekInfo->numBytesDown; rc.command = o->command; Tcl_IncrRefCount (rc.command); PRINT ("in = (%d, %d)\n", seekInfo->numBytesTransform, seekInfo->numBytesDown); FL; RefExecuteCallback (&rc, (Tcl_Interp*) interp, (unsigned char*) "query/ratio", NULL, 0, TRANSMIT_RATIO /* -> naturalRatio */, 1); seekInfo->numBytesTransform = rc.naturalRatio.numBytesTransform; seekInfo->numBytesDown = rc.naturalRatio.numBytesDown; Tcl_DecrRefCount (rc.command); PRINT ("out = (%d, %d)\n", seekInfo->numBytesTransform, seekInfo->numBytesDown); FL; DONE (SeekQueryOptions); } trf2.1.4/generic/bz2lib.c0000644000175000017500000000250111216344223014512 0ustar sergeisergei/* * bz2lib.c -- * * Loader for 'bz2' compression library. * * Copyright (c) 1996 Jan Nijtmans (Jan.Nijtmans.wxs.nl) * All rights reserved. * * CVS: $Id: bz2lib.c,v 1.5 2008/12/11 19:04:25 andreas_kupries Exp $ */ #include "transformInt.h" #ifndef BZ2_LIB_NAME # ifdef __WIN32__ # define BZ2_LIB_NAME "libbz2.dll" # endif /* __WIN32__ */ # ifdef __APPLE__ # define BZ2_LIB_NAME "libbz2.dylib" # endif /* __APPLE__ */ # ifndef BZ2_LIB_NAME # define BZ2_LIB_NAME "libbz2.so" # endif /* BZ2_LIB_NAME */ #endif /* BZ2_LIB_NAME */ static char* symbols [] = { "BZ2_bzCompress", "BZ2_bzCompressEnd", "BZ2_bzCompressInit", "BZ2_bzDecompress", "BZ2_bzDecompressEnd", "BZ2_bzDecompressInit", (char *) NULL }; /* * Global variable containing the vectors into the 'bz2'-library. */ #ifdef BZLIB_STATIC_BUILD bzFunctions bz = { 0, bzCompress, bzCompressEnd, bzCompressInit, bzDecompress, bzDecompressEnd, bzDecompressInit, }; #else bzFunctions bz = {0}; /* THREADING: serialize initialization */ #endif int TrfLoadBZ2lib (interp) Tcl_Interp* interp; { #ifndef BZLIB_STATIC_BUILD int res; TrfLock; /* THREADING: serialize initialization */ res = Trf_LoadLibrary (interp, BZ2_LIB_NAME, (VOID**) &bz, symbols, 6); TrfUnlock; return res; #else return TCL_OK; #endif } trf2.1.4/generic/rs_ecc.c0000644000175000017500000004627311216344224014603 0ustar sergeisergei/* * rs_ecc.c -- * * Implements and registers error correction with Reed-Solomon (255,249,7) block code. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: rs_ecc.c,v 1.10 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Forward declaractions of internally used procedures. */ #define MSG_LEN (249) /* 248 bytes usable, 1 byte length information * (always at end of block) */ #define CODE_LEN (255) void rsencode _ANSI_ARGS_ ((unsigned char m [MSG_LEN], unsigned char c [CODE_LEN])); void rsdecode _ANSI_ARGS_ ((unsigned char c [CODE_LEN], unsigned char m [MSG_LEN], int* errcode)); /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "rs_ecc", NULL, /* filled by TrfInit_RS_ECC, THREADING: serialize initialization */ NULL, /* not used */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_RATIO (248, 255) }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (RS_ECC) */ unsigned char block [MSG_LEN]; unsigned char charCount; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (RS_ECC) */ unsigned char block [CODE_LEN]; unsigned char charCount; } DecoderControl; /* *------------------------------------------------------* * * TrfInit_RS_ECC -- * * ------------------------------------------------* * Register the ECC algorithm implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_RS_ECC (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (RS_ECC) */ memset (c->block, '\0', MSG_LEN); c->charCount = 0; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (RS_ECC) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (RS_ECC) */ c->block [c->charCount] = character; c->charCount ++; if (c->charCount == (MSG_LEN-1)) { char out [CODE_LEN]; c->block [MSG_LEN-1] = c->charCount; /* == MSG_LEN-1 */ rsencode (c->block, (unsigned char*) out); /* not really required: memset (c->block, '\0', MSG_LEN); */ c->charCount = 0; return c->write (c->writeClientData, (unsigned char*) out, CODE_LEN, interp); } return TCL_OK; } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (RS_ECC) */ char out [CODE_LEN], oldchar; int res; /* * Complete chunk with incoming data, generate EC-information, * then use all chunks contained in the buffer. Remember * an incomplete chunk and wait for further calls. */ int k = (MSG_LEN-1) - c->charCount; if (k > bufLen) { /* * We got less information than required to form a full block. * Extend the internal buffer and wait for more. */ memcpy ((VOID*) (c->block + c->charCount), (VOID*) buffer, bufLen); c->charCount += bufLen; return TCL_OK; } if (k < (MSG_LEN-1)) { memcpy ((VOID*) (c->block + c->charCount), (VOID*) buffer, k); c->block [MSG_LEN-1] = c->charCount; /* == MSG_LEN-1 */ rsencode (c->block, (unsigned char*) out); c->charCount = 0; res = c->write (c->writeClientData, (unsigned char*) out, CODE_LEN, interp); buffer += k; bufLen -= k; if (res != TCL_OK) return res; } /* k == (MSG_LEN-1) => internal buffer was empty, so skip it entirely */ while (bufLen > (MSG_LEN-1)) { /* * We are directly manipulating the buffer to get the charCount * of the individual chunks into it. To avoid memory overuns we * query for '>' at the begin of the loop and handle the special * case of 'bufLen == MSG_LEN-1' afterward. */ oldchar = buffer [MSG_LEN-1]; buffer [MSG_LEN-1] = (unsigned char) (MSG_LEN-1); rsencode (buffer, (unsigned char*) out); buffer [MSG_LEN-1] = oldchar; res = c->write (c->writeClientData, (unsigned char*) out, CODE_LEN, interp); buffer += MSG_LEN-1; bufLen -= MSG_LEN-1; if (res != TCL_OK) return res; } memcpy ((VOID*) c->block, (VOID*) buffer, bufLen); c->charCount = bufLen; if (bufLen == (MSG_LEN-1)) { c->block [MSG_LEN-1] = c->charCount; /* == MSG_LEN-1 */ rsencode (c->block, (unsigned char*) out); c->charCount = 0; return c->write (c->writeClientData, (unsigned char*) out, CODE_LEN, interp); } /* else: nothing more to do to remember incomplete data */ return TCL_OK; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (RS_ECC) */ if (c->charCount > 0) { char out [CODE_LEN]; c->block [MSG_LEN-1] = c->charCount; /* < (MSG_LEN-1) */ rsencode (c->block, (unsigned char*) out); return c->write (c->writeClientData, (unsigned char*) out, CODE_LEN, interp); } return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (RS_ECC) */ memset (c->block, '\0', MSG_LEN); c->charCount = 0; } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (RS_ECC) */ memset (c->block, '\0', CODE_LEN); c->charCount = 0; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (RS_ECC) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (RS_ECC) */ c->block [c->charCount] = character; c->charCount ++; if (c->charCount == CODE_LEN) { unsigned char msg [MSG_LEN]; int err; int length; rsdecode (c->block, msg, &err); /* should check decoder result */ /* not really required: memset (c->block, '\0', CODE_LEN); */ c->charCount = 0; length = msg [MSG_LEN-1]; /* <= (MSG_LEN-1) */ /* restrict length to legal range. * unrecoverable errors could have destroyed this information too! */ if (length > (MSG_LEN-1)) length = MSG_LEN-1; return c->write (c->writeClientData, msg, length, interp); } return TCL_OK; } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (RS_ECC) */ unsigned char msg [MSG_LEN]; int err, length, res; /* * Complete chunk with incoming data, generate EC-information, * then use all chunks contained in the buffer. Remember * an incomplete chunk and wait for further calls. */ int k = (CODE_LEN-1) - c->charCount; if (k > bufLen) { /* * We got less information than required to form a full block. * Extend the internal buffer and wait for more. */ memcpy ((VOID*) (c->block + c->charCount), (VOID*) buffer, bufLen); c->charCount += bufLen; return TCL_OK; } if (k < (CODE_LEN-1)) { memcpy ((VOID*) (c->block + c->charCount), (VOID*) buffer, k); rsdecode (c->block, msg, &err); length = msg [MSG_LEN-1]; /* <= (MSG_LEN-1) */ /* restrict length to legal range. * unrecoverable errors could have destroyed this information too! */ if (length > (MSG_LEN-1)) length = MSG_LEN-1; res = c->write (c->writeClientData, msg, length, interp); c->charCount = 0; buffer += k; bufLen -= k; if (res != TCL_OK) return res; } /* k == (MSG_LEN-1) => internal buffer was empty, so skip it entirely */ while (bufLen >= CODE_LEN) { rsdecode (buffer, msg, &err); /* should check decoder result */ length = msg [MSG_LEN-1]; /* <= (MSG_LEN-1) */ /* restrict length to legal range. * unrecoverable errors could have destroyed this information too! */ if (length > (MSG_LEN-1)) length = MSG_LEN-1; res = c->write (c->writeClientData, msg, length, interp); buffer += CODE_LEN; bufLen -= CODE_LEN; if (res != TCL_OK) return res; } if (bufLen > 0) { memcpy ((VOID*) c->block, (VOID*) buffer, bufLen); c->charCount = bufLen; } return TCL_OK; } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (RS_ECC) */ if (c->charCount > 0) { if (interp != NULL) { Tcl_AppendResult (interp, "can not decode incomplete block at end of input", (char*) NULL); } return TCL_ERROR; } return TCL_OK; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (RS_ECC) */ memset (c->block, '\0', CODE_LEN); c->charCount = 0; } /* * External code from here on. */ /* #include rs-ecc / *.c: THREADING: import of three constant vars, read-only => safe */ #include "rs-ecc/gflib.c" #include "rs-ecc/rslib.c" trf2.1.4/generic/trfDecls.h0000644000175000017500000001014511216344305015105 0ustar sergeisergei/* * trfDecls.h -- * * Declarations of functions in the platform independent public Trf API. * * Copyright (c) 1999 by Andreas Kupries * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: trfDecls.h,v 1.2 1999/09/21 18:48:57 aku Exp $ */ #ifndef _TRFDECLS #define _TRFDECLS /* * 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/trf.decls script. */ /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ /* 0 */ EXTERN int Trf_IsInitialized _ANSI_ARGS_((Tcl_Interp * interp)); /* 1 */ EXTERN int Trf_Register _ANSI_ARGS_((Tcl_Interp * interp, CONST Trf_TypeDefinition * type)); /* 2 */ EXTERN Trf_OptionVectors* Trf_ConverterOptions _ANSI_ARGS_((void)); /* 3 */ EXTERN int Trf_LoadLibrary _ANSI_ARGS_((Tcl_Interp * interp, CONST char * libName, VOID ** handlePtr, char ** symbols, int num)); /* 4 */ EXTERN void Trf_LoadFailed _ANSI_ARGS_((VOID** handlePtr)); /* 5 */ EXTERN int Trf_RegisterMessageDigest _ANSI_ARGS_(( Tcl_Interp* interp, CONST Trf_MessageDigestDescription* md_desc)); /* 6 */ EXTERN void Trf_XorBuffer _ANSI_ARGS_((VOID* buffer, VOID* mask, int length)); /* 7 */ EXTERN void Trf_ShiftRegister _ANSI_ARGS_((VOID* buffer, VOID* in, int shift, int buffer_length)); /* 8 */ EXTERN void Trf_FlipRegisterLong _ANSI_ARGS_((VOID* buffer, int length)); /* 9 */ EXTERN void Trf_FlipRegisterShort _ANSI_ARGS_((VOID* buffer, int length)); typedef struct TrfStubHooks { struct TrfIntStubs *trfIntStubs; } TrfStubHooks; typedef struct TrfStubs { int magic; struct TrfStubHooks *hooks; int (*trf_IsInitialized) _ANSI_ARGS_((Tcl_Interp * interp)); /* 0 */ int (*trf_Register) _ANSI_ARGS_((Tcl_Interp * interp, CONST Trf_TypeDefinition * type)); /* 1 */ Trf_OptionVectors* (*trf_ConverterOptions) _ANSI_ARGS_((void)); /* 2 */ int (*trf_LoadLibrary) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * libName, VOID ** handlePtr, char ** symbols, int num)); /* 3 */ void (*trf_LoadFailed) _ANSI_ARGS_((VOID** handlePtr)); /* 4 */ int (*trf_RegisterMessageDigest) _ANSI_ARGS_((Tcl_Interp* interp, CONST Trf_MessageDigestDescription* md_desc)); /* 5 */ void (*trf_XorBuffer) _ANSI_ARGS_((VOID* buffer, VOID* mask, int length)); /* 6 */ void (*trf_ShiftRegister) _ANSI_ARGS_((VOID* buffer, VOID* in, int shift, int buffer_length)); /* 7 */ void (*trf_FlipRegisterLong) _ANSI_ARGS_((VOID* buffer, int length)); /* 8 */ void (*trf_FlipRegisterShort) _ANSI_ARGS_((VOID* buffer, int length)); /* 9 */ } TrfStubs; #ifdef __cplusplus extern "C" { #endif extern TrfStubs *trfStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_TRF_STUBS) && !defined(USE_TRF_STUB_PROCS) /* * Inline function declarations: */ #ifndef Trf_IsInitialized #define Trf_IsInitialized \ (trfStubsPtr->trf_IsInitialized) /* 0 */ #endif #ifndef Trf_Register #define Trf_Register \ (trfStubsPtr->trf_Register) /* 1 */ #endif #ifndef Trf_ConverterOptions #define Trf_ConverterOptions \ (trfStubsPtr->trf_ConverterOptions) /* 2 */ #endif #ifndef Trf_LoadLibrary #define Trf_LoadLibrary \ (trfStubsPtr->trf_LoadLibrary) /* 3 */ #endif #ifndef Trf_LoadFailed #define Trf_LoadFailed \ (trfStubsPtr->trf_LoadFailed) /* 4 */ #endif #ifndef Trf_RegisterMessageDigest #define Trf_RegisterMessageDigest \ (trfStubsPtr->trf_RegisterMessageDigest) /* 5 */ #endif #ifndef Trf_XorBuffer #define Trf_XorBuffer \ (trfStubsPtr->trf_XorBuffer) /* 6 */ #endif #ifndef Trf_ShiftRegister #define Trf_ShiftRegister \ (trfStubsPtr->trf_ShiftRegister) /* 7 */ #endif #ifndef Trf_FlipRegisterLong #define Trf_FlipRegisterLong \ (trfStubsPtr->trf_FlipRegisterLong) /* 8 */ #endif #ifndef Trf_FlipRegisterShort #define Trf_FlipRegisterShort \ (trfStubsPtr->trf_FlipRegisterShort) /* 9 */ #endif #endif /* defined(USE_TRF_STUBS) && !defined(USE_TRF_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _TRFDECLS */ trf2.1.4/generic/rmd128.c0000644000175000017500000001757211216344224014362 0ustar sergeisergei/* * rmd128.c -- * * Implements and registers message digest generator RIPEMD-128. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: rmd128.c,v 1.5 2005/10/06 18:05:46 andreas_kupries Exp $ */ #include "transformInt.h" #include "ripemd/rmd128.h" /* * Generator description * --------------------- * * The RIPEMD-128 alogrithm is used to compute a cryptographically strong * message digest. */ #define DIGEST_SIZE (16) /*#define CTX_TYPE */ #define CONTEXT_SIZE (16) #define CHUNK_SIZE (64) typedef struct ripemd_context { dword state [5]; /* state variables of ripemd-128 */ byte buf [CHUNK_SIZE]; /* buffer of 16-dword's */ byte byteCount; /* number of bytes in buffer */ dword lowc; /* lower half of a 64bit counter */ dword highc; /* upper half of a 64bit counter */ } ripemd_context; /* * Declarations of internal procedures. */ static void MDrmd128_Start _ANSI_ARGS_ ((VOID* context)); static void MDrmd128_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDrmd128_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDrmd128_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); static void CountLength _ANSI_ARGS_ ((ripemd_context* ctx, unsigned int nbytes)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ "ripemd128", sizeof (ripemd_context), DIGEST_SIZE, MDrmd128_Start, MDrmd128_Update, MDrmd128_UpdateBuf, MDrmd128_Final, NULL }; /* *------------------------------------------------------* * * TrfInit_RIPEMD128 -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_RIPEMD128 (interp) Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDrmd128_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDrmd128_Start (context) VOID* context; { ripemd_context* ctx = (ripemd_context*) context; ripemd128_MDinit (ctx->state); memset (ctx->buf, '\0', CHUNK_SIZE); ctx->byteCount = 0; ctx->lowc = 0; ctx->highc = 0; } /* *------------------------------------------------------* * * MDrmd128_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDrmd128_Update (context, character) VOID* context; unsigned int character; { ripemd_context* ctx = (ripemd_context*) context; ctx->buf [ctx->byteCount] = character; ctx->byteCount ++; if (ctx->byteCount == CHUNK_SIZE) { CountLength (ctx, CHUNK_SIZE); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (ctx->buf, CHUNK_SIZE); #endif ripemd128_compress (ctx->state, (dword*) ctx->buf); ctx->byteCount = 0; } } /* *------------------------------------------------------* * * MDrmd128_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDrmd128_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { ripemd_context* ctx = (ripemd_context*) context; if ((ctx->byteCount + bufLen) < CHUNK_SIZE) { /* * Not enough for full chunk. Remember incoming * data and wait for another call containing more data. */ memcpy ((VOID*) (ctx->buf + ctx->byteCount), (VOID*) buffer, bufLen); ctx->byteCount += bufLen; } else { /* * Complete chunk with incoming data, update digest, * then use all chunks contained in the buffer. Remember * an incomplete chunk and wait for further calls. */ int k = CHUNK_SIZE - ctx->byteCount; if (k < CHUNK_SIZE) { memcpy ((VOID*) (ctx->buf + ctx->byteCount), (VOID*) buffer, k); CountLength (ctx, CHUNK_SIZE); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (ctx->buf, CHUNK_SIZE); #endif ripemd128_compress (ctx->state, (dword*) ctx->buf); buffer += k; bufLen -= k; } /* k == CHUNK_SIZE => internal buffer was empty, so skip it entirely */ while (bufLen >= CHUNK_SIZE) { CountLength (ctx, CHUNK_SIZE); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (buffer, CHUNK_SIZE); #endif ripemd128_compress (ctx->state, (dword*) buffer); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (buffer, CHUNK_SIZE); #endif buffer += CHUNK_SIZE; bufLen -= CHUNK_SIZE; } ctx->byteCount = bufLen; if (bufLen > 0) { memcpy ((VOID*) ctx->buf, (VOID*) buffer, bufLen); } } } /* *------------------------------------------------------* * * MDrmd128_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDrmd128_Final (context, digest) VOID* context; VOID* digest; { ripemd_context* ctx = (ripemd_context*) context; CountLength (ctx, ctx->byteCount); ripemd128_MDfinish (ctx->state, ctx->buf, ctx->lowc, ctx->highc); memcpy (digest, ctx->state, DIGEST_SIZE); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (digest, DIGEST_SIZE); #endif } /* *------------------------------------------------------* * * CountLength -- * * ------------------------------------------------* * Update the 64bit counter in the context structure * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void CountLength (ctx, nbytes) ripemd_context* ctx; unsigned int nbytes; { /* update length counter */ if ((ctx->lowc + nbytes) < ctx->lowc) { /* overflow to msb of length */ ctx->highc ++; } ctx->lowc += nbytes; } /* * External code from here on. */ #include "ripemd/rmd128.c" trf2.1.4/generic/init.c0000644000175000017500000001617711216344223014307 0ustar sergeisergei/* * init.c -- * * Implements the C level procedures handling the initialization of this package * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: init.c,v 1.25 2007/10/05 23:12:20 andreas_kupries Exp $ */ #include "transformInt.h" extern TrfStubs trfStubs; /* *------------------------------------------------------* * * Trf_Init -- * * ------------------------------------------------* * Standard procedure required by 'load'. * Initializes this extension. * ------------------------------------------------* * * Sideeffects: * As of 'TrfGetRegistry'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int Trf_Init (interp) Tcl_Interp* interp; { Trf_Registry* registry; int res; #ifdef USE_TCL_STUBS CONST char* actualVersion; actualVersion = Tcl_InitStubs(interp, "8.1", 0); if (actualVersion == NULL) { return TCL_ERROR; } #endif if (Trf_IsInitialized (interp)) { /* * catch multiple initialization of an interpreter */ return TCL_OK; } registry = TrfGetRegistry (interp); if (!registry) { return TCL_ERROR; } #ifdef USE_TCL_STUBS /* * Discern which variant of stacked channels is or can be in use * by the core which loaded us. */ { int major, minor, patchlevel, releasetype; Tcl_GetVersion (&major, &minor, &patchlevel, &releasetype); if (major > 8) { /* Beyond 8.3.2 */ registry->patchVariant = PATCH_832; } else if (major == 8) { if ((minor > 3) || ((minor == 3) && (patchlevel > 1) && (releasetype == TCL_FINAL_RELEASE))) { /* Is 8.3.2 or beyond */ registry->patchVariant = PATCH_832; } else if (minor > 1) { /* Is 8.2 or beyond */ registry->patchVariant = PATCH_82; } else { /* 8.0.x or 8.1.x */ registry->patchVariant = PATCH_ORIG; } } else /* major < 8 */ { Tcl_AppendResult (interp, "Cannot this compilation of Trf with a core below 8.0", (char*) NULL); return TCL_ERROR; } } #endif /* * Register us as a now available package */ PROVIDE (interp, trfStubs); res = TrfInit_Unstack (interp); if (res != TCL_OK) return res; res = TrfInit_Info (interp); if (res != TCL_OK) return res; #ifdef ENABLE_BINIO res = TrfInit_Binio (interp); if (res != TCL_OK) return res; #endif /* * Register error correction algorithms. */ res = TrfInit_RS_ECC (interp); if (res != TCL_OK) return res; /* * Register compressors. */ res = TrfInit_ZIP (interp); if (res != TCL_OK) return res; res = TrfInit_BZ2 (interp); if (res != TCL_OK) return res; /* * Register message digests */ res = TrfInit_CRC (interp); if (res != TCL_OK) return res; res = TrfInit_ADLER (interp); if (res != TCL_OK) return res; res = TrfInit_CRC_ZLIB (interp); if (res != TCL_OK) return res; res = TrfInit_MD5 (interp); if (res != TCL_OK) return res; res = TrfInit_OTP_MD5 (interp); if (res != TCL_OK) return res; res = TrfInit_MD2 (interp); if (res != TCL_OK) return res; res = TrfInit_HAVAL (interp); if (res != TCL_OK) return res; res = TrfInit_SHA (interp); if (res != TCL_OK) return res; res = TrfInit_SHA1 (interp); if (res != TCL_OK) return res; res = TrfInit_OTP_SHA1 (interp); if (res != TCL_OK) return res; res = TrfInit_RIPEMD160 (interp); if (res != TCL_OK) return res; res = TrfInit_RIPEMD128 (interp); if (res != TCL_OK) return res; /* * Register freeform transformation, reflector into tcl level */ res = TrfInit_Transform (interp); if (res != TCL_OK) return res; /* * Register crypt commands for pwd auth. */ res = TrfInit_Crypt (interp); if (res != TCL_OK) return res; /* * Register standard encodings. */ res = TrfInit_Ascii85 (interp); if (res != TCL_OK) return res; res = TrfInit_UU (interp); if (res != TCL_OK) return res; res = TrfInit_B64 (interp); if (res != TCL_OK) return res; res = TrfInit_Bin (interp); if (res != TCL_OK) return res; res = TrfInit_Oct (interp); if (res != TCL_OK) return res; res = TrfInit_OTP_WORDS (interp); if (res != TCL_OK) return res; res = TrfInit_QP (interp); if (res != TCL_OK) return res; return TrfInit_Hex (interp); } /* *------------------------------------------------------* * * Trf_SafeInit -- * * ------------------------------------------------* * Standard procedure required by 'load'. * Initializes this extension for a safe interpreter. * ------------------------------------------------* * * Sideeffects: * As of 'TrfGetRegistry' * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int Trf_SafeInit (interp) Tcl_Interp* interp; { return Trf_Init (interp); } /* *------------------------------------------------------* * * Trf_IsInitialized -- * * ------------------------------------------------* * Checks, wether the extension is initialized in * the specified interpreter. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * 1 if and onlly if the extension is already * initialized in the specified interpreter, * 0 else. * *------------------------------------------------------* */ int Trf_IsInitialized (interp) Tcl_Interp* interp; { Trf_Registry* registry; registry = TrfPeekForRegistry (interp); return registry != (Trf_Registry*) NULL; } #if GT81 && defined (TCL_THREADS) /* THREADING: lock procedures */ /* *------------------------------------------------------* * * Trf(Un)LockIt -- * * ------------------------------------------------* * Internal functions, used to serialize write-access * to several global variables. Required only for * a thread-enabled Tcl 8.1.x and beyond. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * None. * *------------------------------------------------------* */ TCL_DECLARE_MUTEX(trfInitMutex) void TrfLockIt () { Tcl_MutexLock (&trfInitMutex); } void TrfUnlockIt () { Tcl_MutexUnlock (&trfInitMutex); } #endif /* GT81 */ trf2.1.4/generic/trfInt.decls0000644000175000017500000000103511216343142015444 0ustar sergeisergei# trfInt.decls -- # # This file contains the declarations for all unsupported # functions that are exported by the Trf library. This file # is used to generate the trfIntDecls.h file # library trf # Define the unsupported generic interfaces. interface trfInt # Declare each of the functions in the unsupported internal Tcl # interface. These interfaces are allowed to change between versions. # Use at your own risk. Note that the position of functions should not # be changed between versions to avoid gratuitous incompatibilities. trf2.1.4/generic/asc85code.c0000644000175000017500000005045311216344223015115 0ustar sergeisergei/* * asc85code.c -- * * Implements and registers conversion from and to ASCII 85 * representation. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: asc85code.c,v 1.11 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Converter description * --------------------- * * Encoding: * Each sequence of 4 bytes is reinterpreted as 32bit integer number * in bigendian notation and split into into 5 printable characters * via repeated division modulo 85 and addition of character '!'. The * number 0 is a special case and converted to the single character * 'z'. If the last sequence in the input is shorter than 4 bytes, * special processing is invoked: The sequence is padded with 0-bytes, * then converted as usual, but without application of special case 0. * Only the first 'len' bytes written (len being the original number * of bytes in the processed sequence). * * Decoding: * Each sequence of 5 printable characters is converted into a 32bit * integer and the split into 4 bytes (output order is bigendian). A * single character 'z' is converted into 4 0-bytes. If the last * sequence is shorter than 5 bytes, special processing is invoked to * recover the encoded bytes. */ /* * Declarations of internal procedures. */ static Trf_ControlBlock Asc85CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void Asc85DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Asc85Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int Asc85FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void Asc85ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock Asc85CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void Asc85DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Asc85Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int Asc85FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void Asc85ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "ascii85", NULL, /* clientData not used by conversions. */ NULL, /* set later by Trf_InitAscii85 */ /* THREADING: serialize initialization */ { Asc85CreateEncoder, Asc85DeleteEncoder, Asc85Encode, NULL, Asc85FlushEncoder, Asc85ClearEncoder, NULL /* no MaxRead */ }, { Asc85CreateDecoder, Asc85DeleteDecoder, Asc85Decode, NULL, Asc85FlushDecoder, Asc85ClearDecoder, NULL }, TRF_UNSEEKABLE }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (ascii 85) */ unsigned char charCount; unsigned char buf [4]; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (ascii 85) */ unsigned char charCount; unsigned char buf [5]; } DecoderControl; static int CheckQuintuple _ANSI_ARGS_ ((Tcl_Interp* interp, const char* quintuple, int partial)); #define ALL (0) /* *------------------------------------------------------* * * TrfInit_Ascii85 -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Ascii85 (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * Asc85CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock Asc85CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (ascii 85) */ c->charCount = 0; memset (c->buf, '\0', 4); return (ClientData) c; } /* *------------------------------------------------------* * * Asc85DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void Asc85DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (ascii 85) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Asc85Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Asc85Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (ascii 85) */ c->buf [c->charCount] = character; c->charCount ++; if (c->charCount == 4) { char result [5]; int len; unsigned long num; num = ((c->buf [0] << 24) | (c->buf [1] << 16) | (c->buf [2] << 8) | (c->buf [3] << 0)); if (num == 0) { /* * special case 'all zeros' is mapped to 'z' instead of '!!!!!' */ len = 1; result [0] = 'z'; } else { len = 5; result [4] = '!' + (char) (num % 85); num /= 85; result [3] = '!' + (char) (num % 85); num /= 85; result [2] = '!' + (char) (num % 85); num /= 85; result [1] = '!' + (char) (num % 85); num /= 85; result [0] = '!' + (char) (num % 85); num /= 85; } c->charCount = 0; memset (c->buf, '\0', 4); return c->write (c->writeClientData, (unsigned char*) result, len, interp); } return TCL_OK; } /* *------------------------------------------------------* * * Asc85FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Asc85FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (ascii 85) */ if (c->charCount > 0) { char result [5]; int len; unsigned long num; /* * split in the usual way, then write out the head part. * c->buf is already '\0'-padded (due to reset code after every conversion). */ num = ((c->buf [0] << 24) | (c->buf [1] << 16) | (c->buf [2] << 8) | (c->buf [3] << 0)); len = c->charCount + 1; result [4] = '!' + (char) (num % 85); num /= 85; result [3] = '!' + (char) (num % 85); num /= 85; result [2] = '!' + (char) (num % 85); num /= 85; result [1] = '!' + (char) (num % 85); num /= 85; result [0] = '!' + (char) (num % 85); num /= 85; c->charCount = 0; memset (c->buf, '\0', 4); return c->write (c->writeClientData, (unsigned char*) result, len, interp); } return TCL_OK; } /* *------------------------------------------------------* * * Asc85ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void Asc85ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (ascii 85) */ c->charCount = 0; memset (c->buf, '\0', 4); } /* *------------------------------------------------------* * * Asc85CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock Asc85CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (ascii 85) */ c->charCount = 0; memset (c->buf, '\0', 5); return (ClientData) c; } /* *------------------------------------------------------* * * Asc85DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void Asc85DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (ascii 85) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Asc85Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Asc85Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; unsigned char result [4]; int len = 0; /* execute conversion specific code here (ascii 85) */ if ((c->charCount == 0) && (character == 'z')) { /* * convert special case of 'all zero's. */ memset (result, '\0', 4); len = 4; } else { /* * Standard case. */ c->buf [c->charCount] = character; c->charCount ++; if (c->charCount == 5) { unsigned long num = 0; int k; if (TCL_OK != CheckQuintuple (interp, (char*) c->buf, ALL)) return TCL_ERROR; for (k=0; k < 5; k++) { num = num * 85 + (c->buf [k] - '!'); } len = 4; for (k=3; 0 <= k; k --) { /* result [k] = num % 256; num /= 256; */ result [k] = (char) (num & 0xff); num >>= 8; } c->charCount = 0; memset (c->buf, '\0', 5); } } if (len > 0) return c->write (c->writeClientData, result, len, interp); return TCL_OK; } /* *------------------------------------------------------* * * Asc85FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Asc85FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (ascii 85) */ if (c->charCount > 0) { if (c->charCount < 2) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "partial character sequence at end to ", (char*) NULL); Tcl_AppendResult (interp, "short (2 characters required at least)", (char*) NULL); } return TCL_ERROR; } else { /* Partial tuple to convert. * * This is a bit tricky. Binary to ascii conversion * of a partial quadruple yields 5! characters, but * only the first ones were written. During the * number generation these missing values are substituted * by 0, resulting in a value smaller than the one * we started with. Luckily we do know the expected * binary representation (trailing zeros). So we just * have to increment our value to get the correct one. * To make this faster, bit shifting is used. In * addition we do know, that only the upper part is * relevant, so we don't shift up again and avoid * overhead during division. * * Example: * * 'rld' * == 0x72 0x6c 0x64 * == 0x726c6400 * == 1919706112 * == 36 65 78 22 67 * 36 65 78 22 (written) 'Ebo7' * * And now back: * * 36 65 68 22 * == 22584777 * == 1919706045 (after -x-) * == 0x726c63bd * ~~ mask these, then increment next digit by one * -> 0x726c6400 ! * * same effect via shift and increment (/o/) * -> 0x726c64 * retrieve bytes as usual now */ unsigned long num = 0; int partial = c->charCount; int k, zlen; unsigned char result [4]; if (TCL_OK != CheckQuintuple (interp, (char*) c->buf, partial)) return TCL_ERROR; for (k=0; k < partial; k++) { num = num*85 + (c->buf [k] - '!'); } /* -x- */ for (; k < 5; k++) num *= 85; /* /o/ */ partial --; zlen = (4-partial)*8; num = ((num >> zlen) + 1);/* << zlen;*/ for (k = (partial-1); 0 <= k; k--) { /* result [k] = num % 256; num /= 256; */ result [k] = (char) (num & 0xff); num >>= 8; } c->charCount = 0; memset (c->buf, '\0', 5); return c->write (c->writeClientData, result, partial, interp); } } return TCL_OK; } /* *------------------------------------------------------* * * Asc85ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void Asc85ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (ascii 85) */ c->charCount = 0; memset (c->buf, '\0', 5); } /* *------------------------------------------------------* * * CheckQuintuple -- * * ------------------------------------------------* * the specified tuple is checked for correctness. * 'partial > 0' indicates the request to check the * last tuple in the input, its value specifies the * number of bytes the tuple is made of. * ------------------------------------------------* * * Sideeffects: * An error message is placed in the result- * area of the specified interpreter, if the * tuple is illegal for some reason. * * Result: * a standard TCL error code. * *------------------------------------------------------* */ static int CheckQuintuple (interp, quintuple, partial) Tcl_Interp* interp; const char* quintuple; int partial; { #define IN_RANGE(c) (('!' <= (c)) && ((c) <= 'u')) int i, n, ok; n = ((partial > 0) ? partial : 5); /* * Scan tuple for characters out of range !..u * The special case 'z' must have been handled before! */ ok = 1; for (i=0; i < n; i ++) { if (! IN_RANGE (quintuple [i])) { ok = 0; break; } } if (! ok) { if (interp) { char quint [6]; /* * produce string to insert in error message */ for (i=0; i < n; i ++) { quint [i] = quintuple [i]; } quint [i] = '\0'; Tcl_ResetResult (interp); if (partial > 0) { Tcl_AppendResult (interp, "illegal quintuple '", (char*) NULL); Tcl_AppendResult (interp, quint, (char*) NULL); Tcl_AppendResult (interp, "' at end of input (illegal characters)", (char*) NULL); } else { Tcl_AppendResult (interp, "illegal quintuple '", (char*) NULL); Tcl_AppendResult (interp, quint, (char*) NULL); Tcl_AppendResult (interp, "' in input (illegal characters)", (char*) NULL); } } return TCL_ERROR; } #undef IN_RANGE /* Second check (required for complete quintuples only): * Upper limit for encoded value is 2^32-1 == 0xffffffff == s8W-! */ #define EQ(i,x) (quintuple [i] == (x)) #define GR(i,x) (quintuple [i] > (x)) if ((partial == 0) && ((GR (0,'s')) || (EQ (0,'s') && GR (1,'8')) || (EQ (0,'s') && EQ (1,'8') && GR (2, 'W')) || (EQ (0,'s') && EQ (1,'8') && EQ (2, 'W') && GR (3, '-')) || (EQ (0,'s') && EQ (1,'8') && EQ (2, 'W') && EQ (3, '-') && GR (4, '!')))) { if (interp) { char quint [6]; /* produce string to insert in error message */ for (i=0; i < n; i ++) { quint [i] = quintuple [i]; } quint [i] = '\0'; Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal quintuple '", (char*) NULL); Tcl_AppendResult (interp, quint, (char*) NULL); Tcl_AppendResult (interp, "' in input (> 2^32-1)", (char*) NULL); } return TCL_ERROR; } return TCL_OK; } trf2.1.4/generic/crc_zlib.c0000644000175000017500000001307211216344223015122 0ustar sergeisergei/* * crc_zlib.c -- * * Implements and registers message digest generator CRC32 (taken from zlib). * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: crc_zlib.c,v 1.5 2003/01/09 21:27:10 andreas_kupries Exp $ */ #include "transformInt.h" /* * Generator description * --------------------- * * The CRC32 algorithm (contained in library 'zlib') * is used to compute a message digest. */ #define DIGEST_SIZE 4 /* byte == 32 bit */ #define CTX_TYPE uLong /* * Declarations of internal procedures. */ static void MDcrcz_Start _ANSI_ARGS_ ((VOID* context)); static void MDcrcz_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDcrcz_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDcrcz_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); static int MDcrcz_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { "crc-zlib", sizeof (CTX_TYPE), DIGEST_SIZE, MDcrcz_Start, MDcrcz_Update, MDcrcz_UpdateBuf, MDcrcz_Final, MDcrcz_Check }; #define CRC (*((uLong*) context)) /* *------------------------------------------------------* * * TrfInit_CRC_zlib -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_CRC_ZLIB (interp) Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDcrcz_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDcrcz_Start (context) VOID* context; { /* call md specific initialization here */ CRC = zf.zcrc32 (0L, Z_NULL, 0); } /* *------------------------------------------------------* * * MDcrcz_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDcrcz_Update (context, character) VOID* context; unsigned int character; { /* call md specific update here */ unsigned char buf = character; CRC = zf.zcrc32 (CRC, &buf, 1); } /* *------------------------------------------------------* * * MDcrcz_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDcrcz_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { /* call md specific update here */ CRC = zf.zcrc32 (CRC, buffer, bufLen); } /* *------------------------------------------------------* * * MDcrcz_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDcrcz_Final (context, digest) VOID* context; VOID* digest; { /* call md specific finalization here */ uLong crc = CRC; char* out = (char*) digest; /* LITTLE ENDIAN output */ out [3] = (char) ((crc >> 24) & 0xff); out [2] = (char) ((crc >> 16) & 0xff); out [1] = (char) ((crc >> 8) & 0xff); out [0] = (char) ((crc >> 0) & 0xff); } /* *------------------------------------------------------* * * MDcrcz_Check -- * * ------------------------------------------------* * Check for existence of libz, load it. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static int MDcrcz_Check (interp) Tcl_Interp* interp; { return TrfLoadZlib (interp); } trf2.1.4/generic/reflect.c0000644000175000017500000004637411216344224014773 0ustar sergeisergei/* * reflect.c -- * * Implements and registers conversion channel relying on * tcl-scripts to do the conversion. In other words: The * transformation functionality is reflected up into the * tcl-level. In case of binary data this will be usable * only with tcl 8.0 and up. * * * Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: reflect.c,v 1.25 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "reflect.h" /* * Converter description * --------------------- */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int MaxRead _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition reflectDefinition = { "transform", NULL, /* filled by TrfInit_Transform, THREAD: serialize initialization */ NULL, /* filled by TrfInit_Transform, THREAD: serialize initialization */ { CreateEncoder, DeleteEncoder, NULL, EncodeBuffer, FlushEncoder, ClearEncoder, MaxRead }, { CreateDecoder, DeleteDecoder, NULL, DecodeBuffer, FlushDecoder, ClearDecoder, MaxRead }, TRF_UNSEEKABLE }; /* *------------------------------------------------------* * * TrfInit_Transform -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Transform (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ reflectDefinition.options = TrfTransformOptions (); TrfUnlock; return Trf_Register (interp, &reflectDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc* fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { ReflectControl* c; TrfTransformOptionBlock* o = (TrfTransformOptionBlock*) optInfo; int res; c = (ReflectControl*) ckalloc (sizeof (ReflectControl)); c->write = fun; c->writeClientData = writeClientData; c->interp = interp; /* Store reference, tell the interpreter about it. */ c->command = o->command; Tcl_IncrRefCount (c->command); c->maxRead = -1; c->naturalRatio.numBytesTransform = 0; c->naturalRatio.numBytesDown = 0; res = RefExecuteCallback (c, interp, (unsigned char*) "create/write", NULL, 0, TRANSMIT_DONT, 0); if (res != TCL_OK) { Tcl_DecrRefCount (c->command); ckfree ((VOID*) c); return (ClientData) NULL; } return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; RefExecuteCallback (c, NULL, (unsigned char*) "delete/write", NULL, 0, TRANSMIT_DONT, 0); Tcl_DecrRefCount (c->command); ckfree ((VOID*) c); } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; return RefExecuteCallback (c, interp, (unsigned char*) "write", buffer, bufLen, TRANSMIT_DOWN, 1); } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; return RefExecuteCallback (c, interp, (unsigned char*) "flush/write", NULL, 0, TRANSMIT_DOWN, 1); } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; RefExecuteCallback (c, (Tcl_Interp*) NULL, (unsigned char*) "clear/write", NULL, 0, TRANSMIT_DONT, 0); } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc* fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { ReflectControl* c; TrfTransformOptionBlock* o = (TrfTransformOptionBlock*) optInfo; int res; c = (ReflectControl*) ckalloc (sizeof (ReflectControl)); c->write = fun; c->writeClientData = writeClientData; c->interp = interp; c->maxRead = -1; c->naturalRatio.numBytesTransform = 0; c->naturalRatio.numBytesDown = 0; /* Store reference, tell the interpreter about it. */ c->command = o->command; Tcl_IncrRefCount (c->command); res = RefExecuteCallback (c, interp, (unsigned char*) "create/read", NULL, 0, TRANSMIT_DONT, 0); if (res != TCL_OK) { Tcl_DecrRefCount (c->command); ckfree ((VOID*) c); return (ClientData) NULL; } return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; RefExecuteCallback (c, NULL, (unsigned char*) "delete/read", NULL, 0, TRANSMIT_DONT, 0); Tcl_DecrRefCount (c->command); ckfree ((VOID*) c); } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; return RefExecuteCallback (c, interp, (unsigned char*) "read", buffer, bufLen, TRANSMIT_DOWN, 1); } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; return RefExecuteCallback (c, interp, (unsigned char*) "flush/read", NULL, 0, TRANSMIT_DOWN, 1); } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; RefExecuteCallback (c, (Tcl_Interp*) NULL, (unsigned char*) "clear/read", NULL, 0, TRANSMIT_DONT, 0); } /* *------------------------------------------------------* * * MaxRead -- * * ------------------------------------------------* * Query the tcl level of the transformation about * the max. number of bytes to read next time. * ------------------------------------------------* * * Sideeffects: * As of the tcl level. * * Result: * The max. number of bytes to read. * *------------------------------------------------------* */ static int MaxRead (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { ReflectControl* c = (ReflectControl*) ctrlBlock; c->maxRead = -1; /* unbounded consumption */ RefExecuteCallback (c, (Tcl_Interp*) NULL, (unsigned char*) "query/maxRead", NULL, 0, TRANSMIT_NUM /* -> maxRead */, 1); return c->maxRead; } /* *------------------------------------------------------* * * RefExecuteCallback -- * * ------------------------------------------------* * Execute callback for buffer and operation. * ------------------------------------------------* * * Sideeffects: * Everything possible, depending on the * script executed. * * Result: * A standard TCL error code. In case of an * error a message is left in the result area * of the specified interpreter. * *------------------------------------------------------* */ int RefExecuteCallback (c, interp, op, buf, bufLen, transmit, preserve) ReflectControl* c; /* Transformation instance */ Tcl_Interp* interp; /* Interpreter we are running in, possibly NULL */ unsigned char* op; /* Operation to perform by the tcl-level */ unsigned char* buf; /* Data for the operation */ int bufLen; /* Length of data above */ int transmit; /* What to do with the result, see TRANSMIT_xxx */ int preserve; /* Preserve result of transformation interp ? y/n */ { /* * Step 1, create the complete command to execute. Do this by appending * operation and buffer to operate upon to a copy of the callback * definition. We *cannot* create a list containing 3 objects and then use * 'Tcl_EvalObjv', because the command may contain additional prefixed * arguments. Feathers curried commands would come in handy here. */ int res = TCL_OK; Tcl_Obj* resObj; /* See below, switch (transmit) */ Tcl_Obj** listObj; int resLen; unsigned char* resBuf; #if GT81 Tcl_SavedResult ciSave; #endif Tcl_Obj* command; Tcl_Obj* temp; START (RefExecuteCallback); PRINT ("args = (%s | %d | %d | %d)\n", op, bufLen, transmit, preserve); FL; command = Tcl_DuplicateObj (c->command); #if GT81 if (preserve) { PRINTLN ("preserve"); Tcl_SaveResult (c->interp, &ciSave); } #endif if (command == (Tcl_Obj*) NULL) { /* Memory allocation problem */ res = TCL_ERROR; PRINT ("command not duplicated @ %d\n", __LINE__); goto cleanup; } Tcl_IncrRefCount (command); temp = Tcl_NewStringObj ((char*) op, -1); if (temp == (Tcl_Obj*) NULL) { /* Memory allocation problem */ PRINT ("op object not allocated @ %d\n", __LINE__); res = TCL_ERROR; goto cleanup; } res = Tcl_ListObjAppendElement (interp, command, temp); if (res != TCL_OK) goto cleanup; /* * Use a byte-array to prevent the misinterpretation of binary data * coming through as UTF while at the tcl level. */ #if GT81 temp = Tcl_NewByteArrayObj (buf, bufLen); #else temp = Tcl_NewStringObj ((char*) buf, bufLen); #endif if (temp == (Tcl_Obj*) NULL) { /* Memory allocation problem */ #if GT81 PRINT ("bytearray not allocated @ %d\n", __LINE__); #else PRINT ("string not allocated @ %d\n", __LINE__); #endif res = TCL_ERROR; goto cleanup; } res = Tcl_ListObjAppendElement (interp, command, temp); if (res != TCL_OK) goto cleanup; /* * Step 2, execute the command at the global level of the interpreter * used to create the transformation. Destroy the command afterward. * If an error occured, the current interpreter is defined and not equal * to the interpreter for the callback, then copy the error message into * current interpreter. Don't copy if in preservation mode. */ res = Tcl_GlobalEvalObj (c->interp, command); Tcl_DecrRefCount (command); command = (Tcl_Obj*) NULL; if (res != TCL_OK) { /* copy error message from 'c->interp' to actual 'interp'. */ if ((interp != (Tcl_Interp*) NULL) && (c->interp != interp) && !preserve) { Tcl_SetObjResult (interp, Tcl_GetObjResult (c->interp)); } PRINTLN ("!error"); FL; goto cleanup; } /* * Step 3, transmit a possible conversion result to the underlying * channel, or ourselves */ switch (transmit) { case TRANSMIT_DONT: /* nothing to do */ break; case TRANSMIT_DOWN: /* Caller said to expect data in interpreter result area. * Take it, then write it out to the channel system. */ resObj = Tcl_GetObjResult (c->interp); #if GT81 resBuf = (unsigned char*) Tcl_GetByteArrayFromObj (resObj, &resLen); #else resBuf = (unsigned char*) Tcl_GetStringFromObj (resObj, &resLen); #endif res = c->write (c->writeClientData, resBuf, resLen, interp); break; case TRANSMIT_NUM: /* Interpret result as integer number */ resObj = Tcl_GetObjResult (c->interp); Tcl_GetIntFromObj (c->interp, resObj, &c->maxRead); break; case TRANSMIT_RATIO: /* Result should be 2-element list. Ignore superfluous list elements. */ resObj = Tcl_GetObjResult (c->interp); resLen = -1; res = Tcl_ListObjLength(c->interp, resObj, &resLen); c->naturalRatio.numBytesTransform = 0; c->naturalRatio.numBytesDown = 0; if ((res != TCL_OK) || (resLen < 2)) { PRINT ("TRANSMIT_RATIO problem (%d, %d)\n", res == TCL_OK, resLen); PRINTLN ("reset result"); Tcl_ResetResult (c->interp); goto cleanup; } res = Tcl_ListObjGetElements(c->interp, resObj, &resLen, &listObj); Tcl_GetIntFromObj (c->interp, listObj [0], &c->naturalRatio.numBytesTransform); Tcl_GetIntFromObj (c->interp, listObj [1], &c->naturalRatio.numBytesDown); break; } PRINTLN ("reset result"); Tcl_ResetResult (c->interp); #if GT81 if (preserve) { PRINTLN ("restore"); Tcl_RestoreResult (c->interp, &ciSave); } #endif DONE (RefExecuteCallback); return res; cleanup: PRINTLN ("cleanup..."); #if GT81 if (preserve) { PRINTLN ("restore"); Tcl_RestoreResult (c->interp, &ciSave); } #endif if (command != (Tcl_Obj*) NULL) { PRINTLN ("decr-ref command"); Tcl_DecrRefCount (command); } DONE (RefExecuteCallback); return res; } trf2.1.4/generic/otpsha1.c0000644000175000017500000000052411216344223014710 0ustar sergeisergei/* otpsha1.c - the OTP variant of SHA1 */ /* ideally we would like to define a new argument in dig_opt.c that allows us to turn the OTP variant on and off. unfortunately, the variant dictates the size of the resulting digest and that's one thing that's compile time. hence, the hack du'jour... */ #define OTP #include "sha1.c" trf2.1.4/generic/util.c0000644000175000017500000002531211216344224014311 0ustar sergeisergei/* * util.c -- * * Implements helper procedures used by 3->4 encoders (uu, base64) * and other useful things. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: util.c,v 1.9 2007/10/05 23:12:24 andreas_kupries Exp $ */ #include "transformInt.h" static void Split _ANSI_ARGS_ ((CONST char* in, char* out)); /* *------------------------------------------------------* * * TrfSplit3to4 -- * * ------------------------------------------------* * Splits every 3 bytes of input into 4 bytes, * actually 6-bit values and places them in the * target. Padding at the end is done with a value * of '64' (6 bit -> values in range 0..63). * This feature is used by 'TrfApplyEncoding'. * 'length' must be in the range 1, ..., 3. * ------------------------------------------------* * * Sideeffects: * 'out' is changed. * * Result: * See above. * * *------------------------------------------------------* */ void TrfSplit3to4 (in, out, length) CONST unsigned char* in; unsigned char* out; int length; { if (length == 3) { Split ((char*) in, (char*) out); } else { char buf [3]; /* expand incomplete sequence with with '\0' */ memset (buf, '\0', 3); memcpy (buf, in, length); Split (buf, (char*) out); switch (length) { case 1: out [2] = 64; out [3] = 64; break; case 2: out [3] = 64; break; case 0: default: /* should not happen */ Tcl_Panic ("illegal length given to TrfSplit3to4"); } } } /* *------------------------------------------------------* * * TrfMerge4to3 -- * * ------------------------------------------------* * takes 4 bytes from 'in' (6-bit values) and * merges them into 3 bytes (8-bit values). * ------------------------------------------------* * * Sideeffects: * The generated bytes are written to 'out'. * * Results: * See above. * *------------------------------------------------------* */ void TrfMerge4to3 (in, out) CONST unsigned char* in; unsigned char* out; { #define TRF_MASK(i,by,mask) ((in [i] by) & mask) /* * use temp storage to prevent problems in case of * 'in', 'out' overlapping each other. */ unsigned char o1, o2, o3; o1 = TRF_MASK (0, << 2, 0374) | TRF_MASK (1, >> 4, 003); o2 = TRF_MASK (1, << 4, 0360) | TRF_MASK (2, >> 2, 017); o3 = TRF_MASK (2, << 6, 0300) | TRF_MASK (3, >> 0, 077); out [0] = o1; out [1] = o2; out [2] = o3; #undef TRF_MASK } /* *------------------------------------------------------* * * -- * * ------------------------------------------------* * transform 6-bit values into real characters * according to the specified character-mapping. * The map HAS TO contain at least 65 characters, * the last one being the PAD character to use. * ------------------------------------------------* * * Sideeffects: * The characters are read from and written * to 'buf'. * * Results: * See above. * *------------------------------------------------------* */ void TrfApplyEncoding (buf, length, map) unsigned char* buf; int length; CONST char* map; { int i; for (i=0; i < length; i++) { buf [i] = map [buf [i]]; } } /* *------------------------------------------------------* * * TrfReverseEncoding -- * * ------------------------------------------------* * The given string is converted in place into its * equivalent binary representation. The procedure * assummes the string to be encoded with a 3->4 * byte scheme (such as uuencding, base64). * * The map HAS TO contain at least 256 characters. * It is indexed by an 8 bit value to get the 6-bit * binary field corresponding to that value. Any * illegal characters must have the high bit set. * ------------------------------------------------* * * Sideeffects: * The characters are read from and written * to 'buf'. * * Result: * A standard TCL error code * 'hasPadding' returns the number unused * bytes in buf (0..3). * *------------------------------------------------------* */ int TrfReverseEncoding (buf, length, reverseMap, padChar, hasPadding) unsigned char* buf; int length; CONST char* reverseMap; unsigned int padChar; int* hasPadding; { /* * length has to be in the range 1..4. */ int i, pad, maplen; if ((length < 1) || (length > 4)) { Tcl_Panic ("illegal length given to TrfReverseEncoding"); } pad = 4 - length; /* check for more pad chars */ for (i=length-1; (i >= 0) && (padChar == buf [i]); pad++, i--) { buf [i] = '\0'; } if (pad > 2) /* * Only xxxx, xxx= and xx== allowed * (with x as legal character and = as pad-char. */ return TCL_ERROR; *hasPadding = pad; maplen = i+1; /* convert characters to 6-bit values */ for (i=0; i < maplen; i++) { char tmp = reverseMap [buf [i]]; if (tmp & 0x80) /* high-bit set? => illegal character */ return TCL_ERROR; buf [i] = tmp; } return TCL_OK; } /* *------------------------------------------------------* * * Split -- * * ------------------------------------------------* * takes 3 bytes from 'in', splits them into * 4 6-bit values and places them then into 'out'. * ------------------------------------------------* * * Sideeffects: * The generated characters are written to * 'out'. * * Results: * See above. * *------------------------------------------------------* */ static void Split (in, out) CONST char* in; char* out; { out [0] = (077 & (in [0] >> 2)); out [1] = (077 & (((in [0] << 4) & 060) | ((in [1] >> 4) & 017))); out [2] = (077 & (((in [1] << 2) & 074) | ((in [2] >> 6) & 03))); out [3] = (077 & (in [2] & 077)); } /* *------------------------------------------------------* * * Trf_XorBuffer -- * * ------------------------------------------------* * Do an 'exclusive or' of all 'length' bytes in * 'buffer' with the corresponding bytes in 'mask'. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ void Trf_XorBuffer (buffer, mask, length) VOID* buffer; VOID* mask; int length; { unsigned char* b = (unsigned char*) buffer; unsigned char* m = (unsigned char*) mask; while (length > 0) { *b++ ^= *m++; length --; } } /* *------------------------------------------------------* * * Trf_ShiftRegister -- * * ------------------------------------------------* * Take the 'shift' leftmost bytes of 'mask' and * shift them into the rightmost bytes of 'buffer'. * The leftmost bytes of 'buffer' are lost. Both * buffers are assumed to be of size 'length'. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * none. * *------------------------------------------------------* */ void Trf_ShiftRegister (buffer, mask, shift, length) VOID* buffer; VOID* mask; int shift; int length; { assert (shift > 0); if (shift == length) { /* * Special case: Drop the whole old register. */ memcpy (buffer, mask, length); } else { unsigned char* b = (unsigned char*) buffer; unsigned char* m = (unsigned char*) mask; int retained; /* number bytes in 'buffer' to retain */ retained = length - shift; /* left-shift retained bytes of 'buffer' over by * 'shift' bytes to create space for new bytes */ while (retained --) { *b = *(b + shift); b ++; } /* now copy 'shift' bytes from 'input' to shifted tail of 'buffer' */ do { *b++ = *m++; } while (--shift); } } /* *------------------------------------------------------* * * Trf_FlipRegisterShort -- * * ------------------------------------------------* * Swap the bytes for all 2-Byte words contained in * the register. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * none. * *------------------------------------------------------* */ void Trf_FlipRegisterShort (buffer, length) VOID* buffer; int length; { unsigned char tmp; unsigned char* b = (unsigned char*) buffer; int n_shorts = length / 2; int i; for (i=0; i < n_shorts; i++, b+= 2) { tmp = b [0]; b [0] = b [1]; b [1] = tmp; } } /* *------------------------------------------------------* * * Trf_FlipRegisterLong -- * * ------------------------------------------------* * Swap the bytes for all 4-Byte words contained in * the register. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * none. * *------------------------------------------------------* */ void Trf_FlipRegisterLong (buffer, length) VOID* buffer; int length; { unsigned char tmp; unsigned char* b = (unsigned char*) buffer; int n_longs = length / 4; int i; /* * 0 -> 3 * 1 -> 2 * 2 -> 1 * 3 -> 0 */ for (i=0; i < n_longs; i++, b+= 4) { tmp = b [0]; b [0] = b [3]; b [3] = tmp; tmp = b [1]; b [1] = b [2]; b [2] = tmp; } } /* *------------------------------------------------------* */ /* internal procedures, for testing */ void TrfDumpHex (f, buffer, length, next) FILE* f; VOID* buffer; int length; int next; { short i; unsigned char* b = (unsigned char*) buffer; for (i=0; i < length; i++) fprintf (f, "%02x", (unsigned int) (b [i])); switch (next) { case 0: break; case 1: fprintf (f, " "); break; case 2: fprintf (f, "\n"); break; } } void TrfDumpShort (f, buffer, length, next) FILE* f; VOID* buffer; int length; int next; { short i; unsigned short* b = (unsigned short*) buffer; for (i=0; i < (length/2); i++) fprintf (f, "%06d ", (unsigned int) (b [i])); switch (next) { case 0: break; case 1: fprintf (f, " "); break; case 2: fprintf (f, "\n"); break; } } trf2.1.4/generic/transform.h0000644000175000017500000007555611216344305015373 0ustar sergeisergei#ifndef TRF_H #define TRF_H /* -*- c -*- * * transform.h - externally visible facilities of data transformers * * Distributed at MAY-06-2009. * * Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: transform.h,v 1.23 2009/05/07 05:30:35 andreas_kupries Exp $ */ #ifdef __cplusplus extern "C" { #endif #include /* * Definition of module version */ /* #define TRF_VERSION "2.1" #define TRF_MAJOR_VERSION 2 #define TRF_MINOR_VERSION 1 */ /* * Definitions to enable the generation of a DLL under Windows. * Taken from 'ftp://ftp.sunlabs.com/pub/tcl/example.zip(example.c)' */ #if defined(__WIN32__) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN /* * VC++ has an alternate entry point called DllMain, so we need to rename * our entry point. */ #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_Trf # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #endif # if defined(_MSC_VER) # define TRF_EXPORT(a,b) TCL_STORAGE_CLASS a b # else # if defined(__BORLANDC__) # define TRF_EXPORT(a,b) a _export b # else # define TRF_EXPORT(a,b) a b # endif # endif #else # define TRF_EXPORT(a,b) a b #endif /* * Exported tcl level procedures. * * ATTENTION: * due to the fact that cpp - processing with gcc 2.5.8 removes any comments * in macro-arguments (even if called with option '-C') i have to use the * predefined macro __C2MAN__ to distinguish real compilation and manpage * generation, removing _ANSI_ARGS_ in the latter case. */ /* * Initialize extension in standard interpreter. * Extends the interpreter with extension-specific * structures and installs the globally visible * command of Tcl-TRF. Will catch attempts for * multiple initialization of an interpreter. */ #ifdef __C2MAN__ int Trf_Init (Tcl_Interp* interp /* interpreter to initialize */); #else TRF_EXPORT (int,Trf_Init) _ANSI_ARGS_ ((Tcl_Interp* interp)); #endif /* * Initialize extension in SAFE interpreter. * Same as --> Trf_Init. The only security * relevant operations are reading from and * writing to a file. As Tcl-Handles are * given to these commands it is assumed that * they were checked and cleared beforehand. */ #ifdef __C2MAN__ int Trf_SafeInit (Tcl_Interp* interp /* interpreter to initialize */); #else TRF_EXPORT (int,Trf_SafeInit) _ANSI_ARGS_ ((Tcl_Interp* interp)); #endif /* * Check initialization state of specified interpreter. * Check, wether this extension was initialized for the * specified interpreter or not. */ #ifdef __C2MAN__ int Trf_IsInitialized (Tcl_Interp* interp /* interpreter to check for initialization */); #else #ifndef TRF_USE_STUBS TRF_EXPORT (int,Trf_IsInitialized) _ANSI_ARGS_ ((Tcl_Interp* interp)); #endif #endif /* * Exported C level facilities. */ /* * Interface to registry of conversion procedures. */ /* * Structure used to remember the values of fundamental option(s). * The values currently defined remember: * * Handle and access-mode of the channel specified as argument * to option '-attach'. * * Handle of channel specified as argument to '-in'. * * Handle of channel specified as argument to '-out'. * * Name of the seek policy requested by the user. */ typedef struct _Trf_BaseOptions_ { Tcl_Channel attach; /* NULL => immediate mode */ int attach_mode; /* access mode of 'attach' (if not NULL) */ /* Relevant in immediate mode only! (attach == NULL) */ Tcl_Channel source; /* NULL => use non option argument as input */ Tcl_Channel destination; /* NULL => leave transformation result in * interpreter result area */ Tcl_Obj* policy; /* Refers to string object containing the seek policy * to use, if overiding the chosen one is allowed! */ } Trf_BaseOptions; /* * prototypes for procedures used to specify a data transformer. * * 1) vectors for option processing * 2) vectors for data encode/decode. */ /* * opaque type for access to option structures. * mainly defined for more readability of the prototypes following. */ typedef ClientData Trf_Options; /* * Interface to procedures to create a container holding option values. * It is the responsibility of the procedure to create and * initialize a container to hold option values. An opaque * handle to the new container has to be returned. */ #ifdef __C2MAN__ typedef Trf_Options Trf_CreateOptions (ClientData clientData /* arbitrary information, as defined in * Trf_TypeDefinition.clientData */); #else typedef Trf_Options Trf_CreateOptions _ANSI_ARGS_ ((ClientData clientData)); #endif /* * Interface to proceduress to delete a container made with 'Trf_CreateOptions'. * It is the responsibility of this procedure to clear and release * all memory of the specified container (which must have been * created by the corresponding procedure of type 'Trf_CreateOptions'). */ #ifdef __C2MAN__ typedef void Trf_DeleteOptions (Trf_Options options, /* the container to destroy */ ClientData clientData /* arbitrary information, as defined in * Trf_TypeDefinition.clientData */); #else typedef void Trf_DeleteOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); #endif /* * Interface to procedures to check an option container. * The procedure has to check the contents of the specified * container for errors, consistency, etc. It is allowed to * set default values into unspecified slots. Return value * is a standard tcl error code. In case of failure and interp * not NULL an error message should be left in the result area * of the specified interpreter. */ #ifdef __C2MAN__ typedef int Trf_CheckOptions (Trf_Options options, /* container with options to check */ Tcl_Interp* interp, /* interpreter to write error * messages to (NULL possible!) */ CONST Trf_BaseOptions* baseOptions, /* info about common options */ ClientData clientData /* arbitrary information, as defined * in * Trf_TypeDefinition.clientData */); #else typedef int Trf_CheckOptions _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST Trf_BaseOptions* baseOptions, ClientData clientData)); #endif /* * Interface to procedures to define the value of an option. * The procedure takes the specified optionname (rejecting * illegal ones) and places the given optionvalue into the * container. All necessary conversions from a string to the * required type should be done here. Return value is a standard * tcl error code. In case of failure and interp not NULL an * error message should be left in the result area of the * specified interpreter. */ #ifdef __C2MAN__ typedef int Trf_SetOption (Trf_Options options, /* container to place the value into */ Tcl_Interp* interp, /* interpreter for error messages * (NULL possible) */ CONST char* optname, /* name of option to define */ CONST char* optvalue, /* value to set into the container */ ClientData clientData /* arbitrary information, as defined in * Trf_TypeDefinition.clientData */); #else typedef int Trf_SetOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST char* optvalue, ClientData clientData)); #endif #if (TCL_MAJOR_VERSION < 8) #define Tcl_Obj VOID /* create dummy for missing definition */ #endif /* * Interface to procedures to define the value of an option. * The procedure takes the specified optionname (rejecting * illegal ones) and places the given optionvalue into the * container. All necessary conversions from a Tcl_Obj to the * required type should be done here. Return value is a standard * tcl error code. In case of failure and interp not NULL an * error message should be left in the result area of the * specified interpreter. This procedure makes sense for tcl * version 8 and above only */ #ifdef __C2MAN__ typedef int Trf_SetObjOption (Trf_Options options, /* container to place the value into */ Tcl_Interp* interp, /* interpreter for error messages * (NULL possible) */ CONST char* optname, /* name of option to define */ CONST Tcl_Obj* optvalue, /* value to set into the container */ ClientData clientData /* arbitrary information, as defined in * Trf_TypeDefinition.clientData */); #else typedef int Trf_SetObjOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST Tcl_Obj* optvalue, ClientData clientData)); #endif /* * Interface to procedures to query an option container. * The result value decides wether the encoder- or decoder-set of vectors * must be used during immediate execution of the transformer configured * with the container contents. * * Returns: * 0: use decoder. * 1: use encoder. */ #ifdef __C2MAN__ typedef int Trf_QueryOptions (Trf_Options options, /* option container to query */ ClientData clientData /* arbitrary information, as defined in * Trf_TypeDefinition.clientData */); #else typedef int Trf_QueryOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); #endif typedef struct _Trf_SeekInformation_ Trf_SeekInformation; /* * Interface to procedures to query an option container. * The procedure is allowed to change the natural seek policy defined for the * transformation according to the current configuration. * * Returns: * Nothing. */ #ifdef __C2MAN__ typedef void Trf_SeekQueryOptions (Tcl_Interp* interp /* Interpreter to use * for reflecting the * query up into tcl, * if necessary */, Trf_Options options, /* option container * to query */ Trf_SeekInformation* seekInfo, /* The policy to modify */ ClientData clientData /* arbitrary * information, as * defined in * Trf_TypeDefinition.clientData */); #else typedef void Trf_SeekQueryOptions _ANSI_ARGS_ ((Tcl_Interp* interp, Trf_Options options, Trf_SeekInformation* seekInfo, ClientData clientData)); #endif /* * Structure to hold all vectors describing the processing of a specific * option set. The 5 vectors are used to create and delete containers, to * check them for errors, to set option values and to query them for usage * of encoder or decoder vectors. */ typedef struct _Trf_OptionVectors_ { Trf_CreateOptions* createProc; /* create container for option information */ Trf_DeleteOptions* deleteProc; /* delete option container */ Trf_CheckOptions* checkProc; /* check defined options for consistency, errors, ... */ Trf_SetOption* setProc; /* define an option value */ Trf_SetObjOption* setObjProc; /* define an option value via Tcl_Obj (Tcl 8.x) */ Trf_QueryOptions* queryProc; /* query, wether encode (1) / decode (0) requested by options */ Trf_SeekQueryOptions* seekQueryProc; /* query options about changes to the natural seek policy */ } Trf_OptionVectors; /* * opaque type for access to the control structures of an encoder/decoder. * mainly defined for more readability of the following prototypes. */ typedef ClientData Trf_ControlBlock; /* * Interface to procedures used by an encoder/decoder to write its transformation results. * Procedures of this type are called by an encoder/decoder to write * (partial) transformation results, decoupling the final destination * from result generation. Return value is a standard tcl error code. In * case of failure and interp not NULL an error message should be left * in the result area of the specified interpreter. */ #ifdef __C2MAN__ typedef int Trf_WriteProc (ClientData clientData /* arbitrary information, defined during * controlblock creation */, unsigned char* outString /* buffer with characters to write */, int outLen /* number of characters in buffer */, Tcl_Interp* interp /* interpreter for error messages * (NULL possible) */); #else typedef int Trf_WriteProc _ANSI_ARGS_ ((ClientData clientData, unsigned char* outString, int outLen, Tcl_Interp* interp)); #endif /* * Interface to procedure for creation of encoder/decoder control structures. * The procedure has to create a control structure for an encoder/decoder. The * structure must be initialized with the contents of the the option * container. Return value is an opaque handle aof the control structure or NULL * in case of failure. An error message should be left in the result area * of the specified interpreter then. */ #ifdef __C2MAN__ typedef Trf_ControlBlock Trf_CreateCtrlBlock (ClientData writeClientData /* arbitrary information * given as clientdata * to 'fun' */, Trf_WriteProc* fun /* vector to use for writing * generated results */, Trf_Options optInfo /* options to configure the * control */, Tcl_Interp* interp /* interpreter for error * messages */, ClientData clientData /* arbitrary information, * as defined in * Trf_TypeDefinition.clientData */); #else typedef Trf_ControlBlock Trf_CreateCtrlBlock _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); #endif /* * Interface to procedure for destruction of encoder/decoder control structures. * It is the responsibility of the procedure to clear and release all memory * associated to the specified control structure (which must have been created * by the appropriate procedure of type 'Trf_CreateCtrlBlock'). */ #ifdef __C2MAN__ typedef void Trf_DeleteCtrlBlock (Trf_ControlBlock ctrlBlock /* control structure to destroy */, ClientData clientData /* arbitrary information, as defined in * Trf_TypeDefinition.clientData */); #else typedef void Trf_DeleteCtrlBlock _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); #endif /* * Interface to procedures for transformation of a single character. * A procedure of this type is called to encode/decode a single * character. Return value is a standard tcl error code. In case of * failure and interp not NULL an error message should be left in the * result area of the specified interpreter. Only one of 'Trf_TransformCharacter' * and 'Trf_TransformBuffer' must be provided. This one is easier to * implement, the second one should be faster. If both are * provided, -> 'Trf_TransformBuffer' takes precedence. */ #ifdef __C2MAN__ typedef int Trf_TransformCharacter (Trf_ControlBlock ctrlBlock /* state of encoder/decoder */, unsigned int character /* character to transform */, Tcl_Interp* interp /* interpreter for error messages * (NULL possible) */, ClientData clientData /* arbitrary information, as defined * in Trf_TypeDefinition.clientData */); #else typedef int Trf_TransformCharacter _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); #endif /* * Interface to procedures for transformation of character sequences. * A procedure of this type is called to encode/decode a complete buffer. Return * value is a standard tcl error code. In case of failure and interp not * NULL an error message should be left in the result area of the specified * interpreter. Only one of 'Trf_TransformCharacter' and 'Trf_TransformBuffer' * must be provided. The first named is easier to implement, this one should be * faster. If both are provided, -> 'Trf_TransformBuffer' takes precedence. */ #ifdef __C2MAN__ typedef int Trf_TransformBuffer (Trf_ControlBlock ctrlBlock /* state of encoder/decoder */, unsigned char* buf /* characters to transform */, int bufLen /* number of characters */, Tcl_Interp* interp /* interpreter for error messages * (NULL possible) */, ClientData clientData /* arbitrary information, as defined * in Trf_TypeDefinition.clientData */); #else typedef int Trf_TransformBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buf, int bufLen, Tcl_Interp* interp, ClientData clientData)); #endif /* * Interface to procedures used to flush buffered characters. * An encoder/decoder is allowed to buffer characters internally. A procedure * of this type is called just before destruction to invoke special processing * of such characters. Return value is a standard tcl error code. In case of * failure and interp not NULL an error message should be left in the result * area of the specified interpreter. */ #ifdef __C2MAN__ typedef int Trf_FlushTransformation (Trf_ControlBlock ctrlBlock /* state of encoder/decoder */, Tcl_Interp* interp /* interpreter for error messages * (NULL posssible) */, ClientData clientData /* arbitrary information, as defined in * Trf_TypeDefinition.clientData */); #else typedef int Trf_FlushTransformation _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); #endif /* * Interface for procedures to reset the internal state of an encoder/decoder. * The generic io layer of tcl sometimes discards its input buffer. A procedure * of this type will be called in such a case to reset the internal state of * the control structure and to discard buffered characters. */ #ifdef __C2MAN__ typedef void Trf_ClearCtrlBlock (Trf_ControlBlock ctrlBlock /* state of * encoder/decoder */, ClientData clientData /* arbitrary * information, * as defined in * Trf_TypeDefinition.clientData */); #else typedef void Trf_ClearCtrlBlock _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); #endif /* * Interface for procedures to query a transformation about the max. number of bytes to read in the next call to the down channel. * This procedure will be called by the generic trf layer just before reading * data from the channel below the transformation. This way a transformation * is able to control its consumption of characters. An example would be * 'identity with stop after n characters'. This would transfer at most n * characters and then basically fake higher transformations into believing * that EOF occured. Then popping it would reveal the truth. Pattern matching * could be used here too (internet protocols !). */ #ifdef __C2MAN__ typedef int Trf_QueryMaxRead (Trf_ControlBlock ctrlBlock /* state of * encoder/decoder */, ClientData clientData /* arbitrary * information, as * defined in * Trf_TypeDefinition.clientData */); #else typedef int Trf_QueryMaxRead _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); #endif /* * Structure to hold all vectors describing a specific encoder/decoder. * The 5 vectors are ussed to create and delete the controlblock of the * encoder/coder, to transform a single character, to flush all internal * buffers and to reset the control. */ typedef struct _Trf_Vectors_ { Trf_CreateCtrlBlock* createProc; /* create control structure */ Trf_DeleteCtrlBlock* deleteProc; /* delete control structure */ Trf_TransformCharacter* convertProc; /* process a single character */ Trf_TransformBuffer* convertBufProc; /* process a buffer of characters */ Trf_FlushTransformation* flushProc; /* flush possibly buffered * characters */ Trf_ClearCtrlBlock* clearProc; /* reset internal control, clear * buffers */ Trf_QueryMaxRead* maxReadProc; /* Query max. number of characters * to read next time. Possibly NULL. */ } Trf_Vectors; /* * Information about a seek policy. Just the ratio of input to output, if * attached with encode on write. If either one of the values is * zero, the transformation is considered to be unseekable. */ struct _Trf_SeekInformation_ { int numBytesTransform; /* #Bytes used by the transformation as input */ int numBytesDown; /* #Bytes produced for every 'numBytesTransform' */ }; /* * Structure describing a complete transformation. * Consists of option processor and vectors for encoder, decoder. */ typedef struct _Trf_TypeDefinition_ { CONST char* name; /* name of transformation, also name of * created command */ ClientData clientData; /* reference to arbitrary information. * This information is given to all vectors * mentioned below. */ Trf_OptionVectors* options; /* reference to option description, can be * shared between transformation descriptions */ Trf_Vectors encoder; /* description of encoder */ Trf_Vectors decoder; /* description of decoder */ Trf_SeekInformation naturalSeek; /* Information about the natural seek * policy. Compile time configuration. */ } Trf_TypeDefinition; #define TRF_UNSEEKABLE {0, 0} #define TRF_RATIO(in,out) {in, out} /* * Register the specified transformation at the given interpreter. * Extends the given interpreter with a new command giving access * to the transformation described in 'type'. 'type->name' is used * as name of the command. */ #ifdef __C2MAN__ int Trf_Register (Tcl_Interp* interp, /* interpreter to register at */ CONST Trf_TypeDefinition* type /* transformation to register */); #else #ifndef TRF_USE_STUBS TRF_EXPORT (int,Trf_Register) _ANSI_ARGS_ ((Tcl_Interp* interp, CONST Trf_TypeDefinition* type)); #endif #endif /* * Interfaces for easier creation of certain classes of * transformations (message digests) */ /* * transformer class: conversions. * * There is no easier way to create a conversion transformer than * to create it from scratch (use template/cvt_template.c as * template). Additionally the option processor returned below must * be used. */ /* * Return the set of option processing procedures required by conversion transformers. */ #ifdef __C2MAN__ Trf_OptionVectors* Trf_ConverterOptions (void); #else TRF_EXPORT (Trf_OptionVectors*,Trf_ConverterOptions) _ANSI_ARGS_ ((void)); #endif /* * Structure to hold the option information required by conversion transformers. * A structure of this type is created and manipulated by the set of procedures * returned from 'Trf_ConverterOptions'. */ typedef struct _Trf_ConverterOptionBlock { int mode; /* converter mode */ } Trf_ConverterOptionBlock; /* * Posssible modes of a conversions transformer: * * UNKNOWN: initial value, unspecified mode * ENCODE: encode characters * DECODE: decode characters */ #define TRF_UNKNOWN_MODE (0) #define TRF_ENCODE_MODE (1) #define TRF_DECODE_MODE (2) /* * transformer class: message digests. * * The implementation of a message digest algorithm requires * 3 procedures interfacing the special MD-code with the common * code contained in this module (dig_opt.c, digest.c). */ /* * Interface to procedures for initialization of a MD context. * A procedure of this type is called to initialize the structure * containing the state of a special message digest algorithm. The * memory block was allocated by the caller, with the size as specified * in the 'Trf_MessageDigestDescription' structure of the algorithm. */ #ifdef __C2MAN__ typedef void Trf_MDStart (VOID* context /* state to initialize */); #else typedef void Trf_MDStart _ANSI_ARGS_ ((VOID* context)); #endif /* * Interface to procedures for update of a MD context. * A procedure of this type is called for every character to hash * into the final digest. */ #ifdef __C2MAN__ typedef void Trf_MDUpdate (VOID* context /* state to update */, unsigned int character /* character to hash into the state */); #else typedef void Trf_MDUpdate _ANSI_ARGS_ ((VOID* context, unsigned int character)); #endif /* * Interface to procedures for update of a MD context. * A procedure of this type is called for character buffer to hash * into the final digest. This procedure is optional, its definition * has precedence over 'Trf_MDUpdate'. */ #ifdef __C2MAN__ typedef void Trf_MDUpdateBuf (VOID* context /* state to update */, unsigned char* buf /* buffer to hash into the state */, int bufLen /* number of characters in the buffer */); #else typedef void Trf_MDUpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); #endif /* * Interface to procedures for generation of the final digest from a MD state. * A procedure of this type is called after processing the final character. It * is its responsibility to finalize the internal state of the MD algorithm and * to generate the resulting digest from this. */ #ifdef __C2MAN__ typedef void Trf_MDFinal (VOID* context /* state to finalize */, VOID* digest /* result area to fill */); #else typedef void Trf_MDFinal _ANSI_ARGS_ ((VOID* context, VOID* digest)); #endif /* * Interface to procedures for check/manipulation of the environment (shared libraries, ...). * A procedure of this type is called before doing any sort of processing. */ #ifdef __C2MAN__ typedef int Trf_MDCheck (Tcl_Interp* interp /* the interpreter for error messages */); #else typedef int Trf_MDCheck _ANSI_ARGS_ ((Tcl_Interp* interp)); #endif /* * Structure describing a message digest algorithm. * All information required by the common code to interface a message * digest algorithm with it is stored in structures of this type. */ typedef struct _Trf_MessageDigestDescription { char* name; /* name of message digest, also name * of command on tcl level */ unsigned short context_size; /* size of the MD state structure * maintained by 'startProc', 'updateProc' * and 'finalProc' (in byte) */ unsigned short digest_size; /* size of the digest generated by the * described algorithm (in byte) */ Trf_MDStart* startProc; /* initialize a MD state structure */ Trf_MDUpdate* updateProc; /* update the MD state for a single character */ Trf_MDUpdateBuf* updateBufProc; /* update the MD state for a character buffer */ Trf_MDFinal* finalProc; /* generate digest from MD state */ Trf_MDCheck* checkProc; /* check enviroment */ } Trf_MessageDigestDescription; /* * Procedure to register a message digest algorithm in an interpreter. * The procedure registers the described MDA at the given interpreter. Return * value is a standard tcl error code. In case of failure an error message * should be left in the result area of the given interpreter. */ #ifdef __C2MAN__ int Trf_RegisterMessageDigest (Tcl_Interp* interp /* interpreter to register the MD algorithm at */, CONST Trf_MessageDigestDescription* md_desc /* description of the MD * algorithm */); #else #ifndef TRF_USE_STUBS TRF_EXPORT (int,Trf_RegisterMessageDigest) _ANSI_ARGS_ ((Tcl_Interp* interp, CONST Trf_MessageDigestDescription* md_desc)); #endif #endif /* * Internal helper procedures worth exporting. */ /* * General purpose library loader functionality. * Used by -> TrfLoadZlib, -> TrfLoadLibdes. */ #ifndef TRF_USE_STUBS TRF_EXPORT (int,Trf_LoadLibrary) _ANSI_ARGS_ ((Tcl_Interp* interp, CONST char* libName, VOID** handlePtr, char** symbols, int num)); TRF_EXPORT (void,Trf_LoadFailed) _ANSI_ARGS_ ((VOID** handlePtr)); #endif /* * XOR the bytes in a buffer with a mask. * Internally used by the implementation of the * various stream modes available to blockciphers. */ #ifdef __C2MAN__ void Trf_XorBuffer (VOID* buffer, /* buffer to xor the mask with */ VOID* mask, /* mask bytes xor'ed into the buffer */ int length /* length of mask and buffer (in byte) */); #else #ifndef TRF_USE_STUBS TRF_EXPORT (void,Trf_XorBuffer) _ANSI_ARGS_ ((VOID* buffer, VOID* mask, int length)); #endif #endif /* * Shift the register. * The register is shifted 'shift' bytes to the left. The same * number of bytes from the left of the 2nd register ('in') is * inserted at the right of 'buffer' to replace the lost bytes. */ #ifdef __C2MAN__ void Trf_ShiftRegister (VOID* buffer, /* data shifted to the left */ VOID* in, /* 2nd register shifted into the buffer */ int shift, /* number of bytes to shift out (and in) */ int buffer_length /* length of buffer and in (in byte) */); #else #ifndef TRF_USE_STUBS TRF_EXPORT (void,Trf_ShiftRegister) _ANSI_ARGS_ ((VOID* buffer, VOID* in, int shift, int buffer_length)); #endif #endif /* * Swap the bytes of all 2-byte words contained in the buffer. */ #ifdef __C2MAN__ void Trf_FlipRegisterShort (VOID* buffer, /* data to swap */ int length /* length of buffer (in byte) */); #else #ifndef TRF_USE_STUBS TRF_EXPORT (void,Trf_FlipRegisterShort) _ANSI_ARGS_ ((VOID* buffer, int length)); #endif #endif /* * Swap the bytes of all 4-byte words contained in the buffer. */ #ifdef __C2MAN__ void Trf_FlipRegisterLong (VOID* buffer, /* data to swap */ int length /* length of buffer (in byte) */); #else #ifndef TRF_USE_STUBS TRF_EXPORT (void,Trf_FlipRegisterLong) _ANSI_ARGS_ ((VOID* buffer, int length)); #endif #endif /* * End of exported interface */ #ifndef __C2MAN__ #ifndef TRF_USE_STUBS #include "trfDecls.h" #endif #endif /* * Convenience declaration of Trf_InitStubs. * This function is not *implemented* by the trf library, so the storage * class is neither DLLEXPORT nor DLLIMPORT */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS EXTERN char *Trf_InitStubs _ANSI_ARGS_((Tcl_Interp *interp, CONST char *version, int exact)); #ifndef USE_TRF_STUBS #define Trf_InitStubs(interp, version, exact) \ Tcl_PkgRequire(interp, "Trf", version, exact) #endif #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #ifdef __cplusplus } #endif /* C++ */ #endif /* TRF_H */ trf2.1.4/generic/crc.c0000644000175000017500000001434611216344223014107 0ustar sergeisergei/* * crc.c -- * * Implements and registers message digest generator CRC. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: crc.c,v 1.4 2000/08/09 19:13:17 aku Exp $ */ #include "transformInt.h" #include "crc.h" /* * Generator description * --------------------- * * The CRC algorithm is used to compute a message digest. * The polynomial is taken from PGP (parts of the code too). */ #define DIGEST_SIZE (CRCBYTES) #define CTX_TYPE crcword /* * Declarations of internal procedures. */ static void MDcrc_Start _ANSI_ARGS_ ((VOID* context)); static void MDcrc_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDcrc_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDcrc_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { "crc", sizeof (CTX_TYPE), DIGEST_SIZE, MDcrc_Start, MDcrc_Update, MDcrc_UpdateBuf, MDcrc_Final, NULL }; /* * Additional declarations */ static crcword CrcTable [256]; /* THREADING: serialize initialization */ static void GenCrcLookupTable _ANSI_ARGS_ ((crcword polynomial)); /* *------------------------------------------------------* * * TrfInit_CRC -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_CRC (interp) Tcl_Interp* interp; { GenCrcLookupTable (PRZCRC); return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDcrc_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDcrc_Start (context) VOID* context; { /* call md specific initialization here */ *((crcword*) context) = CRCINIT; } /* *------------------------------------------------------* * * MDcrc_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDcrc_Update (context, character) VOID* context; unsigned int character; { /* call md specific update here */ #define UP(ctx) ((ctx) << 8) #define DOWN(ctx) ((ctx) >> CRCSHIFTS) crcword accu; unsigned char buf = character; accu = *((crcword*) context); accu = UP (accu) ^ CrcTable [(unsigned char) (DOWN (accu)) ^ buf]; *((crcword*) context) = accu; #undef UP #undef DOWN } /* *------------------------------------------------------* * * MDcrc_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDcrc_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { /* call md specific update here */ #define UP(ctx) ((ctx) << 8) #define DOWN(ctx) ((ctx) >> CRCSHIFTS) crcword accu; int i; accu = *((crcword*) context); for (i=0; i < bufLen; i++) { accu = UP (accu) ^ CrcTable [(unsigned char) (DOWN (accu)) ^ (buffer [i])]; } *((crcword*) context) = accu; #undef UP #undef DOWN } /* *------------------------------------------------------* * * MDcrc_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDcrc_Final (context, digest) VOID* context; VOID* digest; { /* call md specific finalization here */ crcword crc = maskcrc (* ((crcword*) context)); char* out = (char*) digest; /* -*- PGP -*-, was outcrc, BIGENDIAN output */ /* DEPENDENT on CRCBYTES !!, only a value of 3 is supported here */ out [0] = (char) ((crc >> 16) & 0xff); out [1] = (char) ((crc >> 8) & 0xff); out [2] = (char) ((crc >> 0) & 0xff); /* -*- PGP -*- */ } /* * Initialize lookup table for crc calculation. */ static void GenCrcLookupTable (poly) crcword poly; { /* -*- PGP -*-, was 'mk_crctbl' */ int i; crcword t, *p, *q; TrfLock; /* THREADING: serialize initialization */ p = q = CrcTable; *q++ = 0; *q++ = poly; for (i = 1; i < 128; i++) { t = *++p; if (t & CRCHIBIT) { t <<= 1; *q++ = t ^ poly; *q++ = t; } else { t <<= 1; *q++ = t; *q++ = t ^ poly; } } TrfUnlock; /* -*- PGP -*- */ } trf2.1.4/generic/dig_opt.c0000644000175000017500000003520611216344223014763 0ustar sergeisergei/* * dig_opt.c -- * * Implements the C level procedures handling option processing * for message digest generators. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: dig_opt.c,v 1.11 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * forward declarations of all internally used procedures. */ static Trf_Options CreateOptions _ANSI_ARGS_ ((ClientData clientData)); static void DeleteOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static int CheckOptions _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST Trf_BaseOptions* baseOptions, ClientData clientData)); static int SetOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST Tcl_Obj* optvalue, ClientData clientData)); static int QueryOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static int TargetType _ANSI_ARGS_ ((Tcl_Interp* interp, CONST char* typeString, int* isChannel)); static int DigestMode _ANSI_ARGS_ ((Tcl_Interp* interp, CONST char* modeString, int* mode)); /* *------------------------------------------------------* * * TrfMDOptions -- * * ------------------------------------------------* * Accessor to the set of vectors realizing option * processing for message digest generators. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * See above. * *------------------------------------------------------* */ Trf_OptionVectors* TrfMDOptions () { static Trf_OptionVectors optVec = /* THREADING: constant, read-only => safe */ { CreateOptions, DeleteOptions, CheckOptions, NULL, /* no string procedure for 'SetOption' */ SetOption, QueryOptions, NULL /* unseekable, unchanged by options */ }; return &optVec; } /* *------------------------------------------------------* * * CreateOptions -- * * ------------------------------------------------* * Create option structure for message digest generators. * ------------------------------------------------* * * Sideeffects: * Allocates memory and initializes it as * option structure for message digest generators. * * Result: * A reference to the allocated block of * memory. * *------------------------------------------------------* */ static Trf_Options CreateOptions (clientData) ClientData clientData; { TrfMDOptionBlock* o; o = (TrfMDOptionBlock*) ckalloc (sizeof (TrfMDOptionBlock)); o->behaviour = TRF_IMMEDIATE; /* irrelevant until set by 'CheckOptions' */ o->mode = TRF_UNKNOWN_MODE; o->readDestination = (char*) NULL; o->writeDestination = (char*) NULL; o->rdIsChannel = 0; o->wdIsChannel = 1; o->matchFlag = (char*) NULL; o->vInterp = (Tcl_Interp*) NULL; o->rdChannel = (Tcl_Channel) NULL; o->wdChannel = (Tcl_Channel) NULL; return (Trf_Options) o; } /* *------------------------------------------------------* * * DeleteOptions -- * * ------------------------------------------------* * Delete option structure of a message digest generators. * ------------------------------------------------* * * Sideeffects: * A memory block allocated by 'CreateOptions' * is released. * * Result: * None. * *------------------------------------------------------* */ static void DeleteOptions (options, clientData) Trf_Options options; ClientData clientData; { TrfMDOptionBlock* o = (TrfMDOptionBlock*) options; if (o->readDestination) { ckfree ((char*) o->readDestination); } if (o->writeDestination) { ckfree ((char*) o->writeDestination); } if (o->matchFlag) { ckfree ((char*) o->matchFlag); } ckfree ((char*) o); } /* *------------------------------------------------------* * * CheckOptions -- * * ------------------------------------------------* * Check the given option structure for errors. * ------------------------------------------------* * * Sideeffects: * May modify the given structure to set * default values into uninitialized parts. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int CheckOptions (options, interp, baseOptions, clientData) Trf_Options options; Tcl_Interp* interp; CONST Trf_BaseOptions* baseOptions; ClientData clientData; { TrfMDOptionBlock* o = (TrfMDOptionBlock*) options; Trf_MessageDigestDescription* md_desc = (Trf_MessageDigestDescription*) clientData; /* * Call digest dependent check of environment first. */ START (dig_opt:CheckOptions); if (md_desc->checkProc != NULL) { if (TCL_OK != (*md_desc->checkProc) (interp)) { DONE (dig_opt:CheckOptions); return TCL_ERROR; } } /* TRF_IMMEDIATE: no options allowed * TRF_ATTACH: -mode required * TRF_ABSORB_HASH: -matchflag required (only if channel is read) * TRF_WRITE_HASH: -write/read-destination required according to * access mode of attached channel. If a channel * is used as target, then it has to be writable. * TRF_TRANSPARENT: see TRF_WRITE_HASH. */ if (baseOptions->attach == (Tcl_Channel) NULL) { if ((o->mode != TRF_UNKNOWN_MODE) || (o->matchFlag != (char*) NULL) || (o->readDestination != (char*) NULL) || (o->writeDestination != (char*) NULL)) { /* IMMEDIATE MODE */ Tcl_AppendResult (interp, "immediate: no options allowed", (char*) NULL); DONE (dig_opt:CheckOptions); return TCL_ERROR; } } else { /* ATTACH MODE / FILTER */ if (o->mode == TRF_UNKNOWN_MODE) { Tcl_AppendResult (interp, "attach: -mode not defined", (char*) NULL); DONE (dig_opt:CheckOptions); return TCL_ERROR; } else if (o->mode == TRF_ABSORB_HASH) { if ((baseOptions->attach_mode & TCL_READABLE) && (o->matchFlag == (char*) NULL)) { Tcl_AppendResult (interp, "attach: -matchflag not defined", (char*) NULL); DONE (dig_opt:CheckOptions); return TCL_ERROR; } } else if ((o->mode == TRF_WRITE_HASH) || (o->mode == TRF_TRANSPARENT)) { if (o->matchFlag != (char*) NULL) { Tcl_AppendResult (interp, "attach: -matchflag not allowed", (char*) NULL); DONE (dig_opt:CheckOptions); return TCL_ERROR; } if (baseOptions->attach_mode & TCL_READABLE) { if (o->readDestination == (char*) NULL) { Tcl_AppendResult (interp, "attach, external: -read-destination missing", (char*) NULL); DONE (dig_opt:CheckOptions); return TCL_ERROR; } else if (o->rdIsChannel) { int mode; o->rdChannel = Tcl_GetChannel (interp, (char*) o->readDestination, &mode); if (o->rdChannel == (Tcl_Channel) NULL) { DONE (dig_opt:CheckOptions); return TCL_ERROR; } else if (! (mode & TCL_WRITABLE)) { Tcl_AppendResult (interp, "read destination channel '", o->readDestination, "' not opened for writing", (char*) NULL); DONE (dig_opt:CheckOptions); return TCL_ERROR; } } } if (baseOptions->attach_mode & TCL_WRITABLE) { if (o->writeDestination == (char*) NULL) { Tcl_AppendResult (interp, "attach, external: -write-destination missing", (char*) NULL); DONE (dig_opt:CheckOptions); return TCL_ERROR; } else if (o->wdIsChannel) { int mode; o->wdChannel = Tcl_GetChannel (interp, (char*) o->writeDestination, &mode); if (o->wdChannel == (Tcl_Channel) NULL) { DONE (dig_opt:CheckOptions); return TCL_ERROR; } else if (! (mode & TCL_WRITABLE)) { Tcl_AppendResult (interp, "write destination channel '", o->writeDestination, "' not opened for writing", (char*) NULL); DONE (dig_opt:CheckOptions); return TCL_ERROR; } } } } else { Tcl_Panic ("unknown mode given to dig_opt.c::CheckOptions"); } } o->behaviour = (baseOptions->attach == (Tcl_Channel) NULL ? TRF_IMMEDIATE : TRF_ATTACH); PRINT ("Ok\n"); FL; DONE (dig_opt:CheckOptions); return TCL_OK; } /* *------------------------------------------------------* * * SetOption -- * * ------------------------------------------------* * Define value of given option. * ------------------------------------------------* * * Sideeffects: * Sets the given value into the option * structure * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int SetOption (options, interp, optname, optvalue, clientData) Trf_Options options; Tcl_Interp* interp; CONST char* optname; CONST Tcl_Obj* optvalue; ClientData clientData; { /* Possible options: * * -mode absorb|write|transparent * -matchflag * -write-destination | * -read-destination | */ TrfMDOptionBlock* o = (TrfMDOptionBlock*) options; CONST char* value; int len = strlen (optname); value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); switch (optname [1]) { case 'm': if (len < 3) goto unknown_option; if (0 == strncmp (optname, "-mode", len)) { return DigestMode (interp, value, &o->mode); } else if (0 == strncmp (optname, "-matchflag", len)) { if (o->matchFlag) { ckfree (o->matchFlag); } o->vInterp = interp; o->matchFlag = strcpy (ckalloc (1 + strlen (value)), value); } else goto unknown_option; break; case 'w': if (len < 8) goto unknown_option; if (0 == strncmp (optname, "-write-destination", len)) { if (o->writeDestination) { ckfree (o->writeDestination); } o->vInterp = interp; o->writeDestination = strcpy (ckalloc (1+strlen (value)), value); } else if (0 == strncmp (optname, "-write-type", len)) { return TargetType (interp, value, &o->wdIsChannel); } else goto unknown_option; break; case 'r': if (len < 7) goto unknown_option; if (0 == strncmp (optname, "-read-destination", len)) { if (o->readDestination) { ckfree (o->readDestination); } o->vInterp = interp; o->readDestination = strcpy (ckalloc (1+strlen (value)), value); } else if (0 == strncmp (optname, "-read-type", len)) { return TargetType (interp, value, &o->rdIsChannel); } else goto unknown_option; break; default: goto unknown_option; break; } return TCL_OK; unknown_option: Tcl_AppendResult (interp, "unknown option '", optname, "', should be '-mode', '-matchflag', '-write-destination', '-write-type', '-read-destination' or '-read-type'", (char*) NULL); return TCL_ERROR; } /* *------------------------------------------------------* * * QueryOptions -- * * ------------------------------------------------* * Returns a value indicating wether the encoder or * decoder set of vectors is to be used by immediate * execution. * ------------------------------------------------* * * Sideeffects: * None * * Result: * 1 - use encoder vectors. * 0 - use decoder vectors. * *------------------------------------------------------* */ static int QueryOptions (options, clientData) Trf_Options options; ClientData clientData; { /* Always use encoder for immediate execution */ return 1; } /* *------------------------------------------------------* * * TargetType -- * * ------------------------------------------------* * Determines from a string what destination was * given to the message digest. * ------------------------------------------------* * * Sideeffects: * May leave an error message in the * interpreter result area. * * Result: * A standard Tcl error code, in case of * success 'isChannel' is set too. * *------------------------------------------------------* */ static int TargetType (interp, typeString, isChannel) Tcl_Interp* interp; CONST char* typeString; int* isChannel; { int len = strlen (typeString); switch (typeString [0]) { case 'v': if (0 == strncmp ("variable", typeString, len)) { *isChannel = 0; } else goto unknown_type; break; case 'c': if (0 == strncmp ("channel", typeString, len)) { *isChannel = 1; } else goto unknown_type; break; default: unknown_type: Tcl_AppendResult (interp, "unknown target-type '", typeString, "'", (char*) NULL); return TCL_ERROR; } return TCL_OK; } /* *------------------------------------------------------* * * DigestMode -- * * ------------------------------------------------* * Determines the operation mode of the digest. * ------------------------------------------------* * * Sideeffects: * May leave an error message in the * interpreter result area. * * Result: * A standard Tcl error code, in case of * success 'mode' is set too. * *------------------------------------------------------* */ static int DigestMode (interp, modeString, mode) Tcl_Interp* interp; CONST char* modeString; int* mode; { int len = strlen (modeString); switch (modeString [0]) { case 'a': if (0 == strncmp (modeString, "absorb", len)) { *mode = TRF_ABSORB_HASH; } else goto unknown_mode; break; case 'w': if (0 == strncmp (modeString, "write", len)) { *mode = TRF_WRITE_HASH; } else goto unknown_mode; break; case 't': if (0 == strncmp (modeString, "transparent", len)) { *mode = TRF_TRANSPARENT; } else goto unknown_mode; break; default: unknown_mode: Tcl_AppendResult (interp, "unknown mode '", modeString, "', should be 'absorb', 'write' or 'transparent'", (char*) NULL); return TCL_ERROR; } return TCL_OK; } trf2.1.4/generic/load.c0000644000175000017500000001052011216344223014245 0ustar sergeisergei/* * load.c -- * * general purpose loader for shared libraries. * essentially the last 2 functions of 'imgInit.c' * (see 'Img' library by Jan Nijtmans). * * Copyright (c) 1996 Jan Nijtmans (nijtmans.nici.kun.nl) * All rights reserved. * * CVS: $Id: load.c,v 1.5 1999/09/19 10:33:26 aku Exp $ */ #include "transformInt.h" #define Offset(type,field) ((unsigned long) (((char *) &((type *) 0)->field))) /* *---------------------------------------------------------------------- * * Trf_LoadLibrary -- * * This procedure is called to load a shared library into memory. * If the extension is ".so" (e.g. Solaris, Linux) or ".sl" (HP-UX) * it is possible that the extension is appended or replaced with * a major version number. If the file cannot be found, the version * numbers will be stripped off one by one. e.g. * * HP-UX: libtiff.3.4 Linux,Solaris: libtiff.so.3.4 * libtiff.3 libtiff.so.3 * libtiff.sl libtiff.so * * Results: * TCL_OK if function succeeds. Otherwise TCL_ERROR while the * interpreter will contain an error-message. The last parameter * "num" contains the minimum number of symbols that is required * by the application to succeed. Only the first symbols * will produce an error if they cannot be found. * * Side effects: * At least Library functions become available by the * application. * *---------------------------------------------------------------------- */ typedef struct Functions { VOID *handle; int (* first) _ANSI_ARGS_((void)); int (* next) _ANSI_ARGS_((void)); } Functions; /* MS defines something under this name, avoid the collision */ #define TRF_LOAD_FAILED ((VOID *) -114) int Trf_LoadLibrary (interp, libName, handlePtr, symbols, num) Tcl_Interp *interp; CONST char *libName; VOID **handlePtr; char **symbols; int num; { VOID *handle = (VOID *) NULL; Functions *lib = (Functions *) handlePtr; char **p = (char **) &(lib->first); char **q = symbols; char buf[256]; char *r; int length; if (lib->handle != NULL) { if (lib->handle == TRF_LOAD_FAILED) { Tcl_AppendResult (interp, "cannot open ", (char*) NULL); Tcl_AppendResult (interp, libName, (char*) NULL); } return (lib->handle != TRF_LOAD_FAILED) ? TCL_OK : TCL_ERROR; } length = strlen(libName); strcpy(buf,libName); handle = dlopen(buf, RTLD_NOW); while (handle == NULL) { if ((r = strrchr(buf,'.')) != NULL) { if ((r[1] < '0') || (r[1] > '9')) { Tcl_AppendResult (interp, "cannot open ", (char*) NULL); Tcl_AppendResult (interp, libName, (char*) NULL); Tcl_AppendResult (interp, ": ", (char*) NULL); Tcl_AppendResult (interp, dlerror (), (char*) NULL); lib->handle = TRF_LOAD_FAILED; return TCL_ERROR; } length = r - buf; *r = 0; } if (strchr(buf,'.') == NULL) { strcpy(buf+length,".sl"); length += 3; } dlerror(); handle = dlopen(buf, RTLD_NOW); } buf[0] = '_'; while (*q) { *p = (char *) dlsym(handle,*q); if (*p == (char *)NULL) { strcpy(buf+1,*q); *p = (char *) dlsym(handle,buf); if ((num > 0) && (*p == (char *)NULL)) { Tcl_AppendResult (interp, "cannot open ", (char*) NULL); Tcl_AppendResult (interp, libName, (char*) NULL); Tcl_AppendResult (interp, ": symbol \"", (char*) NULL); Tcl_AppendResult (interp, *q, (char*) NULL); Tcl_AppendResult (interp, "\" not found", (char*) NULL); dlclose(handle); lib->handle = TRF_LOAD_FAILED; return TCL_ERROR; } } q++; num--; p += (Offset(Functions, next) - Offset(Functions, first)) / sizeof(char *); } lib->handle = handle; return TCL_OK; } /* *---------------------------------------------------------------------- * * Trf_LoadFailed -- * * Mark the loaded library as invalid. Remove it from memory * if possible. It will no longer be used in the future. * * Results: * None. * * Side effects: * Next time the same handle is used by TrfLoadLib, it will * fail immediately, without trying to load it. * *---------------------------------------------------------------------- */ void Trf_LoadFailed (handlePtr) VOID **handlePtr; { if ((*handlePtr != NULL) && (*handlePtr != TRF_LOAD_FAILED)) { /* Oops, still loaded. First remove it from menory */ dlclose(*handlePtr); } *handlePtr = TRF_LOAD_FAILED; } trf2.1.4/generic/loadman.h0000644000175000017500000001045111216344305014752 0ustar sergeisergei#ifndef TRF_LOADMANAGER_H #define TRF_LOADMANAGER_H /* -*- c -*- * loadman.h - * * internal definitions for loading of shared libraries required by Trf. * * Copyright (c) 1996-1999 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: loadman.h,v 1.11 2008/12/11 19:04:25 andreas_kupries Exp $ */ /* * The procedures defined here manage the loading of libraries required * by various glue-code for crytographic algorithms. Dependent on the * functionality requested more than one library will be tried before * giving up entirely. * * All following sections define a structure for each algorithm to fill * with the addresses of the functions required here, plus a procedure * to do the filling. */ #ifdef __cplusplus extern "C" { #endif #include "transformInt.h" #ifdef HAVE_MD2_H # ifdef OPENSSL_SUB # include # else # include # endif #else # include "../compat/md2.h" #endif #ifdef HAVE_SHA_H # ifdef OPENSSL_SUB # include # else # include # endif #else # include "../compat/sha.h" #endif #if defined(HAVE_MD5_H) && !defined(MD5_STATIC_BUILD) # ifdef OPENSSL_SUB # include # else # include # endif # ifdef HAVE_UNISTD_H # include # endif #else # include "../md5-crypt/md5.h" # include "../md5-crypt/trf_crypt.h" # define MD5_CTX struct md5_ctx #endif #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_Trf # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #endif /* Structures, variables and functions to load and access the functionality * required for MD2 and SHA1. Affected command in case of failure: md2, sha1. */ /* Structures containing the vectors to jump through to the implementation * of the functionality. */ typedef struct Md2Functions { long loaded; void (* init) _ANSI_ARGS_ ((MD2_CTX* c)); void (* update) _ANSI_ARGS_ ((MD2_CTX* c, unsigned char* data, unsigned long length)); void (* final) _ANSI_ARGS_ ((unsigned char* digest, MD2_CTX* c)); } md2Functions; typedef struct Md5Functions { long loaded; void (* init) __P ((MD5_CTX* c)); void (* update) __P ((MD5_CTX* c, unsigned char* data, unsigned long length)); void* (* final) __P ((unsigned char* digest, MD5_CTX* c)); const char* (* crypt) _ANSI_ARGS_ ((const char* key, const char* salt)); } md5Functions; typedef struct Sha1Functions { long loaded; void (* init) _ANSI_ARGS_ ((SHA_CTX* c)); void (* update) _ANSI_ARGS_ ((SHA_CTX* c, unsigned char* data, unsigned long length)); void (* final) _ANSI_ARGS_ ((unsigned char* digest, SHA_CTX* c)); } sha1Functions; /* Global variables containing the vectors declared above. 99% of the time they * are read, but during load a write is required, which has to be protected by * a mutex in case of a thread-enabled Tcl. */ EXTERN md2Functions md2f; /* THREADING: serialize initialization */ EXTERN md5Functions md5f; /* THREADING: serialize initialization */ EXTERN sha1Functions sha1f; /* THREADING: serialize initialization */ EXTERN int TrfLoadMD2 _ANSI_ARGS_ ((Tcl_Interp *interp)); EXTERN int TrfLoadMD5 _ANSI_ARGS_ ((Tcl_Interp *interp)); EXTERN int TrfLoadSHA1 _ANSI_ARGS_ ((Tcl_Interp *interp)); #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #ifdef __cplusplus } #endif /* C++ */ #endif /* TRF_LOADMANAGER_H */ trf2.1.4/generic/trfIntDecls.h0000644000175000017500000000177511216344305015571 0ustar sergeisergei/* * trfIntDecls.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. * */ #ifndef _TRFINTDECLS #define _TRFINTDECLS /* * 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: */ typedef struct TrfIntStubs { int magic; struct TrfIntStubHooks *hooks; } TrfIntStubs; #ifdef __cplusplus extern "C" { #endif extern TrfIntStubs *trfIntStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_TRF_STUBS) && !defined(USE_TRF_STUB_PROCS) /* * Inline function declarations: */ #endif /* defined(USE_TRF_STUBS) && !defined(USE_TRF_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _TRFINTDECLS */ trf2.1.4/generic/bincode.c0000644000175000017500000004612411216344223014742 0ustar sergeisergei/* * bincode.c -- * * Implements and registers conversion from and to binary representation. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: bincode.c,v 1.12 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include #include "transformInt.h" /* On some systems this definition seems to be missing. */ #ifndef CHAR_BIT #define CHAR_BIT 8 #endif /* * Converter description * --------------------- * * Encoding: * Every byte is converted into CHAR_BIT characters, using elements * in the set {"0", "1"} only. Thus a binary representation is * generated. The MSBit is output first. * * Decoding: * Only characters in the set {"0", "1"} are allowed as input. * Each (CHAR_BIT)-tuple is converted into a single byte. A partial * tuple at the end of input is converted as if padded with "0"s. */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "bin", NULL, /* clientData not used by converters */ NULL, /* set later by TrfInit_Bin, THREADING: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_RATIO (1, 8) }; /* * Use table lookup */ static const char* code [] = { /* THREADING: constant, read-only => safe */ "00000000", "00000001", "00000010", "00000011", "00000100", "00000101", "00000110", "00000111", "00001000", "00001001", "00001010", "00001011", "00001100", "00001101", "00001110", "00001111", "00010000", "00010001", "00010010", "00010011", "00010100", "00010101", "00010110", "00010111", "00011000", "00011001", "00011010", "00011011", "00011100", "00011101", "00011110", "00011111", "00100000", "00100001", "00100010", "00100011", "00100100", "00100101", "00100110", "00100111", "00101000", "00101001", "00101010", "00101011", "00101100", "00101101", "00101110", "00101111", "00110000", "00110001", "00110010", "00110011", "00110100", "00110101", "00110110", "00110111", "00111000", "00111001", "00111010", "00111011", "00111100", "00111101", "00111110", "00111111", "01000000", "01000001", "01000010", "01000011", "01000100", "01000101", "01000110", "01000111", "01001000", "01001001", "01001010", "01001011", "01001100", "01001101", "01001110", "01001111", "01010000", "01010001", "01010010", "01010011", "01010100", "01010101", "01010110", "01010111", "01011000", "01011001", "01011010", "01011011", "01011100", "01011101", "01011110", "01011111", "01100000", "01100001", "01100010", "01100011", "01100100", "01100101", "01100110", "01100111", "01101000", "01101001", "01101010", "01101011", "01101100", "01101101", "01101110", "01101111", "01110000", "01110001", "01110010", "01110011", "01110100", "01110101", "01110110", "01110111", "01111000", "01111001", "01111010", "01111011", "01111100", "01111101", "01111110", "01111111", "10000000", "10000001", "10000010", "10000011", "10000100", "10000101", "10000110", "10000111", "10001000", "10001001", "10001010", "10001011", "10001100", "10001101", "10001110", "10001111", "10010000", "10010001", "10010010", "10010011", "10010100", "10010101", "10010110", "10010111", "10011000", "10011001", "10011010", "10011011", "10011100", "10011101", "10011110", "10011111", "10100000", "10100001", "10100010", "10100011", "10100100", "10100101", "10100110", "10100111", "10101000", "10101001", "10101010", "10101011", "10101100", "10101101", "10101110", "10101111", "10110000", "10110001", "10110010", "10110011", "10110100", "10110101", "10110110", "10110111", "10111000", "10111001", "10111010", "10111011", "10111100", "10111101", "10111110", "10111111", "11000000", "11000001", "11000010", "11000011", "11000100", "11000101", "11000110", "11000111", "11001000", "11001001", "11001010", "11001011", "11001100", "11001101", "11001110", "11001111", "11010000", "11010001", "11010010", "11010011", "11010100", "11010101", "11010110", "11010111", "11011000", "11011001", "11011010", "11011011", "11011100", "11011101", "11011110", "11011111", "11100000", "11100001", "11100010", "11100011", "11100100", "11100101", "11100110", "11100111", "11101000", "11101001", "11101010", "11101011", "11101100", "11101101", "11101110", "11101111", "11110000", "11110001", "11110010", "11110011", "11110100", "11110101", "11110110", "11110111", "11111000", "11111001", "11111010", "11111011", "11111100", "11111101", "11111110", "11111111", }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; unsigned char charCount; /* number of characters assembled so far (0..7) */ unsigned char bench; /* buffer for assembled byte */ } DecoderControl; /* *------------------------------------------------------* * * TrfInit_Bin -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Bin (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; #if 0 unsigned char buffer [CHAR_BIT]; unsigned char out; unsigned short i; unsigned char mask; out = character; memset (buffer, '0', CHAR_BIT); for (out = character, i=0, mask = 1; i < CHAR_BIT; i++, mask <<= 1) { buffer [(CHAR_BIT-1)-i] = ((out & mask) ? '1' : '0'); } return c->write (c->writeClientData, buffer, CHAR_BIT, interp); #endif return c->write (c->writeClientData, (unsigned char*) code [character & 0x00ff], CHAR_BIT, interp); } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; char* out = (char*) ckalloc (8*bufLen+1); int res, i, j; CONST char* ch; for (i=0, j=0; i < bufLen; i++) { ch = code [buffer [i] & 0x00ff]; out [j] = ch [0]; j++; out [j] = ch [1]; j++; out [j] = ch [2]; j++; out [j] = ch [3]; j++; out [j] = ch [4]; j++; out [j] = ch [5]; j++; out [j] = ch [6]; j++; out [j] = ch [7]; j++; } out [j] = '\0'; res = c->write (c->writeClientData, (unsigned char*) out, 8*bufLen, interp); ckfree ((char*) out); return res; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { /* nothing to to */ return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { /* nothing to do */ } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; c->charCount = 0; c->bench = '\0'; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; unsigned char in = character; switch (in) { case '0': c->charCount ++; break; case '1': c->bench |= (1 << (CHAR_BIT-1 - c->charCount)); c->charCount ++; break; default: if (interp) { char buf [10]; if (character < ' ' || character > 127) { sprintf (buf, "0x%02x", character); } else { buf [0] = '\''; buf [1] = character; buf [2] = '\''; buf [3] = '\0'; } Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character ", buf, " found in input", (char*) NULL); } return TCL_ERROR; break; } if (c->charCount >= CHAR_BIT) { int res = c->write (c->writeClientData, &c->bench, 1, interp); c->bench = '\0'; c->charCount = 0; return res; } return TCL_OK; } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { #define IN_RANGE(low,x,high) (((low) <= (x)) && ((x) <= (high))) DecoderControl* c = (DecoderControl*) ctrlBlock; char* out = (char*) ckalloc (7+bufLen/8); int res, i, j; unsigned char character; for (i=0, j=0; i < bufLen; i++) { character = buffer [i]; switch (character) { case '0': c->charCount ++; break; case '1': c->bench |= (1 << (CHAR_BIT-1 - c->charCount)); c->charCount ++; break; default: if (interp) { char buf [10]; if (character < ' ' || character > 127) { sprintf (buf, "0x%02x", character); } else { buf [0] = '\''; buf [1] = character; buf [2] = '\''; buf [3] = '\0'; } Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character ", buf, " found in input", (char*) NULL); } return TCL_ERROR; break; } if (c->charCount >= CHAR_BIT) { out [j] = c->bench; j ++; c->bench = '\0'; c->charCount = 0; } } res = c->write (c->writeClientData, (unsigned char*) out, j, interp); return res; #undef IN_RANGE } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; int res = TCL_OK; if (c->charCount > 0) { res = c->write (c->writeClientData, &c->bench, 1, interp); c->bench = '\0'; c->charCount = 0; } return res; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; c->bench = '\0'; c->charCount = 0; } trf2.1.4/generic/crypt.c0000644000175000017500000001210411216344223014467 0ustar sergeisergei/* * crypt.c -- * * Implements the 'crypt' and 'md5crypt' commands. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: crypt.c,v 1.7 2000/11/18 22:42:31 aku Exp $ */ #include "loadman.h" static int TrfCryptObjCmd _ANSI_ARGS_ ((ClientData notUsed, Tcl_Interp* interp, int objc, struct Tcl_Obj* CONST * objv)); static int TrfMd5CryptObjCmd _ANSI_ARGS_ ((ClientData notUsed, Tcl_Interp* interp, int objc, struct Tcl_Obj* CONST * objv)); /* *---------------------------------------------------------------------- * * TrfCryptObjCmd -- * * This procedure is invoked to process the "crypt" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int TrfCryptObjCmd (notUsed, interp, objc, objv) ClientData notUsed; /* Not used. */ Tcl_Interp* interp; /* Current interpreter. */ int objc; /* Number of arguments. */ struct Tcl_Obj* CONST * objv; /* Argument strings. */ { /* * crypt */ #ifdef __WIN32__ Tcl_SetObjResult (interp, Tcl_NewStringObj ("crypt is not available under Windows", -1)); return TCL_ERROR; #else const char* passwd; const char* salt; Tcl_Obj* res; if (objc != 3) { Tcl_AppendResult (interp, "wrong # args: should be \"crypt passwd salt\"", (char*) NULL); return TCL_ERROR; } passwd = Tcl_GetStringFromObj (objv [1], NULL); salt = Tcl_GetStringFromObj (objv [2], NULL); /* THREADING: Serialize access to result string of 'crypt'. */ TrfLock; res = Tcl_NewStringObj ((char*) crypt (passwd, salt), -1); TrfUnlock; Tcl_SetObjResult (interp, res); return TCL_OK; #endif } /* *---------------------------------------------------------------------- * * TrfMd5CryptObjCmd -- * * This procedure is invoked to process the "md5crypt" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * Unstacks the channel, thereby restoring its parent. * *---------------------------------------------------------------------- */ static int TrfMd5CryptObjCmd (notUsed, interp, objc, objv) ClientData notUsed; /* Not used. */ Tcl_Interp* interp; /* Current interpreter. */ int objc; /* Number of arguments. */ struct Tcl_Obj* CONST * objv; /* Argument strings. */ { /* * md5crypt */ const char* passwd; const char* salt; char salt_b [6]; Tcl_Obj* res; if (TrfLoadMD5 (interp) != TCL_OK) { return TCL_ERROR; } if (objc != 3) { Tcl_AppendResult (interp, "wrong # args: should be \"md5crypt passwd salt\"", (char*) NULL); return TCL_ERROR; } passwd = Tcl_GetStringFromObj (objv [1], NULL); salt = Tcl_GetStringFromObj (objv [2], NULL); /* * Manipulate salt, add magic md5 prefix '$1$'. * The 'crypt +3' later on skips the first three characters of the result, * which again contain the magic marker. */ salt_b [0] = '$'; salt_b [1] = '1'; salt_b [2] = '$'; salt_b [3] = salt [0]; salt_b [4] = salt [1]; salt_b [5] = '\0'; /* THREADING: Serialize access to result string of 'md5f.crypt'. */ TrfLock; res = Tcl_NewStringObj ((char*) md5f.crypt (passwd, salt_b) + 3, -1); TrfUnlock; Tcl_SetObjResult (interp, res); return TCL_OK; } /* *------------------------------------------------------* * * TrfInit_Crypt -- * * ------------------------------------------------* * Register the 'crypt' and 'md5crypt' commands. * ------------------------------------------------* * * Sideeffects: * As of 'Tcl_CreateObjCommand'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Crypt (interp) Tcl_Interp* interp; { Tcl_CreateObjCommand (interp, "crypt", TrfCryptObjCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); Tcl_CreateObjCommand (interp, "md5crypt", TrfMd5CryptObjCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); return TCL_OK; } trf2.1.4/generic/rmd160.c0000644000175000017500000001757211216344224014356 0ustar sergeisergei/* * rmd160.c -- * * Implements and registers message digest generator RIPEMD-160. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: rmd160.c,v 1.5 2005/10/06 18:05:46 andreas_kupries Exp $ */ #include "transformInt.h" #include "ripemd/rmd160.h" /* * Generator description * --------------------- * * The RIPEMD-160 alogrithm is used to compute a cryptographically strong * message digest. */ #define DIGEST_SIZE (20) /*#define CTX_TYPE */ #define CONTEXT_SIZE (20) #define CHUNK_SIZE (64) typedef struct ripemd_context { dword state [5]; /* state variables of ripemd-160 */ byte buf [CHUNK_SIZE]; /* buffer of 16-dword's */ byte byteCount; /* number of bytes in buffer */ dword lowc; /* lower half of a 64bit counter */ dword highc; /* upper half of a 64bit counter */ } ripemd_context; /* * Declarations of internal procedures. */ static void MDrmd160_Start _ANSI_ARGS_ ((VOID* context)); static void MDrmd160_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDrmd160_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDrmd160_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); static void CountLength _ANSI_ARGS_ ((ripemd_context* ctx, unsigned int nbytes)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ "ripemd160", sizeof (ripemd_context), DIGEST_SIZE, MDrmd160_Start, MDrmd160_Update, MDrmd160_UpdateBuf, MDrmd160_Final, NULL }; /* *------------------------------------------------------* * * TrfInit_RIPEMD160 -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_RIPEMD160 (interp) Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDrmd160_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDrmd160_Start (context) VOID* context; { ripemd_context* ctx = (ripemd_context*) context; ripemd160_MDinit (ctx->state); memset (ctx->buf, '\0', CHUNK_SIZE); ctx->byteCount = 0; ctx->lowc = 0; ctx->highc = 0; } /* *------------------------------------------------------* * * MDrmd160_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDrmd160_Update (context, character) VOID* context; unsigned int character; { ripemd_context* ctx = (ripemd_context*) context; ctx->buf [ctx->byteCount] = character; ctx->byteCount ++; if (ctx->byteCount == CHUNK_SIZE) { CountLength (ctx, CHUNK_SIZE); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (ctx->buf, CHUNK_SIZE); #endif ripemd160_compress (ctx->state, (dword*) ctx->buf); ctx->byteCount = 0; } } /* *------------------------------------------------------* * * MDrmd160_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDrmd160_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { ripemd_context* ctx = (ripemd_context*) context; if ((ctx->byteCount + bufLen) < CHUNK_SIZE) { /* * Not enough for full chunk. Remember incoming * data and wait for another call containing more data. */ memcpy ((VOID*) (ctx->buf + ctx->byteCount), (VOID*) buffer, bufLen); ctx->byteCount += bufLen; } else { /* * Complete chunk with incoming data, update digest, * then use all chunks contained in the buffer. Remember * an incomplete chunk and wait for further calls. */ int k = CHUNK_SIZE - ctx->byteCount; if (k < CHUNK_SIZE) { memcpy ((VOID*) (ctx->buf + ctx->byteCount), (VOID*) buffer, k); CountLength (ctx, CHUNK_SIZE); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (ctx->buf, CHUNK_SIZE); #endif ripemd160_compress (ctx->state, (dword*) ctx->buf); buffer += k; bufLen -= k; } /* k == CHUNK_SIZE => internal buffer was empty, so skip it entirely */ while (bufLen >= CHUNK_SIZE) { CountLength (ctx, CHUNK_SIZE); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (buffer, CHUNK_SIZE); #endif ripemd160_compress (ctx->state, (dword*) buffer); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (buffer, CHUNK_SIZE); #endif buffer += CHUNK_SIZE; bufLen -= CHUNK_SIZE; } ctx->byteCount = bufLen; if (bufLen > 0) { memcpy ((VOID*) ctx->buf, (VOID*) buffer, bufLen); } } } /* *------------------------------------------------------* * * MDrmd160_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDrmd160_Final (context, digest) VOID* context; VOID* digest; { ripemd_context* ctx = (ripemd_context*) context; CountLength (ctx, ctx->byteCount); ripemd160_MDfinish (ctx->state, ctx->buf, ctx->lowc, ctx->highc); memcpy (digest, ctx->state, DIGEST_SIZE); #ifdef WORDS_BIGENDIAN Trf_FlipRegisterLong (digest, DIGEST_SIZE); #endif } /* *------------------------------------------------------* * * CountLength -- * * ------------------------------------------------* * Update the 64bit counter in the context structure * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void CountLength (ctx, nbytes) ripemd_context* ctx; unsigned int nbytes; { /* update length counter */ if ((ctx->lowc + nbytes) < ctx->lowc) { /* overflow to msb of length */ ctx->highc ++; } ctx->lowc += nbytes; } /* * External code from here on. */ #include "ripemd/rmd160.c" trf2.1.4/generic/convert.c0000644000175000017500000002120011216344223015003 0ustar sergeisergei/* * convert.c -- * * Implements the C level procedures handling option processing * for converter transformations. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: convert.c,v 1.10 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * forward declarations of all internally used procedures. */ static Trf_Options CreateOptions _ANSI_ARGS_ ((ClientData clientData)); static void DeleteOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static int CheckOptions _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST Trf_BaseOptions* baseOptions, ClientData clientData)); static int SetOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST Tcl_Obj* optvalue, ClientData clientData)); static int QueryOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static void SeekQueryOptions _ANSI_ARGS_ ((Tcl_Interp* interp, Trf_Options options, Trf_SeekInformation* seekInfo, ClientData clientData)); /* *------------------------------------------------------* * * Trf_ConverterOptions -- * * ------------------------------------------------* * Accessor to the set of vectors realizing option * processing for converter procedures. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * See above. * *------------------------------------------------------* */ Trf_OptionVectors* Trf_ConverterOptions () { static Trf_OptionVectors optVec = /* THREADING: constant, read-only => safe */ { CreateOptions, DeleteOptions, CheckOptions, NULL, /* no string procedure for 'SetOption' */ SetOption, QueryOptions, SeekQueryOptions }; return &optVec; } /* *------------------------------------------------------* * * CreateOptions -- * * ------------------------------------------------* * Create option structure for converter transformations. * ------------------------------------------------* * * Sideeffects: * Allocates memory and initializes it as * option structure for converter * transformations. * * Result: * A reference to the allocated block of * memory. * *------------------------------------------------------* */ static Trf_Options CreateOptions (clientData) ClientData clientData; { Trf_ConverterOptionBlock* o; o = (Trf_ConverterOptionBlock*) ckalloc (sizeof (Trf_ConverterOptionBlock)); o->mode = TRF_UNKNOWN_MODE; return (Trf_Options) o; } /* *------------------------------------------------------* * * DeleteOptions -- * * ------------------------------------------------* * Delete option structure of a converter transformations * ------------------------------------------------* * * Sideeffects: * A memory block allocated by 'CreateOptions' * is released. * * Result: * None. * *------------------------------------------------------* */ static void DeleteOptions (options, clientData) Trf_Options options; ClientData clientData; { Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; ckfree ((VOID*) o); } /* *------------------------------------------------------* * * CheckOptions -- * * ------------------------------------------------* * Check the given option structure for errors. * ------------------------------------------------* * * Sideeffects: * May modify the given structure to set * default values into uninitialized parts. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int CheckOptions (options, interp, baseOptions, clientData) Trf_Options options; Tcl_Interp* interp; CONST Trf_BaseOptions* baseOptions; ClientData clientData; { Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; if (baseOptions->attach == (Tcl_Channel) NULL) /* IMMEDIATE? */ { if (o->mode == TRF_UNKNOWN_MODE) { Tcl_AppendResult (interp, "-mode option not set", (char*) NULL); return TCL_ERROR; } } else /* ATTACH */ { if (o->mode == TRF_UNKNOWN_MODE) { o->mode = TRF_ENCODE_MODE; } } return TCL_OK; } /* *------------------------------------------------------* * * SetOption -- * * ------------------------------------------------* * Define value of given option. * ------------------------------------------------* * * Sideeffects: * Sets the given value into the option * structure * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int SetOption (options, interp, optname, optvalue, clientData) Trf_Options options; Tcl_Interp* interp; CONST char* optname; CONST Tcl_Obj* optvalue; ClientData clientData; { Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; int len; CONST char* value; len = strlen (optname+1); switch (optname [1]) { case 'm': if (0 != strncmp (optname, "-mode", len)) goto unknown_option; value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); len = strlen (value); switch (value [0]) { case 'e': if (0 != strncmp (value, "encode", len)) goto unknown_mode; o->mode = TRF_ENCODE_MODE; break; case 'd': if (0 != strncmp (value, "decode", len)) goto unknown_mode; o->mode = TRF_DECODE_MODE; break; default: unknown_mode: Tcl_AppendResult (interp, "unknown mode '", (char*) NULL); Tcl_AppendResult (interp, value, (char*) NULL); Tcl_AppendResult (interp, "', should be 'encode' or 'decode'", (char*) NULL); return TCL_ERROR; break; } /* switch optvalue */ break; default: goto unknown_option; break; } return TCL_OK; unknown_option: Tcl_AppendResult (interp, "unknown option '", (char*) NULL); Tcl_AppendResult (interp, optname, (char*) NULL); Tcl_AppendResult (interp, "', should be '-mode'", (char*) NULL); return TCL_ERROR; } /* *------------------------------------------------------* * * QueryOptions -- * * ------------------------------------------------* * Returns a value indicating wether the encoder or * decoder set of vectors is to be used by immediate * execution. * ------------------------------------------------* * * Sideeffects: * None * * Result: * 1 - use encoder vectors. * 0 - use decoder vectors. * *------------------------------------------------------* */ static int QueryOptions (options, clientData) Trf_Options options; ClientData clientData; { Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; return (o->mode == TRF_ENCODE_MODE ? 1 : 0); } /* *------------------------------------------------------* * * SeekQueryOptions -- * * ------------------------------------------------* * Modifies the natural seek policy according to the * configuration of the transformation. * ------------------------------------------------* * * Sideeffects: * May modify 'seekInfo'. * * Result: * None. * *------------------------------------------------------* */ static void SeekQueryOptions (interp, options, seekInfo, clientData) Tcl_Interp* interp; Trf_Options options; Trf_SeekInformation* seekInfo; ClientData clientData; { Trf_ConverterOptionBlock* o = (Trf_ConverterOptionBlock*) options; if (o->mode == TRF_DECODE_MODE) { /* The conversion is backward, swap the seek information. */ int t = seekInfo->numBytesTransform; seekInfo->numBytesTransform = seekInfo->numBytesDown; seekInfo->numBytesDown = t; } } trf2.1.4/generic/reflect.h0000644000175000017500000000502411216344305014763 0ustar sergeisergei#ifndef TRF_REFLECT_H #define TRF_REFLECT_H /* -*- c -*- * reflect.h - * * internal definitions shared by 'reflect.c' and 'ref_opt.c'. * * Copyright (c) 1999 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: reflect.h,v 1.2 2001/03/27 13:08:32 tcl Exp $ */ #ifdef __cplusplus extern "C" { #endif #include "transformInt.h" #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_Trf # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #endif /* * Definition of the control blocks for en- and decoder. */ typedef struct _ReflectControl_ { Trf_WriteProc* write; ClientData writeClientData; Tcl_Obj* command; /* tcl code to execute for a buffer */ Tcl_Interp* interp; /* interpreter creating the channel */ /* Information queried dynamically from the tcl-level */ int maxRead; Trf_SeekInformation naturalRatio; } ReflectControl; /* * Execute callback for buffer and operation. */ extern int RefExecuteCallback _ANSI_ARGS_ ((ReflectControl* ctrl, Tcl_Interp* interp, unsigned char* op, unsigned char* buf, int bufLen, int transmit, int preserve)); /* Allowed values for transmit. */ #define TRANSMIT_DONT (0) /* No transfer to do */ #define TRANSMIT_DOWN (1) /* Transfer to the underlying channel */ #define TRANSMIT_NUM (4) /* Transfer number to 'maxRead' */ #define TRANSMIT_RATIO (5) /* 2-element list containing seek ratio */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #ifdef __cplusplus } #endif /* C++ */ #endif /* TRF_REFLECT_H */ trf2.1.4/generic/loadman.c0000644000175000017500000001367511216344223014757 0ustar sergeisergei/* * loadman.c -- * * Loader for various crypto libraries. * * Copyright (c) 1997 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * CVS: $Id: loadman.c,v 1.12 2008/12/11 19:04:25 andreas_kupries Exp $ */ #include "loadman.h" /* * Allow the Makefile to define this value */ #ifndef SSL_LIB_NAME # ifdef __WIN32__ # define SSL_LIB_NAME "crypto32.dll" # endif /* __WIN32__ */ # ifdef __APPLE__ # define SSL_LIB_NAME "libcrypto.dylib" # endif /* __APPLE__ */ # ifndef SSL_LIB_NAME # define SSL_LIB_NAME "libcrypto.so" # endif /* SSL_LIB_NAME */ #endif /* SSL_LIB_NAME */ #ifndef CRYPT_LIB_NAME # ifdef __WIN32__ # define CRYPT_LIB_NAME "crypt.dll" # endif /* __WIN32__ */ # ifdef __APPLE__ # define CRYPT_LIB_NAME "libcrypto.dylib" # endif /* __APPLE__ */ # ifndef CRYPT_LIB_NAME # define CRYPT_LIB_NAME "libcrypt.so" # endif /* SSL_LIB_NAME */ #endif /* SSL_LIB_NAME */ typedef struct SslLibFunctions { void* handle; /* MD2 */ void (* md2_init) _ANSI_ARGS_ ((MD2_CTX* c)); void (* md2_update) _ANSI_ARGS_ ((MD2_CTX* c, unsigned char* data, unsigned long length)); void (* md2_final) _ANSI_ARGS_ ((unsigned char* digest, MD2_CTX* c)); /* SHA1 */ void (* sha1_init) _ANSI_ARGS_ ((SHA_CTX* c)); void (* sha1_update) _ANSI_ARGS_ ((SHA_CTX* c, unsigned char* data, unsigned long length)); void (* sha1_final) _ANSI_ARGS_ ((unsigned char* digest, SHA_CTX* c)); } sslLibFunctions; static char* ssl_symbols [] = { /* md2 */ "MD2_Init", "MD2_Update", "MD2_Final", /* sha1 */ "SHA1_Init", "SHA1_Update", "SHA1_Final", /* -- */ (char *) NULL, }; #ifndef MD5_STATIC_BUILD static char* crypt_symbols [] = { /* md5 */ "MD5_Init", "MD5_Update", "MD5_Final", "crypt", /* -- */ (char *) NULL, }; #endif /* * Global variables containing the vectors to DES, MD2, ... */ md2Functions md2f = {0}; /* THREADING: serialize initialization */ sha1Functions sha1f = {0}; /* THREADING: serialize initialization */ md5Functions md5f = {0}; /* THREADING: serialize initialization */ #ifdef MD5_STATIC_BUILD #include "../md5-crypt/md5.h" /* THREADING: import of one constant var, read-only => safe */ extern char *md5_crypt(const char *key, const char *salt); static void md5_update(MD5_CTX *c, unsigned char* data, unsigned long length) { md5_process_bytes(data, length, c); } static void md5_final(unsigned char* digest, MD5_CTX* c) { md5_finish_ctx(c, digest); } #endif /* * Internal global var's, contains all vectors loaded from SSL's 'cryptlib'. * contains all vectors loaded from 'libdes' library. */ static sslLibFunctions ssl; /* THREADING: serialize initialization */ /* *------------------------------------------------------* * * TrfLoadMD2 -- * * ------------------------------------------------* * Makes MD2 functionality available. * ------------------------------------------------* * * Sideeffects: * Loads the required shared library and * makes the addresses of MD2 functionality * available. In case of failure an error * message is left in the result area of * the specified interpreter. * * Result: * A standard tcl error code. * *------------------------------------------------------* */ int TrfLoadMD2 (interp) Tcl_Interp* interp; { int res; TrfLock; /* THREADING: serialize initialization */ if (md2f.loaded) { TrfUnlock; return TCL_OK; } res = Trf_LoadLibrary (interp, SSL_LIB_NAME, (VOID**) &ssl, ssl_symbols, 0); if ((res == TCL_OK) && (ssl.md2_init != NULL) && (ssl.md2_update != NULL) && (ssl.md2_final != NULL)) { md2f.loaded = 1; md2f.init = ssl.md2_init; md2f.update = ssl.md2_update; md2f.final = ssl.md2_final; TrfUnlock; return TCL_OK; } TrfUnlock; return TCL_ERROR; } /* *------------------------------------------------------* * * TrfLoadMD5 -- * * ------------------------------------------------* * Makes MD5 functionality available. * ------------------------------------------------* * * Sideeffects: * Loads the required shared library and * makes the addresses of MD5 functionality * available. In case of failure an error * message is left in the result area of * the specified interpreter. * * Result: * A standard tcl error code. * *------------------------------------------------------* */ int TrfLoadMD5 (interp) Tcl_Interp* interp; { #ifdef MD5_STATIC_BUILD md5f.loaded = 1; md5f.init = md5_init_ctx; md5f.update = md5_update; md5f.final = md5_final; md5f.crypt = md5_crypt; return TCL_OK; #else int res; TrfLock; /* THREADING: serialize initialization */ res = Trf_LoadLibrary (interp, CRYPT_LIB_NAME, (VOID**) &md5f, crypt_symbols, 0); TrfUnlock; return res; #endif } /* *------------------------------------------------------* * * TrfLoadSHA1 -- * * ------------------------------------------------* * Makes SHA-1 functionality available. * ------------------------------------------------* * * Sideeffects: * Loads the required shared library and * makes the addresses of SHA-1 functionality * available. In case of failure an error * message is left in the result area of * the specified interpreter. * * * Result: * A standard tcl error code. * *------------------------------------------------------* */ int TrfLoadSHA1 (interp) Tcl_Interp* interp; { int res; TrfLock; /* THREADING: serialize initialization */ if (sha1f.loaded) { TrfUnlock; return TCL_OK; } res = Trf_LoadLibrary (interp, SSL_LIB_NAME, (VOID**) &ssl, ssl_symbols, 0); if ((res == TCL_OK) && (ssl.sha1_init != NULL) && (ssl.sha1_update != NULL) && (ssl.sha1_final != NULL)) { sha1f.loaded = 1; sha1f.init = ssl.sha1_init; sha1f.update = ssl.sha1_update; sha1f.final = ssl.sha1_final; TrfUnlock; return TCL_OK; } TrfUnlock; return TCL_ERROR; } trf2.1.4/generic/otpcode.c0000644000175000017500000011353111216344223014771 0ustar sergeisergei/* * otpcode.c -- * * Implements and registers conversion from and to OTP's english words. * * * Copyright (c) 1999 Marshall Rose (mrose@dbc.mtview.ca.us) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: otpcode.c,v 1.7 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include #include "transformInt.h" /* * Converter description * --------------------- * * Reference: * RFC 2289 * * Encoding: * Each sequence of 64-bits is converted to OTP's 6 english words. * For ease of readability, a newline is written after each 6 words. * * Decoding: * Each 6 word sequence is converted to 64-bits. */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "otp_words", NULL, /* clientData not used by conversions. */ NULL, /* set later by TrfInit_OTP_WORDS, THREAD: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_UNSEEKABLE }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (otp_words encode) */ int charCount; unsigned char buf[8]; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (otp_words decode) */ int charCount; int wordCount; char words[6][5]; } DecoderControl; /* taken from RFC 2289... */ static unsigned long extract _ANSI_ARGS_ ((char *s, int start, int length)); static void insert _ANSI_ARGS_ ((char *s, int x, int start, int length)); static int wsrch _ANSI_ARGS_ ((char *w, int low, int high)); /* Dictionary for integer-word translations */ static char Wp[2048][4] = { /* THREADING: constant, read-only => safe */ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE", "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN", "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO", "ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE", "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW", "FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", "FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO", "GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD", "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", "HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT", "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", "COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT", "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", "DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", "DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE", "DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", "EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS", "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT", "FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", "FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD", "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB", "GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", "GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", "HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB", "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", "HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM", "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", "KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", "KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", "OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF", "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE", "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE", "RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL", "SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL", "SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", "SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW", "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", "SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", "SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE", "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL", "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE", "THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE", "TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT", "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM", "WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL", "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR", "YELL", "YOGA", "YOKE" }; /* *------------------------------------------------------* * * TrfInit_OTP_WORDS -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_OTP_WORDS (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (otp_words encode) */ ClearEncoder ((Trf_ControlBlock) c, clientData); return ((ClientData) c); } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (otp_words encode) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (otp_words encode) */ if (c -> charCount == 8) { int i = FlushEncoder (ctrlBlock, interp, clientData); if (i == TCL_OK) i = c -> write (c -> writeClientData, (unsigned char*) "\n", 1, interp); if (i != TCL_OK) return i; } c -> buf[c -> charCount++] = character; return TCL_OK; } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { /* EncoderControl* c = (EncoderControl*) ctrlBlock; unused */ /* execute conversion specific code here (otp_words encode) */ int i = TCL_OK; while (bufLen-- > 0) { if ((i = Encode (ctrlBlock, *buffer++ & 0xff, interp, clientData)) != TCL_OK) break; } return i; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (otp_words encode) */ int i, p; char cp[10]; switch (c -> charCount) { case 8: break; case 0: return TCL_OK; default: if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "input string must be a multiple of 64-bits", (char *) NULL); } return TCL_ERROR; } memset (cp, '\0', sizeof cp); memcpy (cp, c -> buf, sizeof c -> buf); for (p = 0, i = 0; i < 64; i += 2) p += extract (cp, i, 2); cp[sizeof c -> buf] = (char) (p << 6); for (p = 0; p <= 55; p += 11) { char *w = &Wp[extract (cp, p, 11)][0]; char buf[5]; memset (buf, '\0', sizeof buf); for (i = 0; i < 4; i++) { buf[i] = *w++; } i = c -> write (c -> writeClientData, (unsigned char*) buf, strlen (buf), interp); if ((i == TCL_OK) && (p != 55)) i = c -> write (c -> writeClientData, (unsigned char*) " ", 1, interp); if (i != TCL_OK) return i; } ClearEncoder (ctrlBlock, clientData); return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (otp_words encode) */ c -> charCount = 0; memset (c -> buf, '\0', sizeof c -> buf); } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (otp_words decode) */ ClearDecoder ((Trf_ControlBlock) c, clientData); return ((ClientData) c); } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (otp_words decode) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (otp_words decode) */ char x = character & 0xff; char *cp; if (c -> wordCount == 6) { int i = FlushDecoder (ctrlBlock, interp, clientData); if (i != TCL_OK) return i; } if (!isascii (x)) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "invalid character", (char *) NULL); } return TCL_ERROR; } switch (x) { case ' ': /* fall through */ case '\t': /* fall through */ case '\n': /* fall through */ case ',': if (c -> charCount == 0) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "empty word", (char *) NULL); } return TCL_ERROR; } c -> charCount = 0; c -> wordCount++; return TCL_OK; default: if (c -> charCount == 4) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "word too long", (char *) NULL); } return TCL_ERROR; } if (islower (x)) { x = toupper (x); } break; } switch (x) { case '5': x = 'S'; break; case '1': x = 'L'; break; case '0': x = 'O'; break; } cp = &(c -> words[c -> wordCount][0]); cp[c -> charCount++] = x; cp[c -> charCount] = '\0'; return TCL_OK; } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { /* DecoderControl* c = (DecoderControl*) ctrlBlock; unused */ /* execute conversion specific code here (otp_words decode) */ int i = TCL_OK; while (bufLen-- > 0) { if ((i = Decode (ctrlBlock, *buffer++ & 0xff, interp, clientData)) != TCL_OK) break; } return i; } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (otp_words decode) */ int i; unsigned long p; char b[9]; if ((c -> wordCount == 5) && (c -> charCount > 0)) c -> wordCount = 6; switch (c -> wordCount) { case 6: break; case 0: if (c -> charCount == 0) return TCL_OK; /* else fall through... */ default: if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "too few words", (char *) NULL); } return TCL_ERROR; } memset (b, '\0', sizeof b); for (c -> wordCount = 0, p = 0; c -> wordCount < 6; c -> wordCount++, p += 11) { int lo, hi; int v; char *w = &c -> words[c -> wordCount][0]; if (strlen (w) < 4) lo = 0, hi = 570; else lo = 571, hi = 2047; if ((v = wsrch (w, lo, hi)) < 0) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "unknown word \"", w, "\"", (char *) NULL); } return TCL_ERROR; } insert (b, v, p, 11); } for (p = 0, i = 0; i < 64; i += 2) p += extract (b, i, 2); if ((p & 0x03) != extract (b, 64, 2)) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "parity error", (char *) NULL); } return TCL_ERROR; } i = c -> write (c -> writeClientData, (unsigned char*) b, 8, interp); if (i != TCL_OK) return i; ClearDecoder (ctrlBlock, clientData); return TCL_OK; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (otp_words decode) */ c -> charCount = 0; c -> wordCount = 0; memset (c -> words, '\0', sizeof c -> words); } /* subroutines taken from the module put.c in the original Bellcore reference distribution */ /* Dictionary binary search */ static int wsrch(w,low,high) char *w; int low, high; { int i,j; for(;;) { i = (low + high)/2; if((j = strncmp(w,Wp[i],4)) == 0) return i; /* Found it */ if(high == low+1){ /* Avoid effects of integer truncation in /2 */ if(strncmp(w,Wp[high],4) == 0) return high; else return -1; } if(low >= high) return -1; /* I don't *think* this can happen...*/ if(j < 0) high = i; /* Search lower half */ else low = i; /* Search upper half */ } } static void insert(s, x, start, length) char *s; int x; int start, length; { unsigned char cl; unsigned char cc; unsigned char cr; unsigned long y; int shift; assert(length <= 11); assert(start >= 0); assert(length >= 0); assert(start +length <= 66); shift = ((8 -(( start + length) % 8))%8); y = (long) (x << shift); cl = (unsigned char) ((y >> 16) & 0xff); cc = (unsigned char) ((y >> 8) & 0xff); cr = (unsigned char) (y & 0xff); if(shift + length > 16) { s[start /8] |= cl; s[start/8 +1] |= cc; s[start/8 +2] |= cr; } else if(shift +length > 8) { s[start/8] |= cc; s[start/8 + 1] |= cr; } else { s[start/8] |= cr; } } /* Extract 'length' bits from the char array 's' starting with bit 'start' */ static unsigned long extract(s, start, length) char *s; int start, length; { unsigned char cl; unsigned char cc; unsigned char cr; unsigned long x; assert(length <= 11); assert(start >= 0); assert(length >= 0); assert(start +length <= 66); cl = s[start/8]; cc = s[start/8 +1]; cr = s[start/8 +2]; x = ((long)(cl<<8 | cc) <<8 | cr) ; x = x >> (24 - (length + (start %8))); x =( x & (0xffff >> (16-length) ) ); return(x); } trf2.1.4/generic/zip.c0000644000175000017500000006517511216344224014151 0ustar sergeisergei/* * zip.c -- * * Implements and registers compressor based on deflate (LZ77 variant). * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: zip.c,v 1.21 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static void ZlibError _ANSI_ARGS_ ((Tcl_Interp* interp, z_streamp state, int errcode, CONST char* prefix)); static const char* ZlibErrorMsg _ANSI_ARGS_ ((z_streamp state, int errcode)); static int MaxReadDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "zip", NULL, /* client data not used */ NULL, /* filled later (TrfInit_ZIP), THREADING: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, MaxReadDecoder }, TRF_UNSEEKABLE }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (ZIP) */ z_stream state; /* compressor state */ char* output_buffer; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; int nowrap; /* add conversion specific items here (ZIP) */ z_stream state; /* decompressor state */ char* output_buffer; int stop; /* Boolean flag. Set after * reaching Z_STREAM_END */ } DecoderControl; #define KILO (1024) #define OUT_SIZE (32 * KILO) /* *------------------------------------------------------* * * TrfInit_ZIP -- * * ------------------------------------------------* * Register the compressor implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_ZIP (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = TrfZIPOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc* fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; TrfZipOptionBlock* o = (TrfZipOptionBlock*) optInfo; int res; START (ZipCreateEncoder); c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (ZIP) */ c->state.zalloc = Z_NULL; c->state.zfree = Z_NULL; c->state.opaque = Z_NULL; c->output_buffer = (char*) ckalloc (OUT_SIZE); if (c->output_buffer == (char*) NULL) { ckfree ((VOID*) c); DONE (ZipCreateEncoder); return (ClientData) NULL; } PRINT ("deflateInit (%d, %s)\n", o->level, ZLIB_VERSION); FL; #if 0 res = zf.zdeflateInit_ (&c->state, o->level, ZLIB_VERSION, sizeof(z_stream)); #endif res = zf.zdeflateInit2_ (&c->state, o->level, Z_DEFLATED, o->nowrap ? -MAX_WBITS : MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY, ZLIB_VERSION, sizeof(z_stream)); IN; PRINTLN (ZlibErrorMsg (&c->state, res)); FL; OT; if (res != Z_OK) { if (interp) { ZlibError (interp, &c->state, res, "compressor/init"); } ckfree ((VOID*) c->output_buffer); ckfree ((VOID*) c); DONE (ZipCreateEncoder); return (ClientData) NULL; } DONE (ZipCreateEncoder); return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (ZIP) */ START (ZipDeleteEncoder); PRINT ("deflateEnd ()\n"); FL; zf.zdeflateEnd (&c->state); ckfree ((char*) c->output_buffer); ckfree ((char*) c); DONE (ZipDeleteEncoder); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (ZIP) */ char in; int res; START (ZipEncode); in = character; c->state.next_in = (Bytef*) ∈ c->state.avail_in = 1; for (;;) { if (c->state.avail_in <= 0) { PRINTLN ("Nothing to process"); break; } c->state.next_out = (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; PRINT ("deflate (Z_NO_FLUSH)\n"); FL; res = zf.zdeflate (&c->state, Z_NO_FLUSH); IN; PRINTLN (ZlibErrorMsg (&c->state, res)); FL; OT; if (res < Z_OK) { if (interp) { ZlibError (interp, &c->state, res, "compressor"); } DONE (ZipEncode); return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { DONE (ZipEncode); return res; } } if (c->state.avail_in > 0) continue; if ((c->state.avail_out == 0) && (res == Z_OK)) continue; break; } DONE (ZipEncode); return TCL_OK; } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (ZIP) */ int res; START (ZipEncodeBuffer); PRINT ("Data = %d {\n", bufLen); DUMP (bufLen, buffer); PRINT ("}\n"); c->state.next_in = (Bytef*) buffer; c->state.avail_in = bufLen; for (;;) { if (c->state.avail_in <= 0) { PRINTLN ("Nothing to process"); break; } c->state.next_out = (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; PRINT ("deflate (Z_NO_FLUSH)\n"); FL; res = zf.zdeflate (&c->state, Z_NO_FLUSH); IN; PRINTLN (ZlibErrorMsg (&c->state, res)); FL; OT; if (res < Z_OK) { if (interp) { ZlibError (interp, &c->state, res, "compressor"); } DONE (ZipEncodeBuffer); return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { DONE (ZipEncodeBuffer); return res; } } if (c->state.avail_in > 0) continue; if ((c->state.avail_out == 0) && (res == Z_OK)) continue; break; } DONE (ZipEncodeBuffer); return TCL_OK; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (ZIP) */ int res; START (ZipFlushEncoder); c->state.next_in = (Bytef*) NULL; c->state.avail_in = 0; for (;;) { c->state.next_out = (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; PRINT ("deflate (Z_FINISH)\n"); FL; res = zf.zdeflate (&c->state, Z_FINISH); IN; PRINTLN (ZlibErrorMsg (&c->state, res)); FL; OT; if (res < Z_OK) { if (interp) { ZlibError (interp, &c->state, res, "compressor/flush"); } DONE (ZipFlushEncoder); return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { DONE (ZipFlushEncoder); return res; } } if ((c->state.avail_out == 0) && (res == Z_OK)) continue; break; } DONE (ZipFlushEncoder); return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; START (ZipClearEncoder); PRINT ("deflateReset ()\n"); FL; /* execute conversion specific code here (ZIP) */ zf.zdeflateReset (&c->state); DONE (ZipClearEncoder); } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc* fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; TrfZipOptionBlock* o = (TrfZipOptionBlock*) optInfo; int res; START (ZipCreateDecoder); c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; c->nowrap = o->nowrap; c->stop = 0; /* initialize conversion specific items here (ZIP) */ c->state.zalloc = Z_NULL; c->state.zfree = Z_NULL; c->state.opaque = Z_NULL; c->output_buffer = (char*) ckalloc (OUT_SIZE); if (c->output_buffer == (char*) NULL) { ckfree ((VOID*) c); DONE (ZipCreateDecoder); return (ClientData) NULL; } PRINT ("inflateInit (%s, nowrap=%d)\n", ZLIB_VERSION, o->nowrap); FL; #if 0 res = zf.zinflateInit_ (&c->state, ZLIB_VERSION, sizeof (z_stream)); #endif res = zf.zinflateInit2_ (&c->state, o->nowrap ? -MAX_WBITS : MAX_WBITS, ZLIB_VERSION, sizeof (z_stream)); IN; PRINTLN (ZlibErrorMsg (&c->state, res)); FL; OT; if (res != Z_OK) { if (interp) { ZlibError (interp, &c->state, res, "decompressor/init"); } ckfree ((VOID*) c->output_buffer); ckfree ((VOID*) c); DONE (ZipCreateDecoder); return (ClientData) NULL; } DONE (ZipCreateDecoder); return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (ZIP) */ START (ZipDeleteDecoder); PRINT ("inflateEnd ()\n"); FL; zf.zinflateEnd (&c->state); ckfree ((char*) c->output_buffer); ckfree ((char*) c); DONE (ZipDeleteDecoder); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (ZIP) */ char in; int res; START (ZipDecode); /* if (c->stop) { PRINTLN ("stopped"); DONE (ZipDecode); return TCL_OK; } */ in = character; c->state.next_in = (Bytef*) ∈ c->state.avail_in = 1; for (;;) { if (c->state.avail_in <= 0) { PRINTLN ("Nothing to process"); break; } c->state.next_out = (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; PRINT ("inflate (Z_NO_FLUSH)\n"); FL; res = zf.zinflate (&c->state, Z_NO_FLUSH); IN; PRINTLN (ZlibErrorMsg (&c->state, res)); FL; OT; if (res < Z_OK) { if (interp) { ZlibError (interp, &c->state, res, "decompressor"); } DONE (ZipDecode); return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { DONE (ZipDecode); return res; } } /* 29.11.1999, AK */ if (res == Z_STREAM_END) { /* Don't process the remainining characters, they are not part of the * compressed stream. Push them back into the channel downward and then * fake our upstream user into EOF. */ PRINTLN ("STOP"); c->stop = 1; break; } /**/ if (c->state.avail_in > 0) { PRINTLN ("More to process"); continue; } if ((c->state.avail_out == 0) && (res == Z_OK)) { PRINTLN ("Output space exhausted, still ok"); continue; } break; } DONE (ZipDecode); return TCL_OK; } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (ZIP) */ int res; START (ZipDecodeBuffer); PRINT ("Data = %d {\n", bufLen); DUMP (bufLen, buffer); PRINT ("}\n"); /* if (c->stop) { PRINTLN ("stopped"); DONE (ZipDecodeBuffer); return TCL_OK; } */ c->state.next_in = (Bytef*) buffer; c->state.avail_in = bufLen; for (;;) { if (c->state.avail_in <= 0) { PRINTLN ("Nothing to process"); break; } c->state.next_out = (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; PRINT ("inflate (Z_NO_FLUSH)\n"); FL; res = zf.zinflate (&c->state, Z_NO_FLUSH); IN; PRINTLN (ZlibErrorMsg (&c->state, res)); FL; OT; if (res < Z_OK) { if (interp) { ZlibError (interp, &c->state, res, "decompressor"); } DONE (ZipDecodeBuffer); return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { DONE (ZipDecodeBuffer); return res; } } /* 29.11.1999, AK */ if (res == Z_STREAM_END) { /* Don't process the remainining characters, they are not part of the * compressed stream. Push them back into the channel downward and then * fake our upstream user into EOF. */ PRINTLN ("STOP"); c->stop = 1; break; }/**/ if (c->state.avail_in > 0) { PRINTLN ("More to process"); continue; } if ((c->state.avail_out == 0) && (res == Z_OK)) { PRINTLN ("Output space exhausted, still ok"); continue; } break; } DONE (ZipDecodeBuffer); return TCL_OK; } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (ZIP) */ int res; START (ZipFlushDecoder); c->state.next_in = (Bytef*) c->output_buffer; /* fake out 'inflate' */ c->state.avail_in = 0; for (;;) { c->state.next_out = (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; if (c->nowrap) { /* * Hack required by zlib: Supply an additional dummy * byte in order to force the generation of Z_STREAM_END. */ c->state.avail_in = 1; } PRINT ("inflate (Z_FINISH)\n"); FL; res = zf.zinflate (&c->state, Z_FINISH); IN; PRINTLN (ZlibErrorMsg (&c->state, res)); FL; OT; if ((res < Z_OK) || (res == Z_NEED_DICT)) { if (interp) { ZlibError (interp, &c->state, res, "decompressor/flush"); } DONE (ZipFlushDecoder); return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { DONE (ZipFlushDecoder); return res; } } if ((c->state.avail_out == 0) && (res == Z_OK)) continue; break; } DONE (ZipFlushDecoder); return TCL_OK; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; START (ZipClearDecoder); PRINT ("inflateReset ()\n"); FL; /* execute conversion specific code here (ZIP) */ zf.zinflateReset (&c->state); DONE (ZipClearDecoder); } /* *------------------------------------------------------* * * MaxReadDecoder -- * * ------------------------------------------------* * Depending on the state of the decompressor the layer above is * told to read exactly one byte or nothing at all. The latter * happens iff the decompressor found that he is at the end of * the compressed stream (Z_STREAM_END). The former (reading * exactly one byte) is necessary to avoid reading data behind * the end of the compressed stream. We are unable to give this * data back to the channel below, i.e. it is lost after this * transformation is unstacked. A most undesirable property. The * disadvantage of the current solution is of course a loss of * performance. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * The number of characters the generic Trf layer is * allowed to read from the channel below. * *------------------------------------------------------* */ static int MaxReadDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; int max = c->stop ? 0 : 1; START (MaxReadDecoder); PRINT ("Stop = %d --> %d\n", c->stop, max); FL; DONE (MaxReadDecoder); return max; } /* *------------------------------------------------------* * * ZlibError -- * * ------------------------------------------------* * Append error message from zlib-state to interpreter * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ZlibError (interp, state, errcode, prefix) Tcl_Interp* interp; z_streamp state; int errcode; CONST char* prefix; { Tcl_AppendResult (interp, "zlib error (", (char*) NULL); Tcl_AppendResult (interp, prefix, (char*) NULL); Tcl_AppendResult (interp, "): ", (char*) NULL); Tcl_AppendResult (interp, ZlibErrorMsg (state, errcode), (char*) NULL); } /* *------------------------------------------------------* * * ZlibErrorMsg -- * * ------------------------------------------------* * Return the error message from the zlib-state. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static const char* ZlibErrorMsg (state, errcode) z_streamp state; int errcode; { CONST char* msg; if (state->msg != NULL) { msg = state->msg; } else { /* * A table-lookup might have been nicer, but this * is more secure against changes of the codevalues * used by zlib. */ switch (errcode) { case Z_MEM_ERROR: msg = "not enough memory available"; break; case Z_BUF_ERROR: msg = "no progress was possible"; break; case Z_STREAM_ERROR: msg = "inconsistent stream state"; break; case Z_DATA_ERROR: msg = "incoming data corrupted"; break; case Z_VERSION_ERROR: msg = "inconsistent version"; break; case Z_NEED_DICT: msg = "dictionary required"; break; case Z_STREAM_END: msg = "stream ends here, flushed out"; break; case Z_OK: msg = "ok"; break; default: msg = "?"; break; } } return msg; } trf2.1.4/generic/unstack.c0000644000175000017500000000637511216344224015014 0ustar sergeisergei/* * unstack.c -- * * Implements the 'unstack' command to remove a conversion. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: unstack.c,v 1.9 2000/08/09 19:13:18 aku Exp $ */ #include "transformInt.h" static int TrfUnstackObjCmd _ANSI_ARGS_ ((ClientData notUsed, Tcl_Interp* interp, int objc, struct Tcl_Obj* CONST * objv)); /* *---------------------------------------------------------------------- * * TrfUnstackCmd -- * * This procedure is invoked to process the "unstack" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * Unstacks the channel, thereby restoring its parent. * *---------------------------------------------------------------------- */ static int TrfUnstackObjCmd (notUsed, interp, objc, objv) ClientData notUsed; /* Not used. */ Tcl_Interp* interp; /* Current interpreter. */ int objc; /* Number of arguments. */ struct Tcl_Obj* CONST * objv; /* Argument strings. */ { /* * unstack */ Tcl_Channel chan; int mode; #ifdef USE_TCL_STUBS if (Tcl_UnstackChannel == NULL) { const char* cmd = Tcl_GetStringFromObj (objv [0], NULL); Tcl_AppendResult (interp, cmd, " is not available as the required ", "patch to the core was not applied", (char*) NULL); return TCL_ERROR; } #endif if ((objc < 2) || (objc > 2)) { Tcl_AppendResult (interp, "wrong # args: should be \"unstack channel\"", (char*) NULL); return TCL_ERROR; } chan = Tcl_GetChannel (interp, Tcl_GetStringFromObj (objv [1], NULL), &mode); if (chan == (Tcl_Channel) NULL) { return TCL_ERROR; } Tcl_UnstackChannel (interp, chan); return TCL_OK; } /* *------------------------------------------------------* * * TrfInit_Unstack -- * * ------------------------------------------------* * Register the 'unstack' command. * ------------------------------------------------* * * Sideeffects: * As of 'Tcl_CreateObjCommand'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Unstack (interp) Tcl_Interp* interp; { Tcl_CreateObjCommand (interp, "unstack", TrfUnstackObjCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); return TCL_OK; } trf2.1.4/generic/sha1.c0000644000175000017500000001343711216344224014175 0ustar sergeisergei/* * sha1.c -- * * Implements and registers message digest generator SHA1. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: sha1.c,v 1.3 2000/08/09 19:13:18 aku Exp $ */ #include "loadman.h" /* * Generator description * --------------------- * * The SHA1 alogrithm is used to compute a cryptographically strong * message digest. */ #ifndef OTP #define DIGEST_SIZE (SHA_DIGEST_LENGTH) #else #define DIGEST_SIZE (8) #endif #define CTX_TYPE SHA_CTX /* * Declarations of internal procedures. */ static void MDsha1_Start _ANSI_ARGS_ ((VOID* context)); static void MDsha1_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDsha1_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDsha1_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); static int MDsha1_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ #ifndef OTP "sha1", #else "otp_sha1", #endif sizeof (CTX_TYPE), DIGEST_SIZE, MDsha1_Start, MDsha1_Update, MDsha1_UpdateBuf, MDsha1_Final, MDsha1_Check }; /* *------------------------------------------------------* * * TrfInit_SHA1 -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int #ifndef OTP TrfInit_SHA1 (interp) #else TrfInit_OTP_SHA1 (interp) #endif Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDsha1_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDsha1_Start (context) VOID* context; { sha1f.init ((SHA_CTX*) context); } /* *------------------------------------------------------* * * MDsha1_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDsha1_Update (context, character) VOID* context; unsigned int character; { unsigned char buf = character; sha1f.update ((SHA_CTX*) context, &buf, 1); } /* *------------------------------------------------------* * * MDsha1_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDsha1_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { sha1f.update ((SHA_CTX*) context, (unsigned char*) buffer, bufLen); } /* *------------------------------------------------------* * * MDsha1_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDsha1_Final (context, digest) VOID* context; VOID* digest; { #ifndef OTP sha1f.final ((unsigned char*) digest, (SHA_CTX*) context); #else unsigned int result[SHA_DIGEST_LENGTH / sizeof (char)]; sha1f.final ((unsigned char*) result, (SHA_CTX*) context); result[0] ^= result[2]; result[1] ^= result[3]; result[0] ^= result[4]; Trf_FlipRegisterLong ((VOID*) result, DIGEST_SIZE); memcpy ((VOID *) digest, (VOID *) result, DIGEST_SIZE); #endif } /* *------------------------------------------------------* * * MDsha1_Check -- * * ------------------------------------------------* * Do global one-time initializations of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * Loads the shared library containing the * SHA1 functionality * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int MDsha1_Check (interp) Tcl_Interp* interp; { return TrfLoadSHA1 (interp); } trf2.1.4/generic/registry.c0000644000175000017500000035730211216344224015213 0ustar sergeisergei/* * registry.c -- * * Implements the C level procedures handling the registry * * * Copyright (c) 1996-1999 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: registry.c,v 1.58 2009/05/07 05:30:35 andreas_kupries Exp $ */ #include "transformInt.h" /* * Code used to associate the registry with an interpreter. */ #define ASSOC "binTrf" #ifdef TRF_DEBUG int n = 0; #endif /* * Possible values for 'flags' field in control structure. */ #define CHANNEL_ASYNC (1<<0) /* non-blocking mode */ /* * Number of milliseconds to wait before firing an event to flush * out information waiting in buffers (fileevent support). * * Relevant for only Tcl 8.0 and beyond. */ #define TRF_DELAY (5) /* * Structures used by an attached transformation procedure * * => Information stored for a single direction of the channel. * => Information required by a result buffer. * => Information stored for the complete channel. */ typedef struct _DirectionInfo_ { Trf_ControlBlock control; /* control block of transformation */ Trf_Vectors* vectors; /* vectors used during the transformation */ } DirectionInfo; /* * Definition of the structure containing the information about the * internal input buffer. */ typedef struct _SeekState_ SeekState; typedef struct _ResultBuffer_ { unsigned char* buf; /* Reference to the buffer area */ int allocated; /* Allocated size of the buffer area */ int used; /* Number of bytes in the buffer, <= allocated */ SeekState* seekState; } ResultBuffer; typedef struct _SeekConfig_ { int overideAllowed; /* Boolean flag. If set the user may overide the * standard policy with his own choice */ Trf_SeekInformation natural; /* Natural seek policy, copied from the * transform definition */ Trf_SeekInformation chosen; /* Seek policy chosen from natural policy * and the underlying channels; */ int identity; /* Flag, set if 'identity' was forced by the * user. */ } SeekConfig; struct _SeekState_ { /* -- Integrity conditions -- * * BufStartLoc == BufEndLoc implies ResultLength(&result) == 0. * BufStartLoc == BufEndLoc implies UpLoc == BufStart. * * UP_CONVERT (DownLoc - AheadOffset) == BufEndLoc * * UpXLoc % seekState.used.numBytesTransform == 0 * <=> Transform may seek only in multiples of its input tuples. * * (DownLoc - AheadOffset) % seekState.used.numBytesDown == 0 * <=> Downstream channel operates in multiples of the transformation * output tuples, except for possible offsets because of read ahead. * * UP_CONVERT (DownZero) == 0 * * -- Integrity conditions -- */ Trf_SeekInformation used; /* Seek policy currently in effect, might * be chosen by user */ int allowed; /* Flag. Set for seekable transforms. Derived * from the contents of 'used'. */ int upLoc; /* Current location of file pointer in the * transformed stream. */ int upBufStartLoc; /* Same as above, for start of read buffer (result) */ int upBufEndLoc; /* See above, for the character after the end of the * buffer. */ int downLoc; /* Current location of the file pointer in the channel * downstream. */ int downZero; /* location downstream equivalent to UpLoc == 0 */ int aheadOffset; /* #Bytes DownLoc is after the down location of * BufEnd. Values > 0 indicate incomplete data in the * transform buffer itself. */ int changed; /* Flag, set if seeking occured with 'identity' set */ }; /** XXX change definition for 8.2, at compile time */ typedef struct _TrfTransformationInstance_ { #ifdef USE_TCL_STUBS int patchVariant; /* See transformInt.h, Trf_Registry */ #endif /* 04/13/1999 Fileevent patch from Matt Newman */ Tcl_Channel self; /* Our own channel handle */ Tcl_Channel parent; /* The channel we are stacked upon. Relevant * only for values PATCH_ORIG and PATCH_832 of * 'patchVariant', see above. */ int readIsFlushed; /* flag to note wether in.flushProc was called or not */ /* 04/13/1999 Fileevent patch from Matt Newman */ int flags; /* currently CHANNEL_ASYNC or zero */ int watchMask; /* current TrfWatch mask */ int mode; /* mode of parent channel, * OR'ed combination of * TCL_READABLE, TCL_WRITABLE */ /* Tcl_Transformation standard; data required for all transformation * instances. */ DirectionInfo in; /* information for transformation of read data */ DirectionInfo out; /* information for transformation of written data */ ClientData clientData; /* copy from entry->trfType->clientData */ /* * internal result buffer used during transformations of incoming data. * Stores results waiting for retrieval too, i.e. state information * carried from call to call. */ ResultBuffer result; /* Number of bytes written during a down transformation. */ int lastWritten; /* Number of bytes stored during an up transformation */ int lastStored; /* Timer for automatic push out of information sitting in various channel * buffers. Used by the fileevent support. See 'ChannelHandler'. */ Tcl_TimerToken timer; /* Information about the chosen and used seek policy and wether the user * is allowed to change it. Runtime configuration. */ SeekConfig seekCfg; /* More seek information, runtime state. */ SeekState seekState; #ifdef TRF_STREAM_DEBUG char* name; /* Name of transformation command */ unsigned long inCounter; /* Number of bytes read from below */ unsigned long outCounter; /* Number of bytes stored in 'result' */ #endif } TrfTransformationInstance; #ifdef TRF_STREAM_DEBUG #define STREAM_IN(trans,blen,buf) {int i; for (i=0;i<(blen);i++,(trans)->inCounter++) {printf ("%p:%s:in_\t%d\t%02x\n", (trans), (trans)->name, (trans)->inCounter, 0xff & ((buf) [i]));}} #define STREAM_OUT(trans,blen,buf) {int i; for (i=0;i<(blen);i++,(trans)->outCounter++) {printf ("%p:%s:out\t%d\t%02x\n", (trans), (trans)->name, (trans)->outCounter, 0xff & ((buf) [i]));}} #else #define STREAM_IN(t,bl,b) #define STREAM_OUT(t,bl,b) #endif #define INCREMENT (512) #define READ_CHUNK_SIZE 4096 #define TRF_UP_CONVERT(trans,k) \ (((k) / trans->seekState.used.numBytesDown) * trans->seekState.used.numBytesTransform) #define TRF_DOWN_CONVERT(trans,k) \ (((k) / trans->seekState.used.numBytesTransform) * trans->seekState.used.numBytesDown) #define TRF_IS_UNSEEKABLE(si) \ (((si).numBytesTransform == 0) || ((si).numBytesDown == 0)) #define TRF_SET_UNSEEKABLE(si) \ {(si).numBytesTransform = 0 ; (si).numBytesDown = 0;} /* * forward declarations of all internally used procedures. */ static Tcl_ChannelType* AllocChannelType _ANSI_ARGS_ ((int* sizePtr)); static Tcl_ChannelType* InitializeChannelType _ANSI_ARGS_ ((CONST char* name, int patchVariant)); static int TrfUnregister _ANSI_ARGS_ ((Tcl_Interp* interp, Trf_RegistryEntry* entry)); static void TrfDeleteRegistry _ANSI_ARGS_ ((ClientData clientData, Tcl_Interp *interp)); static int TrfExecuteObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp* interp, int objc, struct Tcl_Obj* CONST objv [])); static void TrfDeleteCmd _ANSI_ARGS_((ClientData clientData)); #if 0 static int TrfInfoObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp* interp, int objc, struct Tcl_Obj* CONST objv [])); #endif /* 04/13/1999 Fileevent patch from Matt Newman */ static int TrfBlock _ANSI_ARGS_ ((ClientData instanceData, int mode)); static int TrfClose _ANSI_ARGS_ ((ClientData instanceData, Tcl_Interp* interp)); static int TrfInput _ANSI_ARGS_ ((ClientData instanceData, char* buf, int toRead, int* errorCodePtr)); static int TrfOutput _ANSI_ARGS_ ((ClientData instanceData, CONST84 char* buf, int toWrite, int* errorCodePtr)); static int TrfSeek _ANSI_ARGS_ ((ClientData instanceData, long offset, int mode, int* errorCodePtr)); static void TrfWatch _ANSI_ARGS_ ((ClientData instanceData, int mask)); static int TrfGetFile _ANSI_ARGS_ ((ClientData instanceData, int direction, ClientData* handlePtr)); static int TrfGetOption _ANSI_ARGS_ ((ClientData instanceData, Tcl_Interp* interp, CONST84 char* optionName, Tcl_DString* dsPtr)); static int TrfSetOption _ANSI_ARGS_((ClientData instanceData, Tcl_Interp* interp, CONST char* optionName, CONST char* value)); #ifdef USE_TCL_STUBS static int TrfNotify _ANSI_ARGS_((ClientData instanceData, int interestMask)); #endif static int TransformImmediate _ANSI_ARGS_ ((Tcl_Interp* interp, Trf_RegistryEntry* entry, Tcl_Channel source, Tcl_Channel destination, struct Tcl_Obj* CONST in, Trf_Options optInfo)); static int AttachTransform _ANSI_ARGS_ ((Trf_RegistryEntry* entry, Trf_BaseOptions* baseOpt, Trf_Options optInfo, Tcl_Interp* interp)); static int PutDestination _ANSI_ARGS_ ((ClientData clientData, unsigned char* outString, int outLen, Tcl_Interp* interp)); static int PutDestinationImm _ANSI_ARGS_ ((ClientData clientData, unsigned char* outString, int outLen, Tcl_Interp* interp)); static int PutTrans _ANSI_ARGS_ ((ClientData clientData, unsigned char* outString, int outLen, Tcl_Interp* interp)); static int PutInterpResult _ANSI_ARGS_ ((ClientData clientData, unsigned char* outString, int outLen, Tcl_Interp* interp)); /* 04/13/1999 Fileevent patch from Matt Newman */ static void ChannelHandler _ANSI_ARGS_ ((ClientData clientData, int mask)); static void ChannelHandlerTimer _ANSI_ARGS_ ((ClientData clientData)); #ifdef USE_TCL_STUBS static Tcl_Channel DownChannel _ANSI_ARGS_ ((TrfTransformationInstance* ctrl)); static int DownSeek _ANSI_ARGS_ ((TrfTransformationInstance* ctrl, int offset, int mode)); static int DownRead _ANSI_ARGS_ ((TrfTransformationInstance* ctrl, char* buf, int toRead)); static int DownWrite _ANSI_ARGS_ ((TrfTransformationInstance* ctrl, char* buf, int toWrite)); static int DownSOpt _ANSI_ARGS_ ((Tcl_Interp* interp, TrfTransformationInstance* ctrl, CONST char* optionName, CONST char* value)); static int DownGOpt _ANSI_ARGS_ ((Tcl_Interp* interp, TrfTransformationInstance* ctrl, CONST84 char* optionName, Tcl_DString* dsPtr)); #define DOWNC(trans) (DownChannel (trans)) #define TELL(trans) (SEEK (trans, 0, SEEK_CUR)) #define SEEK(trans,off,mode) (DownSeek ((trans), (off), (mode))) #define READ(trans,buf,toRead) (DownRead ((trans), (buf), (toRead))) #define WRITE(trans,buf,toWrite) (DownWrite ((trans), (buf), (toWrite))) #define SETOPT(i,trans,opt,val) (DownSOpt ((i), (trans), (opt), (val))) #define GETOPT(i,trans,opt,ds) (DownGOpt ((i), (trans), (opt), (ds))) #else #define DOWNC(trans) ((trans)->parent) #define TELL(trans) (SEEK (trans, 0, SEEK_CUR)) #define SEEK(trans,off,mode) (Tcl_Seek ((trans)->parent, (off), (mode))) #define READ(trans,buf,toRead) (Tcl_Read ((trans)->parent, (buf), (toRead))) #define WRITE(trans,buf,toWrite) (Tcl_Write ((trans)->parent, (buf), (toWrite))) #define SETOPT(i,trans,opt,val) (Tcl_SetChannelOption ((i), (trans)->parent, (opt), (val))) #define GETOPT(i,trans,opt,ds) (Tcl_GetChannelOption ((i), (trans)->parent, (opt), (ds))) #endif /* Convenience macro for allocation * of new transformation instances. */ #define NEW_TRANSFORM \ (TrfTransformationInstance*) ckalloc (sizeof (TrfTransformationInstance)); /* Procedures to handle the internal timer. */ static void TimerKill _ANSI_ARGS_ ((TrfTransformationInstance* trans)); static void TimerSetup _ANSI_ARGS_ ((TrfTransformationInstance* trans)); static void ChannelHandlerKS _ANSI_ARGS_ ((TrfTransformationInstance* trans, int mask)); /* Procedures to handle the internal read buffer. */ static void ResultClear _ANSI_ARGS_ ((ResultBuffer* r)); static void ResultInit _ANSI_ARGS_ ((ResultBuffer* r)); static int ResultLength _ANSI_ARGS_ ((ResultBuffer* r)); static int ResultCopy _ANSI_ARGS_ ((ResultBuffer* r, unsigned char* buf, int toRead)); static void ResultDiscardAtStart _ANSI_ARGS_ ((ResultBuffer* r, int n)); static void ResultAdd _ANSI_ARGS_ ((ResultBuffer* r, unsigned char* buf, int toWrite)); /* * Procedures to handle seeking information. */ static void SeekCalculatePolicies _ANSI_ARGS_ ((TrfTransformationInstance* trans)); static void SeekInitialize _ANSI_ARGS_ ((TrfTransformationInstance* trans)); static void SeekClearBuffer _ANSI_ARGS_ ((TrfTransformationInstance* trans, int which)); static void SeekSynchronize _ANSI_ARGS_ ((TrfTransformationInstance* trans, Tcl_Channel parent)); static Tcl_Obj* SeekStateGet _ANSI_ARGS_ ((Tcl_Interp* interp, SeekState* state)); static Tcl_Obj* SeekConfigGet _ANSI_ARGS_ ((Tcl_Interp* interp, SeekConfig* cfg)); static void SeekPolicyGet _ANSI_ARGS_ ((TrfTransformationInstance* trans, char* policy)); #ifdef TRF_DEBUG static void SeekDump _ANSI_ARGS_ ((TrfTransformationInstance* trans, CONST char* place)); #define SEEK_DUMP(str) SeekDump (trans, #str) #else #define SEEK_DUMP(str) #endif /* *------------------------------------------------------* * * TrfGetRegistry -- * * ------------------------------------------------* * Accessor to the interpreter associated registry * of transformations. * ------------------------------------------------* * * Sideeffects: * Allocates and initializes the hashtable * during the first call and associates it * with the specified interpreter. * * Result: * The internal registry of transformations. * *------------------------------------------------------* */ Trf_Registry* TrfGetRegistry (interp) Tcl_Interp* interp; { Trf_Registry* registry; START (TrfGetRegistry); registry = TrfPeekForRegistry (interp); if (registry == (Trf_Registry*) NULL) { registry = (Trf_Registry*) ckalloc (sizeof (Trf_Registry)); registry->registry = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable)); Tcl_InitHashTable (registry->registry, TCL_STRING_KEYS); Tcl_SetAssocData (interp, ASSOC, TrfDeleteRegistry, (ClientData) registry); } DONE (TrfGetRegistry); return registry; } /* *------------------------------------------------------* * * TrfPeekForRegistry -- * * ------------------------------------------------* * Accessor to the interpreter associated registry * of transformations. Does not create the registry * (in contrast to 'TrfGetRegistry'). * ------------------------------------------------* * * Sideeffects: * None. * * Result: * The internal registry of transformations. * *------------------------------------------------------* */ Trf_Registry* TrfPeekForRegistry (interp) Tcl_Interp* interp; { Tcl_InterpDeleteProc* proc; START (TrfPeekForRegistry); proc = TrfDeleteRegistry; DONE (TrfPeekForRegistry); return (Trf_Registry*) Tcl_GetAssocData (interp, ASSOC, &proc); } /* *------------------------------------------------------* * * Trf_Register -- * * ------------------------------------------------* * Announce a transformation to the registry associated * with the specified interpreter. * ------------------------------------------------* * * Sideeffects: * May create the registry. Allocates and * initializes the structure describing * the announced transformation. * * Result: * A standard TCL error code. * *------------------------------------------------------* */ int Trf_Register (interp, type) Tcl_Interp* interp; CONST Trf_TypeDefinition* type; { Trf_Registry* registry; Trf_RegistryEntry* entry; Tcl_HashEntry* hPtr; int new; START (Trf_Register); PRINT ("(%p, \"%s\")\n", type, type->name); FL; registry = TrfGetRegistry (interp); /* * Already defined ? */ hPtr = Tcl_FindHashEntry (registry->registry, (char*) type->name); if (hPtr != (Tcl_HashEntry*) NULL) { PRINT ("Already defined!\n"); FL; DONE (Trf_Register); return TCL_ERROR; } /* * Check validity of given structure */ #define IMPLY(a,b) ((! (a)) || (b)) /* assert (type->options); */ assert (IMPLY(type->options != NULL, type->options->createProc != NULL)); assert (IMPLY(type->options != NULL, type->options->deleteProc != NULL)); assert (IMPLY(type->options != NULL, type->options->checkProc != NULL)); assert (IMPLY(type->options != NULL, (type->options->setProc != NULL) || (type->options->setObjProc != NULL))); assert (IMPLY(type->options != NULL, type->options->queryProc != NULL)); assert (type->encoder.createProc); assert (type->encoder.deleteProc); assert ((type->encoder.convertProc != NULL) || (type->encoder.convertBufProc != NULL)); assert (type->encoder.flushProc); assert (type->encoder.clearProc); assert (type->decoder.createProc); assert (type->decoder.deleteProc); assert ((type->decoder.convertProc != NULL) || (type->decoder.convertBufProc != NULL)); assert (type->decoder.flushProc); assert (type->decoder.clearProc); /* * Generate command to execute transformations immediately or to generate * filters. */ entry = (Trf_RegistryEntry*) ckalloc (sizeof (Trf_RegistryEntry)); entry->registry = registry; entry->trfType = (Trf_TypeDefinition*) type; entry->interp = interp; #ifndef USE_TCL_STUBS entry->transType = InitializeChannelType (type->name, -1); #else entry->transType = InitializeChannelType (type->name, registry->patchVariant); #endif entry->trfCommand = Tcl_CreateObjCommand (interp, (char*) type->name, TrfExecuteObjCmd, (ClientData) entry, TrfDeleteCmd); /* * Add entry to internal registry. */ hPtr = Tcl_CreateHashEntry (registry->registry, (char*) type->name, &new); Tcl_SetHashValue (hPtr, entry); DONE (Trf_Register); return TCL_OK; } /* *------------------------------------------------------* * * Trf_Unregister -- * * ------------------------------------------------* * Removes the transformation from the registry * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated in 'Trf_Register'. * * Result: * A standard TCL error code. * *------------------------------------------------------* */ static int TrfUnregister (interp, entry) Tcl_Interp* interp; Trf_RegistryEntry* entry; { Trf_Registry* registry; Tcl_HashEntry* hPtr; START (Trf_Unregister); registry = TrfGetRegistry (interp); hPtr = Tcl_FindHashEntry (registry->registry, (char*) entry->trfType->name); ckfree ((char*) entry->transType); ckfree ((char*) entry); Tcl_DeleteHashEntry (hPtr); DONE (Trf_Unregister); return TCL_OK; } /* *------------------------------------------------------* * * TrfDeleteRegistry -- * * ------------------------------------------------* * Trap handler. Called by the Tcl core during * interpreter destruction. Destroys the registry * of transformations. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated in 'TrfGetRegistry'. * * Result: * None. * *------------------------------------------------------* */ static void TrfDeleteRegistry (clientData, interp) ClientData clientData; Tcl_Interp* interp; { Trf_Registry* registry = (Trf_Registry*) clientData; START (TrfDeleteRegistry); /* * The commands are already deleted, therefore the hashtable is empty here. */ Tcl_DeleteHashTable (registry->registry); ckfree ((char*) registry); DONE (TrfDeleteRegistry); } /* (readable) shortcuts for calling the option processing vectors. */ #define CLT (entry->trfType->clientData) #define OPT (entry->trfType->options) #define CREATE_OPTINFO (OPT ? (*OPT->createProc) (CLT) : NULL) #define DELETE_OPTINFO if (optInfo) (*OPT->deleteProc) (optInfo, CLT) #define CHECK_OPTINFO(baseOpt) (optInfo ? (*OPT->checkProc) (optInfo, interp, &baseOpt, CLT) : TCL_OK) #define SET_OPTION(opt,optval) (optInfo ? (*OPT->setProc) (optInfo, interp, opt, optval, CLT) : TCL_ERROR) #define SET_OPTION_OBJ(opt,optval) (optInfo ? (*OPT->setObjProc) (optInfo, interp, opt, optval, CLT) : TCL_ERROR) #define ENCODE_REQUEST(entry,optInfo) (optInfo ? (*OPT->queryProc) (optInfo, CLT) : 1) /* *------------------------------------------------------* * * TrfExecuteObjCmd -- * * ------------------------------------------------* * Implementation procedure for all transformations. * Equivalent to 'TrfExecuteCmd', but using the new * Object interfaces. * ------------------------------------------------* * * Sideeffects: * See 'TrfExecuteCmd'. * * Result: * A standard TCL error code. * *------------------------------------------------------* */ static int TrfExecuteObjCmd (clientData, interp, objc, objv) ClientData clientData; Tcl_Interp* interp; int objc; struct Tcl_Obj* CONST * objv; { /* (readable) shortcuts for calling the option processing vectors. * as defined in 'TrfExecuteCmd'. */ int res, len; /* Tcl_Channel source, destination;*/ /* int src_mode, dst_mode;*/ const char* cmd; const char* option; struct Tcl_Obj* optarg; Trf_RegistryEntry* entry; Trf_Options optInfo; Trf_BaseOptions baseOpt; int mode; int wrong_mod2; int wrong_number; START (TrfExecuteObjCmd); #ifdef TRF_DEBUG { int i; for (i = 0; i < objc; i++) { PRINT ("Argument [%03d] = \"%s\"\n", i, Tcl_GetStringFromObj (objv [i], NULL)); FL; } } #endif baseOpt.attach = (Tcl_Channel) NULL; baseOpt.attach_mode = 0; baseOpt.source = (Tcl_Channel) NULL; baseOpt.destination = (Tcl_Channel) NULL; baseOpt.policy = (Tcl_Obj*) NULL; entry = (Trf_RegistryEntry*) clientData; cmd = Tcl_GetStringFromObj (objv [0], NULL); objc --; objv ++; optInfo = CREATE_OPTINFO; PRINT ("Processing options...\n"); FL; IN; while ((objc > 0) && (*Tcl_GetStringFromObj (objv [0], NULL) == '-')) { /* * Process options, as long as they are found */ option = Tcl_GetStringFromObj (objv [0], NULL); if (0 == strcmp (option, "--")) { /* end of option list */ objc--, objv++; break; } wrong_number = (objc < 2); /* option, but without argument */ optarg = objv [1]; objc -= 2; objv += 2; len = strlen (option); if (len < 2) goto unknown_option; switch (option [1]) { case 'a': if (0 != strncmp (option, "-attach", len)) goto check_for_trans_option; if (wrong_number) { Tcl_AppendResult (interp, cmd, ": wrong # args, option \"", option, "\" requires an argument", (char*) NULL); OT; goto cleanup_after_error; } baseOpt.attach = Tcl_GetChannel (interp, Tcl_GetStringFromObj (optarg, NULL), &baseOpt.attach_mode); if (baseOpt.attach == (Tcl_Channel) NULL) { OT; goto cleanup_after_error; } break; case 'i': if (0 != strncmp (option, "-in", len)) goto check_for_trans_option; if (wrong_number) { Tcl_AppendResult (interp, cmd, ": wrong # args, option \"", option, "\" requires an argument", (char*) NULL); OT; goto cleanup_after_error; } baseOpt.source = Tcl_GetChannel (interp, Tcl_GetStringFromObj (optarg, NULL), &mode); if (baseOpt.source == (Tcl_Channel) NULL) goto cleanup_after_error; if (! (mode & TCL_READABLE)) { Tcl_AppendResult (interp, cmd, ": source-channel not readable", (char*) NULL); OT; goto cleanup_after_error; } break; case 'o': if (0 != strncmp (option, "-out", len)) goto check_for_trans_option; if (wrong_number) { Tcl_AppendResult (interp, cmd, ": wrong # args, option \"", option, "\" requires an argument", (char*) NULL); OT; goto cleanup_after_error; } baseOpt.destination = Tcl_GetChannel (interp, Tcl_GetStringFromObj (optarg, NULL), &mode); if (baseOpt.destination == (Tcl_Channel) NULL) { OT; goto cleanup_after_error; } if (! (mode & TCL_WRITABLE)) { Tcl_AppendResult (interp, cmd, ": destination-channel not writable", (char*) NULL); OT; goto cleanup_after_error; } break; case 's': if (0 != strncmp (option, "-seekpolicy", len)) goto check_for_trans_option; if (wrong_number) { Tcl_AppendResult (interp, cmd, ": wrong # args, option \"", option, "\" requires an argument", (char*) NULL); OT; goto cleanup_after_error; } baseOpt.policy = optarg; Tcl_IncrRefCount (optarg); break; default: check_for_trans_option: if (wrong_number) { Tcl_AppendResult (interp, cmd, ": wrong # args, all options require an argument", (char*) NULL); OT; goto cleanup_after_error; } if ((*OPT->setObjProc) == NULL) { res = SET_OPTION (option, Tcl_GetStringFromObj (optarg, NULL)); } else { res = SET_OPTION_OBJ (option, optarg); } if (res != TCL_OK) { OT; goto cleanup_after_error; } break; } /* switch option */ } /* while options */ OT; /* * Check argument restrictions, insert defaults if necessary, * execute the required operation. */ if ((baseOpt.attach != (Tcl_Channel) NULL) && ((baseOpt.source != (Tcl_Channel) NULL) || (baseOpt.destination != (Tcl_Channel) NULL))) { Tcl_AppendResult (interp, cmd, ": inconsistent options, -in/-out not allowed with -attach", (char*) NULL); PRINT ("Inconsistent options\n"); FL; goto cleanup_after_error; } if ((baseOpt.attach == (Tcl_Channel) NULL) && baseOpt.policy != (Tcl_Obj*) NULL) { Tcl_AppendResult (interp, cmd, ": inconsistent options, -seekpolicy ", "not allowed without -attach", (char*) NULL); PRINT ("Inconsistent options\n"); FL; goto cleanup_after_error; } if ((baseOpt.source == (Tcl_Channel) NULL) && (baseOpt.attach == (Tcl_Channel) NULL)) wrong_mod2 = 0; else wrong_mod2 = 1; if (wrong_mod2 == (objc % 2)) { Tcl_AppendResult (interp, cmd, ": wrong # args", (char*) NULL); PRINT ("Wrong # args\n"); FL; goto cleanup_after_error; } res = CHECK_OPTINFO (baseOpt); if (res != TCL_OK) { DELETE_OPTINFO; PRINT ("Options contain errors\n"); FL; DONE (TrfExecuteObjCmd); return TCL_ERROR; } if (baseOpt.attach == (Tcl_Channel) NULL) /* TRF_IMMEDIATE */ { /* * Immediate execution of transformation requested. */ res = TransformImmediate (interp, entry, baseOpt.source, baseOpt.destination, objv [0], optInfo); } else /* TRF_ATTACH */ { /* * User requested attachment of transformation procedure to a channel. * In case of a stub-aware interpreter use that to check for the * existence of the necessary patches ! Bail out if not. */ #ifdef USE_TCL_STUBS if (Tcl_StackChannel == NULL) { Tcl_AppendResult (interp, cmd, ": this feature (-attach) is not ", "available as the required patch to the core ", "was not applied", (char*) NULL); DELETE_OPTINFO; PRINT ("-attach not available\n"); FL; DONE (TrfExecuteObjCmd); return TCL_ERROR; } #endif res = AttachTransform (entry, &baseOpt, optInfo, interp); if (baseOpt.policy != (Tcl_Obj*) NULL) { Tcl_DecrRefCount (baseOpt.policy); baseOpt.policy = (Tcl_Obj*) NULL; } } DELETE_OPTINFO; DONE (TrfExecuteObjCmd); return res; unknown_option: PRINT ("Unknown option \"%s\"\n", option); FL; OT; Tcl_AppendResult (interp, cmd, ": unknown option '", option, "', should be '-attach/in/out' or '-seekpolicy'", (char*) NULL); /* fall through to cleanup */ cleanup_after_error: DELETE_OPTINFO; DONE (TrfExecuteObjCmd); return TCL_ERROR; } /* *------------------------------------------------------* * * TrfDeleteCmd -- * * ------------------------------------------------* * Trap handler. Called by the Tcl core during * destruction of the command for invocation of a * transformation. * ------------------------------------------------* * * Sideeffects: * Removes the transformation from the registry. * * Result: * None. * *------------------------------------------------------* */ static void TrfDeleteCmd (clientData) ClientData clientData; { Trf_RegistryEntry* entry; START (TrfDeleteCmd); entry = (Trf_RegistryEntry*) clientData; TrfUnregister (entry->interp, entry); DONE (TrfDeleteCmd); } /* *---------------------------------------------------------------------- * * TrfInfoObjCmd -- * * This procedure is invoked to process the "trfinfo" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ #if 0 static int TrfInfoObjCmd (notUsed, interp, objc, objv) ClientData notUsed; /* Not used. */ Tcl_Interp* interp; /* Current interpreter. */ int objc; struct Tcl_Obj* CONST * objv; { /* * trfinfo */ static char* subcmd [] = { "seekstate", "seekcfg", NULL }; enum subcmd { TRFINFO_SEEKSTATE, TRFINFO_SEEKCFG }; Tcl_Channel chan; int mode, pindex; char* chanName; TrfTransformationInstance* trans; if ((objc < 2) || (objc > 3)) { Tcl_AppendResult (interp, "wrong # args: should be \"trfinfo cmd channel\"", (char*) NULL); return TCL_ERROR; } chanName = Tcl_GetStringFromObj (objv [2], NULL); chan = Tcl_GetChannel (interp, chanName, &mode); if (chan == (Tcl_Channel) NULL) { return TCL_ERROR; } if (Tcl_GetChannelType (chan)->seekProc != TrfSeek) { /* No trf transformation, info not applicable. */ Tcl_AppendResult (interp, "channel \"", chanName, "\" is no transformation from trf", (char*) NULL); return TCL_ERROR; } /* Peek into the instance structure and return the requested * information. */ if (Tcl_GetIndexFromObj(interp, objv [1], subcmd, "subcommand", 0, &pindex) != TCL_OK) { return TCL_ERROR; } trans = (TrfTransformationInstance*) Tcl_GetChannelInstanceData (chan); switch (pindex) { case TRFINFO_SEEKSTATE: { Tcl_Obj* state = SeekStateGet (interp, &trans->seekState); if (state == NULL) return TCL_ERROR; Tcl_SetObjResult (interp, state); return TCL_OK; } break; case TRFINFO_SEEKCFG: { Tcl_Obj* cfg = SeekConfigGet (interp, &trans->seekCfg); if (cfg == NULL) return TCL_ERROR; Tcl_SetObjResult (interp, cfg); return TCL_OK; } break; default: /* impossible */ return TCL_ERROR; } /* We should not come to this place */ return TCL_ERROR; } #endif /* *------------------------------------------------------* * * TrfInit_Info -- * * ------------------------------------------------* * Register the 'info' command. * ------------------------------------------------* * * Sideeffects: * As of 'Tcl_CreateObjCommand'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Info (interp) Tcl_Interp* interp; { #if 0 Tcl_CreateObjCommand (interp, "trfinfo", TrfInfoObjCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); #endif return TCL_OK; } /* 04/13/1999 Fileevent patch from Matt Newman */ /* *------------------------------------------------------* * * TrfBlock -- * * ------------------------------------------------* * Trap handler. Called by the generic IO system * during option processing to change the blocking * mode of the channel. * ------------------------------------------------* * * Sideeffects: * Forwards the request to the underlying * channel. * * Result: * 0 if successful, errno when failed. * *------------------------------------------------------* */ static int TrfBlock (instanceData, mode) ClientData instanceData; int mode; { TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; char block [2] = {0,0}; Tcl_Channel parent; START (TrfBlock); PRINT ("Mode = %d\n", mode); FL; parent = DOWNC (trans); if (mode == TCL_MODE_NONBLOCKING) { trans->flags |= CHANNEL_ASYNC; block [0] = '0'; } else { trans->flags &= ~(CHANNEL_ASYNC); block [0] = '1'; } #ifndef USE_TCL_STUBS Tcl_SetChannelOption (NULL, parent, "-blocking", block); #else if ((trans->patchVariant == PATCH_ORIG) || (trans->patchVariant == PATCH_82)) { /* * Both old-style patch and first integrated version of the patch * require the transformation to pass the blocking mode to the * channel downstream. The newest implementation (PATCH_832) * handles this in the core. */ Tcl_SetChannelOption (NULL, parent, "-blocking", block); } #endif DONE (TrfBlock); return 0; } /* *------------------------------------------------------* * * TrfClose -- * * ------------------------------------------------* * Trap handler. Called by the generic IO system * during destruction of the transformation channel. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated in * 'AttachTransform'. * * Result: * None. * *------------------------------------------------------* */ static int TrfClose (instanceData, interp) ClientData instanceData; Tcl_Interp* interp; { /* * The parent channel will be removed automatically * (if necessary and/or desired). */ TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; Tcl_Channel parent; START (TrfClose); #ifndef USE_TCL_STUBS if ((trans == (TrfTransformationInstance*) NULL) || (interp == (Tcl_Interp*) NULL)) { /* Hack, prevent 8.0 from crashing upon exit if channels * with transformations were left open during exit * * Suggested by Mikhail Teterin 25.11.1999. */ DONE (TrfClose); return TCL_OK; } #endif parent = DOWNC (trans); /* 04/13/1999 Fileevent patch from Matt Newman * Remove event handler to underlying channel, this could * be because we are closing for real, or being "unstacked". */ #ifndef USE_TCL_STUBS Tcl_DeleteChannelHandler (parent, ChannelHandler, (ClientData) trans); #else if ((trans->patchVariant == PATCH_ORIG) || (trans->patchVariant == PATCH_82)) { Tcl_DeleteChannelHandler (parent, ChannelHandler, (ClientData) trans); } /* * PATCH_832 doesn't use channelhandlers for communication of events * between the channels of stack anymore. */ #endif TimerKill (trans); /* * Flush data waiting in transformation buffers to output. * Flush input too, maybe there are side effects other * parts do rely on (-> message digests). */ if (trans->mode & TCL_WRITABLE) { PRINT ("out.flushproc\n"); FL; trans->out.vectors->flushProc (trans->out.control, (Tcl_Interp*) NULL, trans->clientData); } if (trans->mode & TCL_READABLE) { if (!trans->readIsFlushed) { PRINT ("in_.flushproc\n"); FL; trans->readIsFlushed = 1; trans->in.vectors->flushProc (trans->in.control, (Tcl_Interp*) NULL, trans->clientData); } } if (trans->mode & TCL_WRITABLE) { PRINT ("out.deleteproc\n"); FL; trans->out.vectors->deleteProc (trans->out.control, trans->clientData); } if (trans->mode & TCL_READABLE) { PRINT ("in_.deleteproc\n"); FL; trans->in.vectors->deleteProc (trans->in.control, trans->clientData); } ResultClear (&trans->result); /* * Complement to NEW_TRANSFORM in AttachChannel. * [Bug 2788106]. */ ckfree(trans); DONE (TrfClose); return TCL_OK; } /* *------------------------------------------------------* * * TrfInput -- * * ------------------------------------------------* * Called by the generic IO system to convert read data. * ------------------------------------------------* * * Sideeffects: * As defined by the conversion. * * Result: * A transformed buffer. * *------------------------------------------------------* */ static int TrfInput (instanceData, buf, toRead, errorCodePtr) ClientData instanceData; char* buf; int toRead; int* errorCodePtr; { TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; int gotBytes, read, i, res, copied, maxRead; Tcl_Channel parent; START (TrfInput); PRINT ("trans = %p, toRead = %d\n", trans, toRead); FL; parent = DOWNC (trans); /* should assert (trans->mode & TCL_READABLE) */ gotBytes = 0; SEEK_DUMP (TrfInput; Start); while (toRead > 0) { /* Loop until the request is satisfied * (or no data available from below, possibly EOF). */ SEEK_DUMP (TrfInput; Loop_); /* The position may be inside the buffer, and not at its start. * Remove the superfluous data now. There was no need to do it * earlier, as intervening seeks and writes could have discarded * the buffer completely, seeked back to an earlier point in it, etc. * We can be sure that the location is not behind its end! * And for an empty buffer location and buffer start are identical, * bypassing this code. See integrity constraints listed in the * description of Trf_TransformationInstance. */ if (trans->seekState.upLoc > trans->seekState.upBufStartLoc) { ResultDiscardAtStart (&trans->result, trans->seekState.upLoc - trans->seekState.upBufStartLoc); } /* Assertion: UpLoc == UpBufStartLoc now. */ SEEK_DUMP (TrfInput; Disc<); copied = ResultCopy (&trans->result, (unsigned char*) buf, toRead); toRead -= copied; buf += copied; gotBytes += copied; trans->seekState.upLoc += copied; SEEK_DUMP (TrfInput; Copy<); if (toRead == 0) { PRINT ("Got %d, satisfied from result buffer\n", gotBytes); FL; DONE (TrfInput); return gotBytes; } /* The buffer is exhausted, but the caller wants even more. We now have * to go to the underlying channel, get more bytes and then transform * them for delivery. We may not get that we want (full EOF or temporary * out of data). This part has to manipulate the various seek locations * in a more complicated way to keep everything in sync. */ /* Assertion: UpLoc == UpBufEndLoc now (and == UpBufStartLoc). * Additionally: UP_CONVERT (DownLoc - AheadOffset) == BufEndLoc */ /* * Length (trans->result) == 0, toRead > 0 here Use 'buf'! as target * to store the intermediary information read from the parent channel. * * Ask the transform how much data it allows us to read from * the underlying channel. This feature allows the transform to * signal EOF upstream although there is none downstream. Useful * to control an unbounded 'fcopy' for example, either through counting * bytes, or by pattern matching. */ if (trans->in.vectors->maxReadProc == (Trf_QueryMaxRead*) NULL) maxRead = -1; else maxRead = trans->in.vectors->maxReadProc (trans->in.control, trans->clientData); if (maxRead >= 0) { if (maxRead < toRead) { toRead = maxRead; } } /* else: 'maxRead < 0' == Accept the current value of toRead */ if (toRead <= 0) { PRINT ("Got %d, constrained by script\n", gotBytes); FL; DONE (TrfInput); return gotBytes; } PRINT ("Read from parent %p\n", parent); IN; IN; read = READ (trans, buf, toRead); OT; OT; PRINT ("................\n"); /*PRTSTR ("Retrieved = {%d, \"%s\"}\n", read, buf);*/ PRINT ("Retrieved = %d {\n", read); DUMP (read, buf); PRINT ("}\n"); STREAM_IN (trans, read, buf); if (read < 0) { /* Report errors to caller. * The state of the seek system is unchanged! */ if ((Tcl_GetErrno () == EAGAIN) && (gotBytes > 0)) { /* EAGAIN is a special situation. If we had some data * before we report that instead of the request to re-try. */ PRINT ("Got %d, read < 0, \n", gotBytes); FL; DONE (TrfInput); return gotBytes; } *errorCodePtr = Tcl_GetErrno (); PRINT ("Got %d, read < 0, report error %d\n", gotBytes, *errorCodePtr); FL; DONE (TrfInput); return -1; } if (read == 0) { /* Check wether we hit on EOF in 'parent' or * not. If not differentiate between blocking and * non-blocking modes. In non-blocking mode we ran * temporarily out of data. Signal this to the caller * via EWOULDBLOCK and error return (-1). In the other * cases we simply return what we got and let the * caller wait for more. On the other hand, if we got * an EOF we have to convert and flush all waiting * partial data. */ /* 04/13/1999 Fileevent patch from Matt Newman */ if (! Tcl_Eof (parent)) { /* The state of the seek system is unchanged! */ if (gotBytes == 0 && trans->flags & CHANNEL_ASYNC) { *errorCodePtr = EWOULDBLOCK; PRINT ("Got %d, report EWOULDBLOCK\n", gotBytes); FL; DONE (TrfInput); return -1; } else { PRINT ("(Got = %d || not async)\n", gotBytes); FL; DONE (TrfInput); return gotBytes; } } else { PRINT ("EOF in downstream channel\n"); FL; if (trans->readIsFlushed) { /* The state of the seek system is unchanged! */ /* already flushed, nothing to do anymore */ PRINT ("Got %d, !read flushed\n", gotBytes); FL; DONE (TrfInput); return gotBytes; } /* Now this is a bit different. The partial data waiting is converted * and returned. So the 'AheadOffset' changes despite the location * downstream not changing at all. It is now the negative of its * additive inverse modulo 'numBytesDown': * -((-k)%n) == -((n-1)-k) == k+1-n. */ PRINT ("in_.flushproc\n"); FL; trans->readIsFlushed = 1; trans->lastStored = 0; res = trans->in.vectors->flushProc (trans->in.control, (Tcl_Interp*) NULL, trans->clientData); if (trans->seekState.allowed && trans->seekState.used.numBytesDown > 1) { trans->seekState.aheadOffset += -trans->seekState.used.numBytesDown; } SEEK_DUMP (TrfInput; AhdC<); if (ResultLength (&trans->result) == 0) { /* we had nothing to flush */ PRINT ("Got %d, read flushed / no result\n", gotBytes); FL; DONE (TrfInput); return gotBytes; } continue; /* at: while (toRead > 0) */ } } /* read == 0 */ /* Transform the read chunk, which was not empty. * The transformation processes 'read + aheadOffset' bytes. * So UP_CONVERT (read+ahead) == #bytes produced == ResultLength! * And (read+ahead) % #down == #bytes now waiting == new ahead. */ SEEK_DUMP (TrfInput; Read<); trans->lastStored = 0; if (trans->in.vectors->convertBufProc){ PRINT ("in_.convertbufproc\n"); FL; res = trans->in.vectors->convertBufProc (trans->in.control, (unsigned char*) buf, read, (Tcl_Interp*) NULL, trans->clientData); } else { PRINT ("in_.convertproc\n"); FL; res = TCL_OK; for (i=0; i < read; i++) { res = trans->in.vectors->convertProc (trans->in.control, buf [i], (Tcl_Interp*) NULL, trans->clientData); if (res != TCL_OK) { break; } } } if (res != TCL_OK) { *errorCodePtr = EINVAL; PRINT ("Got %d, report error in transform (EINVAL)\n", gotBytes); FL; DONE (TrfInput); return -1; } /* Assert: UP_CONVERT (read+ahead) == ResultLength! */ trans->seekState.downLoc += read; if (trans->seekState.allowed) { trans->seekState.aheadOffset += (read % trans->seekState.used.numBytesDown); trans->seekState.aheadOffset %= trans->seekState.used.numBytesDown; } } /* while toRead > 0 */ SEEK_DUMP (TrfInput; Loop<); PRINT ("Got %d, after loop\n", gotBytes); FL; DONE (TrfInput); return gotBytes; } /* *------------------------------------------------------* * * TrfOutput -- * * ------------------------------------------------* * Called by the generic IO system to convert data * waiting to be written. * ------------------------------------------------* * * Sideeffects: * As defined by the transformation. * * Result: * A transformed buffer. * *------------------------------------------------------* */ static int TrfOutput (instanceData, buf, toWrite, errorCodePtr) ClientData instanceData; CONST84 char* buf; int toWrite; int* errorCodePtr; { TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; int i, res; Tcl_Channel parent; START (TrfOutput); parent = DOWNC (trans); /* should assert (trans->mode & TCL_WRITABLE) */ /* * transformation results are automatically written to * the parent channel ('PutDestination' was configured * as write procedure in 'AttachTransform'). */ if (toWrite == 0) { /* Nothing came in to write, ignore the call */ PRINT ("Nothing to write\n"); FL; DONE (TrfOutput); return 0; } SEEK_DUMP (TrfOutput; Start); /* toWrite / seekState.used.numBytesTransform = #tuples converted. * toWrite % seekState.used.numBytesTransform = #Bytes waiting in the transform. */ SeekSynchronize (trans, parent); SEEK_DUMP (TrfOutput; Syncd); trans->lastWritten = 0; if (trans->out.vectors->convertBufProc){ PRINT ("out.convertbufproc\n"); FL; res = trans->out.vectors->convertBufProc (trans->out.control, (unsigned char*) buf, toWrite, (Tcl_Interp*) NULL, trans->clientData); } else { PRINT ("out.convertproc\n"); FL; res = TCL_OK; for (i=0; i < toWrite; i++) { res = trans->out.vectors->convertProc (trans->out.control, buf [i], (Tcl_Interp*) NULL, trans->clientData); if (res != TCL_OK) { break; } } } if (res != TCL_OK) { *errorCodePtr = EINVAL; PRINT ("error EINVAL\n"); FL; DONE (TrfInput); return -1; } /* Update seek state to new location * Assert: lastWritten == TRF_DOWN_CONVERT (trans, toWrite) */ trans->seekState.upLoc += toWrite; trans->seekState.upBufStartLoc = trans->seekState.upLoc; trans->seekState.upBufEndLoc = trans->seekState.upLoc; trans->seekState.downLoc += trans->lastWritten; trans->lastWritten = 0; SEEK_DUMP (TrfOutput; Done_); /* In the last statement above the integer division automatically * strips off the #bytes waiting in the transform. */ PRINT ("Written: %d\n", toWrite); FL; DONE (TrfOutput); return toWrite; } /* *------------------------------------------------------* * * TrfSeek -- * * ------------------------------------------------* * This procedure is called by the generic IO level * to move the access point in a channel. * ------------------------------------------------* * * Sideeffects: * Moves the location at which the channel * will be accessed in future operations. * Flushes all transformation buffers, then * forwards it to the underlying channel. * * Result: * -1 if failed, the new position if * successful. An output argument contains * the POSIX error code if an error * occurred, or zero. * *------------------------------------------------------* */ static int TrfSeek (instanceData, offset, mode, errorCodePtr) ClientData instanceData; /* The channel to manipulate */ long offset; /* Size of movement. */ int mode; /* How to move */ int* errorCodePtr; /* Location of error flag. */ { TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; int result; Tcl_Channel parent; int newLoc; START (TrfSeek); PRINT ("(Mode = %d, Offset = %ld)\n", mode, offset); FL; parent = DOWNC (trans); /* * Several things to look at before deciding what to do. * Is it a tell request ? * Is the channel unseekable ? * If not, are we in pass-down mode ? * If not, check buffer boundaries, etc. before discarding buffers, etc. */ if ((offset == 0) && (mode == SEEK_CUR)) { /* Tell location. */ PRINT ("[Tell], Location = %d\n", trans->seekState.upLoc); FL; DONE (TrfSeek); return trans->seekState.upLoc; } if (!trans->seekState.allowed) { *errorCodePtr = EINVAL; PRINT ("[Unseekable]\n"); FL; DONE (TrfSeek); return -1; } /* Assert: seekState.allowed, numBytesDown > 0, numBytesTransform > 0 */ if (trans->seekCfg.identity) { /* Pass down mode. Pass request and record the change. This is used after * restoration of constrained seek to force the usage of a new zero-point. */ PRINT ("[Passing down]\n"); FL; SeekClearBuffer (trans, TCL_WRITABLE | TCL_READABLE); trans->seekState.changed = 1; result = SEEK (trans, offset, mode); *errorCodePtr = (result == -1) ? Tcl_GetErrno () : 0; SEEK_DUMP (TrfSeek; Pass<); DONE (TrfSeek); return result; } /* Constrained seeking, as specified by the transformation. */ if (mode == SEEK_SET) { /* Convert and handle absolute from start as relative to current * location. */ PRINT ("[Seek from start] => Seek relative\n"); FL; result = TrfSeek (trans, offset - trans->seekState.upLoc, SEEK_CUR, errorCodePtr); DONE (TrfSeek); return result; } if (mode == SEEK_END) { /* Can't do that right now! TODO */ *errorCodePtr = EINVAL; PRINT ("[Seek from end not available]"); FL; DONE (TrfSeek); return -1; } /* Seeking relative to the current location. */ newLoc = trans->seekState.upLoc + offset; if (newLoc % trans->seekState.used.numBytesTransform) { /* Seek allowed only to locations which are multiples of the input. */ *errorCodePtr = EINVAL; PRINT ("Seek constrained to multiples of input tuples\n"); FL; DONE (TrfSeek); return -1; } if (newLoc < 0) { *errorCodePtr = EINVAL; PRINT ("[Seek relative], cannot seek before start of stream\n"); FL; DONE (TrfSeek); return -1; } if ((newLoc < trans->seekState.upBufStartLoc) || (trans->seekState.upBufEndLoc <= newLoc)) { /* We are seeking out of the read buffer. * Discard it, adjust our position and seek the channel below to the * equivalent position. */ int offsetDown, newDownLoc; PRINT ("[Seek relative], beyond read buffer\n"); FL; newDownLoc = trans->seekState.downZero + TRF_DOWN_CONVERT (trans, newLoc); offsetDown = newDownLoc - trans->seekState.downLoc; SeekClearBuffer (trans, TCL_WRITABLE | TCL_READABLE); if (offsetDown != 0) { result = SEEK (trans, offsetDown, SEEK_CUR); *errorCodePtr = (result == -1) ? Tcl_GetErrno () : 0; } trans->seekState.downLoc += offsetDown; trans->seekState.upLoc = newLoc; trans->seekState.upBufStartLoc = newLoc; trans->seekState.upBufEndLoc = newLoc; SEEK_DUMP (TrfSeek; NoBuf); DONE (TrfSeek); return newLoc; } /* We are still inside the buffer, adjust the position * and clear out incomplete data waiting in the write * buffers, they are now invalid. */ SeekClearBuffer (trans, TCL_WRITABLE); trans->seekState.upLoc = newLoc; SEEK_DUMP (TrfSeek; Base_); DONE (TrfSeek); return newLoc; } /* *------------------------------------------------------* * * TrfWatch -- * * ------------------------------------------------* * Initialize the notifier to watch Tcl_Files from * this channel. * ------------------------------------------------* * * Sideeffects: * Sets up the notifier so that a future * event on the channel will be seen by Tcl. * * Result: * None. * *------------------------------------------------------* */ /* ARGSUSED */ static void TrfWatch (instanceData, mask) ClientData instanceData; /* Channel to watch */ int mask; /* Events of interest */ { /* * 08/01/2000 - Completely rewritten to support as many versions of * the core and their different implementation s of stacked channels. */ /* 04/13/1999 Fileevent patch from Matt Newman * Added the comments. */ /* The caller expressed interest in events occuring for this * channel. Instead of forwarding the call to the underlying * channel we now express our interest in events on that * channel. This will ripple through all stacked channels to * the bottom-most real one actually able to generate events * (files, sockets, pipes, ...). The improvement beyond the * simple forwarding is that the generated events will ripple * back up to us, until they reach the channel the user * expressed his interest in (via fileevent). This way the * low-level events are propagated upward to the place where * the real event script resides, something which does not * happen in the simple forwarding model. It loses these events. */ TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; START (TrfWatch); #ifndef USE_TCL_STUBS /* 8.0.x. Original patch. */ if (mask == trans->watchMask) { /* No changes in the expressed interest, skip this call. */ DONE (TrfWatch); return; } ChannelHandlerKS (trans, mask); #else /* 8.1. and up */ if ((trans->patchVariant == PATCH_ORIG) || (trans->patchVariant == PATCH_82)) { if (mask == trans->watchMask) { /* No changes in the expressed interest, skip this call. */ DONE (TrfWatch); return; } ChannelHandlerKS (trans, mask); } else if (trans->patchVariant == PATCH_832) { /* 8.3.2 and up */ Tcl_DriverWatchProc* watchProc; Tcl_Channel parent; trans->watchMask = mask; /* No channel handlers any more. We will be notified automatically * about events on the channel below via a call to our * 'TransformNotifyProc'. But we have to pass the interest down now. * We are allowed to add additional 'interest' to the mask if we want * to. But this transformation has no such interest. It just passes * the request down, unchanged. */ parent = DOWNC (trans); watchProc = Tcl_ChannelWatchProc (Tcl_GetChannelType (parent)); (*watchProc) (Tcl_GetChannelInstanceData(parent), mask); } else { Tcl_Panic ("Illegal value for 'patchVariant'"); } #endif /* * Management of the internal timer. */ if (!(mask & TCL_READABLE) || (ResultLength(&trans->result) == 0)) { /* A pending timer may exist, but either is there no (more) * interest in the events it generates or nothing is available * for reading. Remove it, if existing. */ TimerKill (trans); } else { /* There might be no pending timer, but there is interest in * readable events and we actually have data waiting, so * generate a timer to flush that if it does not exist. */ TimerSetup (trans); } DONE (TrfWatch); } /* *------------------------------------------------------* * * TrfGetFile -- * * ------------------------------------------------* * Called from Tcl_GetChannelHandle to retrieve * OS specific file handle from inside this channel. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * The appropriate Tcl_File or NULL if not * present. * *------------------------------------------------------* */ static int TrfGetFile (instanceData, direction, handlePtr) ClientData instanceData; /* Channel to query */ int direction; /* Direction of interest */ ClientData* handlePtr; /* Place to store the handle into */ { /* * return handle belonging to parent channel */ TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; Tcl_Channel parent; START (TrfGetFile); parent = DOWNC (trans); DONE (TrfGetFile); return Tcl_GetChannelHandle (parent, direction, handlePtr); } /* *------------------------------------------------------* * * TrfSetOption -- * * ------------------------------------------------* * Called by the generic layer to handle the reconfi- * guration of channel specific options. Unknown * options are passed downstream. * ------------------------------------------------* * * Sideeffects: * As defined by the channel downstream. * * Result: * A standard TCL error code. * *------------------------------------------------------* */ static int TrfSetOption (instanceData, interp, optionName, value) ClientData instanceData; Tcl_Interp* interp; CONST char* optionName; CONST char* value; { /* Recognized options: * * -seekpolicy Accepted values: unseekable, identity, {} */ TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; START (TrfSetOption); if (0 == strcmp (optionName, "-seekpolicy")) { /* The seekpolicy is about to be changed. Make sure that we got a valid * value and that it really changes the used policy. Failing the first * test causes an error, failing the second causes the system to silently * ignore this request. Reconfiguration will fail for a non-overidable * policy too. */ if (!trans->seekCfg.overideAllowed) { Tcl_SetErrno (EINVAL); Tcl_AppendResult (interp, "It is not allowed to overide ", "the seek policy used by this channel.", NULL); DONE (TrfSetOption); return TCL_ERROR; } if (0 == strcmp (value, "unseekable")) { if (!trans->seekState.allowed) { /* Ignore the request if the channel already uses this policy. */ DONE (TrfSetOption); return TCL_OK; } TRF_SET_UNSEEKABLE (trans->seekState.used); trans->seekState.allowed = 0; trans->seekCfg.identity = 0; /* Changed is not touched! We might have been forced to identity * before, and have to remember this for any restoration. */ } else if (0 == strcmp (value, "identity")) { if (trans->seekState.allowed && (trans->seekState.used.numBytesTransform == 1) && (trans->seekState.used.numBytesDown == 1)) { /* Ignore the request if the channel already uses this policy. */ DONE (TrfSetOption); return TCL_OK; } trans->seekState.used.numBytesTransform = 1; trans->seekState.used.numBytesDown = 1; trans->seekState.allowed = 1; trans->seekCfg.identity = 1; trans->seekState.changed = 0; } else if (0 == strcmp (value, "")) { if ((trans->seekState.used.numBytesTransform == trans->seekCfg.chosen.numBytesTransform) && (trans->seekState.used.numBytesDown == trans->seekCfg.chosen.numBytesDown)) { /* Ignore the request if the channel already uses hios chosen policy. */ DONE (TrfSetOption); return TCL_OK; } trans->seekState.used.numBytesTransform = trans->seekCfg.chosen.numBytesTransform; trans->seekState.used.numBytesDown = trans->seekCfg.chosen.numBytesDown; trans->seekState.allowed = !TRF_IS_UNSEEKABLE (trans->seekState.used); if (trans->seekState.changed) { /* Define new base location. Resync up and down to get the * proper location without read-ahead. Reinitialize the * upper location. */ Tcl_Channel parent = DOWNC (trans); SeekSynchronize (trans, parent); trans->seekState.downLoc = TELL (trans); #ifdef USE_TCL_STUBS if (trans->patchVariant == PATCH_832) { trans->seekState.downLoc -= Tcl_ChannelBuffered (parent); } #endif trans->seekState.downZero = trans->seekState.downLoc; trans->seekState.aheadOffset = 0; trans->seekState.upLoc = 0; trans->seekState.upBufStartLoc = 0; trans->seekState.upBufEndLoc = ResultLength (&trans->result); } trans->seekCfg.identity = 0; trans->seekState.changed = 0; } else { Tcl_SetErrno (EINVAL); Tcl_AppendResult (interp, "Invalid value \"", value, "\", must be one of 'unseekable', 'identity' or ''.", NULL); DONE (TrfSetOption); return TCL_ERROR; } } else { int res; res = SETOPT (interp, trans, optionName, value); DONE (TrfSetOption); return res; } DONE (TrfSetOption); return TCL_OK; } /* *------------------------------------------------------* * * TrfGetOption -- * * ------------------------------------------------* * Called by generic layer to handle requests for * the values of channel specific options. As this * channel type does not have such, it simply passes * all requests downstream. * ------------------------------------------------* * * Sideeffects: * Adds characters to the DString refered by * 'dsPtr'. * * Result: * A standard TCL error code. * *------------------------------------------------------* */ static int TrfGetOption (instanceData, interp, optionName, dsPtr) ClientData instanceData; Tcl_Interp* interp; CONST84 char* optionName; Tcl_DString* dsPtr; { /* Recognized options: * * -seekcfg * -seekstate * -seekpolicy */ TrfTransformationInstance* trans = (TrfTransformationInstance*) instanceData; if (optionName == (char*) NULL) { /* A list of options and their values was requested, */ Tcl_Obj* tmp; char policy [20]; SeekPolicyGet (trans, policy); Tcl_DStringAppendElement (dsPtr, "-seekpolicy"); Tcl_DStringAppendElement (dsPtr, policy); Tcl_DStringAppendElement (dsPtr, "-seekcfg"); tmp = SeekConfigGet (interp, &trans->seekCfg); Tcl_DStringAppendElement (dsPtr, Tcl_GetStringFromObj (tmp, NULL)); Tcl_DecrRefCount (tmp); Tcl_DStringAppendElement (dsPtr, "-seekstate"); tmp = SeekStateGet (interp, &trans->seekState); Tcl_DStringAppendElement (dsPtr, Tcl_GetStringFromObj (tmp, NULL)); Tcl_DecrRefCount (tmp); /* Pass the request down to all channels below so that we may a complete * state. */ return GETOPT (interp, trans, optionName, dsPtr); } else if (0 == strcmp (optionName, "-seekpolicy")) { /* Deduce the policy in effect, use chosen/used * policy and identity to do this. Use a helper * procedure to allow easy reuse in the code above. */ char policy [20]; SeekPolicyGet (trans, policy); Tcl_DStringAppend (dsPtr, policy, -1); return TCL_OK; } else if (0 == strcmp (optionName, "-seekcfg")) { Tcl_Obj* tmp; tmp = SeekConfigGet (interp, &trans->seekCfg); Tcl_DStringAppend (dsPtr, Tcl_GetStringFromObj (tmp, NULL), -1); Tcl_DecrRefCount (tmp); return TCL_OK; } else if (0 == strcmp (optionName, "-seekstate")) { Tcl_Obj* tmp; tmp = SeekStateGet (interp, &trans->seekState); Tcl_DStringAppend (dsPtr, Tcl_GetStringFromObj (tmp, NULL), -1); Tcl_DecrRefCount (tmp); return TCL_OK; } else { /* Unknown option. Pass it down to the channels below, maybe one * of them is able to handle this request. */ return GETOPT (interp, trans, optionName, dsPtr); #if 0 Tcl_SetErrno (EINVAL); return Tcl_BadChannelOption (interp, optionName, "seekcfg seekstate"); #endif } } #ifdef USE_TCL_STUBS /* *------------------------------------------------------* * * TrfNotify -- * * ------------------------------------------------* * Called by the generic layer of 8.3.2 and higher * to handle events coming from below. We simply pass * them upward. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * The unchanged interest mask. * *------------------------------------------------------* */ static int TrfNotify (instanceData, interestMask) ClientData instanceData; int interestMask; { /* * An event occured in the underlying channel. This transformation * doesn't process such events thus returns the incoming mask * unchanged. * * We do delete an existing timer. It was not fired, yet we are * here, so the channel below generated such an event and we don't * have to. The renewal of the interest after the execution of * channel handlers will eventually cause us to recreate the timer * (in TrfWatch). */ TimerKill ((TrfTransformationInstance*) instanceData); return interestMask; } #endif /* *------------------------------------------------------* * * TransformImmediate -- * * ------------------------------------------------* * Read from source, apply the specified transformation * and write the result to destination. * ------------------------------------------------* * * Sideeffects: * The access points of source and destination * change, data is added to destination too. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int TransformImmediate (interp, entry, source, destination, in, optInfo) Tcl_Interp* interp; Trf_RegistryEntry* entry; Tcl_Channel source; Tcl_Channel destination; struct Tcl_Obj* CONST in; Trf_Options optInfo; { Trf_Vectors* v; Trf_ControlBlock control; int res = TCL_OK; ResultBuffer r; START (TransformImmediate); if (ENCODE_REQUEST (entry, optInfo)) { v = &(entry->trfType->encoder); } else { v = &(entry->trfType->decoder); } /* Take care of output (channel vs. interpreter result area). */ if (destination == (Tcl_Channel) NULL) { ResultInit (&r); PRINT ("___.createproc\n"); FL; control = v->createProc ((ClientData) &r, PutInterpResult, optInfo, interp, entry->trfType->clientData); } else { PRINT ("___.createproc\n"); FL; control = v->createProc ((ClientData) destination, PutDestinationImm, optInfo, interp, entry->trfType->clientData); } if (control == (Trf_ControlBlock) NULL) { DONE (TransformImmediate); return TCL_ERROR; } /* Now differentiate between immediate value and channel as input. */ if (source == (Tcl_Channel) NULL) { /* Immediate value. * -- VERSION DEPENDENT CODE -- */ int length; unsigned char* buf; buf = GET_DATA (in, &length); if (v->convertBufProc) { /* play it safe, use a copy, avoid clobbering the input. */ unsigned char* tmp; tmp = (unsigned char*) ckalloc (length); memcpy (tmp, buf, length); PRINT ("___.convertbufproc\n"); FL; res = v->convertBufProc (control, tmp, length, interp, entry->trfType->clientData); ckfree ((char*) tmp); } else { unsigned int i, c; PRINT ("___.convertproc\n"); FL; for (i=0; i < ((unsigned int) length); i++) { c = buf [i]; res = v->convertProc (control, c, interp, entry->trfType->clientData); if (res != TCL_OK) break; } } if (res == TCL_OK) { PRINT ("___.flushproc\n"); FL; res = v->flushProc (control, interp, entry->trfType->clientData); } } else { /* Read from channel. */ unsigned char* buf; int actuallyRead; buf = (unsigned char*) ckalloc (READ_CHUNK_SIZE); while (1) { if (Tcl_Eof (source)) break; actuallyRead = Tcl_Read (source, (char*) buf, READ_CHUNK_SIZE); if (actuallyRead <= 0) break; if (v->convertBufProc) { PRINT ("___.convertbufproc\n"); FL; res = v->convertBufProc (control, buf, actuallyRead, interp, entry->trfType->clientData); } else { unsigned int i, c; PRINT ("___.convertproc\n"); FL; for (i=0; i < ((unsigned int) actuallyRead); i++) { c = buf [i]; res = v->convertProc (control, c, interp, entry->trfType->clientData); if (res != TCL_OK) break; } } if (res != TCL_OK) break; } ckfree ((char*) buf); if (res == TCL_OK) res = v->flushProc (control, interp, entry->trfType->clientData); } PRINT ("___.deleteproc\n"); FL; v->deleteProc (control, entry->trfType->clientData); if (destination == (Tcl_Channel) NULL) { /* Now write into interpreter result area. */ if (res == TCL_OK) { Tcl_ResetResult (interp); if (r.buf != NULL) { Tcl_Obj* o = NEW_DATA (r); Tcl_IncrRefCount (o); Tcl_SetObjResult (interp, o); Tcl_DecrRefCount (o); } } ResultClear (&r); } DONE (TransformImmediate); return res; } /* *------------------------------------------------------* * * AttachTransform -- * * ------------------------------------------------* * Create an instance of a transformation and * associate as filter it with the specified channel. * ------------------------------------------------* * * Sideeffects: * Allocates memory, changes the internal * state of the channel. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int AttachTransform (entry, baseOpt, optInfo, interp) Trf_RegistryEntry* entry; Trf_BaseOptions* baseOpt; Trf_Options optInfo; Tcl_Interp* interp; { TrfTransformationInstance* trans; trans = NEW_TRANSFORM; START (AttachTransform); #ifdef TRF_STREAM_DEBUG trans->inCounter = 0; trans->outCounter = 0; trans->name = (char*) entry->trfType->name; #endif #ifdef USE_TCL_STUBS trans->patchVariant = entry->registry->patchVariant; #endif /* trans->standard.typePtr = entry->transType; */ trans->clientData = entry->trfType->clientData; if (trans->patchVariant == PATCH_832) { trans->parent = Tcl_GetTopChannel (baseOpt->attach); } else { trans->parent = baseOpt->attach; } trans->readIsFlushed = 0; /* 04/13/1999 Fileevent patch from Matt Newman */ trans->flags = 0; trans->watchMask = 0; /* 03/28/2000 Added by DNew@Invisible.Net because Purify says so. */ trans->lastStored = 0; trans->mode = Tcl_GetChannelMode (baseOpt->attach); trans->timer = (Tcl_TimerToken) NULL; if (ENCODE_REQUEST (entry, optInfo)) { /* ENCODE on write * DECODE on read */ trans->out.vectors = ((trans->mode & TCL_WRITABLE) ? &entry->trfType->encoder : NULL); trans->in.vectors = ((trans->mode & TCL_READABLE) ? &entry->trfType->decoder : NULL); } else /* mode == DECODE */ { /* DECODE on write * ENCODE on read */ trans->out.vectors = ((trans->mode & TCL_WRITABLE) ? &entry->trfType->decoder : NULL); trans->in.vectors = ((trans->mode & TCL_READABLE) ? &entry->trfType->encoder : NULL); } /* 'PutDestination' is ok for write, only read * requires 'PutTrans' and its internal buffer. */ if (trans->mode & TCL_WRITABLE) { PRINT ("out.createproc\n"); FL; trans->out.control = trans->out.vectors->createProc ((ClientData) trans, PutDestination, optInfo, interp, trans->clientData); if (trans->out.control == (Trf_ControlBlock) NULL) { ckfree ((char*) trans); DONE (AttachTransform); return TCL_ERROR; } } if (trans->mode & TCL_READABLE) { PRINT ("in_.createproc\n"); FL; trans->in.control = trans->in.vectors->createProc ((ClientData) trans, PutTrans, optInfo, interp, trans->clientData); if (trans->in.control == (Trf_ControlBlock) NULL) { ckfree ((char*) trans); DONE (AttachTransform); return TCL_ERROR; } } ResultInit (&trans->result); trans->result.seekState = &trans->seekState; /* * Build channel from converter definition and stack it upon the one we * shall attach to. */ /* Discard information dangerous for the integrated patch. * (This makes sure that we don't miss any place using this pointer * without generating a crash (instead of some silent failure, like * thrashing far away memory)). */ #ifndef USE_TCL_STUBS trans->self = Tcl_StackChannel (interp, entry->transType, (ClientData) trans, trans->mode, trans->parent); #else if ((trans->patchVariant == PATCH_ORIG) || (trans->patchVariant == PATCH_832)) { trans->self = Tcl_StackChannel (interp, entry->transType, (ClientData) trans, trans->mode, trans->parent); } else if (trans->patchVariant == PATCH_82) { trans->parent = NULL; trans->self = baseOpt->attach; Tcl_StackChannel (interp, entry->transType, (ClientData) trans, trans->mode, trans->self); } else { Tcl_Panic ("Illegal value for 'patchVariant'"); } #endif if (trans->self == (Tcl_Channel) NULL) { ckfree ((char*) trans); Tcl_AppendResult (interp, "internal error in Tcl_StackChannel", (char*) NULL); DONE (AttachTransform); return TCL_ERROR; } /* Initialize the seek subsystem. */ PRINTLN ("Initialize Seeking"); PRINTLN ("Copy configuration"); trans->seekCfg.natural.numBytesTransform = entry->trfType->naturalSeek.numBytesTransform; trans->seekCfg.natural.numBytesDown = entry->trfType->naturalSeek.numBytesDown; if (optInfo && (*OPT->seekQueryProc != (Trf_SeekQueryOptions*) NULL)) { PRINTLN ("Query seekQueryProc"); (*OPT->seekQueryProc) (interp, optInfo, &trans->seekCfg.natural, CLT); } PRINTLN ("Determine Policy"); SeekCalculatePolicies (trans); PRINTLN (" Initialize"); SeekInitialize (trans); /* Check for options overiding the policy. If they do despite being not * allowed to do so we have to remove the transformation and break it down. * We do this by calling 'Unstack', which does all the necessary things for * us. */ PRINTLN (" Policy options ?"); if (baseOpt->policy != (Tcl_Obj*) NULL) { if (TCL_OK != TrfSetOption ((ClientData) trans, interp, "-seekpolicy", Tcl_GetStringFromObj (baseOpt->policy, NULL))) { /* An error prevented setting a policy. Save the resulting error * message across the necessary unstacking of the now faulty * transformation. */ #if GT81 Tcl_SavedResult ciSave; Tcl_SaveResult (interp, &ciSave); Tcl_UnstackChannel (interp, trans->self); Tcl_RestoreResult (interp, &ciSave); #else Tcl_UnstackChannel (interp, trans->self); #endif DONE (AttachTransform); return TCL_ERROR; } } /* Tcl_RegisterChannel (interp, new); */ Tcl_AppendResult (interp, Tcl_GetChannelName (trans->self), (char*) NULL); DONE (AttachTransform); return TCL_OK; } /* *------------------------------------------------------* * * PutDestination -- * * ------------------------------------------------* * Handler used by a transformation to write its results. * ------------------------------------------------* * * Sideeffects: * Writes to the channel. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int PutDestination (clientData, outString, outLen, interp) ClientData clientData; unsigned char* outString; int outLen; Tcl_Interp* interp; { TrfTransformationInstance* trans = (TrfTransformationInstance*) clientData; int res; Tcl_Channel parent; START (PutDestination); /*PRTSTR ("Data = {%d, \"%s\"}\n", outLen, outString);*/ PRINT ("Data = %d {\n", outLen); DUMP (outLen, outString); PRINT ("}\n"); parent = DOWNC (trans); trans->lastWritten += outLen; res = WRITE (trans, (char*) outString, outLen); if (res < 0) { if (interp) { Tcl_AppendResult (interp, "error writing \"", Tcl_GetChannelName (parent), "\": ", Tcl_PosixError (interp), (char*) NULL); } PRINT ("ERROR /written = %d, errno = %d, (%d) %s\n", res, Tcl_GetErrno (), EACCES, strerror (Tcl_GetErrno ())); DONE (PutDestination); return TCL_ERROR; } DONE (PutDestination); return TCL_OK; } /* *------------------------------------------------------* * * PutDestinationImm -- * * ------------------------------------------------* * Handler used during an immediate transformation * to write its results into the -out channel. * ------------------------------------------------* * * Sideeffects: * Writes to the channel. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int PutDestinationImm (clientData, outString, outLen, interp) ClientData clientData; unsigned char* outString; int outLen; Tcl_Interp* interp; { int res; Tcl_Channel destination = (Tcl_Channel) clientData; START (PutDestinationImm); /*PRTSTR ("Data = {%d, \"%s\"}\n", outLen, outString);*/ PRINT ("Data = %d {\n", outLen); DUMP (outLen, outString); PRINT ("}\n"); res = Tcl_Write (destination, (char*) outString, outLen); if (res < 0) { if (interp) { Tcl_AppendResult (interp, "error writing \"", Tcl_GetChannelName (destination), "\": ", Tcl_PosixError (interp), (char*) NULL); } DONE (PutDestinationImm); return TCL_ERROR; } DONE (PutDestinationImm); return TCL_OK; } /* *------------------------------------------------------* * * PutTrans -- * * ------------------------------------------------* * Handler used by a transformation to write its * results (to be read later). Used by transformations * acting as filter. * ------------------------------------------------* * * Sideeffects: * May allocate memory. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int PutTrans (clientData, outString, outLen, interp) ClientData clientData; unsigned char* outString; int outLen; Tcl_Interp* interp; { TrfTransformationInstance* trans = (TrfTransformationInstance*) clientData; START (PutTrans); /*PRTSTR ("Data = {%d, \"%s\"}\n", outLen, outString);*/ PRINT ("Data = %d {\n", outLen); DUMP (outLen, outString); PRINT ("}\n"); STREAM_OUT (trans, outLen, outString); trans->lastStored += outLen; ResultAdd (&trans->result, outString, outLen); DONE (PutTrans); return TCL_OK; } /* *------------------------------------------------------* * * PutInterpResult -- * * ------------------------------------------------* * Handler used by a transformation to write its * results into the interpreter result area. * ------------------------------------------------* * * Sideeffects: * changes the contents of the interpreter * result area. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int PutInterpResult (clientData, outString, outLen, interp) ClientData clientData; unsigned char* outString; int outLen; Tcl_Interp* interp; { ResultBuffer* r = (ResultBuffer*) clientData; START (PutInterpResult); /*PRTSTR ("Data = {%d, \"%s\"}\n", outLen, outString);*/ PRINT ("Data = %d {\n", outLen); DUMP (outLen, outString); PRINT ("}\n"); ResultAdd (r, outString, outLen); DONE (PutInterpResult); return TCL_OK; } /* 04/13/1999 Fileevent patch from Matt Newman */ /* *------------------------------------------------------* * * ChannelHandler -- * * ------------------------------------------------* * Handler called by Tcl as a result of * Tcl_CreateChannelHandler - to inform us of activity * on the underlying channel. * ------------------------------------------------* * * Sideeffects: * May generate subsequent calls to * Tcl_NotifyChannel. * * Result: * None. * *------------------------------------------------------* */ static void ChannelHandler (clientData, mask) ClientData clientData; int mask; { /* * An event occured in the underlying channel. Forward it to * ourself. This will either execute an attached event script * (fileevent) or an intermediate handler like this one propagating * the event further upward. * * This procedure is called only for the original and the 8.2 * patch. The 8.2.3 patch uses a new vector in the driver to get and * handle events coming from below. */ TrfTransformationInstance* trans = (TrfTransformationInstance*) clientData; #ifndef USE_TCL_STUBS /* * Core 8.0.x. Forward the event to ourselves. */ Tcl_NotifyChannel (trans->self, mask); #else /* * Check for the correct variants first. Forwarding the event is not * required for the 8.2 patch. For that variant the core, * i.e. Tcl_NotifyChannel loops over all channels in the stack by * itself. */ if (trans->patchVariant == PATCH_832) { Tcl_Panic ("Illegal value for 'patchVariant' in ChannelHandler"); } if (trans->patchVariant == PATCH_ORIG) { Tcl_NotifyChannel (trans->self, mask); } #endif /* * Check the I/O-Buffers of this channel for waiting information. * Setup a timer generating an artificial event for us if we have * such. We could call Tcl_NotifyChannel directly, but this would * starve other event sources, so a timer is used to prevent that. */ TimerKill (trans); /* Check for waiting data, flush it out with a timer. */ #ifndef USE_TCL_STUBS if ((mask & TCL_READABLE) && ((ResultLength (&trans->result) > 0) || (Tcl_InputBuffered (trans->self) > 0))) { TimerSetup (trans); } #else if (trans->patchVariant != PATCH_ORIG) { if ((mask & TCL_READABLE) && (ResultLength (&trans->result) > 0)) { TimerSetup (trans); } } else { if ((mask & TCL_READABLE) && ((ResultLength (&trans->result) > 0) || (Tcl_InputBuffered (trans->self) > 0))) { TimerSetup (trans); } } #endif } /* *------------------------------------------------------* * * ChannelHandlerTimer -- * * ------------------------------------------------* * Called by the notifier (-> timer) to flush out * information waiting in channel buffers. * ------------------------------------------------* * * Sideeffects: * As of 'ChannelHandler'. * * Result: * None. * *------------------------------------------------------* */ static void ChannelHandlerTimer (clientData) ClientData clientData; /* Transformation to query */ { TrfTransformationInstance* trans = (TrfTransformationInstance*) clientData; trans->timer = (Tcl_TimerToken) NULL; #ifndef USE_TCL_STUBS /* 8.0.x. * Use the channel handler itself to do the necessary actions */ ChannelHandler (clientData, trans->watchMask); #else if ((trans->patchVariant == PATCH_82) || (trans->patchVariant == PATCH_832)) { /* * Use the standard notification mechanism to invoke all channel * handlers. */ Tcl_NotifyChannel (trans->self, TCL_READABLE); } else { /* PATCH_ORIG, seee 8.0.x */ ChannelHandler (clientData, trans->watchMask); } #endif } #ifdef USE_TCL_STUBS /* *------------------------------------------------------* * * DownSOpt -- * * Helper procedure. Writes an option to the downstream channel. * * Sideeffects: * As of Tcl_SetChannelOption * * Result: * A standard tcl error code. * *------------------------------------------------------* */ static int DownSOpt (interp, ctrl, optionName, value) Tcl_Interp* interp; TrfTransformationInstance* ctrl; CONST char* optionName; CONST char* value; { Tcl_Channel parent = DOWNC (ctrl); if (ctrl->patchVariant == PATCH_832) { /* * The newly written patch forces direct use of the driver. */ Tcl_DriverSetOptionProc *setOptionProc = Tcl_ChannelSetOptionProc (Tcl_GetChannelType (parent)); if (setOptionProc != NULL) { return (*setOptionProc) (Tcl_GetChannelInstanceData (parent), interp, optionName, value); } else { return TCL_ERROR; } } else { return Tcl_SetChannelOption (interp, parent, optionName, value); } } /* *------------------------------------------------------* * * DownGOpt -- * * Helper procedure. Reads options from the downstream channel. * * Sideeffects: * As of Tcl_GetChannelOption * * Result: * A standard tcl error code. * *------------------------------------------------------* */ static int DownGOpt (interp, ctrl, optionName, dsPtr) Tcl_Interp* interp; TrfTransformationInstance* ctrl; CONST84 char* optionName; Tcl_DString* dsPtr; { Tcl_Channel parent = DOWNC (ctrl); if (ctrl->patchVariant == PATCH_832) { /* * The newly written patch forces direct use of the driver. */ Tcl_DriverGetOptionProc *getOptionProc = Tcl_ChannelGetOptionProc (Tcl_GetChannelType (parent)); if (getOptionProc != NULL) { return (*getOptionProc) (Tcl_GetChannelInstanceData (parent), interp, optionName, dsPtr); } /* * Downstream channel has no driver to get options. Fall back on * some default behaviour. A query for all options is ok. A * request for a specific unknown option OTOH has to fail. */ if (optionName == (char*) NULL) { return TCL_OK; } else { return TCL_ERROR; } } else { return Tcl_GetChannelOption (interp, parent, optionName, dsPtr); } } /* *------------------------------------------------------* * * DownWrite -- * * Helper procedure. Writes to the downstream channel. * * Sideeffects: * As of TclWrite / Tcl_WriteRaw * * Result: * The number of bytes written. * *------------------------------------------------------* */ static int DownWrite (ctrl, buf, toWrite) TrfTransformationInstance* ctrl; char* buf; int toWrite; { Tcl_Channel parent = DOWNC (ctrl); if (ctrl->patchVariant == PATCH_832) { /* * The newly written patch forces use of the new raw-API. */ PRINT ("WriteRaw %p %s\n", parent, Tcl_GetChannelType (parent)->typeName); return Tcl_WriteRaw (parent, buf, toWrite); } else { return Tcl_Write (parent, buf, toWrite); } return TCL_OK; } /* *------------------------------------------------------* * * DownRead -- * * Helper procedure. Reads from the downstream channel. * * Sideeffects: * As of TclRead / Tcl_ReadRaw * * Result: * The number of bytes read. * *------------------------------------------------------* */ static int DownRead (ctrl, buf, toRead) TrfTransformationInstance* ctrl; char* buf; int toRead; { Tcl_Channel parent = DOWNC (ctrl); if (ctrl->patchVariant == PATCH_832) { /* * The newly written patch forces use of the new raw-API. */ return Tcl_ReadRaw (parent, buf, toRead); } else { return Tcl_Read (parent, buf, toRead); } return TCL_OK; } /* *------------------------------------------------------* * * DownSeek -- * * Helper procedure. Asks the downstream channel * to seek, or for its current location. * * Sideeffects: * None. * * Result: * The location in the downstream channel * *------------------------------------------------------* */ static int DownSeek (ctrl, offset, mode) TrfTransformationInstance* ctrl; int offset; int mode; { Tcl_Channel parent = DOWNC (ctrl); if (ctrl->patchVariant == PATCH_832) { /* * The newly rewritten patch forces the transformation into * directly using the seek-proc of the downstream driver. Tcl_Seek * would compensate for the stack and cause and infinite recursion * blowing the stack. */ Tcl_ChannelType* parentType = Tcl_GetChannelType (parent); Tcl_DriverSeekProc* parentSeekProc = Tcl_ChannelSeekProc (parentType); int errorCode; if (parentSeekProc == (Tcl_DriverSeekProc*) NULL) { return -1; } return (*parentSeekProc) (Tcl_GetChannelInstanceData (parent), offset, mode, &errorCode); } /* * (ctrl->patchVariant == PATCH_ORIG) * (ctrl->patchVariant == PATCH_82) * * Both the original patch for stacked channels and rewritten * implementation for 8.2. have the same simple semantics for * getting at the location of the downstream channel. * * Just use the standard 'Tcl_Seek'. */ return (int) Tcl_Seek (parent, offset, mode); } /* *------------------------------------------------------* * * DownChannel -- * * Helper procedure. Finds the downstream channel. * * Sideeffects: * May modify 'self'. * * Result: * None. * *------------------------------------------------------* */ static Tcl_Channel DownChannel (ctrl) TrfTransformationInstance* ctrl; { Tcl_Channel self; Tcl_Channel next; if ((ctrl->patchVariant == PATCH_ORIG) || (ctrl->patchVariant == PATCH_832)) { /* * Both the original patch for stacked channels and rewritten * implementation for 8.3.2. have simple semantics for getting at * the parent of a channel. */ return ctrl->parent; } /* * The first rewrite of the stacked channel patch initially included * in 8.2. requires that a transformation searches it's channel in * the whole stack. Only for the versions of the core using this * implementation, 8.2 till 8.3.1, the comments below apply. */ /* The reason for the existence of this procedure is * the fact that stacking a transform over another * transform will leave our internal pointer unchanged, * and thus pointing to the new transform, and not the * Channel structure containing the saved state of this * transform. This is the price to pay for leaving * Tcl_Channel references intact. The only other solution * is an extension of Tcl_ChannelType with another driver * procedure to notify a Channel about the (un)stacking. * * It walks the chain of Channel structures until it * finds the one pointing having 'ctrl' as instanceData * and then returns the superceding channel to that. */ self = ctrl->self; while ((ClientData) ctrl != Tcl_GetChannelInstanceData (self)) { next = Tcl_GetStackedChannel (self); if (next == (Tcl_Channel) NULL) { /* 09/24/1999 Unstacking bug, found by Matt Newman . * * We were unable to find the channel structure for this * transformation in the chain of stacked channel. This * means that we are currently in the process of unstacking * it *and* there were some bytes waiting which are now * flushed. In this situation the pointer to the channel * itself already refers to the parent channel we have to * write the bytes into, so we return that. */ return ctrl->self; } self = next; } return Tcl_GetStackedChannel (self); } #endif /* *------------------------------------------------------* * * ResultClear -- * * Deallocates any memory allocated by 'ResultAdd'. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ResultClear (r) ResultBuffer* r; /* Reference to the buffer to clear out */ { r->used = 0; if (r->allocated) { ckfree ((char*) r->buf); r->buf = (unsigned char*) NULL; r->allocated = 0; } if (r->seekState != (SeekState*) NULL) { r->seekState->upBufStartLoc = r->seekState->upLoc; r->seekState->upBufEndLoc = r->seekState->upLoc; } } /* *------------------------------------------------------* * * ResultInit -- * * Initializes the specified buffer structure. The * structure will contain valid information for an * emtpy buffer. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ResultInit (r) ResultBuffer* r; /* Reference to the structure to initialize */ { r->used = 0; r->allocated = 0; r->buf = (unsigned char*) NULL; r->seekState = (SeekState*) NULL; } /* *------------------------------------------------------* * * ResultLength -- * * Returns the number of bytes stored in the buffer. * * Sideeffects: * None. * * Result: * An integer, see above too. * *------------------------------------------------------* */ static int ResultLength (r) ResultBuffer* r; /* The structure to query */ { return r->used; } /* *------------------------------------------------------* * * ResultCopy -- * * Copies the requested number of bytes from the * buffer into the specified array and removes them * from the buffer afterward. Copies less if there * is not enough data in the buffer. * * Sideeffects: * See above. * * Result: * The number of actually copied bytes, * possibly less than 'toRead'. * *------------------------------------------------------* */ static int ResultCopy (r, buf, toRead) ResultBuffer* r; /* The buffer to read from */ unsigned char* buf; /* The buffer to copy into */ int toRead; /* Number of requested bytes */ { int copied; START (ResultCopy); PRINT ("request = %d, have = %d\n", toRead, r->used); FL; if (r->used == 0) { /* Nothing to copy in the case of an empty buffer. */ copied = 0; goto done; } if (r->used == toRead) { /* We have just enough. Copy everything to the caller. */ memcpy ((VOID*) buf, (VOID*) r->buf, toRead); r->used = 0; copied = toRead; goto done; } if (r->used > toRead) { /* The internal buffer contains more than requested. * Copy the requested subset to the caller, and shift * the remaining bytes down. */ memcpy ((VOID*) buf, (VOID*) r->buf, toRead); memmove ((VOID*) r->buf, (VOID*) (r->buf + toRead), r->used - toRead); r->used -= toRead; copied = toRead; goto done; } /* There is not enough in the buffer to satisfy the caller, so * take everything. */ memcpy ((VOID*) buf, (VOID*) r->buf, r->used); toRead = r->used; r->used = 0; copied = toRead; /* -- common postwork code ------- */ done: if ((copied > 0) && (r->seekState != (SeekState*) NULL)) { r->seekState->upBufStartLoc += copied; } DONE (ResultCopy); return copied; } /* *------------------------------------------------------* * * ResultDiscardAtStart -- * * Removes the n bytes at the beginning of the buffer * from it. Clears the buffer if n is greater than * its length. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ResultDiscardAtStart (r, n) ResultBuffer* r; /* The buffer to manipulate */ int n; /* Number of bytes to remove */ { START (ResultDiscardAtStart); PRINT ("n = %d, have = %d\n", n, r->used); FL; if (r->used == 0) { /* Nothing to remove in the case of an empty buffer. */ DONE (ResultDiscardAtStart); return; } if (n > r->used) { ResultClear (r); DONE (ResultDiscardAtStart); return; } /* Shift remaining information down */ memmove ((VOID*) r->buf, (VOID*) (r->buf + n), r->used - n); r->used -= n; if (r->seekState != (SeekState*) NULL) { r->seekState->upBufStartLoc += n; } DONE (ResultCopy); } /* *------------------------------------------------------* * * ResultAdd -- * * Adds the bytes in the specified array to the * buffer, by appending it. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ResultAdd (r, buf, toWrite) ResultBuffer* r; /* The buffer to extend */ unsigned char* buf; /* The buffer to read from */ int toWrite; /* The number of bytes in 'buf' */ { START (ResultAdd); PRINT ("have %d, adding %d\n", r->used, toWrite); FL; if ((r->used + toWrite + 1) > r->allocated) { /* Extension of the internal buffer is required. */ if (r->allocated == 0) { r->allocated = toWrite + INCREMENT; r->buf = (unsigned char*) ckalloc (r->allocated); } else { r->allocated += toWrite + INCREMENT; r->buf = (unsigned char*) ckrealloc((char*) r->buf, r->allocated); } } /* now copy data */ memcpy (r->buf + r->used, buf, toWrite); r->used += toWrite; if (r->seekState != (SeekState*) NULL) { r->seekState->upBufEndLoc += toWrite; } DONE (ResultAdd); } /* *------------------------------------------------------* * * SeekCalculatePolicies -- * * Computes standard and used policy from the natural * policy of the transformation, all transformations * below and its base channel. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void SeekCalculatePolicies (trans) TrfTransformationInstance* trans; { /* Define seek related runtime configuration. * seekCfg.overideAllowed, seekCfg.chosen, seekState.used * * i. some transformation below unseekable ? not-overidable unseekable * ii. base channel unseekable ? see above * iii. naturally unseekable ? overidable unseekable. * * WARNING: For 8.0 and 8.1 we will always return 'unseekable'. Due to a * missing 'Tcl_GetStackedChannel' we are unable to go down through the * stack of transformations. */ #ifndef USE_TCL_STUBS START (SeekCalculatePolicies); PRINTLN ("8.0., no Tcl_GetStackedChannel, unseekable, no overide"); TRF_SET_UNSEEKABLE (trans->seekCfg.chosen); trans->seekCfg.overideAllowed = 0; #else Tcl_Channel self = trans->self; Tcl_Channel next; int stopped = 0; START (SeekCalculatePolicies); if (trans->patchVariant == PATCH_ORIG) { PRINTLN ("8.1., no Tcl_GetStackedChannel, unseekable, no overide"); TRF_SET_UNSEEKABLE (trans->seekCfg.chosen); trans->seekCfg.overideAllowed = 0; goto done; } /* 8.2 or higher */ while (self != (Tcl_Channel) NULL) { PRINT ("Check %p\n", self); FL; #if GT81 next = Tcl_GetStackedChannel (self); #else /* In case of 8.1 and higher we can use the (integrated or patched) * 'Tcl_GetStackedChannel' to find the next transform in a general * way. Else we have to check the type of 'next' itself before trying * to peek into its structure. If it is no Trf transform we cannot go * deeper into the stack. But that is not necessary, as the result of * 'unseekable' will not change anymore. */ if (Tcl_GetChannelType (self)->seekProc != TrfSeek) { PRINTLN ("Can't go further down, unseekable, disallow overide"); TRF_SET_UNSEEKABLE (trans->seekCfg.chosen); trans->seekCfg.overideAllowed = 0; stopped = 1; break; } next = ((TrfTransformationInstance*) Tcl_GetChannelInstanceData (self))->parent; #endif if (next == (Tcl_Channel) NULL) { /* self points to base channel (ii). */ if (Tcl_GetChannelType (self)->seekProc == (Tcl_DriverSeekProc*) NULL) { /* Base is unseekable. */ PRINTLN ("Base is unseekable"); TRF_SET_UNSEEKABLE (trans->seekCfg.chosen); trans->seekCfg.overideAllowed = 0; stopped = 1; break; } } else { /* 'next' points to a transformation. */ Tcl_Channel nextAfter; #if GT81 nextAfter = Tcl_GetStackedChannel (next); #else nextAfter = ((TrfTransformationInstance*) Tcl_GetChannelInstanceData (next))->parent; #endif if (nextAfter != (Tcl_Channel) NULL) { /* next points to a transformation below the top (i). * Assume unseekable for a non-trf transformation, else peek directly * into the relevant structure */ if (Tcl_GetChannelType (next)->seekProc != TrfSeek) { PRINTLN ("Unknown type of transform, unseekable, no overide"); TRF_SET_UNSEEKABLE (trans->seekCfg.chosen); trans->seekCfg.overideAllowed = 0; stopped = 1; } else { TrfTransformationInstance* down = (TrfTransformationInstance*) Tcl_GetChannelInstanceData (next); if (!down->seekState.allowed) { PRINTLN ("Trf transform, unseekable"); TRF_SET_UNSEEKABLE (trans->seekCfg.chosen); trans->seekCfg.overideAllowed = 0; stopped = 1; } } } else { /* Next points to the base channel */ /* assert (0); */ } } self = next; } PRINTLN ("Looping done"); if (!stopped) { PRINTLN ("Search went through, check natural policy"); if (TRF_IS_UNSEEKABLE (trans->seekCfg.natural)) { /* Naturally unseekable (iii) */ PRINTLN ("Naturally unseekable"); TRF_SET_UNSEEKABLE (trans->seekCfg.chosen); trans->seekCfg.overideAllowed = 1; } else { /* Take the natural ratio. */ PRINTLN ("naturally seekable"); trans->seekCfg.chosen.numBytesTransform = trans->seekCfg.natural.numBytesTransform; trans->seekCfg.chosen.numBytesDown = trans->seekCfg.natural.numBytesDown; trans->seekCfg.overideAllowed = 1; } } #endif PRINTLN ("Copy ratio chosen :- used"); #ifdef USE_TCL_STUBS done: #endif trans->seekState.used.numBytesTransform = trans->seekCfg.chosen.numBytesTransform; trans->seekState.used.numBytesDown = trans->seekCfg.chosen.numBytesDown; trans->seekState.allowed = !TRF_IS_UNSEEKABLE (trans->seekState.used); DONE (SeekCalculatePolicies); } /* *------------------------------------------------------* * * SeekInitialize -- * * Initialize the runtime state of the seek mechanisms * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void SeekInitialize (trans) TrfTransformationInstance* trans; { trans->seekState.upLoc = 0; trans->seekState.upBufStartLoc = 0; trans->seekState.upBufEndLoc = 0; if (trans->seekState.allowed) { trans->seekState.downLoc = TELL (trans); #ifdef USE_TCL_STUBS if (trans->patchVariant == PATCH_832) { trans->seekState.downLoc -= Tcl_ChannelBuffered (DOWNC (trans)); } #endif trans->seekState.downZero = trans->seekState.downLoc; trans->seekState.aheadOffset = 0; } else { trans->seekState.downLoc = 0; trans->seekState.downZero = 0; trans->seekState.aheadOffset = 0; } trans->seekCfg.identity = 0; trans->seekState.changed = 0; SEEK_DUMP (Seek Initialized); } /* *------------------------------------------------------* * * SeekClearBuffer -- * * Clear read / write buffers of the transformation, * as specified by the second argument. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void SeekClearBuffer (trans, which) TrfTransformationInstance* trans; int which; { /* * Discard everything in the input and output buffers, both * in the transformation and in the generic layer of Trf. */ if (trans->mode & which & TCL_WRITABLE) { PRINT ("out.clearproc\n"); FL; trans->out.vectors->clearProc (trans->out.control, trans->clientData); } if (trans->mode & which & TCL_READABLE) { PRINT ("in.clearproc\n"); FL; trans->in.vectors->clearProc (trans->in.control, trans->clientData); trans->readIsFlushed = 0; ResultClear (&trans->result); } } /* *------------------------------------------------------* * * SeekSynchronize -- * * Discard an existing read buffer and annulate the * read ahead in the downstream channel. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void SeekSynchronize (trans, parent) TrfTransformationInstance* trans; Tcl_Channel parent; { int offsetDown; if (!trans->seekState.allowed) { /* No synchronisation required for an unseekable transform */ return; } if ((trans->seekState.upLoc == trans->seekState.upBufEndLoc) && (trans->seekState.aheadOffset == 0)) { /* Up and down locations are in sync, nothing to do. */ return; } PRINT ("in.clearproc\n"); FL; trans->in.vectors->clearProc (trans->in.control, trans->clientData); trans->readIsFlushed = 0; offsetDown = TRF_DOWN_CONVERT (trans, trans->seekState.upLoc - trans->seekState.upBufEndLoc); offsetDown -= trans->seekState.aheadOffset; /* !! */ ResultClear (&trans->result); if (offsetDown != 0) { SEEK (trans, offsetDown, SEEK_CUR); } trans->seekState.downLoc += offsetDown; } /* *------------------------------------------------------* * * SeekPolicyGet -- * * Compute the currently used policy and store its * name into the character buffer. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void SeekPolicyGet (trans, policy) TrfTransformationInstance* trans; char* policy; { if (trans->seekCfg.identity) { /* identity forced */ strcpy (policy, "identity"); return; } if (!trans->seekState.allowed && ((trans->seekState.used.numBytesTransform != trans->seekCfg.chosen.numBytesTransform) || (trans->seekState.used.numBytesDown != trans->seekCfg.chosen.numBytesDown))) { /* unseekable forced */ strcpy (policy, "unseekable"); return; } /* chosen policy in effect */ strcpy (policy, ""); return; } /* *------------------------------------------------------* * * SeekConfigGet -- * * Generates a list containing the current configuration * of the seek system in a readable manner. * * Sideeffects: * See above. * * Result: * An Tcl_Obj, or NULL. * *------------------------------------------------------* */ static Tcl_Obj* SeekConfigGet (interp, cfg) Tcl_Interp* interp; SeekConfig* cfg; { int res; Tcl_Obj* list = (Tcl_Obj*) NULL; Tcl_Obj* sub1 = (Tcl_Obj*) NULL; Tcl_Obj* sub2 = (Tcl_Obj*) NULL; list = Tcl_NewListObj (0, NULL); if (list == (Tcl_Obj*) NULL) { goto error; } LIST_ADDSTR (error, list, "ratioNatural"); sub1 = Tcl_NewListObj (0, NULL); if (sub1 == (Tcl_Obj*) NULL) { goto error; } LIST_ADDINT (error, sub1, cfg->natural.numBytesTransform); LIST_ADDINT (error, sub1, cfg->natural.numBytesDown); LIST_ADDOBJ (error, list, sub1); LIST_ADDSTR (error, list, "ratioChosen"); sub2 = Tcl_NewListObj (0, NULL); if (sub2 == (Tcl_Obj*) NULL) { goto error; } LIST_ADDINT (error, sub2, cfg->chosen.numBytesTransform); LIST_ADDINT (error, sub2, cfg->chosen.numBytesDown); LIST_ADDOBJ (error, list, sub2); LIST_ADDSTR (error, list, "overideAllowed"); LIST_ADDINT (error, list, cfg->overideAllowed); LIST_ADDSTR (error, list, "identityForced"); LIST_ADDINT (error, list, cfg->identity); return list; error: /* Cleanup any remnants of errors above */ if (list != (Tcl_Obj*) NULL) { Tcl_DecrRefCount (list); } if (sub1 != (Tcl_Obj*) NULL) { Tcl_DecrRefCount (sub1); } if (sub2 != (Tcl_Obj*) NULL) { Tcl_DecrRefCount (sub2); } return NULL; } /* *------------------------------------------------------* * * SeekStateGet -- * * Generates a list containing the current state of * the seek system in a readable manner. * * Sideeffects: * See above. * * Result: * An Tcl_Obj, or NULL. * *------------------------------------------------------* */ static Tcl_Obj* SeekStateGet (interp, state) Tcl_Interp* interp; SeekState* state; { int res; Tcl_Obj* list = (Tcl_Obj*) NULL; Tcl_Obj* sub = (Tcl_Obj*) NULL; list = Tcl_NewListObj (0, NULL); if (list == (Tcl_Obj*) NULL) { goto error; } LIST_ADDSTR (error, list, "seekable"); LIST_ADDINT (error, list, state->allowed); LIST_ADDSTR (error, list, "ratio"); sub = Tcl_NewListObj (0, NULL); if (sub == (Tcl_Obj*) NULL) { goto error; } LIST_ADDINT (error, sub, state->used.numBytesTransform); LIST_ADDINT (error, sub, state->used.numBytesDown); LIST_ADDOBJ (error, list, sub); LIST_ADDSTR (error, list, "up"); LIST_ADDINT (error, list, state->upLoc); LIST_ADDSTR (error, list, "upBufStart"); LIST_ADDINT (error, list, state->upBufStartLoc); LIST_ADDSTR (error, list, "upBufEnd"); LIST_ADDINT (error, list, state->upBufEndLoc); LIST_ADDSTR (error, list, "down"); LIST_ADDINT (error, list, state->downLoc); LIST_ADDSTR (error, list, "downBase"); LIST_ADDINT (error, list, state->downZero); LIST_ADDSTR (error, list, "downAhead"); LIST_ADDINT (error, list, state->aheadOffset); LIST_ADDSTR (error, list, "changed"); LIST_ADDINT (error, list, state->changed); return list; error: /* Cleanup any remnants of errors above */ if (list != (Tcl_Obj*) NULL) { Tcl_DecrRefCount (list); } if (sub != (Tcl_Obj*) NULL) { Tcl_DecrRefCount (sub); } return NULL; } #ifdef TRF_DEBUG /* *------------------------------------------------------* * * PrintString -- * * Defined only in debug mode, enforces correct * printing of strings by adding a \0 after its value. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ void PrintString (fmt,len,bytes) char* fmt; int len; char* bytes; { char* tmp = (char*) ckalloc (len+1); memcpy (tmp, bytes, len); tmp [len] = '\0'; PRINT (fmt, len, tmp); ckfree (tmp); } /* *------------------------------------------------------* * * DumpString -- * * Defined only in debug mode, dumps information * in hex blocks * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ void DumpString (n,len,bytes) int n; int len; char* bytes; { int i, c; for (i=0, c=0; i < len; i++, c++) { if (c == 0) { BLNKS; } printf (" %02x", (0xff & bytes [i])); if (c == 16) { c = -1; printf ("\n"); } } if (c != 0) { printf ("\n"); } } /* *------------------------------------------------------* * * SeekDump -- * * Defined only in debug mode, dumps the complete * state of all seek variables. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void SeekDump (trans, place) TrfTransformationInstance* trans; CONST char* place; { int loc; Tcl_Channel parent = DOWNC (trans); loc = TELL (trans); #if 0 PRINT ("SeekDump (%s) {\n", place); FL; IN; PRINT ("ratio up:down %d : %d\n", trans->seekState.used.numBytesTransform, trans->seekState.used.numBytesDown); FL; PRINT ("seekable %d\n", trans->seekState.allowed); FL; PRINT ("up %d [%d .. %d]\n", trans->seekState.upLoc, trans->seekState.upBufStartLoc, trans->seekState.upBufEndLoc); FL; PRINT ("down %d [%d] | %d\n", trans->seekState.downLoc, trans->seekState.aheadOffset, loc); FL; PRINT ("base %d\n", trans->seekState.downZero); FL; PRINT ("identity force %d\n", trans->seekCfg.identity); FL; PRINT ("seek while ident %d\n", trans->seekState.changed); FL; PRINT ("read buffer %d\n", ResultLength (&trans->result)); FL; OT ; PRINT ("}\n"); FL; #else PRINT ("SkDmp (%s) ", place); FL; #if 0 NPRINT ("(%2d : %2d) | ", trans->seekCfg.natural.numBytesTransform, trans->seekCfg.natural.numBytesDown); FL; NPRINT ("(%2d : %2d) | ", trans->seekCfg.chosen.numBytesTransform, trans->seekCfg.chosen.numBytesDown); FL; #endif NPRINT ("%2d:%2d /%1d |r %5d |u %5d [%5d..%5d] |d %5d [%2d] %5d | %5d | %1d %1d", trans->seekState.used.numBytesTransform, trans->seekState.used.numBytesDown, trans->seekState.allowed, ResultLength (&trans->result), trans->seekState.upLoc, trans->seekState.upBufStartLoc, trans->seekState.upBufEndLoc, trans->seekState.downLoc, trans->seekState.aheadOffset, loc, trans->seekState.downZero, trans->seekCfg.identity, trans->seekState.changed ); FL; NPRINT ("\n"); FL; #endif } #endif /* *------------------------------------------------------* * * AllocChannelType -- * * Allocates a new ChannelType structure. * * * Sideeffects: * See above. * * Result: * A reference to the new structure. * *------------------------------------------------------* */ static Tcl_ChannelType* AllocChannelType (sizePtr) int* sizePtr; { /* * Allocation of a new channeltype structure is not easy, because of * the various version of the core and subsequent changes to the * structure. The main challenge is to allocate enough memory for * modern versions even if this extension is compiled against one * of the older variants! * * (1) Versions before stubs (8.0.x) are simple, because they are * supported only if the extension is compiled against exactly * that version of the core. * * (2) With stubs we just determine the difference between the older * and modern variant and overallocate accordingly if compiled * against an older variant. */ int size = sizeof(Tcl_ChannelType); /* Base size */ #ifdef USE_TCL_STUBS /* * Size of a procedure pointer. We assume that all procedure * pointers are of the same size, regardless of exact type * (arguments and return values). * * 8.1. First version containing close2proc. Baseline. * 8.3.2 Three additional vectors. Moved blockMode, new flush- and * handlerProc's. * 8.4+ wide seek, and thread action. * * => Compilation against earlier version has to overallocate five * procedure pointers. */ #if !(GT832) size += 5 * procPtrSize; #endif #endif if (sizePtr != (int*) NULL) { *sizePtr = size; } return (Tcl_ChannelType*) ckalloc (size); } /* *------------------------------------------------------* * * InitializeChannelType -- * * Initializes a new ChannelType structure. * * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static Tcl_ChannelType* InitializeChannelType (name, patchVariant) CONST char* name; int patchVariant; { Tcl_ChannelType* tct; int size; /* * Initialization of a new channeltype structure is not easy, * because of the various version of the core and subsequent changes * to the structure. The main problem is if compiled against an * older version how to access the elements of the structure not * known in that version. It is made a bit easier because the * allocation routine returns the allocated size. This allows us to * clear out the entire structure. So we just have to deal with the * elements to set and not the ones left alone. */ tct = AllocChannelType (&size); tct->typeName = (char*) name; memset ((VOID*) tct, '\0', size); /* * Common elements of the structure (no changes in location or name) */ tct->closeProc = TrfClose; tct->inputProc = TrfInput; tct->outputProc = TrfOutput; tct->seekProc = TrfSeek; tct->setOptionProc = TrfSetOption; tct->getOptionProc = TrfGetOption; tct->watchProc = TrfWatch; tct->getHandleProc = TrfGetFile; /* * No need to handle close2Proc. Already cleared with the 'memset' * above. */ /* * blockModeProc is a twister. For 8.0.x we can access it * immediately. For the higher versions we have to make some * runtime-choices, and their implementation depends on the version * we compile against. */ #ifndef USE_TCL_STUBS /* 8.0.x */ tct->blockModeProc = TrfBlock; #else #if GT832 /* 8.3.2. and higher. Direct access to all elements possible. Use *'patchVariant' information to select the values to use. */ if ((patchVariant == PATCH_ORIG) || (patchVariant == PATCH_82)) { /* The 'version' element of 8.3.2 is in the the place of the * blockModeProc. For the original patch in 8.1.x and the firstly * included (8.2) we have to set our blockModeProc into this * place. */ tct->version = (Tcl_ChannelTypeVersion) TrfBlock; } else /* patchVariant == PATCH_832 */ { /* For the 8.3.2 core we present ourselves as a version 2 * driver. This means a speciial value in version (ex * blockModeProc), blockModeProc in a different place and of * course usage of the handlerProc. */ tct->version = TCL_CHANNEL_VERSION_2; tct->blockModeProc = TrfBlock; tct->handlerProc = TrfNotify; } #else /* Same as above, but as we are compiling against an older core we * have to create some definitions for the new elements as the compiler * does not know them by name. */ if ((patchVariant == PATCH_ORIG) || (patchVariant == PATCH_82)) { /* The 'version' element of 8.3.2 is in the the place of the * blockModeProc. For the original patch in 8.1.x and the firstly * included (8.2) we have to set our blockModeProc into this * place. */ tct->blockModeProc = TrfBlock; } else /* patchVariant == PATCH_832 */ { /* For the 8.3.2 core we present ourselves as a version 2 * driver. This means a special value in version (ex * blockModeProc), blockModeProc in a different place and of * course usage of the handlerProc. */ #define TRF_CHANNEL_VERSION_2 ((TrfChannelTypeVersion) 0x2) #define BMP (*((Tcl_DriverBlockModeProc**) (&(tct->close2Proc) + 1))) #define HP (*((TrfDriverHandlerProc**) (&(tct->close2Proc) + 3))) typedef struct TrfChannelTypeVersion_* TrfChannelTypeVersion; typedef int (TrfDriverHandlerProc) _ANSI_ARGS_((ClientData instanceData, int interestMask)); tct->blockModeProc = (Tcl_DriverBlockModeProc*) TRF_CHANNEL_VERSION_2; BMP = TrfBlock; HP = TrfNotify; #undef BMP #undef HP #undef TRF_CHANNEL_VERSION_2 } #endif #endif return tct; } /* *------------------------------------------------------* * * TimerKill -- * * Timer management. Removes the internal timer * if it exists. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void TimerKill (trans) TrfTransformationInstance* trans; { if (trans->timer != (Tcl_TimerToken) NULL) { /* Delete an existing flush-out timer, * prevent it from firing on removed channel. */ Tcl_DeleteTimerHandler (trans->timer); trans->timer = (Tcl_TimerToken) NULL; PRINT ("Timer deleted ..."); FL; } } /* *------------------------------------------------------* * * TimerSetup -- * * Timer management. Creates the internal timer * if it does not exist. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void TimerSetup (trans) TrfTransformationInstance* trans; { if (trans->timer == (Tcl_TimerToken) NULL) { trans->timer = Tcl_CreateTimerHandler (TRF_DELAY, ChannelHandlerTimer, (ClientData) trans); } } /* *------------------------------------------------------* * * ChannelHandlerKS -- * * Management of channel handlers. Deletes/Recreates * as required by the specified mask. * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ChannelHandlerKS (trans, mask) TrfTransformationInstance* trans; int mask; { /* * This procedure is called only for the original and the 8.2 * patch. The new 8.2.3 patch does not use channel handlers but a * separate NotifyHandler in the driver. */ Tcl_Channel parent = DOWNC (trans); if (trans->watchMask) { /* * Remove event handler to underlying channel, this could * be because we are closing for real, or being "unstacked". */ Tcl_DeleteChannelHandler (parent, ChannelHandler, (ClientData) trans); } trans->watchMask = mask; if (trans->watchMask) { /* * Setup active monitor for events on underlying Channel */ Tcl_CreateChannelHandler (parent, trans->watchMask, ChannelHandler, (ClientData) trans); } } trf2.1.4/generic/trf.decls0000644000175000017500000000275011216343142014776 0ustar sergeisergei# trf.decls -- # # This file contains the declarations for all supported public # functions that are exported by the Trf library via the stubs table. # This file is used to generate the trfDecls.h file. # library trf # Define the tcl interface with several sub interfaces: # tclPlat - platform specific public # tclInt - generic private # tclPlatInt - platform specific private interface trf hooks {trfInt} # Declare each of the functions in the public Trf interface. Note that # every index should never be reused for a different function in order # to preserve backwards compatibility. declare 0 generic { int Trf_IsInitialized(Tcl_Interp *interp) } declare 1 generic { int Trf_Register(Tcl_Interp *interp, CONST Trf_TypeDefinition *type) } declare 2 generic { Trf_OptionVectors* Trf_ConverterOptions(void) } declare 3 generic { int Trf_LoadLibrary(Tcl_Interp *interp, CONST char *libName, VOID **handlePtr, char **symbols, int num) } declare 4 generic { void Trf_LoadFailed(VOID** handlePtr) } declare 5 generic { int Trf_RegisterMessageDigest (Tcl_Interp* interp, CONST Trf_MessageDigestDescription* md_desc) } declare 6 generic { void Trf_XorBuffer (VOID* buffer, VOID* mask, int length) } declare 7 generic { void Trf_ShiftRegister (VOID* buffer, VOID* in, int shift, int buffer_length) } declare 8 generic { void Trf_FlipRegisterLong (VOID* buffer, int length) } declare 9 generic { void Trf_FlipRegisterShort (VOID* buffer, int length) } trf2.1.4/generic/b64code.c0000644000175000017500000004605611216344223014571 0ustar sergeisergei/* * b64code.c -- * * Implements and registers conversion from and to base64-encoded * representation. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: b64code.c,v 1.13 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Converter description * --------------------- * * Encoding: * Each sequence of 3 bytes is expanded into 4 printable characters * using the 4 6bit-sequences contained in the 3 bytes. The mapping * from 6bit value to printable characters is done with the BASE64 map. * Special processing is done for incomplete byte sequences at the * end of the input (1,2 bytes). * * Decoding: * Each sequence of 4 characters is mapped into 4 6bit values using * the reverse BASE64 map and then concatenated to form 3 8bit bytes. * Special processing is done for incomplete character sequences at * the end of the input (1,2,3 bytes). */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "base64", NULL, /* clientData not used by conversions. */ NULL, /* set later by Trf_InitB64, THREADING: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, NULL, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, NULL, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_RATIO (3, 4) }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (base64 encode) */ unsigned char charCount; unsigned char buf [3]; #define QPERLIN (76 >> 2) /* according to RFC 2045 */ int quads; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (base64 decode) */ unsigned char charCount; unsigned char buf [4]; unsigned char expectFlush; } DecoderControl; /* * Character mapping for base64 encode (bin -> ascii) * * Index this array by a 6-bit value to obtain the corresponding * 8-bit character. The last character (index 64) is the pad char (=) * | * 1 2 3 4 5 6 6 * 01234567890123456789012345678901234567890123456789012345678901234 */ static CONST char* baseMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; /* basemap: THREADING: constant, read-only => safe */ #define PAD '=' /* * Character mappings for base64 decode (ascii -> bin) * * Index this array by a 8 bit value to get the 6-bit binary field * corresponding to that value. Any illegal characters have high bit set. */ #define Ccc (CONST char) /* Ccc = CONST char cast */ static CONST char baseMapReverse [] = { /* THREADING: constant, read-only => safe */ Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0076, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0077, Ccc 0064, Ccc 0065, Ccc 0066, Ccc 0067, Ccc 0070, Ccc 0071, Ccc 0072, Ccc 0073, Ccc 0074, Ccc 0075, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0000, Ccc 0001, Ccc 0002, Ccc 0003, Ccc 0004, Ccc 0005, Ccc 0006, Ccc 0007, Ccc 0010, Ccc 0011, Ccc 0012, Ccc 0013, Ccc 0014, Ccc 0015, Ccc 0016, Ccc 0017, Ccc 0020, Ccc 0021, Ccc 0022, Ccc 0023, Ccc 0024, Ccc 0025, Ccc 0026, Ccc 0027, Ccc 0030, Ccc 0031, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0032, Ccc 0033, Ccc 0034, Ccc 0035, Ccc 0036, Ccc 0037, Ccc 0040, Ccc 0041, Ccc 0042, Ccc 0043, Ccc 0044, Ccc 0045, Ccc 0046, Ccc 0047, Ccc 0050, Ccc 0051, Ccc 0052, Ccc 0053, Ccc 0054, Ccc 0055, Ccc 0056, Ccc 0057, Ccc 0060, Ccc 0061, Ccc 0062, Ccc 0063, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, /* */ Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200 }; #undef Ccc /* *------------------------------------------------------* * * TrfInit_B64 -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_B64 (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (base64 encode) */ c->charCount = 0; memset (c->buf, '\0', 3); c->quads = 0; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (base64 encode) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (base64 encode) */ c->buf [c->charCount] = character; c->charCount ++; if (c->charCount == 3) { int i; unsigned char buf [4]; TrfSplit3to4 (c->buf, buf, 3); #define CRLF_AT(i,v) ((v[i] == '\r') && (v[i+1] == '\n')) #define CRLF_IN(v) (CRLF_AT(0,v) || CRLF_AT(1,v)) /* dbg + * / #if 0 if (CRLF_IN (c->buf)){ printf ("split (%d,%d,%d) = %d,%d,%d,%d = ", c->buf [0], c->buf [1], c->buf [2], buf [0], buf [1], buf [2], buf [3]); } #endif / **/ TrfApplyEncoding (buf, 4, baseMap); /** / if (CRLF_IN (c->buf)) { printf ("%c%c%c%c\n", buf [0], buf [1], buf [2], buf [3]); fflush (stdout); } / * dbg - */ c->charCount = 0; memset (c->buf, '\0', 3); if ((i = c->write (c->writeClientData, buf, 4, interp)) != TCL_OK) return i; if (++c->quads >= QPERLIN) { c->quads = 0; return c->write (c->writeClientData, (unsigned char*) "\n", 1, interp); } } return TCL_OK; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (base64 encode) */ if (c->charCount > 0) { int i; unsigned char buf [4]; TrfSplit3to4 (c->buf, buf, c->charCount); TrfApplyEncoding (buf, 4, baseMap); c->charCount = 0; memset (c->buf, '\0', 3); if ((i = c->write (c->writeClientData, buf, 4, interp)) != TCL_OK) return i; } c->quads = 0; return c->write (c->writeClientData, (unsigned char*) "\n", 1, interp); } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (base64 encode) */ c->charCount = 0; memset (c->buf, '\0', 3); } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (base64 decode) */ c->charCount = 0; memset (c->buf, '\0', 4); c->expectFlush = 0; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (base64 decode) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (base64 decode) */ if ((character == '\r') || (character == '\n')) return TCL_OK; /* ignore any ! illegal character - RFC 2045 */ if (((char) baseMapReverse [character]) & 0x80) return TCL_OK; if (c->expectFlush) { /* * We had a quadruple with pad characters at the last call, * this had to be the last characters in input! coming here * now indicates, that the padding characters were in the * middle of the string, therefore illegal. */ if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal padding inside the string", (char*) NULL); } return TCL_ERROR; } c->buf [c->charCount] = character; c->charCount ++; if (c->charCount == 4) { int res, hasPadding; unsigned char buf [3]; hasPadding = 0; res = TrfReverseEncoding (c->buf, 4, baseMapReverse, PAD, &hasPadding); if (res != TCL_OK) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character found in input", (char*) NULL); } return res; } if (hasPadding) c->expectFlush = 1; TrfMerge4to3 (c->buf, buf); c->charCount = 0; memset (c->buf, '\0', 4); return c->write (c->writeClientData, buf, 3-hasPadding, interp); } return TCL_OK; } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (base64 decode) */ /* * expectFlush && c->charcount > 0 impossible, catched * in 'Decode' already. */ if (c->charCount > 0) { /* * Convert, as if padded with the pad-character. */ int res, hasPadding; unsigned char buf [3]; hasPadding = 0; res = TrfReverseEncoding (c->buf, c->charCount, baseMapReverse, PAD, &hasPadding); if (res != TCL_OK) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character found in input", (char*) NULL); } return res; } TrfMerge4to3 (c->buf, buf); c->charCount = 0; memset (c->buf, '\0', 4); return c->write (c->writeClientData, buf, 3-hasPadding, interp); } return TCL_OK; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (base64 decode) */ c->charCount = 0; memset (c->buf, '\0', 4); c->expectFlush = 0; } trf2.1.4/generic/md5/0000755000175000017500000000000011216344734013660 5ustar sergeisergeitrf2.1.4/generic/md5/md5.c0000644000175000017500000002610511216343142014505 0ustar sergeisergei/* *********************************************************************** ** md5.c -- the source code for MD5 routines ** ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** *********************************************************************** */ /* * Edited 7 May 93 by CP to change the interface to match that * of the MD5 routines in RSAREF. Due to this alteration, this * code is "derived from the RSA Data Security, Inc. MD5 Message- * Digest Algorithm". (See below.) */ /* *********************************************************************** ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** ** ** ** License to copy and use this software is granted provided that ** ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function. ** ** ** ** License is also granted to make and use derivative works ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** ** material mentioning or referencing the derived work. ** ** ** ** RSA Data Security, Inc. makes no representations concerning ** ** either the merchantability of this software or the suitability ** ** of this software for any particular purpose. It is provided "as ** ** is" without express or implied warranty of any kind. ** ** ** ** These notices must be retained in any copies of any part of this ** ** documentation and/or software. ** *********************************************************************** */ #include "md5.h" /* *********************************************************************** ** Message-digest routines: ** ** To form the message digest for a message M ** ** (1) Initialize a context buffer mdContext using MD5Init ** ** (2) Call MD5Update on mdContext and M ** ** (3) Call MD5Final on mdContext ** ** The message digest is now in the bugffer passed to MD5Final ** *********************************************************************** */ static unsigned char PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* F, G, H and I are basic MD5 functions */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ /* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s, ac) \ {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) \ {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) \ {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) \ {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* The routine MD5Init initializes the message-digest context mdContext. All fields are set to zero. */ void MD5Init (mdContext) MD5_CTX *mdContext; { mdContext->i[0] = mdContext->i[1] = (UINT4)0; /* Load magic initialization constants. */ mdContext->buf[0] = (UINT4)0x67452301L; mdContext->buf[1] = (UINT4)0xefcdab89L; mdContext->buf[2] = (UINT4)0x98badcfeL; mdContext->buf[3] = (UINT4)0x10325476L; } /* The routine MD5Update updates the message-digest context to account for the presence of each of the characters inBuf[0..inLen-1] in the message whose digest is being computed. */ void MD5Update (mdContext, inBuf, inLen) register MD5_CTX *mdContext; unsigned char *inBuf; unsigned int inLen; { register int i, ii; int mdi; UINT4 in[16]; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* update number of bits */ if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) mdContext->i[1]++; mdContext->i[0] += ((UINT4)inLen << 3); mdContext->i[1] += ((UINT4)inLen >> 29); while (inLen--) { /* add new character to buffer, increment mdi */ mdContext->in[mdi++] = *inBuf++; /* transform if necessary */ if (mdi == 0x40) { for (i = 0, ii = 0; i < 16; i++, ii += 4) in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); Transform (mdContext->buf, in); mdi = 0; } } } /* The routine MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[0...15]. */ void MD5Final (digest, mdContext) unsigned char digest[16]; MD5_CTX *mdContext; { UINT4 in[16]; int mdi; unsigned int i, ii; unsigned int padLen; /* save number of bits */ in[14] = mdContext->i[0]; in[15] = mdContext->i[1]; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* pad out to 56 mod 64 */ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); MD5Update (mdContext, PADDING, padLen); /* append length in bits and transform */ for (i = 0, ii = 0; i < 14; i++, ii += 4) in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); Transform (mdContext->buf, in); /* store buffer in digest */ for (i = 0, ii = 0; i < 4; i++, ii += 4) { digest[ii] = (unsigned char) (mdContext->buf[i] & 0xFF); digest[ii+1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); } } /* Basic MD5 step. Transforms buf based on in. Note that if the Mysterious Constants are arranged backwards in little-endian order and decrypted with the DES they produce OCCULT MESSAGES! */ void Transform(buf, in) register UINT4 *buf; register UINT4 *in; { register UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; /* Round 1 */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 FF ( a, b, c, d, in[ 0], S11, 0xD76AA478L); /* 1 */ FF ( d, a, b, c, in[ 1], S12, 0xE8C7B756L); /* 2 */ FF ( c, d, a, b, in[ 2], S13, 0x242070DBL); /* 3 */ FF ( b, c, d, a, in[ 3], S14, 0xC1BDCEEEL); /* 4 */ FF ( a, b, c, d, in[ 4], S11, 0xF57C0FAFL); /* 5 */ FF ( d, a, b, c, in[ 5], S12, 0x4787C62AL); /* 6 */ FF ( c, d, a, b, in[ 6], S13, 0xA8304613L); /* 7 */ FF ( b, c, d, a, in[ 7], S14, 0xFD469501L); /* 8 */ FF ( a, b, c, d, in[ 8], S11, 0x698098D8L); /* 9 */ FF ( d, a, b, c, in[ 9], S12, 0x8B44F7AFL); /* 10 */ FF ( c, d, a, b, in[10], S13, 0xFFFF5BB1L); /* 11 */ FF ( b, c, d, a, in[11], S14, 0x895CD7BEL); /* 12 */ FF ( a, b, c, d, in[12], S11, 0x6B901122L); /* 13 */ FF ( d, a, b, c, in[13], S12, 0xFD987193L); /* 14 */ FF ( c, d, a, b, in[14], S13, 0xA679438EL); /* 15 */ FF ( b, c, d, a, in[15], S14, 0x49B40821L); /* 16 */ /* Round 2 */ #define S21 5 #define S22 9 #define S23 14 #define S24 20 GG ( a, b, c, d, in[ 1], S21, 0xF61E2562L); /* 17 */ GG ( d, a, b, c, in[ 6], S22, 0xC040B340L); /* 18 */ GG ( c, d, a, b, in[11], S23, 0x265E5A51L); /* 19 */ GG ( b, c, d, a, in[ 0], S24, 0xE9B6C7AAL); /* 20 */ GG ( a, b, c, d, in[ 5], S21, 0xD62F105DL); /* 21 */ GG ( d, a, b, c, in[10], S22, 0x02441453L); /* 22 */ GG ( c, d, a, b, in[15], S23, 0xD8A1E681L); /* 23 */ GG ( b, c, d, a, in[ 4], S24, 0xE7D3FBC8L); /* 24 */ GG ( a, b, c, d, in[ 9], S21, 0x21E1CDE6L); /* 25 */ GG ( d, a, b, c, in[14], S22, 0xC33707D6L); /* 26 */ GG ( c, d, a, b, in[ 3], S23, 0xF4D50D87L); /* 27 */ GG ( b, c, d, a, in[ 8], S24, 0x455A14EDL); /* 28 */ GG ( a, b, c, d, in[13], S21, 0xA9E3E905L); /* 29 */ GG ( d, a, b, c, in[ 2], S22, 0xFCEFA3F8L); /* 30 */ GG ( c, d, a, b, in[ 7], S23, 0x676F02D9L); /* 31 */ GG ( b, c, d, a, in[12], S24, 0x8D2A4C8AL); /* 32 */ /* Round 3 */ #define S31 4 #define S32 11 #define S33 16 #define S34 23 HH ( a, b, c, d, in[ 5], S31, 0xFFFA3942L); /* 33 */ HH ( d, a, b, c, in[ 8], S32, 0x8771F681L); /* 34 */ HH ( c, d, a, b, in[11], S33, 0x6D9D6122L); /* 35 */ HH ( b, c, d, a, in[14], S34, 0xFDE5380CL); /* 36 */ HH ( a, b, c, d, in[ 1], S31, 0xA4BEEA44L); /* 37 */ HH ( d, a, b, c, in[ 4], S32, 0x4BDECFA9L); /* 38 */ HH ( c, d, a, b, in[ 7], S33, 0xF6BB4B60L); /* 39 */ HH ( b, c, d, a, in[10], S34, 0xBEBFBC70L); /* 40 */ HH ( a, b, c, d, in[13], S31, 0x289B7EC6L); /* 41 */ HH ( d, a, b, c, in[ 0], S32, 0xEAA127FAL); /* 42 */ HH ( c, d, a, b, in[ 3], S33, 0xD4EF3085L); /* 43 */ HH ( b, c, d, a, in[ 6], S34, 0x04881D05L); /* 44 */ HH ( a, b, c, d, in[ 9], S31, 0xD9D4D039L); /* 45 */ HH ( d, a, b, c, in[12], S32, 0xE6DB99E5L); /* 46 */ HH ( c, d, a, b, in[15], S33, 0x1FA27CF8L); /* 47 */ HH ( b, c, d, a, in[ 2], S34, 0xC4AC5665L); /* 48 */ /* Round 4 */ #define S41 6 #define S42 10 #define S43 15 #define S44 21 II ( a, b, c, d, in[ 0], S41, 0xF4292244L); /* 49 */ II ( d, a, b, c, in[ 7], S42, 0x432AFF97L); /* 50 */ II ( c, d, a, b, in[14], S43, 0xAB9423A7L); /* 51 */ II ( b, c, d, a, in[ 5], S44, 0xFC93A039L); /* 52 */ II ( a, b, c, d, in[12], S41, 0x655B59C3L); /* 53 */ II ( d, a, b, c, in[ 3], S42, 0x8F0CCC92L); /* 54 */ II ( c, d, a, b, in[10], S43, 0xFFEFF47DL); /* 55 */ II ( b, c, d, a, in[ 1], S44, 0x85845DD1L); /* 56 */ II ( a, b, c, d, in[ 8], S41, 0x6FA87E4FL); /* 57 */ II ( d, a, b, c, in[15], S42, 0xFE2CE6E0L); /* 58 */ II ( c, d, a, b, in[ 6], S43, 0xA3014314L); /* 59 */ II ( b, c, d, a, in[13], S44, 0x4E0811A1L); /* 60 */ II ( a, b, c, d, in[ 4], S41, 0xF7537E82L); /* 61 */ II ( d, a, b, c, in[11], S42, 0xBD3AF235L); /* 62 */ II ( c, d, a, b, in[ 2], S43, 0x2AD7D2BBL); /* 63 */ II ( b, c, d, a, in[ 9], S44, 0xEB86D391L); /* 64 */ buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } trf2.1.4/generic/md5/md5.h0000644000175000017500000000660211216343142014512 0ustar sergeisergei#ifndef MD5_H #define MD5_H /* *********************************************************************** ** md5.h -- header file for implementation of MD5 ** ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** ** Revised (for MD5): RLR 4/27/91 ** ** -- G modified to have y&~z instead of y&z ** ** -- FF, GG, HH modified to add in last register done ** ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** ** -- distinct additive constant for each step ** ** -- round 4 added, working mod 7 ** *********************************************************************** */ /* * Edited 7 May 93 by CP to change the interface to match that * of the MD5 routines in RSAREF. Due to this alteration, this * code is "derived from the RSA Data Security, Inc. MD5 Message- * Digest Algorithm". (See below.) Also added argument names * to the prototypes. */ /* *********************************************************************** ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** ** ** ** License to copy and use this software is granted provided that ** ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function. ** ** ** ** License is also granted to make and use derivative works ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** ** material mentioning or referencing the derived work. ** ** ** ** RSA Data Security, Inc. makes no representations concerning ** ** either the merchantability of this software or the suitability ** ** of this software for any particular purpose. It is provided "as ** ** is" without express or implied warranty of any kind. ** ** ** ** These notices must be retained in any copies of any part of this ** ** documentation and/or software. ** *********************************************************************** */ #include /* typedef a 32-bit type */ #ifdef __alpha typedef unsigned int UINT4; #else typedef unsigned long int UINT4; #endif /* Data structure for MD5 (Message-Digest) computation */ typedef struct { UINT4 buf[4]; /* scratch buffer */ UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ unsigned char in[64]; /* input buffer */ } MD5_CTX; void MD5Init _ANSI_ARGS_ ((MD5_CTX *mdContext)); void MD5Update _ANSI_ARGS_ ((MD5_CTX *mdContext, unsigned char *bug, unsigned int len)); void MD5Final _ANSI_ARGS_ ((unsigned char digest[16], MD5_CTX *mdContext)); void Transform _ANSI_ARGS_ ((UINT4 *buf, UINT4 *in)); #endif trf2.1.4/generic/zip_opt.c0000644000175000017500000002213211216344224015015 0ustar sergeisergei/* * zip_opt.c -- * * Implements the C level procedures handling option processing * for ZIP transformations. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: zip_opt.c,v 1.12 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * forward declarations of all internally used procedures. */ static Trf_Options CreateOptions _ANSI_ARGS_ ((ClientData clientData)); static void DeleteOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static int CheckOptions _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST Trf_BaseOptions* baseOptions, ClientData clientData)); static int SetOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST Tcl_Obj* optvalue, ClientData clientData)); static int QueryOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); /* *------------------------------------------------------* * * TrfZIPOptions -- * * ------------------------------------------------* * Accessor to the set of vectors realizing option * processing for ZIP procedures. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * See above. * *------------------------------------------------------* */ Trf_OptionVectors* TrfZIPOptions () { static Trf_OptionVectors optVec = /* THREADING: constant, read-only => safe */ { CreateOptions, DeleteOptions, CheckOptions, NULL, /* no string procedure for 'SetOption' */ SetOption, QueryOptions, NULL /* unseekable, unchanged by options */ }; return &optVec; } /* *------------------------------------------------------* * * CreateOptions -- * * ------------------------------------------------* * Create option structure for ZIP transformations. * ------------------------------------------------* * * Sideeffects: * Allocates memory and initializes it as * option structure for ZIP * transformations. * * Result: * A reference to the allocated block of * memory. * *------------------------------------------------------* */ static Trf_Options CreateOptions (clientData) ClientData clientData; { TrfZipOptionBlock* o; o = (TrfZipOptionBlock*) ckalloc (sizeof (TrfZipOptionBlock)); o->mode = TRF_UNKNOWN_MODE; o->level = TRF_DEFAULT_LEVEL; o->nowrap = 0; return (Trf_Options) o; } /* *------------------------------------------------------* * * DeleteOptions -- * * ------------------------------------------------* * Delete option structure of a ZIP transformations * ------------------------------------------------* * * Sideeffects: * A memory block allocated by 'CreateOptions' * is released. * * Result: * None. * *------------------------------------------------------* */ static void DeleteOptions (options, clientData) Trf_Options options; ClientData clientData; { ckfree ((VOID*) options); } /* *------------------------------------------------------* * * CheckOptions -- * * ------------------------------------------------* * Check the given option structure for errors. * ------------------------------------------------* * * Sideeffects: * May modify the given structure to set * default values into uninitialized parts. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int CheckOptions (options, interp, baseOptions, clientData) Trf_Options options; Tcl_Interp* interp; CONST Trf_BaseOptions* baseOptions; ClientData clientData; { TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; /* * 'zip' is used, therefore load the required library. * And bail out if it is not available. */ if (TCL_OK != TrfLoadZlib (interp)) { return TCL_ERROR; } /* * Now perform the real option check. */ if (baseOptions->attach == (Tcl_Channel) NULL) /* IMMEDIATE? */ { if (o->mode == TRF_UNKNOWN_MODE) { Tcl_AppendResult (interp, "-mode option not set", (char*) NULL); return TCL_ERROR; } } else /* ATTACH */ { if (o->mode == TRF_UNKNOWN_MODE) { o->mode = TRF_COMPRESS; } } return TCL_OK; } /* *------------------------------------------------------* * * SetOption -- * * ------------------------------------------------* * Define value of given option. * ------------------------------------------------* * * Sideeffects: * Sets the given value into the option * structure * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int SetOption (options, interp, optname, optvalue, clientData) Trf_Options options; Tcl_Interp* interp; CONST char* optname; CONST Tcl_Obj* optvalue; ClientData clientData; { /* Possible options: * * -level * -level default * -mode compress|decompress * -nowrap * -nowrap default */ TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; int len = strlen (optname + 1); CONST char* value; switch (optname [1]) { case 'l': if (0 != strncmp (optname, "-level", len)) goto unknown_option; value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); len = strlen (value); if (0 == strncmp (value, "default", len)) { o->level = TRF_DEFAULT_LEVEL; } else { int res, val; int v; res = Tcl_GetIntFromObj (interp, (Tcl_Obj*) optvalue, &v); val = v; if (res != TCL_OK) { return res; } if ((val < TRF_MIN_LEVEL) || (val > TRF_MAX_LEVEL)) { Tcl_AppendResult (interp, "level out of range ", (char*) NULL); Tcl_AppendResult (interp, TRF_MIN_LEVEL_STR, (char*) NULL); Tcl_AppendResult (interp, "..", (char*) NULL); Tcl_AppendResult (interp, TRF_MAX_LEVEL_STR, (char*) NULL); return TCL_ERROR; } o->level = val; } break; case 'm': if (0 != strncmp (optname, "-mode", len)) goto unknown_option; value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); len = strlen (value); switch (value [0]) { case 'c': if (0 != strncmp (value, "compress", len)) goto unknown_mode; o->mode = TRF_COMPRESS; break; case 'd': if (0 != strncmp (value, "decompress", len)) goto unknown_mode; o->mode = TRF_DECOMPRESS; break; default: unknown_mode: Tcl_AppendResult (interp, "unknown mode '", (char*) NULL); Tcl_AppendResult (interp, value, (char*) NULL); Tcl_AppendResult (interp, "', should be 'compress' or 'decompress'", (char*) NULL); return TCL_ERROR; break; } /* switch optvalue */ break; case 'n': if (0 != strncmp (optname, "-nowrap", len)) goto unknown_option; value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); len = strlen (value); if (0 == strncmp (value, "default", len)) { o->nowrap = 0; } else { int res, val; res = Tcl_GetBooleanFromObj (interp, (Tcl_Obj*) optvalue, &val); if (res != TCL_OK) { return res; } o->nowrap = val; } break; default: goto unknown_option; break; } return TCL_OK; unknown_option: Tcl_AppendResult (interp, "unknown option '", (char*) NULL); Tcl_AppendResult (interp, optname, (char*) NULL); Tcl_AppendResult (interp, "', should be '-level', '-mode' or '-nowrap'", (char*) NULL); return TCL_ERROR; } /* *------------------------------------------------------* * * QueryOptions -- * * ------------------------------------------------* * Returns a value indicating wether the encoder or * decoder set of vectors is to be used by immediate * execution. * ------------------------------------------------* * * Sideeffects: * None * * Result: * 1 - use encoder vectors. * 0 - use decoder vectors. * *------------------------------------------------------* */ static int QueryOptions (options, clientData) Trf_Options options; ClientData clientData; { TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; return (o->mode == TRF_COMPRESS ? 1 : 0); } trf2.1.4/generic/bz2.c0000644000175000017500000005132211216344223014030 0ustar sergeisergei/* * bz2.c -- * * Implements and registers compressor based on bzip2. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: bz2.c,v 1.8 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static void Bz2libError _ANSI_ARGS_ ((Tcl_Interp* interp, bz_stream* state, int errcode, CONST char* prefix)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "bz2", NULL, /* client data not used */ NULL, /* filled by TrfInit_ZB2, THREADING: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_UNSEEKABLE }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (BZ2) */ bz_stream state; /* compressor state */ char* output_buffer; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (BZ2) */ bz_stream state; /* decompressor state */ char* output_buffer; int lastRes; } DecoderControl; #define KILO (1024) #define OUT_SIZE (32 * KILO) /* *------------------------------------------------------* * * TrfInit_BZ2 -- * * ------------------------------------------------* * Register the compressor implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_BZ2 (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = TrfBZ2Options (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc* fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; TrfBz2OptionBlock* o = (TrfBz2OptionBlock*) optInfo; int res; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (BZ2) */ c->state.bzalloc = NULL; c->state.bzfree = NULL; c->state.opaque = NULL; c->output_buffer = (char*) ckalloc (OUT_SIZE); if (c->output_buffer == (char*) NULL) { ckfree ((VOID*) c); return (ClientData) NULL; } res = bz.bcompressInit (&c->state, o->level, 0, 0); if (res != BZ_OK) { if (interp) { Bz2libError (interp, &c->state, res, "compressor/init"); } ckfree ((VOID*) c->output_buffer); ckfree ((VOID*) c); return (ClientData) NULL; } return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (BZ2) */ bz.bcompressEnd (&c->state); ckfree ((char*) c->output_buffer); ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (BZ2) */ char in; int res; in = character; c->state.next_in = (unsigned char*) (Bytef*) ∈ c->state.avail_in = 1; for (;;) { c->state.next_out = (unsigned char*) (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; res = bz.bcompress (&c->state, BZ_RUN); if (res < BZ_OK) { if (interp) { Bz2libError (interp, &c->state, res, "compressor"); } return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { return res; } } if (c->state.avail_in > 0) continue; if ((c->state.avail_out == 0) && (res == BZ_OK)) continue; break; } return TCL_OK; } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (BZ2) */ int res; c->state.next_in = (unsigned char*) (Bytef*) buffer; c->state.avail_in = bufLen; for (;;) { c->state.next_out = (unsigned char*) (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; res = bz.bcompress (&c->state, BZ_RUN); if (res < BZ_OK) { if (interp) { Bz2libError (interp, &c->state, res, "compressor"); } return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { return res; } } if (c->state.avail_in > 0) continue; if ((c->state.avail_out == 0) && (res == BZ_OK)) continue; break; } return TCL_OK; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (BZ2) */ int res; c->state.next_in = (unsigned char*) (Bytef*) NULL; c->state.avail_in = 0; for (;;) { c->state.next_out = (unsigned char*) (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; res = bz.bcompress (&c->state, BZ_FINISH); if (res < BZ_OK) { if (interp) { Bz2libError (interp, &c->state, res, "compressor/flush"); } return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { return res; } } if ((c->state.avail_out == 0) && (res == BZ_OK)) continue; break; } return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { /* EncoderControl* c = (EncoderControl*) ctrlBlock; */ /* execute conversion specific code here (BZ2) */ /* bz.bcompressReset (&c->state); */ } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc* fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; int res; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (BZ2) */ c->state.bzalloc = NULL; c->state.bzfree = NULL; c->state.opaque = NULL; c->output_buffer = (char*) ckalloc (OUT_SIZE); if (c->output_buffer == (char*) NULL) { ckfree ((VOID*) c); return (ClientData) NULL; } res = bz.bdecompressInit (&c->state, 0, 0); if (res != BZ_OK) { if (interp) { Bz2libError (interp, &c->state, res, "decompressor/init"); } ckfree ((VOID*) c->output_buffer); ckfree ((VOID*) c); return (ClientData) NULL; } c->lastRes = res; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (BZ2) */ bz.bdecompressEnd (&c->state); ckfree ((char*) c->output_buffer); ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (BZ2) */ char in; int res; in = character; c->state.next_in = (unsigned char*) (Bytef*) ∈ c->state.avail_in = 1; for (;;) { c->state.next_out = (unsigned char*) (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; res = bz.bdecompress (&c->state); c->lastRes = res; if ((res < BZ_OK) && (res != BZ_STREAM_END)) { if (interp) { Bz2libError (interp, &c->state, res, "decompressor"); } return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { return res; } } if (c->state.avail_in > 0) continue; if ((c->state.avail_out == 0) && (res == BZ_OK)) continue; break; } return TCL_OK; } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (BZ2) */ int res; c->state.next_in = (unsigned char*) (Bytef*) buffer; c->state.avail_in = bufLen; for (;;) { c->state.next_out = (unsigned char*) (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; res = bz.bdecompress (&c->state); c->lastRes = res; if ((res < BZ_OK) && (res != BZ_STREAM_END)) { if (interp) { Bz2libError (interp, &c->state, res, "decompressor"); } return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { return res; } } if (c->state.avail_in > 0) continue; if ((c->state.avail_out == 0) && (res == BZ_OK)) continue; break; } return TCL_OK; } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (BZ2) */ int res; if (c->lastRes == BZ_STREAM_END) { /* Essentially already flushed ! */ return TCL_OK; } c->state.next_in = (unsigned char*) (Bytef*) c->output_buffer; /* fake out * 'inflate' */ c->state.avail_in = 0; for (;;) { c->state.next_out = (unsigned char*) (Bytef*) c->output_buffer; c->state.avail_out = OUT_SIZE; res = bz.bdecompress (&c->state); if ((res < BZ_OK) && (res != BZ_STREAM_END)) { if (interp) { Bz2libError (interp, &c->state, res, "decompressor/flush"); } return TCL_ERROR; } if (c->state.avail_out < OUT_SIZE) { res = c->write (c->writeClientData, (unsigned char*) c->output_buffer, OUT_SIZE - c->state.avail_out, interp); if (res != TCL_OK) { return res; } } if ((c->state.avail_out == 0) && (res == BZ_OK)) continue; break; } return TCL_OK; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { /* DecoderControl* c = (DecoderControl*) ctrlBlock; */ /* execute conversion specific code here (BZ2) */ /* bz.bdecompressReset (&c->state); */ } /* *------------------------------------------------------* * * Bz2libError -- * * ------------------------------------------------* * Append error message from bzlib-state to interpreter * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void Bz2libError (interp, state, errcode, prefix) Tcl_Interp* interp; bz_stream* state; int errcode; CONST char* prefix; { CONST char* msg; /* * A table-lookup might have been nicer, but this * is more secure against changes of the codevalues * used by bzlib. */ switch (errcode) { case BZ_MEM_ERROR: msg = "not enough memory available"; break; case BZ_SEQUENCE_ERROR: msg = "sequence error"; break; case BZ_PARAM_ERROR: msg = "param error"; break; case BZ_DATA_ERROR: msg = "incoming data corrupted"; break; case BZ_DATA_ERROR_MAGIC: msg = "magic number corrupted"; break; case BZ_IO_ERROR: msg = "io error"; break; case BZ_UNEXPECTED_EOF: msg = "unexpected eof"; break; case BZ_OUTBUFF_FULL: msg = "output buffer full"; break; default: msg = "?"; break; } Tcl_AppendResult (interp, "bz2lib error (", (char*) NULL); Tcl_AppendResult (interp, prefix, (char*) NULL); Tcl_AppendResult (interp, "): ", (char*) NULL); Tcl_AppendResult (interp, msg, (char*) NULL); } trf2.1.4/generic/octcode.c0000644000175000017500000004273011216344223014756 0ustar sergeisergei/* * octcode.c -- * * Implements and registers conversion from and to octal representation. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: octcode.c,v 1.11 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Converter description * --------------------- * * Encoding: * Every byte is converted into 3 characters, using elements * in the set {0, ..., 7} only. Thus a octal representation is * generated. The MSBit is output first. * * Decoding: * Only characters in the set {0, ..., 7} are allowed as input. * Each 3-tuple is converted into a single byte. One or two * characters at the end of input are converted as if padded * with "0"s. */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc* fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "oct", NULL, /* clientData not used by converters */ NULL, /* set later by TrfInit_Oct, THREADING: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_RATIO (1, 3) }; /* * Use table lookup */ static const char* code [] = { /* THREADING: constant, read-only => safe */ "000", "001", "002", "003", "004", "005", "006", "007", "010", "011", "012", "013", "014", "015", "016", "017", "020", "021", "022", "023", "024", "025", "026", "027", "030", "031", "032", "033", "034", "035", "036", "037", "040", "041", "042", "043", "044", "045", "046", "047", "050", "051", "052", "053", "054", "055", "056", "057", "060", "061", "062", "063", "064", "065", "066", "067", "070", "071", "072", "073", "074", "075", "076", "077", "100", "101", "102", "103", "104", "105", "106", "107", "110", "111", "112", "113", "114", "115", "116", "117", "120", "121", "122", "123", "124", "125", "126", "127", "130", "131", "132", "133", "134", "135", "136", "137", "140", "141", "142", "143", "144", "145", "146", "147", "150", "151", "152", "153", "154", "155", "156", "157", "160", "161", "162", "163", "164", "165", "166", "167", "170", "171", "172", "173", "174", "175", "176", "177", "200", "201", "202", "203", "204", "205", "206", "207", "210", "211", "212", "213", "214", "215", "216", "217", "220", "221", "222", "223", "224", "225", "226", "227", "230", "231", "232", "233", "234", "235", "236", "237", "240", "241", "242", "243", "244", "245", "246", "247", "250", "251", "252", "253", "254", "255", "256", "257", "260", "261", "262", "263", "264", "265", "266", "267", "270", "271", "272", "273", "274", "275", "276", "277", "300", "301", "302", "303", "304", "305", "306", "307", "310", "311", "312", "313", "314", "315", "316", "317", "320", "321", "322", "323", "324", "325", "326", "327", "330", "331", "332", "333", "334", "335", "336", "337", "340", "341", "342", "343", "344", "345", "346", "347", "350", "351", "352", "353", "354", "355", "356", "357", "360", "361", "362", "363", "364", "365", "366", "367", "370", "371", "372", "373", "374", "375", "376", "377", }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; unsigned char charCount; /* number of characters assembled so far (0..3) */ unsigned char bench; /* buffer for assembled byte */ } DecoderControl; /* *------------------------------------------------------* * * TrfInit_Oct -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Oct (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; #if 0 unsigned char buffer [3]; char high = (character >> 6) & 0x03; char mid = (character >> 3) & 0x07; char low = character & 0x07; buffer [0] = high + '0'; buffer [1] = mid + '0'; buffer [2] = low + '0'; return c->write (c->writeClientData, buffer, 3, interp); #endif return c->write (c->writeClientData, (unsigned char*) code [character & 0x00ff], 3, interp); } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; char* out = (char*) ckalloc (3*bufLen+1); int res, i, j; CONST char* ch; for (i=0, j=0; i < bufLen; i++) { ch = code [buffer [i] & 0x00ff]; out [j] = ch [0]; j++; out [j] = ch [1]; j++; out [j] = ch [2]; j++; } out [j] = '\0'; res = c->write (c->writeClientData, (unsigned char*) out, 3*bufLen, interp); ckfree ((char*) out); return res; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { /* nothing to to */ return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { /* nothing to do */ } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; c->charCount = 0; c->bench = '\0'; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; #define IN_RANGE(low,x,high) (((low) <= (x)) && ((x) <= (high))) if ((! IN_RANGE ('0', character, '7')) || ((c->charCount == 0) && (character > '3'))) { if (interp) { char buf [10]; if (character < ' ' || character > 127) { sprintf (buf, "0x%02x", character); } else { buf [0] = '\''; buf [1] = character; buf [2] = '\''; buf [3] = '\0'; } Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character ", buf, " found in input", (char*) NULL); } return TCL_ERROR; } character -= '0'; c->bench |= (character << (3 * (2 - c->charCount))); c->charCount ++; if (c->charCount >= 3) { int res = c->write (c->writeClientData, &c->bench, 1, interp); c->bench = '\0'; c->charCount = 0; return res; } return TCL_OK; #undef IN_RANGE } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { #define IN_RANGE(low,x,high) (((low) <= (x)) && ((x) <= (high))) DecoderControl* c = (DecoderControl*) ctrlBlock; char* out = (char*) ckalloc (2+bufLen/3); int res, i, j; unsigned char character; for (i=0, j=0; i < bufLen; i++) { character = buffer [i]; if ((! IN_RANGE ('0', character, '7')) || ((c->charCount == 0) && (character > '3'))) { if (interp) { char buf [10]; if (character < ' ' || character > 127) { sprintf (buf, "0x%02x", character); } else { buf [0] = '\''; buf [1] = character; buf [2] = '\''; buf [3] = '\0'; } Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character ", buf, " found in input", (char*) NULL); } return TCL_ERROR; } character -= '0'; c->bench |= (character << (3 * (2 - c->charCount))); c->charCount ++; if (c->charCount >= 3) { out [j] = c->bench; j ++; c->bench = '\0'; c->charCount = 0; } } res = c->write (c->writeClientData, (unsigned char*) out, j, interp); return res; #undef IN_RANGE } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; int res = TCL_OK; if (c->charCount > 0) { res = c->write (c->writeClientData, &c->bench, 1, interp); c->bench = '\0'; c->charCount = 0; } return res; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; c->bench = '\0'; c->charCount = 0; } trf2.1.4/generic/digest.c0000644000175000017500000007007111216344223014614 0ustar sergeisergei/* * digest.c -- * * Implements and registers code common to all message digests. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: digest.c,v 1.18 2009/05/07 05:30:35 andreas_kupries Exp $ */ #include "transformInt.h" /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Generator definition. */ static Trf_TypeDefinition mdDefinition = /* THREADING: constant, read-only => safe */ { NULL, /* filled later by Trf_RegisterMessageDigest (in a copy) */ NULL, /* filled later by Trf_RegisterMessageDigest (in a copy) */ NULL, /* filled later by Trf_RegisterMessageDigest (in a copy) */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_UNSEEKABLE }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; int operation_mode; char* destHandle; /* Name of target for ATTACH_WRITE */ Tcl_Channel dest; /* Channel target for ATTACH_WRITE. possibly NULL */ Tcl_Interp* vInterp; /* Interpreter containing 'destHandle', if name of variable */ /* Possible combinations: * destHandle != NULL, vInterp != NULL, dest == NULL /ATTACH_WRITE, to variable * destHandle == NULL, vInterp == NULL, dest != NULL /ATTACH_WRITE, to channel * destHandle == NULL, vInterp == NULL, dest == NULL /ATTACH_ABSORB, or IMMEDIATE * * TRF_TRANSPARENT <=> TRF_WRITE_HASH */ VOID* context; } EncoderControl; #define IMMEDIATE (0) #define ATTACH_ABSORB (1) #define ATTACH_WRITE (2) #define ATTACH_TRANS (3) typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; int operation_mode; char* destHandle; /* Name of target for ATTACH_WRITE */ Tcl_Channel dest; /* Channel target for ATTACH_WRITE. possibly NULL */ Tcl_Interp* vInterp; /* Interpreter containing 'destHandle', if name of variable */ /* Possible combinations: * destHandle != NULL, dest == NULL /ATTACH_WRITE, to variable * destHandle == NULL, dest != NULL /ATTACH_WRITE, to channel * destHandle == NULL, dest == NULL /ATTACH_ABSORB, or IMMEDIATE * vInterp always set, because of 'matchFlag'. * * TRF_TRANSPARENT <=> TRF_WRITE_HASH */ VOID* context; char* matchFlag; /* target for ATTACH_ABSORB */ unsigned char* digest_buffer; short buffer_pos; unsigned short charCount; } DecoderControl; static int WriteDigest _ANSI_ARGS_ ((Tcl_Interp* interp, char* destHandle, Tcl_Channel dest, char* digest, Trf_MessageDigestDescription* md)); /* *------------------------------------------------------* * * Trf_RegisterMessageDigest -- * * ------------------------------------------------* * Register the specified generator as transformer. * ------------------------------------------------* * * Sideeffects: * Allocates memory. As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int Trf_RegisterMessageDigest (interp, md_desc) Tcl_Interp* interp; CONST Trf_MessageDigestDescription* md_desc; { Trf_TypeDefinition* md; int res; START (Trf_RegisterMessageDigest); /* THREADING: read-only access => safe */ md = (Trf_TypeDefinition*) ckalloc (sizeof (Trf_TypeDefinition)); memcpy ((VOID*) md, (VOID*) &mdDefinition, sizeof (Trf_TypeDefinition)); md->name = md_desc->name; md->clientData = (ClientData) md_desc; md->options = TrfMDOptions (); PRINT ("MD_Desc %p\n", md_desc); FL; IN; PRINT ("Name: %s\n", md_desc->name); PRINT ("Context: %d\n", md_desc->context_size); PRINT ("Digest: %d\n", md_desc->digest_size); PRINT ("Start: %p\n", md_desc->startProc); PRINT ("Update: %p\n", md_desc->updateProc); PRINT ("UpdateBuf: %p\n", md_desc->updateBufProc); PRINT ("Final %p\n", md_desc->finalProc); PRINT ("Check: %p\n", md_desc->checkProc); OT; res = Trf_Register (interp, md); /* 'md' is a memory leak, it will never be released. */ DONE (Trf_RegisterMessageDigest); return res; } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; TrfMDOptionBlock* o = (TrfMDOptionBlock*) optInfo; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; START (digest.CreateEncoder); PRINT ("%p: %s\n", md, md->name); c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; PRINT ("Setting up state\n"); FL; if ((o->behaviour == TRF_IMMEDIATE) || (o->mode == TRF_ABSORB_HASH)) { c->operation_mode = (o->behaviour == TRF_IMMEDIATE) ? IMMEDIATE : ATTACH_ABSORB; c->vInterp = (Tcl_Interp*) NULL; c->destHandle = (char*) NULL; c->dest = (Tcl_Channel) NULL; } else { if (o->mode == TRF_WRITE_HASH) c->operation_mode = ATTACH_WRITE; else c->operation_mode = ATTACH_TRANS; if (o->wdIsChannel) { c->vInterp = (Tcl_Interp*) NULL; c->destHandle = (char*) NULL; c->dest = o->wdChannel; } else { c->vInterp = o->vInterp; c->destHandle = o->writeDestination; c->dest = (Tcl_Channel) NULL; o->writeDestination = (char*) NULL; /* ownership moved, prevent early free */ } } /* * Create and initialize the context. */ PRINT ("Setting up context (%d bytes)\n", md->context_size); FL; c->context = (VOID*) ckalloc (md->context_size); (*md->startProc) (c->context); DONE (digest.CreateEncoder); return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* [Bug 2788106]. */ if (c->destHandle) { ckfree (c->destHandle); } ckfree ((char*) c->context); ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; unsigned char buf; buf = character; (*md->updateProc) (c->context, character); if ((c->operation_mode == ATTACH_ABSORB) || (c->operation_mode == ATTACH_TRANS)) { /* * absorption/transparent mode: incoming characters flow * unchanged through transformation. */ return c->write (c->writeClientData, &buf, 1, interp); } return TCL_OK; } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; if (*md->updateBufProc != (Trf_MDUpdateBuf*) NULL) { (*md->updateBufProc) (c->context, buffer, bufLen); } else { unsigned int character, i; for (i=0; i < ((unsigned int) bufLen); i++) { character = buffer [i]; (*md->updateProc) (c->context, character); } } if ((c->operation_mode == ATTACH_ABSORB) || (c->operation_mode == ATTACH_TRANS)) { /* * absorption/transparent mode: incoming characters flow * unchanged through transformation. */ return c->write (c->writeClientData, buffer, bufLen, interp); } return TCL_OK; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; char* digest; int res = TCL_OK; /* * Get a bit more, for a trailing \0 in 7.6, see 'WriteDigest' too */ digest = (char*) ckalloc (2 + md->digest_size); (*md->finalProc) (c->context, digest); if ((c->operation_mode == ATTACH_WRITE) || (c->operation_mode == ATTACH_TRANS)) { res = WriteDigest (c->vInterp, c->destHandle, c->dest, digest, md); } else { /* * Immediate execution or attached channel absorbing the checksum. */ /* -W- check wether digest can be declared 'uchar*', or if this has * -W- other sideeffects, see lines 636, 653, 82 too. */ res = c->write (c->writeClientData, (unsigned char*) digest, md->digest_size, interp); } ckfree (digest); return res; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; (*md->startProc) (c->context); } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; TrfMDOptionBlock* o = (TrfMDOptionBlock*) optInfo; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; c->matchFlag = o->matchFlag; c->vInterp = o->vInterp; o->matchFlag = NULL; /* impossible: (o->behaviour == TRF_IMMEDIATE) */ if (o->mode == TRF_ABSORB_HASH) { c->operation_mode = ATTACH_ABSORB; c->destHandle = (char*) NULL; c->dest = (Tcl_Channel) NULL; } else { if (o->mode == TRF_WRITE_HASH) c->operation_mode = ATTACH_WRITE; else c->operation_mode = ATTACH_TRANS; if (o->rdIsChannel) { c->destHandle = (char*) NULL; c->dest = o->rdChannel; } else { c->destHandle = o->readDestination; c->dest = (Tcl_Channel) NULL; o->readDestination = (char*) NULL; /* ownership moved, prevent early free */ } } c->buffer_pos = 0; c->charCount = 0; c->context = (VOID*) ckalloc (md->context_size); (*md->startProc) (c->context); c->digest_buffer = (unsigned char*) ckalloc (md->digest_size); memset (c->digest_buffer, '\0', md->digest_size); return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* [Bug 2788106]. */ if (c->destHandle) { ckfree (c->destHandle); } ckfree ((char*) c->digest_buffer); ckfree ((char*) c->context); ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; char buf; if (c->operation_mode == ATTACH_WRITE) { buf = character; (*md->updateProc) (c->context, character); } else if (c->operation_mode == ATTACH_TRANS) { buf = character; (*md->updateProc) (c->context, character); return c->write (c->writeClientData, (unsigned char*) &buf, 1, interp); } else { if (c->charCount == md->digest_size) { /* * ringbuffer full, forward oldest character * and replace with new one. */ buf = c->digest_buffer [c->buffer_pos]; c->digest_buffer [c->buffer_pos] = character; c->buffer_pos ++; c->buffer_pos %= md->digest_size; character = buf; (*md->updateProc) (c->context, character); return c->write (c->writeClientData, (unsigned char*) &buf, 1, interp); } else { /* * Fill ringbuffer. */ c->digest_buffer [c->buffer_pos] = character; c->buffer_pos ++; c->charCount ++; } } return TCL_OK; } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; if (c->operation_mode == ATTACH_WRITE) { if (*md->updateBufProc != (Trf_MDUpdateBuf*) NULL) { (*md->updateBufProc) (c->context, buffer, bufLen); } else { int character, i; for (i=0; i < bufLen; i++) { character = buffer [i]; (*md->updateProc) (c->context, character); } } } else if (c->operation_mode == ATTACH_TRANS) { if (*md->updateBufProc != (Trf_MDUpdateBuf*) NULL) { (*md->updateBufProc) (c->context, buffer, bufLen); } else { int character, i; for (i=0; i < bufLen; i++) { character = buffer [i]; (*md->updateProc) (c->context, character); } } return c->write (c->writeClientData, buffer, bufLen, interp); } else { /* try to use more than character at a time. */ if (*md->updateBufProc != NULL) { /* * 2 cases: * * - Incoming buffer and data stored from previous calls are less * or just enough to fill the ringbuffer. Copy the incoming bytes * into the buffer and return. * * - Incoming data + ringbuffer contain more than reqired for a * digest. Concatenate both and use the oldest bytes to update the * hash context. Place the remaining 'digest_size' bytes into the * ringbuffer again. * * Both cases assume the ringbuffer data to be starting at index '0'. */ if ((c->charCount + bufLen) <= md->digest_size) { /* extend ring buffer */ memcpy ( (VOID*) (c->digest_buffer + c->charCount), (VOID*) buffer, bufLen); c->charCount += bufLen; } else { /* * n contains the number of bytes we are allowed to hash into the context. */ int n = c->charCount + bufLen - md->digest_size; int res; if (c->charCount > 0) { if (n <= c->charCount) { /* * update context, then shift down the remaining bytes */ (*md->updateBufProc) (c->context, c->digest_buffer, n); res = c->write (c->writeClientData, c->digest_buffer, n, interp); memmove ((VOID*) c->digest_buffer, (VOID*) (c->digest_buffer + n), c->charCount - n); c->charCount -= n; n = 0; } else { /* * Hash everything inside the buffer. */ (*md->updateBufProc) (c->context, c->digest_buffer, c->charCount); res = c->write (c->writeClientData, c->digest_buffer, c->charCount, interp); n -= c->charCount; c->charCount = 0; } if (res != TCL_OK) return res; } if (n > 0) { (*md->updateBufProc) (c->context, buffer, n); res = c->write (c->writeClientData, buffer, n, interp); memcpy ((VOID*) (c->digest_buffer + c->charCount), (VOID*) (buffer + n), (bufLen - n)); c->charCount = md->digest_size; /* <=> 'c->charCount += bufLen - n;' */ if (res != TCL_OK) return res; } } } else { /* * no 'updateBufProc', simulate it using the * underlying single character routine */ int character, i, res; char buf; for (i=0; i < bufLen; i++) { buf = c->digest_buffer [c->buffer_pos]; character = buffer [i]; if (c->charCount == md->digest_size) { /* * ringbuffer full, forward oldest character * and replace with new one. */ c->digest_buffer [c->buffer_pos] = character; c->buffer_pos ++; c->buffer_pos %= md->digest_size; character = buf; (*md->updateProc) (c->context, character); res = c->write (c->writeClientData, (unsigned char*) &buf, 1, interp); if (res != TCL_OK) return res; } else { /* * Fill ringbuffer. */ c->digest_buffer [c->buffer_pos] = character; c->buffer_pos ++; c->charCount ++; } } /* for */ } } return TCL_OK; } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; char* digest; int res= TCL_OK; /* * Get a bit more, for a trailing \0 in 7.6, see 'WriteDigest' too */ digest = (char*) ckalloc (2 + md->digest_size); (*md->finalProc) (c->context, digest); if ((c->operation_mode == ATTACH_WRITE) || (c->operation_mode == ATTACH_TRANS)) { res = WriteDigest (c->vInterp, c->destHandle, c->dest, digest, md); } else if (c->charCount < md->digest_size) { /* * ATTACH_ABSORB, not enough data in input! */ if (interp) { Tcl_AppendResult (interp, "not enough bytes in input", (char*) NULL); } res = TCL_ERROR; } else { char* result_text; if (c->buffer_pos > 0) { /* * Reorder bytes in ringbuffer to form the correct digest. */ char* temp; int i,j; temp = (char*) ckalloc (md->digest_size); for (i= c->buffer_pos, j=0; j < md->digest_size; i = (i+1) % md->digest_size, j++) { temp [j] = c->digest_buffer [i]; } memcpy ((VOID*) c->digest_buffer, (VOID*) temp, md->digest_size); ckfree (temp); } /* * Compare computed and transmitted checksums. */ result_text = (0 == memcmp ((VOID*) digest, (VOID*) c->digest_buffer, md->digest_size) ? "ok" : "failed"); Tcl_SetVar (c->vInterp, c->matchFlag, result_text, TCL_GLOBAL_ONLY); } ckfree (digest); return res; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; Trf_MessageDigestDescription* md = (Trf_MessageDigestDescription*) clientData; c->buffer_pos = 0; c->charCount = 0; (*md->startProc) (c->context); memset (c->digest_buffer, '\0', md->digest_size); } /* *------------------------------------------------------* * * WriteDigest -- * * ------------------------------------------------* * Writes the generated digest into the destination * variable, or channel. * ------------------------------------------------* * * Sideeffects: * May leave an error message in the * interpreter result area. * * Result: * A standard Tcl error message. * *------------------------------------------------------* */ static int WriteDigest (interp, destHandle, dest, digest, md) Tcl_Interp* interp; char* destHandle; Tcl_Channel dest; char* digest; Trf_MessageDigestDescription* md; { if (destHandle != (char*) NULL) { #if GT81 Tcl_Obj* digestObj = Tcl_NewByteArrayObj (digest, md->digest_size); #else Tcl_Obj* digestObj = Tcl_NewStringObj (digest, md->digest_size); #endif Tcl_Obj* result; /*#if GT81 / * 8.1 and beyond * / Tcl_IncrRefCount(digestObj); result = Tcl_SetObjVar2 (interp, destHandle, (char*) NULL, digestObj, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); #else*/ /* 8.0 section */ Tcl_Obj* varName = Tcl_NewStringObj (destHandle, strlen (destHandle)); Tcl_IncrRefCount(varName); Tcl_IncrRefCount(digestObj); result = Tcl_ObjSetVar2 (interp, varName, (Tcl_Obj*) NULL, digestObj, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY | TCL_PARSE_PART1); Tcl_DecrRefCount(varName); /*#endif / * GT81 */ Tcl_DecrRefCount(digestObj); if (result == (Tcl_Obj*) NULL) { return TCL_ERROR; } } else if (dest != (Tcl_Channel) NULL) { int res = Tcl_Write (dest, digest, md->digest_size); if (res < 0) { if (interp) { Tcl_AppendResult (interp, "error writing \"", Tcl_GetChannelName (dest), "\": ", Tcl_PosixError (interp), (char*) NULL); } return TCL_ERROR; } } return TCL_OK; } trf2.1.4/generic/bz2_opt.c0000644000175000017500000002105311216344223014710 0ustar sergeisergei/* * bz2_opt.c -- * * Implements the C level procedures handling option processing * for ZIP transformations. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: bz2_opt.c,v 1.5 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * forward declarations of all internally used procedures. */ static Trf_Options CreateOptions _ANSI_ARGS_ ((ClientData clientData)); static void DeleteOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static int CheckOptions _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST Trf_BaseOptions* baseOptions, ClientData clientData)); static int SetOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST Tcl_Obj* optvalue, ClientData clientData)); static int QueryOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); /* *------------------------------------------------------* * * TrfBZ2Options -- * * ------------------------------------------------* * Accessor to the set of vectors realizing option * processing for ZIP procedures. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * See above. * *------------------------------------------------------* */ Trf_OptionVectors* TrfBZ2Options () { static Trf_OptionVectors optVec = /* THREADING: constant, read-only => safe */ { CreateOptions, DeleteOptions, CheckOptions, NULL, /* no string procedure for 'SetOption' */ SetOption, QueryOptions, NULL /* unseekable, unchanged by options */ }; return &optVec; } /* *------------------------------------------------------* * * CreateOptions -- * * ------------------------------------------------* * Create option structure for ZIP transformations. * ------------------------------------------------* * * Sideeffects: * Allocates memory and initializes it as * option structure for ZIP * transformations. * * Result: * A reference to the allocated block of * memory. * *------------------------------------------------------* */ static Trf_Options CreateOptions (clientData) ClientData clientData; { TrfZipOptionBlock* o; o = (TrfZipOptionBlock*) ckalloc (sizeof (TrfZipOptionBlock)); o->mode = TRF_UNKNOWN_MODE; o->level = 9; return (Trf_Options) o; } /* *------------------------------------------------------* * * DeleteOptions -- * * ------------------------------------------------* * Delete option structure of a ZIP transformations * ------------------------------------------------* * * Sideeffects: * A memory block allocated by 'CreateOptions' * is released. * * Result: * None. * *------------------------------------------------------* */ static void DeleteOptions (options, clientData) Trf_Options options; ClientData clientData; { ckfree ((VOID*) options); } /* *------------------------------------------------------* * * CheckOptions -- * * ------------------------------------------------* * Check the given option structure for errors. * ------------------------------------------------* * * Sideeffects: * May modify the given structure to set * default values into uninitialized parts. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int CheckOptions (options, interp, baseOptions, clientData) Trf_Options options; Tcl_Interp* interp; CONST Trf_BaseOptions* baseOptions; ClientData clientData; { TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; /* * 'bz2' is used, therefore load the required library. * And bail out if it is not available. */ if (TCL_OK != TrfLoadBZ2lib (interp)) { return TCL_ERROR; } /* * Now perform the real option check. */ if (baseOptions->attach == (Tcl_Channel) NULL) /* IMMEDIATE? */ { if (o->mode == TRF_UNKNOWN_MODE) { Tcl_AppendResult (interp, "-mode option not set", (char*) NULL); return TCL_ERROR; } } else /* ATTACH */ { if (o->mode == TRF_UNKNOWN_MODE) { o->mode = TRF_COMPRESS; } } return TCL_OK; } /* *------------------------------------------------------* * * SetOption -- * * ------------------------------------------------* * Define value of given option. * ------------------------------------------------* * * Sideeffects: * Sets the given value into the option * structure * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int SetOption (options, interp, optname, optvalue, clientData) Trf_Options options; Tcl_Interp* interp; CONST char* optname; CONST Tcl_Obj* optvalue; ClientData clientData; { /* Possible options: * * -level * -level default * -mode compress|decompress */ TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; int len = strlen (optname + 1); CONST char* value; switch (optname [1]) { case 'l': if (0 != strncmp (optname, "-level", len)) goto unknown_option; value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); len = strlen (value); if (0 == strncmp (value, "default", len)) { o->level = 9; } else { int res, val; int v; res = Tcl_GetIntFromObj (interp, (Tcl_Obj*) optvalue, &v); val = v; if (res != TCL_OK) { return res; } if ((val < TRF_MIN_LEVEL) || (val > TRF_MAX_LEVEL)) { Tcl_AppendResult (interp, "level out of range ", (char*) NULL); Tcl_AppendResult (interp, TRF_MIN_LEVEL_STR, (char*) NULL); Tcl_AppendResult (interp, "..", (char*) NULL); Tcl_AppendResult (interp, TRF_MAX_LEVEL_STR, (char*) NULL); return TCL_ERROR; } o->level = val; } break; case 'm': if (0 != strncmp (optname, "-mode", len)) goto unknown_option; value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); len = strlen (value); switch (value [0]) { case 'c': if (0 != strncmp (value, "compress", len)) goto unknown_mode; o->mode = TRF_COMPRESS; break; case 'd': if (0 != strncmp (value, "decompress", len)) goto unknown_mode; o->mode = TRF_DECOMPRESS; break; default: unknown_mode: Tcl_AppendResult (interp, "unknown mode '", (char*) NULL); Tcl_AppendResult (interp, value, (char*) NULL); Tcl_AppendResult (interp, "', should be 'compress' or 'decompress'", (char*) NULL); return TCL_ERROR; break; } /* switch optvalue */ break; default: goto unknown_option; break; } return TCL_OK; unknown_option: Tcl_AppendResult (interp, "unknown option '", (char*) NULL); Tcl_AppendResult (interp, optname, (char*) NULL); Tcl_AppendResult (interp, "', should be '-level' or '-mode'", (char*) NULL); return TCL_ERROR; } /* *------------------------------------------------------* * * QueryOptions -- * * ------------------------------------------------* * Returns a value indicating wether the encoder or * decoder set of vectors is to be used by immediate * execution. * ------------------------------------------------* * * Sideeffects: * None * * Result: * 1 - use encoder vectors. * 0 - use decoder vectors. * *------------------------------------------------------* */ static int QueryOptions (options, clientData) Trf_Options options; ClientData clientData; { TrfZipOptionBlock* o = (TrfZipOptionBlock*) options; return (o->mode == TRF_COMPRESS ? 1 : 0); } trf2.1.4/generic/trfStubLib.c0000644000175000017500000000361611216344224015417 0ustar sergeisergei/* * trfStubLib.c -- * * Stub object that will be statically linked into extensions that wish * to access Trf. */ /* * 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 Trf_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 #ifndef USE_TRF_STUBS #define USE_TRF_STUBS #endif #undef USE_TRF_STUB_PROCS #include "transform.h" #include "trfIntDecls.h" /* * Ensure that Trf_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 TrfStubs *trfStubsPtr; TrfIntStubs *trfIntStubsPtr; /* *---------------------------------------------------------------------- * * Trf_InitStubs -- * * Checks that the correct version of Trf is loaded and that it * supports stubs. It then initialises the stub table pointers. * * Results: * The actual version of Trf that satisfies the request, or * NULL to indicate that an error occurred. * * Side effects: * Sets the stub table pointers. * *---------------------------------------------------------------------- */ #ifdef Trf_InitStubs #undef Trf_InitStubs #endif char * Trf_InitStubs(interp, version, exact) Tcl_Interp *interp; CONST char *version; int exact; { CONST char *actualVersion; actualVersion = Tcl_PkgRequireEx(interp, "Trf", (char *) version, exact, (ClientData *) &trfStubsPtr); if (!actualVersion) { return NULL; } if (!trfStubsPtr) { Tcl_SetResult(interp, "This implementation of Trf does not support stubs", TCL_STATIC); return NULL; } trfIntStubsPtr = trfStubsPtr->hooks->trfIntStubs; return (char*) actualVersion; } trf2.1.4/generic/templates/0000755000175000017500000000000011216344734015171 5ustar sergeisergeitrf2.1.4/generic/templates/cvt_template.c0000644000175000017500000003126211216344305020022 0ustar sergeisergei/* * XXX.c -- * * Implements and registers conversion from and to XXX representation. * * * Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: cvt_template.c,v 1.3 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Converter description * --------------------- */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, int character, Tcl_Interp* interp, ClientData clientData)); static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, int character, Tcl_Interp* interp, ClientData clientData)); static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned char* buffer, int bufLen, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "XXX", NULL, /* filled later (TrfInit_XXX) */ NULL, /* filled later (TrfInit_XXX) */ { CreateEncoder, DeleteEncoder, Encode, EncodeBuffer, FlushEncoder, ClearEncoder }, { CreateDecoder, DeleteDecoder, Decode, DecodeBuffer, FlushDecoder, ClearDecoder } }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (XXX) */ } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (XXX) */ } DecoderControl; /* *------------------------------------------------------* * * TrfInit_XXX -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_XXX (interp) Tcl_Interp* interp; { convDefinition.options = TrfYYYOptions (); return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (XXX) */ return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (XXX) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (XXX) */ } /* *------------------------------------------------------* * * EncodeBuffer -- * * ------------------------------------------------* * Encode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (XXX) */ } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (XXX) */ } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (XXX) */ } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (XXX) */ return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (XXX) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (XXX) */ } /* *------------------------------------------------------* * * DecodeBuffer -- * * ------------------------------------------------* * Decode the given buffer and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned char* buffer; int bufLen; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (XXX) */ } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (XXX) */ } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (XXX) */ } trf2.1.4/generic/templates/opt_template.c0000644000175000017500000001462311216344305020032 0ustar sergeisergei/* * xxx_opt.c -- * * Implements the C level procedures handling option processing * for XXX transformations. * * * Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: opt_template.c,v 1.2 1997/02/11 22:11:00 aku Exp $ */ #include "transformInt.h" /* * forward declarations of all internally used procedures. */ static Trf_Options CreateOptions _ANSI_ARGS_ ((ClientData clientData)); static void DeleteOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); static int CheckOptions _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST Trf_BaseOptions* baseOptions, ClientData clientData)); #if (TCL_MAJOR_VERSION >= 8) static int SetOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST Tcl_Obj* optvalue, ClientData clientData)); #else static int SetOption _ANSI_ARGS_ ((Trf_Options options, Tcl_Interp* interp, CONST char* optname, CONST char* optvalue, ClientData clientData)); #endif static int QueryOptions _ANSI_ARGS_ ((Trf_Options options, ClientData clientData)); /* *------------------------------------------------------* * * Trf_XXXOptions -- * * ------------------------------------------------* * Accessor to the set of vectors realizing option * processing for XXX procedures. * ------------------------------------------------* * * Sideeffects: * None. * * Result: * See above. * *------------------------------------------------------* */ Trf_OptionVectors* Trf_XXXOptions () { static Trf_OptionVectors optVec = { CreateOptions, DeleteOptions, CheckOptions, #if (TCL_MAJOR_VERSION >= 8) NULL, /* no string procedure */ SetOption, #else SetOption, NULL, /* no object procedure */ #endif QueryOptions }; return &optVec; } /* *------------------------------------------------------* * * CreateOptions -- * * ------------------------------------------------* * Create option structure for XXX transformations. * ------------------------------------------------* * * Sideeffects: * Allocates memory and initializes it as * option structure for XXX * transformations. * * Result: * A reference to the allocated block of * memory. * *------------------------------------------------------* */ static Trf_Options CreateOptions (clientData) ClientData clientData; { return (Trf_Options) NULL; } /* *------------------------------------------------------* * * DeleteOptions -- * * ------------------------------------------------* * Delete option structure of a XXX transformations * ------------------------------------------------* * * Sideeffects: * A memory block allocated by 'CreateOptions' * is released. * * Result: * None. * *------------------------------------------------------* */ static void DeleteOptions (options, clientData) Trf_Options options; ClientData clientData; { } /* *------------------------------------------------------* * * CheckOptions -- * * ------------------------------------------------* * Check the given option structure for errors. * ------------------------------------------------* * * Sideeffects: * May modify the given structure to set * default values into uninitialized parts. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int CheckOptions (options, interp, baseOptions, clientData) Trf_Options options; Tcl_Interp* interp; CONST Trf_BaseOptions* baseOptions; ClientData clientData; { return TCL_OK; } /* *------------------------------------------------------* * * SetOption -- * * ------------------------------------------------* * Define value of given option. * ------------------------------------------------* * * Sideeffects: * Sets the given value into the option * structure * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ static int SetOption (options, interp, optname, optvalue, clientData) Trf_Options options; Tcl_Interp* interp; CONST char* optname; #if (TCL_MAJOR_VERSION >= 8) CONST Tcl_Obj* optvalue; #else CONST char* optvalue; #endif ClientData clientData; { /* Possible options: * */ CONST char* value; int len = strlen (optname + 1); /* move into case-code if possible */ #if (TCL_MAJOR_VERSION >= 8) value = Tcl_GetStringFromObj ((Tcl_Obj*) optvalue, NULL); #else value = optvalue; #endif switch (optname [1]) { default: goto unknown_option; break; } return TCL_OK; unknown_option: ADD_RES (interp, "unknown option '"); ADD_RES (interp, optname); ADD_RES (interp, "'"); return TCL_ERROR; } /* *------------------------------------------------------* * * QueryOptions -- * * ------------------------------------------------* * Returns a value indicating wether the encoder or * decoder set of vectors is to be used by immediate * execution. * ------------------------------------------------* * * Sideeffects: * None * * Result: * 1 - use encoder vectors. * 0 - use decoder vectors. * *------------------------------------------------------* */ static int QueryOptions (options, clientData) Trf_Options options; ClientData clientData; { return 0; } trf2.1.4/generic/templates/md_template.c0000644000175000017500000001402311216344305017622 0ustar sergeisergei/* * xxx.c -- * * Implements and registers message digest generator XXX. * * * Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: md_template.c,v 1.1.1.1 1997/02/05 20:51:08 aku Exp $ */ #include "transformInt.h" #include "xxx/xxx.h" /* * Generator description * --------------------- * * The XXX alogrithm is used to compute a cryptographically strong * message digest. */ #define DIGEST_SIZE (0) #define CTX_TYPE XXX /* * Declarations of internal procedures. */ static void MD_Start _ANSI_ARGS_ ((VOID* context)); static void MD_Update _ANSI_ARGS_ ((VOID* context, int character)); static void MD_UpdateBuf _ANSI_ARGS_ ((VOID* context, char* buffer, int bufLen)); static void MD_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); static int MD_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { "xxx", sizeof (CTX_TYPE), DIGEST_SIZE, MD_Start, MD_Update, MD_UpdateBuf, MD_Final, MD_Check }; /* *------------------------------------------------------* * * TrfInit_XXX -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_XXX (interp) Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MD_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MD_Start (context) VOID* context; { /* call md specific initialization here */ } /* *------------------------------------------------------* * * MD_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MD_Update (context, character) VOID* context; int character; { char buf = character; /* call md specific update here */ } /* *------------------------------------------------------* * * MD_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MD_Updatebuf (context, buffer, bufLen) VOID* context; char* buffer; int bufLen; { sha_trf_info* s = context; if ((s->count + bufLen) < CHUNK_SIZE) { /* * Not enough for full chunk. Remember incoming * data and wait for another call containing more data. */ memcpy ((VOID*) (s->buf + s->count), (VOID*) buffer, bufLen); s->count += bufLen; } else { /* * Complete chunk with incoming data, update digest, * then use all chunks contained in the buffer. Remember * an incomplete chunk and wait for further calls. */ int k = CHUNK_SIZE - s->count; if (k < CHUNK_SIZE) { memcpy ((VOID*) (s->buf + s->count), (VOID*) buffer, k); sha_update (&s->s, s->buf, CHUNK_SIZE); buffer += k; bufLen -= k; } /* k == CHUNK_SIZE => internal buffer was empty, so skip it entirely */ while (bufLen > CHUNK_SIZE) { sha_update (&s->s, buffer, CHUNK_SIZE); buffer += CHUNK_SIZE; bufLen -= CHUNK_SIZE; } s->count = bufLen; if (bufLen > 0) memcpy ((VOID*) s->buf, (VOID*) buffer, bufLen); } } /* *------------------------------------------------------* * * MD_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MD_Final (context, digest) VOID* context; VOID* digest; { /* call md specific finalization here */ } /* *------------------------------------------------------* * * MD_Check -- * * ------------------------------------------------* * Check environment (required shared libs, ...). * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static int MD_Check (interp) Tcl_Interp* interp; { return TCL_OK; } /* * External code from here on. */ #include "xxx/xxx.c" trf2.1.4/generic/haval.c0000644000175000017500000001155111216344223014426 0ustar sergeisergei/* * haval.c -- * * Implements and registers message digest generator HAVAL. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: haval.c,v 1.4 2000/08/09 19:13:17 aku Exp $ */ #include "transformInt.h" #include "haval.1996/haval.h" /* * Generator description * --------------------- * * The HAVAL alogrithm is used to compute a cryptographically strong * message digest. */ #define DIGEST_SIZE (32) #define CTX_TYPE haval_state /* * Declarations of internal procedures. */ static void MDHaval_Start _ANSI_ARGS_ ((VOID* context)); static void MDHaval_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDHaval_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDHaval_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ "haval", sizeof (CTX_TYPE), DIGEST_SIZE, MDHaval_Start, MDHaval_Update, MDHaval_UpdateBuf, MDHaval_Final, NULL }; /* *------------------------------------------------------* * * TrfInit_HAVAL -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_HAVAL (interp) Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDHaval_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDHaval_Start (context) VOID* context; { haval_start ((CTX_TYPE*) context); } /* *------------------------------------------------------* * * MDHaval_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDHaval_Update (context, character) VOID* context; unsigned int character; { unsigned char buf = character; haval_hash ((CTX_TYPE*) context, &buf, 1); } /* *------------------------------------------------------* * * MDHaval_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDHaval_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { haval_hash ((CTX_TYPE*) context, (unsigned char*) buffer, bufLen); } /* *------------------------------------------------------* * * MDHaval_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDHaval_Final (context, digest) VOID* context; VOID* digest; { haval_end ((CTX_TYPE*) context, (unsigned char*) digest); } /* * External code from here on. */ #include "haval.1996/haval.c" /* THREADING: import of one constant var, read-only => safe */ trf2.1.4/generic/binio.c0000644000175000017500000006264011216344223014440 0ustar sergeisergei /* * binio.c -- * * Implementation of a binary input and output. * * Copyright (c) Jan 1997, Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: binio.c,v 1.11 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" #ifdef ENABLE_BINIO #include /* * Forward declarations of internal procedures. */ static int CopyCmd _ANSI_ARGS_((Tcl_Interp *interp, int argc, char** argv)); static int PackCmd _ANSI_ARGS_((Tcl_Interp *interp, int argc, char** argv)); static int UnpackCmd _ANSI_ARGS_((Tcl_Interp *interp, int argc, char** argv)); static int BinioCmd _ANSI_ARGS_((ClientData notUsed, Tcl_Interp* interp, int argc, char** argv)); static void ReorderBytes _ANSI_ARGS_ ((char* buf, int len /*2,4,8*/)); static int GetHex _ANSI_ARGS_ ((Tcl_Interp* interp, char* text, long int* result)); static int GetOctal _ANSI_ARGS_ ((Tcl_Interp* interp, char* text, long int* result)); /* * Return at most this number of bytes in one call to Tcl_Read: */ #define KILO 1024 #ifndef READ_CHUNK_SIZE #define READ_CHUNK_SIZE (16*KILO) #endif /* * Union to overlay the different possible types used in 'pack', 'unpack'. */ typedef union { double d; float f; long int li; unsigned long ul; int i; unsigned int ui; short int si; unsigned short us; char c; unsigned char uc; } conversion; /* *------------------------------------------------------* * * CopyCmd -- * * ------------------------------------------------* * This procedure realizes the 'binio copy' command. * See the manpages for details on what it does. * ------------------------------------------------* * * Sideeffects: * See user documentation. * * Result: * A standard tcl error code. * *------------------------------------------------------* */ /* ARGSUSED */ static int CopyCmd (interp, argc, argv) Tcl_Interp* interp; /* The interpreter we are working in */ int argc; /* # arguments */ char** argv; /* trailing arguments */ { /* * Allowed syntax: * inChannel outChannel ?count? * * code taken from 'unsupported0'. */ Tcl_Channel inChan, outChan; int requested; char *bufPtr; int actuallyRead, actuallyWritten, totalRead, toReadNow, mode; /* * Assume we want to copy the entire channel. */ requested = INT_MAX; if ((argc < 2) || (argc > 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"binio copy inChannel outChannel ?chunkSize?\"", (char *) NULL); return TCL_ERROR; } inChan = Tcl_GetChannel(interp, argv[0], &mode); if (inChan == (Tcl_Channel) NULL) { return TCL_ERROR; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", argv[0], "\" wasn't opened for reading", (char *) NULL); return TCL_ERROR; } outChan = Tcl_GetChannel(interp, argv[1], &mode); if (outChan == (Tcl_Channel) NULL) { return TCL_ERROR; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", argv[1], "\" wasn't opened for writing", (char *) NULL); return TCL_ERROR; } if (argc == 3) { if (Tcl_GetInt(interp, argv[2], &requested) != TCL_OK) { return TCL_ERROR; } if (requested < 0) { requested = INT_MAX; } } bufPtr = ckalloc((unsigned) READ_CHUNK_SIZE); for (totalRead = 0; requested > 0; totalRead += actuallyRead, requested -= actuallyRead) { toReadNow = requested; if (toReadNow > READ_CHUNK_SIZE) { toReadNow = READ_CHUNK_SIZE; } actuallyRead = Tcl_Read(inChan, bufPtr, toReadNow); if (actuallyRead < 0) { ckfree (bufPtr); Tcl_AppendResult(interp, argv[0], ": ", Tcl_GetChannelName(inChan), Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } else if (actuallyRead == 0) { ckfree (bufPtr); sprintf(interp->result, "%d", totalRead); return TCL_OK; } actuallyWritten = Tcl_Write(outChan, bufPtr, actuallyRead); if (actuallyWritten < 0) { ckfree (bufPtr); Tcl_AppendResult(interp, argv[0], ": ", Tcl_GetChannelName(outChan), Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } } ckfree(bufPtr); sprintf(interp->result, "%d", totalRead); return TCL_OK; } /* *------------------------------------------------------* * * PackCmd -- * * ------------------------------------------------* * This procedure realizes the 'binio pack' command. * See the manpages for details on what it does. * ------------------------------------------------* * * Sideeffects: * See user documentation. * * Result: * A standard tcl error code. * *------------------------------------------------------* */ /* ARGSUSED */ static int PackCmd (interp, argc, argv) Tcl_Interp* interp; /* The interpreter we are working in */ int argc; /* # arguments */ char** argv; /* trailing arguments */ { Tcl_Channel outChan; /* The channel to write to */ char* format; conversion cvt; char buffer [50]; char* bufPtr = (char*) NULL; int bufLen = 0; int packed, actuallyWritten, reorder, mode; /* * Allowed syntax: * outChannel format ?data1 data2 ...? */ if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"binio pack outChannel format ?data1 data2 ...?\"", (char *) NULL); return TCL_ERROR; } outChan = Tcl_GetChannel(interp, argv[0], &mode); if (outChan == (Tcl_Channel) NULL) { return TCL_ERROR; } if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, "channel \"", argv[0], "\" wasn't opened for writing", (char *) NULL); return TCL_ERROR; } format = argv [1]; argc -= 2; argv += 2; for (packed = 0 ; format [0] != '\0'; format += 2, argc --, argv ++, packed ++) { if (format [0] != '%') { char buf [3]; buf [0] = format [0]; buf [1] = format [1]; buf [2] = '\0'; Tcl_AppendResult (interp, "unknown format specification '", buf, "'", (char*) NULL); return TCL_ERROR; } if (argc == 0) { Tcl_AppendResult (interp, "more format specifiers than data items", (char*) NULL); return TCL_ERROR; } reorder = 1; /* prepare for usual case */ /* * Possible specifications: * - %d specifies that the corresponding value is a four byte signed int. * - %u specifies that the corresponding value is a four byte unsigned int. * - %o specifies that the corresponding value is a four byte octal signed int. * - %x specifies that the corresponding value is a four byte hexadecimal signed int. * - %l specifies that the corresponding value is an eight byte signed int. * - %L specifies that the corresponding value is an eight byte unsigned int. * - %D specifies that the corresponding value is a two byte signed int. * - %U specifies that the corresponding value is a two byte unsigned int. * - %O specifies that the corresponding value is a two byte octal signed int. * - %X specifies that the corresponding value is a two byte hexadecimal signed int. * - %c specifies that the corresponding value is a one byte signed int (char). * - %C specifies that the corresponding value is a one byte unsigned int. * - %f specifies that the corresponding value is a four byte floating point number. * - %F specifies that the corresponding value is an eight byte floating point number. * - %s specifies that the corresponding value is a NULL terminated string. */ switch (format [1]) { case 'd': case 'u': case 'l': case 'L': case 'D': case 'U': case 'c': case 'C': if (TCL_OK != Tcl_GetInt (interp, argv [0], &cvt.i)) { return TCL_ERROR; } switch (format [1]) { case 'd': bufPtr = (char*) &cvt.i; bufLen = sizeof (int); break; case 'u': cvt.ui = (unsigned int) cvt.i; bufPtr = (char*) &cvt.ui; bufLen = sizeof (unsigned int); break; case 'l': cvt.li = (long int) cvt.i; bufPtr = (char*) &cvt.li; bufLen = sizeof (long int); break; case 'L': cvt.ul = (unsigned long) cvt.i; bufPtr = (char*) &cvt.ul; bufLen = sizeof (unsigned long); break; case 'D': cvt.si = (short int) cvt.i; bufPtr = (char*) &cvt.si; bufLen = sizeof (short int); break; case 'U': cvt.us = (short int) cvt.i; bufPtr = (char*) &cvt.us; bufLen = sizeof (unsigned short); break; case 'c': cvt.c = (char) cvt.i; bufPtr = (char*) &cvt.c; bufLen = sizeof (char); break; case 'C': cvt.uc = (unsigned char) cvt.i; bufPtr = (char*) &cvt.uc; bufLen = sizeof (unsigned char); break; } /* switch */ break; case 'o': case 'O': if (TCL_OK != GetOctal (interp, argv [0], &cvt.li)) { return TCL_ERROR; } if (format [1] == 'O') { cvt.si = (short int) cvt.i; bufPtr = (char*) &cvt.si; bufLen = sizeof (short int); } else { cvt.i = (int) cvt.li; bufPtr = (char*) &cvt.i; bufLen = sizeof (int); } break; case 'x': case 'X': if (TCL_OK != GetHex (interp, argv [0], &cvt.li)) { return TCL_ERROR; } if (format [1] == 'X') { cvt.si = (short int) cvt.i; bufPtr = (char*) &cvt.si; bufLen = sizeof (short int); } else { cvt.i = (int) cvt.li; bufPtr = (char*) &cvt.i; bufLen = sizeof (int); } break; case 'f': case 'F': if (TCL_OK != Tcl_GetDouble (interp, argv [0], &cvt.d)) { return TCL_ERROR; } if (format [1] == 'f') { cvt.f = (float) cvt.d; bufPtr = (char*) &cvt.f; bufLen = sizeof (float); } else { bufPtr = (char*) &cvt.d; bufLen = sizeof (double); } break; case 's': bufPtr = argv [0]; bufLen = strlen (argv [0]); reorder = 0; break; } /* switch */ /* check, wether reordering is required or not. * upon answer `yes` do the reordering here too. */ if ((bufLen > 1) && reorder && (Tcl_GetHostByteorder () != Tcl_GetChannelByteorder (outChan))) { ReorderBytes (bufPtr, bufLen); } actuallyWritten = Tcl_Write (outChan, bufPtr, bufLen); if (actuallyWritten < 0) { Tcl_AppendResult(interp, "binio pack: ", Tcl_GetChannelName(outChan), Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } } /* for (format) */ /* return number of packed items */ sprintf (buffer, "%d", packed); Tcl_AppendResult (interp, buffer, (char*) NULL); return TCL_OK; } /* *------------------------------------------------------* * * UnpackCmd -- * * ------------------------------------------------* * This procedure realizes the 'binio unpack' command. * See the manpages for details on what it does. * ------------------------------------------------* * * Sideeffects: * See user documentation. * * Result: * A standard tcl error code. * *------------------------------------------------------* */ /* ARGSUSED */ static int UnpackCmd (interp, argc, argv) Tcl_Interp* interp; /* The interpreter we are working in */ int argc; /* # arguments */ char** argv; /* trailing arguments */ { Tcl_Channel inChan; /* The channel to read from */ conversion cvt; int mode, unpacked, actuallyRead; int length; /* length of single item, * < 0 => variable length (string) * 0 is illegal. */ char buffer [50]; /* to hold most of the read information (and its conversion) */ char* format; char* val; /* * Allowed syntax: * format ?var1 var2 ...? */ if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"binio unpack outChannel format ?var1 var2 ...?\"", (char *) NULL); return TCL_ERROR; } inChan = Tcl_GetChannel(interp, argv[0], &mode); if (inChan == (Tcl_Channel) NULL) { return TCL_ERROR; } if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, "channel \"", argv[0], "\" wasn't opened for reading", (char *) NULL); return TCL_ERROR; } if (Tcl_Eof (inChan)) { /* * cannot convert behind end of channel. * no error, just unpack nothing ! */ Tcl_AppendResult (interp, "0", (char*) NULL); return TCL_OK; } format = argv [1]; argc -= 2; argv += 2; for (unpacked = 0 ; format [0] != '\0'; format += 2, argc --, argv ++, unpacked ++) { if (format [0] != '%') { char buf [3]; buf [0] = format [0]; buf [1] = format [1]; buf [2] = '\0'; Tcl_AppendResult (interp, "unknown format specification '", buf, "'", (char*) NULL); return TCL_ERROR; } if (argc == 0) { Tcl_AppendResult (interp, "more format specifiers than variables", (char*) NULL); return TCL_ERROR; } length = 0; /* illegal marker, to catch missing cases later */ /* * Possible specifications: * - %d specifies that the corresponding value is a four byte signed int. * - %u specifies that the corresponding value is a four byte unsigned int. * - %o specifies that the corresponding value is a four byte octal signed int. * - %x specifies that the corresponding value is a four byte hexadecimal signed int. * - %f specifies that the corresponding value is a four byte floating point number. * * - %l specifies that the corresponding value is an eight byte signed int. * - %L specifies that the corresponding value is an eight byte unsigned int. * - %F specifies that the corresponding value is an eight byte floating point number. * * - %D specifies that the corresponding value is a two byte signed int. * - %U specifies that the corresponding value is a two byte unsigned int. * - %O specifies that the corresponding value is a two byte octal signed int. * - %X specifies that the corresponding value is a two byte hexadecimal signed int. * * - %c specifies that the corresponding value is a one byte signed int (char). * - %C specifies that the corresponding value is a one byte unsigned int. * * - %s specifies that the corresponding value is a NULL terminated string. */ /* first: determine number of bytes required, then read these. * at last do the conversion and write into the associated variable. */ switch (format [1]) { case 'l': case 'L': #if SIZEOF_LONG_INT != 8 Tcl_AppendResult (interp, "binio unpack: %l / %L not supported, no 8byte integers here", NULL); return TCL_ERROR; #endif case 'F': length = 8; break; case 'd': case 'u': case 'o': case 'x': case 'f': length = 4; break; case 'D': case 'U': case 'O': case 'X': length = 2; break; case 'c': case 'C': length = 1; break; case 's': length = -1; /* variable length, string terminated by '\0'. */ break; } if (length == 0) { format [2] = '\0'; Tcl_AppendResult (interp, "binio unpack: internal error, missing case for format ", format, NULL); return TCL_ERROR; } else if (length < 0) { /* variable length, string terminated by '\0'. (%s) */ Tcl_DString data; Tcl_DStringInit (&data); while (! Tcl_Eof (inChan)) { actuallyRead = Tcl_Read (inChan, buffer, 1); if (actuallyRead < 0) { Tcl_AppendResult(interp, "binio unpack: ", Tcl_GetChannelName(inChan), Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } else if (actuallyRead > 0) { Tcl_DStringAppend (&data, buffer, 1); if (buffer [0] == '\0') { break; } } } /* while */ val = Tcl_SetVar (interp, argv [0], data.string, TCL_LEAVE_ERR_MSG); Tcl_DStringFree (&data); if (val == NULL) { return TCL_ERROR; } } else { /* handle item with fixed lengths */ actuallyRead = Tcl_Read (inChan, buffer, length); if (actuallyRead < 0) { Tcl_AppendResult(interp, "binio unpack: ", Tcl_GetChannelName(inChan), Tcl_PosixError(interp), (char *) NULL); return TCL_ERROR; } /* check, wether reordering is required or not. * upon answer `yes` do the reordering here too. */ if ((length > 1) && (Tcl_GetHostByteorder () != Tcl_GetChannelByteorder (inChan))) { ReorderBytes (buffer, length); } switch (format [1]) { case 'd': #if SIZEOF_INT == 4 /* 'int' is our 4 byte integer on this machine */ memcpy ((VOID*) &cvt.i, (VOID*) buffer, length); sprintf (buffer, "%d", cvt.i); #else /* 'int' seems to be equal to 'short' (2 byte), so use 'long int' instead */ memcpy ((VOID*) &cvt.li, (VOID*) buffer, length); sprintf (buffer, "%ld", cvt.li); #endif break; case 'o': #if SIZEOF_INT == 4 /* 'int' is our 4 byte integer on this machine */ memcpy ((VOID*) &cvt.i, (VOID*) buffer, length); sprintf (buffer, "%o", cvt.i); #else /* 'int' seems to be equal to 'short' (2 byte), so use 'long int' instead */ memcpy ((VOID*) &cvt.li, (VOID*) buffer, length); sprintf (buffer, "%lo", cvt.li); #endif break; case 'x': #if SIZEOF_INT == 4 /* 'int' is our 4 byte integer on this machine */ memcpy ((VOID*) &cvt.i, (VOID*) buffer, length); sprintf (buffer, "%08x", cvt.i); #else /* 'int' seems to be equal to 'short' (2 byte), so use 'long int' instead */ memcpy ((VOID*) &cvt.li, (VOID*) buffer, length); sprintf (buffer, "%08lx", cvt.li); #endif break; case 'u': #if SIZEOF_INT == 4 /* 'unsigned int' is our 4 byte integer on this machine */ memcpy ((VOID*) &cvt.ui, (VOID*) buffer, length); sprintf (buffer, "%u", cvt.ui); #else /* 'int' seems to be equal to 'short' (2 byte), so use 'unsigned long' instead */ memcpy ((VOID*) &cvt.ul, (VOID*) buffer, length); sprintf (buffer, "%lu", cvt.ul); #endif break; case 'D': /* 'short int' is our 2 byte integer on this machine */ memcpy ((VOID*) &cvt.si, (VOID*) buffer, length); sprintf (buffer, "%d", cvt.si); break; case 'O': /* 'short int' is our 2 byte integer on this machine */ memcpy ((VOID*) &cvt.si, (VOID*) buffer, length); sprintf (buffer, "%o", cvt.si); break; case 'X': /* 'short int' is our 2 byte integer on this machine */ memcpy ((VOID*) &cvt.si, (VOID*) buffer, length); sprintf (buffer, "%04x", cvt.si); break; case 'U': /* 'unsigned short' is our 2 byte integer on this machine */ memcpy ((VOID*) &cvt.us, (VOID*) buffer, length); sprintf (buffer, "%u", cvt.us); break; case 'l': /* assume SIZEOF_LONG_INT == 8 */ memcpy ((VOID*) &cvt.li, (VOID*) buffer, length); sprintf (buffer, "%ld", cvt.li); break; case 'L': /* assume SIZEOF_LONG_INT == 8 */ memcpy ((VOID*) &cvt.ul, (VOID*) buffer, length); sprintf (buffer, "%lu", cvt.ul); break; case 'c': memcpy ((VOID*) &cvt.c, (VOID*) buffer, length); cvt.i = cvt.c; sprintf (buffer, "%d", cvt.i); break; case 'C': memcpy ((VOID*) &cvt.uc, (VOID*) buffer, length); cvt.ui = cvt.uc; sprintf (buffer, "%u", cvt.ui); break; case 'f': memcpy ((VOID*) &cvt.f, (VOID*) buffer, length); sprintf (buffer, "%f", cvt.f); break; case 'F': memcpy ((VOID*) &cvt.d, (VOID*) buffer, length); sprintf (buffer, "%f", cvt.d); break; case 's': Tcl_AppendResult (interp, "binio unpack: internal error, wrong branch for %s", NULL); return TCL_ERROR; break; } /* switch */ val = Tcl_SetVar (interp, argv [0], buffer, TCL_LEAVE_ERR_MSG); if (val == NULL) { return TCL_ERROR; } } /* if (length < 0) */ } /* for (format) */ /* return number of unpacked items */ sprintf (buffer, "%d", unpacked); Tcl_AppendResult (interp, buffer, (char*) NULL); return TCL_OK; } /* *------------------------------------------------------* * * ReorderBytes -- * * ------------------------------------------------* * This procedure reorders the bytes in a buffer to * match real and intended byteorder. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * The incoming buffer 'buf' contains the * reorderd bytes. * *------------------------------------------------------* */ static void ReorderBytes (buf, len) char* buf; int len; { #define FLIP(a,b) c = buf [a]; buf [a] = buf [b]; buf [b] = c; char c; if (len == 2) { FLIP (0,1); } else if (len == 4) { FLIP (0,3); FLIP (1,2); } else if (len == 8) { FLIP (0,7); FLIP (1,6); FLIP (2,5); FLIP (3,4); } else { Tcl_Panic ("unknown buffer size %d", len); } } /* *------------------------------------------------------* * * GetHex -- * * ------------------------------------------------* * Read a string containing a number in hexadecimal * representation and convert it into a long integer. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * 'result' contains the conversion result. * A standard tcl error code. * *------------------------------------------------------* */ static int GetHex (interp, text, result) Tcl_Interp* interp; char* text; long int* result; { int match; match = sscanf (text, "%lx", result); if (match != 1) { Tcl_AppendResult (interp, "expected hexadecimal integer, but got \"", text, "\"", (char*) NULL); return TCL_ERROR; } return TCL_OK; } /* *------------------------------------------------------* * * GetOctal -- * * ------------------------------------------------* * Read a string containing a number in octal * representation and convert it into a long integer. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * 'result' contains the conversion result. * A standard tcl error code. * *------------------------------------------------------* */ static int GetOctal (interp, text, result) Tcl_Interp* interp; char* text; long int* result; { int match; match = sscanf (text, "%lo", result); if (match != 1) { Tcl_AppendResult (interp, "expected octal integer, but got \"", text, "\"", (char*) NULL); return TCL_ERROR; } return TCL_OK; } /* *------------------------------------------------------* * * BinioCmd -- * * ------------------------------------------------* * This procedure realizes the 'binio' command. * See the manpages for details on what it does. * ------------------------------------------------* * * Sideeffects: * See the user documentation. * * Result: * A standard Tcl result. * *------------------------------------------------------* */ /* ARGSUSED */ static int BinioCmd (notUsed, interp, argc, argv) ClientData notUsed; /* Not used. */ Tcl_Interp* interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char** argv; /* Argument strings. */ { /* * Allowed syntax: * * binio copy inChannel outChannel ?count? * binio pack outChannel format ?data1 data2 ...? * binio unpack inChannel format ?var1 var2 ...? */ int len; char c; Tcl_Channel a; int mode; if (argc < 3) { Tcl_AppendResult (interp, "wrong # args: should be \"binio option channel ?arg arg...?\"", (char*) NULL); return TCL_ERROR; } c = argv [1][0]; len = strlen (argv [1]); a = Tcl_GetChannel (interp, argv [2], &mode); if (a == (Tcl_Channel) NULL) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "binio ", argv [1], ": channel expected as 2nd argument, got \"", argv [2], "\"", (char*) NULL); return TCL_ERROR; } switch (c) { case 'c': if (0 == strncmp (argv [1], "copy", len)) { return CopyCmd (interp, argc - 2, argv + 2); } else goto unknown_option; break; case 'p': if (0 == strncmp (argv [1], "pack", len)) { return PackCmd (interp, argc - 2, argv + 2); } else goto unknown_option; break; case 'u': if (0 == strncmp (argv [1], "unpack", len)) { return UnpackCmd (interp, argc - 2, argv + 2); } else goto unknown_option; break; default: unknown_option: Tcl_AppendResult (interp, "binio: bad option \"", argv [1], "\": should be one of copy, pack or unpack", (char*) NULL); return TCL_ERROR; } return TCL_OK; } #endif /* ENABLE_BINIO */ /* *------------------------------------------------------* * * TrfInit_Binio -- * * ------------------------------------------------* * Initializes this command. * ------------------------------------------------* * * Sideeffects: * As of 'Tcl_CreateCommand'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_Binio (interp) Tcl_Interp* interp; { #ifdef ENABLE_BINIO Tcl_CreateCommand (interp, "binio", BinioCmd, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); #endif /* ENABLE_BINIO */ return TCL_OK; } trf2.1.4/generic/zlib.c0000644000175000017500000000353211216344224014274 0ustar sergeisergei/* * zlib.c -- * * Loader for 'zlib' compression library. * * Copyright (c) 1996 Jan Nijtmans (nijtmans.nici.kun.nl) * All rights reserved. * * CVS: $Id: zlib.c,v 1.15 2003/01/09 21:27:12 andreas_kupries Exp $ */ #include "transformInt.h" #ifdef __WIN32__ #define Z_LIB_NAME "zlib.dll" #endif #ifndef Z_LIB_NAME #define Z_LIB_NAME LIBZ_DEFAULTNAME #endif static char* symbols [] = { "deflate", "deflateEnd", "deflateInit2_", "deflateReset", "inflate", "inflateEnd", "inflateInit2_", "inflateReset", "adler32", "crc32", (char *) NULL }; /* * Global variable containing the vectors into the 'zlib'-library. */ #ifdef ZLIB_STATIC_BUILD zFunctions zf = { 0, deflate, deflateEnd, deflateInit_, deflateReset, inflate, inflateEnd, inflateInit_, inflateReset, adler32, crc32, }; #else zFunctions zf = {0}; /* THREADING: serialize initialization */ #endif int TrfLoadZlib (interp) Tcl_Interp* interp; { #ifndef ZLIB_STATIC_BUILD int res; #ifdef HAVE_zlibtcl_PACKAGE /* Try to use zlibtcl first. This makes loading much easier. */ if (Zlibtcl_InitStubs(interp, ZLIBTCL_VERSION, 0) != NULL) { /* * Copy stub information into the table the rest of Trf is using. */ zf.handle = 0; zf.zdeflate = deflate ; zf.zdeflateEnd = deflateEnd ; zf.zdeflateInit2_ = deflateInit2_; zf.zdeflateReset = deflateReset ; zf.zinflate = inflate ; zf.zinflateEnd = inflateEnd ; zf.zinflateInit2_ = inflateInit2_; zf.zinflateReset = inflateReset ; zf.zadler32 = adler32 ; zf.zcrc32 = crc32 ; return TCL_OK; } #endif TrfLock; /* THREADING: serialize initialization */ res = Trf_LoadLibrary (interp, Z_LIB_NAME, (VOID**) &zf, symbols, 10); TrfUnlock; return res; #else return TCL_OK; #endif } trf2.1.4/generic/crc.h0000644000175000017500000000361111216344305014106 0ustar sergeisergei#ifndef CRC_H #define CRC_H /* * Everything in here is taken from PGP */ #define CRCBITS 24 /* may be 16, 24, or 32 */ #define CRCBYTES 3 /* may be 2, 3, or 4 */ #ifdef __alpha #define crcword unsigned int /* if CRCBITS is 24 or 32 */ #else #define crcword unsigned long /* if CRCBITS is 24 or 32 */ #endif #define CCITTCRC 0x1021 /* CCITT's 16-bit CRC generator polynomial */ #define PRZCRC 0x864cfbL /* PRZ's 24-bit CRC generator polynomial */ #define CRCINIT 0xB704CEL /* Init value for CRC accumulator */ #if (CRCBITS == 16) || (CRCBITS == 32) #define maskcrc(crc) ((crcword) (crc)) /* if CRCBITS is 16 or 32 */ #else #define maskcrc(crc) ((crc) & 0xffffffL) /* if CRCBITS is 24 */ #endif #define CRCHIBIT ((crcword) (1L<<(CRCBITS-1))) /* 0x8000 if CRCBITS is 16 */ #define CRCSHIFTS (CRCBITS-8) /* Notes on making a good 24-bit CRC-- The primitive irreducible polynomial of degree 23 over GF(2), 040435651 (octal), comes from Appendix C of "Error Correcting Codes, 2nd edition" by Peterson and Weldon, page 490. This polynomial was chosen for its uniform density of ones and zeros, which has better error detection properties than polynomials with a minimal number of nonzero terms. Multiplying this primitive degree-23 polynomial by the polynomial x+1 yields the additional property of detecting any odd number of bits in error, which means it adds parity. This approach was recommended by Neal Glover. To multiply the polynomial 040435651 by x+1, shift it left 1 bit and bitwise add (xor) the unshifted version back in. Dropping the unused upper bit (bit 24) produces a CRC-24 generator bitmask of 041446373 octal, or 0x864cfb hex. You can detect spurious leading zeros or framing errors in the message by initializing the CRC accumulator to some agreed-upon nonzero "random-like" value, but this is a bit nonstandard. */ #endif /* CRC */ trf2.1.4/generic/otpmd5.c0000644000175000017500000000052411216344223014541 0ustar sergeisergei/* otpmd5.c - the OTP variant of MD5 */ /* ideally we would like to define a new argument in dig_opt.c that allows us to turn the OTP variant on and off. unfortunately, the variant dictates the size of the resulting digest and that's one thing that's compile time. hence, the hack du'jour... */ #define OTP #include "md5dig.c" trf2.1.4/generic/trfStubInit.c0000644000175000017500000000163711216344224015615 0ustar sergeisergei/* * trfStubInit.c -- * * This file contains the initializers for the Trf stub vectors. * */ #include "transformInt.h" /* * 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/trf.decls script. */ /* !BEGIN!: Do not edit below this line. */ TrfIntStubs trfIntStubs = { TCL_STUB_MAGIC, NULL, }; static TrfStubHooks trfStubHooks = { &trfIntStubs }; TrfStubs trfStubs = { TCL_STUB_MAGIC, &trfStubHooks, Trf_IsInitialized, /* 0 */ Trf_Register, /* 1 */ Trf_ConverterOptions, /* 2 */ Trf_LoadLibrary, /* 3 */ Trf_LoadFailed, /* 4 */ Trf_RegisterMessageDigest, /* 5 */ Trf_XorBuffer, /* 6 */ Trf_ShiftRegister, /* 7 */ Trf_FlipRegisterLong, /* 8 */ Trf_FlipRegisterShort, /* 9 */ }; /* !END!: Do not edit above this line. */ trf2.1.4/generic/sha/0000755000175000017500000000000011216344734013746 5ustar sergeisergeitrf2.1.4/generic/sha/header.txt0000644000175000017500000000043711216343142015733 0ustar sergeisergei# The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: sha.c sha.h sha_driver.c sha.good.outputs Makefile # appgen.c # Wrapped by uweh@taylor.src.umd.edu on Sat Nov 5 17:12:49 1994 trf2.1.4/generic/sha/appgen.c0000644000175000017500000000050111216343142015350 0ustar sergeisergei#include #include int main(int c, char **v) { int i, t; t = atoi(v[1]); if (t == 3) { for (i = 0; i < 1000000; ++i) { putchar('a'); } } else if (t == 2) { printf("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); } else { printf("abc"); } return(0); } trf2.1.4/generic/sha/sha_driver.c0000644000175000017500000000104111216343142016224 0ustar sergeisergei/* NIST Secure Hash Algorithm */ #include #include #include #include #include "sha.h" int main(int argc, char **argv) { FILE *fin; SHA_INFO sha_info; if (argc < 2) { fin = stdin; sha_stream(&sha_info, fin); sha_print(&sha_info); } else { while (--argc) { fin = fopen(*(++argv), "rb"); if (fin == NULL) { printf("error opening %s for reading\n", *argv); } else { sha_stream(&sha_info, fin); sha_print(&sha_info); fclose(fin); } } } return(0); } trf2.1.4/generic/sha/nist_secure_hash_specs.txt0000644000175000017500000006620211216343142021230 0ustar sergeisergei Federal Information Processing Standards Publication YY DRAFT 1992 January 22 DRAFT Specifications for a SECURE HASH STANDARD (SHS) 1. INTRODUCTION The Secure Hash Algorithm (SHA) specified in this standard is necessary to ensure the security of the Digital Signature Standard. When a message of length < 2^64 bits is input, the SHA produces a 160-bit representation of the message called the message digest. The message digest is used during generation of a signature for the message. The same message digest should be computed for the received version of the message, during the process of verifying the signature. Any change to the message in transit will, with very high probability, result in a different message digest, and the signature will fail to verify. The SHA is designed to have the following properties: it is computationally infeasible to recover a message corresponding to a given message digest, or to find two different messages which produce the same message digest. 2. BIT STRINGS AND INTEGERS The following terminology related to bit strings and integers will be used: a. hex digit = 0, 1, ... , 9, a, ... , f. A hex digit is the representation of a 4-bit string. Examples: 7 = 0111, a = 1010. b. word = 32-bit string b(31) b(30) ... b(0). A word may be represented as a sequence of 8 hex digits. To convert the latter to a 32-bit string, each hex digit is converted to a 4-bit string as in (a). Example: a103fe23 = 1010 0001 0000 0011 1111 1110 0010 0011. A word is also the representation of an unsigned integer between 0 and 2^32 - 1, inclusive, with the most significant bit first. Example: the hex string a103fe23 represents the decimal integer 2701393443. c. block = 512-bit string. A block may be represented as a sequence of 16 words. d. integer: each integer x in the standard will satisfy 0 <= x < 2^64. For the purpose of this standard, "integer" and "unsigned integer" are equivalent. If an integer x satisfies 0 <= x < 2^32, x may be represented as a word as in (b). If 2^32 <= x < 2^64, then x = 2^32 y + z where 0 <= y < 2^32 and 0 <= z < 2^32. Hence y and z can be represented as words A and B, respectively, and x can be represented as the pair of words (A,B). Suppose 0 <= x < 2^32. To convert x to a 32-bit string, the following algorithm may be employed: y(0) = x; for i = 0 to 31 do { b(i) = 1 if y(i) is odd, b(i) = 0 if y(i) is even; y(i+1) = (y(i) - b(i))/2; } Then x has the 32-bit representation b(31) b(30) ... b(0). Example: 25 = 00000000 00000000 00000000 00011001 = hex 00000019. If 2^32 <= x < 2^64, the 2-word representation of x is obtained similarly. Example: 2^35 + 25 = 8 * 2^32 + 25 = 00000000 00000000 00000000 00001000 00000000 00000000 00000000 00011001 = hex 00000008 00000019. Conversely, the string b(31) b(30) ... b(0) represents the integer b(31) * 2^31 + b(30) * 2^30 + ... + b(1) * 2 + b(0). 3. OPERATIONS ON WORDS The following logical operators will be applied to words: AND = bitwise logical and. OR = bitwise logical inclusive-or. XOR = bitwise logical exclusive-or. ~x = bitwise logical complement of x. Example: 01101100101110011101001001111011 XOR 01100101110000010110100110110111 -------------------------------- = 00001001011110001011101111001100. Another operation on words is A + B. This is defined as follows: words A and B represent integers x and y, where 0 <= x < 2^32 and 0 <= y < 2^32. Compute z = (x + y) mod 2^32. Then 0 <= z < 2^32. Convert z to a word, C, and define A + B = C. Another function on words is S(n,X), where X is a word and n is an integer with 0 <= n < 32. This is defined by S(n,X) = (X << n) OR (X >> 32-n). In the above, X << n is obtained as follows: discard the leftmost n bits of X and then pad the result with n zeroes on the right (the result will still be 32 bits). X >> m is obtained by discarding the rightmost m bits of X and then padding the result with m zeroes on the left. Thus S(n,X) is equivalent to a circular shift of X by n positions to the left. 4. MESSAGE PADDING The SHA takes bit strings as input. Thus, for the purpose of this standard, a message will be considered to be a bit string. The length of the message is the number of bits (the empty message has length 0). If the number of bits in a message is a multiple of 8, for compactness we can represent the message in hex. Suppose a message has length L < 2^64. Before it is input to the SHA, the message is padded on the right as follows: a. "1" is appended. Example: if the original message is "01010011", this is padded to "010100111". b. If necessary, "0"s are then appended until the number of bits in the padded message is congruent to 448 modulo 512. Example: suppose the original message is the bit string 01100001 01100010 01100011 01100100 01100101. After step (a) this gives 01100001 01100010 01100011 01100100 01100101 1. The number of bits in the above is 41; we pad with 407 "0"s to make the length of the padded message congruent to 448 modulo 512. This gives (in hex) 61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000. Note that the padding is arranged so that at this point the padded message contains 16s + 14 words, for some s >= 0. c. Obtain the 2-word representation of L = the number of bits in the original message. If L < 2^32 then the first word is all zeroes. Append these two words to the padded message. Example: suppose the original message is as in (b). Then L = 40 (note that L is computed before any padding). The two-word representation of 40 is hex 00000000 00000028. Hence the final padded message is hex 61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000028. The final padded message will contain 16N words for some N > 0. Example: in (c) above, the final padded message has N = 1. The final padded message may be regarded as a sequence of N blocks M(1) , M(2), ... , M(N), where each M(i) contains 16 words and M(1) is leftmost. 5. FUNCTIONS USED A sequence of logical functions f(0,x,y,z), ... , f(79,x,y,z) is used in the SHA. Each f operates on three 32-bit words {x,y,z} and produces a 32-bit word as output. f(t,x,y,z) is defined as follows: for words x,y,z, f(t,x,y,z) = (x AND y) OR (~x AND z) (0 <= t <= 19) f(t,x,y,z) = x XOR y XOR z (20 <= t <= 39) f(t,x,y,z) = (x AND y) OR (x AND z) OR (y AND z) (40 <= t <= 59) f(t,x,y,z) = x XOR y XOR z (60 <= t <= 79). 6. CONSTANTS USED A sequence of constant words K(0), K(1), ... , K(79) is used in the SHA. In hex these are given by K(t) = 5a827999 (0 <= t <= 19) K(t) = 6ed9eba1 (20 <= t <= 39) K(t) = 8f1bbcdc (40 <= t <= 59) K(t) = ca62c1d6 (60 <= t <= 79). 7. COMPUTING THE MESSAGE DIGEST The message digest is computed using the final padded message. The computation uses two buffers, each consisting of five 32-bit words, and a sequence of eighty 32-bit words. The words of the first 5-word buffer are labeled A,B,C,D,E. The words of the second 5-word buffer are labeled h0, h1, h2, h3, h4. The words of the 80- word sequence are labeled W(0), W(1), ... , W(79). A single word buffer TEMP is also employed. To generate the message digest, the 16-word blocks M(1), M(2), ... , M(N) defined in Section 4 are processed in order. The processing of each M(i) involves 80 steps. Before processing any blocks, the {hj} are initialized as follows: in hex, h0 = 67452301 h1 = efcdab89 h2 = 98badcfe h3 = 10325476 h4 = c3d2e1f0. Now M(1), M(2), ... , M(N) are processed. To process M(i), we proceed as follows: a. Divide M(i) into 16 words W(0), W(1), ... , W(15), where W(0) is the leftmost word. b. For t = 16 to 79 let W(t) = W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16). c. Let A = h0, B = h1, C = h2, D = h3, E = h4. d. For t = 0 to 79 do TEMP = S(5,A) + f(t,B,C,D) + E + W(t) + K(t); E = D; D = C; C = S(30,B); B = A; A = TEMP; e. Let h0 = h0 + A, h1 = h1 + B, h2 = h2 + C, h3 = h3 + D, h4 = h4 + E. After processing M(N), the message digest is the 160-bit string represented by the 5 words h0 h1 h2 h3 h4. The above assumes that the sequence W(0), ... , W(79) is implemented as an array of eighty 32-bit words. This is efficient from the standpoint of minimization of execution time, since the addresses of W(t-3), ... , W(t-16) in step (b) are easily computed. If space is at a premium, an alternative is to regard { W(t) } as a circular queue, which may be implemented using an array of sixteen 32-bit words W[0], ... W[15]. In this case, in hex let MASK = 0000000f. Then processing of M(i) is as follows: aa. Divide M(i) into 16 words W[0], ... , W[15], where W[0] is the leftmost word. bb. Let A = h0, B = h1, C = h2, D = h3, E = h4. cc. For t = 0 to 79 do s = t AND MASK; if (t >= 16) W[s] = W[(s + 13) AND MASK] XOR W[(s + 8) AND MASK] XOR W[(s + 2) AND MASK] XOR W[s]; TEMP = S(5,A) + f(t,B,C,D) + E + W[s] + K(t); E = D; D = C; C = S(30,B); B = A; A = TEMP; dd. Let h0 = h0 + A, h1 = h1 + B, h2 = h2 + C, h3 = h3 + D, h4 = h4 + E. Both (a) - (d) and (aa) - (dd) yield the same message digest. Although using (aa) - (dd) saves sixty-four 32-bit words of storage, it is likely to lengthen execution time due to the increased complexity of the address computations for the { W[t] } in step (cc). Other computation methods which give identical results may be implemented in conformance with the standard. Examples are given in the appendices. APPENDIX A. A SAMPLE MESSAGE AND ITS MESSAGE DIGEST This appendix is for informational purposes only and is not required to meet the standard. Let the message be the ASCII binary-coded form of "abc", i.e. 01100001 01100010 01100011. This message has length L = 24. In step (a) of Section 4, we append "1", giving a new length of 25. In step (b) we append 423 "0"s. In step (c) we append hex 00000000 00000018, the 2-word representation of 24. Thus the final padded message consists of one block, so that N = 1 in the notation of Section 4. The single block has hex words W[ 0] = 61626380 W[ 1] = 00000000 W[ 2] = 00000000 W[ 3] = 00000000 W[ 4] = 00000000 W[ 5] = 00000000 W[ 6] = 00000000 W[ 7] = 00000000 W[ 8] = 00000000 W[ 9] = 00000000 W[10] = 00000000 W[11] = 00000000 W[12] = 00000000 W[13] = 00000000 W[14] = 00000000 W[15] = 00000018 Initial hex values of h: h0 h1 h2 h3 h4 67452301 efcdab89 98badcfe 10325476 c3d2e1f0 Hex values of A,B,C,D,E after pass t of the "for t = 0 to 79" loop (step (d) or (cc)) in Section 7: A B C D E t = 0: 0116fc33 67452301 7bf36ae2 98badcfe 10325476 t = 1: 8990536d 0116fc33 59d148c0 7bf36ae2 98badcfe t = 2: a1390f08 8990536d c045bf0c 59d148c0 7bf36ae2 t = 3: cdd8e11b a1390f08 626414db c045bf0c 59d148c0 t = 4: cfd499de cdd8e11b 284e43c2 626414db c045bf0c t = 5: 3fc7ca40 cfd499de f3763846 284e43c2 626414db t = 6: 993e30c1 3fc7ca40 b3f52677 f3763846 284e43c2 t = 7: 9e8c07d4 993e30c1 0ff1f290 b3f52677 f3763846 t = 8: 4b6ae328 9e8c07d4 664f8c30 0ff1f290 b3f52677 t = 9: 8351f929 4b6ae328 27a301f5 664f8c30 0ff1f290 t = 10: fbda9e89 8351f929 12dab8ca 27a301f5 664f8c30 t = 11: 63188fe4 fbda9e89 60d47e4a 12dab8ca 27a301f5 t = 12: 4607b664 63188fe4 7ef6a7a2 60d47e4a 12dab8ca t = 13: 9128f695 4607b664 18c623f9 7ef6a7a2 60d47e4a t = 14: 196bee77 9128f695 1181ed99 18c623f9 7ef6a7a2 t = 15: 20bdd62f 196bee77 644a3da5 1181ed99 18c623f9 t = 16: ed2ff4a3 20bdd62f c65afb9d 644a3da5 1181ed99 t = 17: 565df73c ed2ff4a3 c82f758b c65afb9d 644a3da5 t = 18: 550b1e7f 565df73c fb4bfd28 c82f758b c65afb9d t = 19: fe0f9e4b 550b1e7f 15977dcf fb4bfd28 c82f758b t = 20: b4d4c943 fe0f9e4b d542c79f 15977dcf fb4bfd28 t = 21: 43993572 b4d4c943 ff83e792 d542c79f 15977dcf t = 22: f7106486 43993572 ed353250 ff83e792 d542c79f t = 23: 775924e6 f7106486 90e64d5c ed353250 ff83e792 t = 24: 45a7ef23 775924e6 bdc41921 90e64d5c ed353250 t = 25: ccead674 45a7ef23 9dd64939 bdc41921 90e64d5c t = 26: 02d0c6d1 ccead674 d169fbc8 9dd64939 bdc41921 t = 27: 070c437f 02d0c6d1 333ab59d d169fbc8 9dd64939 t = 28: 301e90be 070c437f 40b431b4 333ab59d d169fbc8 t = 29: b898c685 301e90be c1c310df 40b431b4 333ab59d t = 30: 669723e2 b898c685 8c07a42f c1c310df 40b431b4 t = 31: d9316f96 669723e2 6e2631a1 8c07a42f c1c310df t = 32: db81a5c7 d9316f96 99a5c8f8 6e2631a1 8c07a42f t = 33: 99c8dfb2 db81a5c7 b64c5be5 99a5c8f8 6e2631a1 t = 34: 6be6ae07 99c8dfb2 f6e06971 b64c5be5 99a5c8f8 t = 35: c01cc62c 6be6ae07 a67237ec f6e06971 b64c5be5 t = 36: 6433fdd0 c01cc62c daf9ab81 a67237ec f6e06971 t = 37: 0a33ccf7 6433fdd0 3007318b daf9ab81 a67237ec t = 38: 4bf58dc8 0a33ccf7 190cff74 3007318b daf9ab81 t = 39: ebbd5233 4bf58dc8 c28cf33d 190cff74 3007318b t = 40: 825a3460 ebbd5233 12fd6372 c28cf33d 190cff74 t = 41: b62cbb93 825a3460 faef548c 12fd6372 c28cf33d t = 42: aa3f9707 b62cbb93 20968d18 faef548c 12fd6372 t = 43: fe1d0273 aa3f9707 ed8b2ee4 20968d18 faef548c t = 44: 57ad526b fe1d0273 ea8fe5c1 ed8b2ee4 20968d18 t = 45: 93ebbe3f 57ad526b ff87409c ea8fe5c1 ed8b2ee4 t = 46: f9adf47b 93ebbe3f d5eb549a ff87409c ea8fe5c1 t = 47: 875586d2 f9adf47b e4faef8f d5eb549a ff87409c t = 48: d0a22ffb 875586d2 fe6b7d1e e4faef8f d5eb549a t = 49: c12b6426 d0a22ffb a1d561b4 fe6b7d1e e4faef8f t = 50: ebc90281 c12b6426 f4288bfe a1d561b4 fe6b7d1e t = 51: e7d0ec05 ebc90281 b04ad909 f4288bfe a1d561b4 t = 52: 7cb98e55 e7d0ec05 7af240a0 b04ad909 f4288bfe t = 53: 0d48dba2 7cb98e55 79f43b01 7af240a0 b04ad909 t = 54: c2d477bf 0d48dba2 5f2e6395 79f43b01 7af240a0 t = 55: 236bd48d c2d477bf 835236e8 5f2e6395 79f43b01 t = 56: 9b4364d6 236bd48d f0b51def 835236e8 5f2e6395 t = 57: 5b8c33c9 9b4364d6 48daf523 f0b51def 835236e8 t = 58: be2a4656 5b8c33c9 a6d0d935 48daf523 f0b51def t = 59: 8ff296db be2a4656 56e30cf2 a6d0d935 48daf523 t = 60: c10c8993 8ff296db af8a9195 56e30cf2 a6d0d935 t = 61: 6ac23cbf c10c8993 e3fca5b6 af8a9195 56e30cf2 t = 62: 0708247d 6ac23cbf f0432264 e3fca5b6 af8a9195 t = 63: 35d201f8 0708247d dab08f2f f0432264 e3fca5b6 t = 64: 969b2fc8 35d201f8 41c2091f dab08f2f f0432264 t = 65: 3cac6514 969b2fc8 0d74807e 41c2091f dab08f2f t = 66: 14cd9a35 3cac6514 25a6cbf2 0d74807e 41c2091f t = 67: ba564047 14cd9a35 0f2b1945 25a6cbf2 0d74807e t = 68: c241f74d ba564047 4533668d 0f2b1945 25a6cbf2 t = 69: 2896b70f c241f74d ee959011 4533668d 0f2b1945 t = 70: 564bbed1 2896b70f 70907dd3 ee959011 4533668d t = 71: 8fa15d5a 564bbed1 ca25adc3 70907dd3 ee959011 t = 72: 9a226c11 8fa15d5a 5592efb4 ca25adc3 70907dd3 t = 73: f0b94489 9a226c11 a3e85756 5592efb4 ca25adc3 t = 74: 1809d5e2 f0b94489 66889b04 a3e85756 5592efb4 t = 75: b86c5a40 1809d5e2 7c2e5122 66889b04 a3e85756 t = 76: dfe7e487 b86c5a40 86027578 7c2e5122 66889b04 t = 77: 70286c07 dfe7e487 2e1b1690 86027578 7c2e5122 t = 78: 24ff7ed5 70286c07 f7f9f921 2e1b1690 86027578 t = 79: 9a1f95a8 24ff7ed5 dc0a1b01 f7f9f921 2e1b1690 After processing, values of h: h0 h1 h2 h3 h4 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880 Message digest = 0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880 APPENDIX B. A SECOND SAMPLE MESSAGE AND ITS MESSAGE DIGEST This appendix is for informational purposes only and is not required to meet the standard. Let the message be the binary-coded form (cf. Appendix A) of the ASCII string "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" Since each of the 56 characters is converted to 8 bits, the length of the message is L = 448. In step (a) of Section 4, we append "1", giving a new length of 449. In step (b) we append 511 "0"s, producing a new message of length 960 which is congruent to 448 modulo 512 (note that 511 "0"s are the most that ever need to be appended). In step (c) we append the 2-word representation of 448, i.e., hex 00000000 000001c0. This gives N = 2. Initial values of h: h0 h1 h2 h3 h4 67452301 efcdab89 98badcfe 10325476 c3d2e1f0 Start processing block 1. Words of block 1: W[ 0] = 61626364 W[ 1] = 62636465 W[ 2] = 63646566 W[ 3] = 64656667 W[ 4] = 65666768 W[ 5] = 66676869 W[ 6] = 6768696a W[ 7] = 68696a6b W[ 8] = 696a6b6c W[ 9] = 6a6b6c6d W[10] = 6b6c6d6e W[11] = 6c6d6e6f W[12] = 6d6e6f70 W[13] = 6e6f7071 W[14] = 80000000 W[15] = 00000000 Hex values of A,B,C,D,E after pass t of the "for t = 0 to 79" loop (step (d) or (cc)) in Section 7: A B C D E t = 0: 0116fc17 67452301 7bf36ae2 98badcfe 10325476 t = 1: ebf3b452 0116fc17 59d148c0 7bf36ae2 98badcfe t = 2: 5109913a ebf3b452 c045bf05 59d148c0 7bf36ae2 t = 3: 2c4f6eac 5109913a bafced14 c045bf05 59d148c0 t = 4: 33f4ae5b 2c4f6eac 9442644e bafced14 c045bf05 t = 5: 96b85189 33f4ae5b 0b13dbab 9442644e bafced14 t = 6: db04cb58 96b85189 ccfd2b96 0b13dbab 9442644e t = 7: 45833f0f db04cb58 65ae1462 ccfd2b96 0b13dbab t = 8: c565c35e 45833f0f 36c132d6 65ae1462 ccfd2b96 t = 9: 6350afda c565c35e d160cfc3 36c132d6 65ae1462 t = 10: 8993ea77 6350afda b15970d7 d160cfc3 36c132d6 t = 11: e19ecaa2 8993ea77 98d42bf6 b15970d7 d160cfc3 t = 12: 8603481e e19ecaa2 e264fa9d 98d42bf6 b15970d7 t = 13: 32f94a85 8603481e b867b2a8 e264fa9d 98d42bf6 t = 14: b2e7a8be 32f94a85 a180d207 b867b2a8 e264fa9d t = 15: 42637e39 b2e7a8be 4cbe52a1 a180d207 b867b2a8 t = 16: 66036329 42637e39 acb9ea2f 4cbe52a1 a180d207 t = 17: b59a89e4 66036329 5098df8e acb9ea2f 4cbe52a1 t = 18: 90b9433e b59a89e4 5980d8ca 5098df8e acb9ea2f t = 19: db5227e2 90b9433e 2d66a279 5980d8ca 5098df8e t = 20: 91241034 db5227e2 a42e50cf 2d66a279 5980d8ca t = 21: 4c06bd64 91241034 b6d489f8 a42e50cf 2d66a279 t = 22: 8665831e 4c06bd64 2449040d b6d489f8 a42e50cf t = 23: 3f62d9ec 8665831e 1301af59 2449040d b6d489f8 t = 24: cd40e178 3f62d9ec a19960c7 1301af59 2449040d t = 25: d83e484e cd40e178 0fd8b67b a19960c7 1301af59 t = 26: d70940fe d83e484e 3350385e 0fd8b67b a19960c7 t = 27: 39b6981b d70940fe b60f9213 3350385e 0fd8b67b t = 28: 694303ae 39b6981b b5c2503f b60f9213 3350385e t = 29: 8e08fd0a 694303ae ce6da606 b5c2503f b60f9213 t = 30: fbff1ba5 8e08fd0a 9a50c0eb ce6da606 b5c2503f t = 31: 8ab96092 fbff1ba5 a3823f42 9a50c0eb ce6da606 t = 32: 4206057a 8ab96092 7effc6e9 a3823f42 9a50c0eb t = 33: 2cbcfc1a 4206057a a2ae5824 7effc6e9 a3823f42 t = 34: 505759f3 2cbcfc1a 9081815e a2ae5824 7effc6e9 t = 35: 05bb8ec9 505759f3 8b2f3f06 9081815e a2ae5824 t = 36: a0fc08a0 05bb8ec9 d415d67c 8b2f3f06 9081815e t = 37: 8664f5e1 a0fc08a0 416ee3b2 d415d67c 8b2f3f06 t = 38: fe3d2a4f 8664f5e1 283f0228 416ee3b2 d415d67c t = 39: 07d02aa9 fe3d2a4f 61993d78 283f0228 416ee3b2 t = 40: 38d7321c 07d02aa9 ff8f4a93 61993d78 283f0228 t = 41: 1f3ca4c0 38d7321c 41f40aaa ff8f4a93 61993d78 t = 42: df27aa0c 1f3ca4c0 0e35cc87 41f40aaa ff8f4a93 t = 43: 84e2dba6 df27aa0c 07cf2930 0e35cc87 41f40aaa t = 44: 8797eb77 84e2dba6 37c9ea83 07cf2930 0e35cc87 t = 45: 9d220100 8797eb77 a138b6e9 37c9ea83 07cf2930 t = 46: cb326b71 9d220100 e1e5fadd a138b6e9 37c9ea83 t = 47: 505de66f cb326b71 27488040 e1e5fadd a138b6e9 t = 48: ffdf8e6f 505de66f 72cc9adc 27488040 e1e5fadd t = 49: 47a17a6f ffdf8e6f d417799b 72cc9adc 27488040 t = 50: 2c742cf4 47a17a6f fff7e39b d417799b 72cc9adc t = 51: 692c82f3 2c742cf4 d1e85e9b fff7e39b d417799b t = 52: 741a7aeb 692c82f3 0b1d0b3d d1e85e9b fff7e39b t = 53: e89625b3 741a7aeb da4b20bc 0b1d0b3d d1e85e9b t = 54: bb527c29 e89625b3 dd069eba da4b20bc 0b1d0b3d t = 55: 609a8616 bb527c29 fa25896c dd069eba da4b20bc t = 56: 5e259ced 609a8616 6ed49f0a fa25896c dd069eba t = 57: fdce04c4 5e259ced 9826a185 6ed49f0a fa25896c t = 58: 2a35958f fdce04c4 5789673b 9826a185 6ed49f0a t = 59: 029a9dbb 2a35958f 3f738131 5789673b 9826a185 t = 60: 651604ab 029a9dbb ca8d6563 3f738131 5789673b t = 61: 3f163f73 651604ab c0a6a76e ca8d6563 3f738131 t = 62: 60e30527 3f163f73 d945812a c0a6a76e ca8d6563 t = 63: da53f35e 60e30527 cfc58fdc d945812a c0a6a76e t = 64: 59f8e302 da53f35e d838c149 cfc58fdc d945812a t = 65: be75732c 59f8e302 b694fcd7 d838c149 cfc58fdc t = 66: 8d8dfd49 be75732c 967e38c0 b694fcd7 d838c149 t = 67: 556247fc 8d8dfd49 2f9d5ccb 967e38c0 b694fcd7 t = 68: c416c3e2 556247fc 63637f52 2f9d5ccb 967e38c0 t = 69: 64c244c9 c416c3e2 155891ff 63637f52 2f9d5ccb t = 70: b0df5b97 64c244c9 b105b0f8 155891ff 63637f52 t = 71: 905723fe b0df5b97 59309132 b105b0f8 155891ff t = 72: 49946022 905723fe ec37d6e5 59309132 b105b0f8 t = 73: b3a64db3 49946022 a415c8ff ec37d6e5 59309132 t = 74: 281589bc b3a64db3 92651808 a415c8ff ec37d6e5 t = 75: 4623888d 281589bc ece9936c 92651808 a415c8ff t = 76: 74eb04b7 4623888d 0a05626f ece9936c 92651808 t = 77: 035d4cd9 74eb04b7 5188e223 0a05626f ece9936c t = 78: b2bdd7d0 035d4cd9 dd3ac12d 5188e223 0a05626f t = 79: 1d750196 b2bdd7d0 40d75336 dd3ac12d 5188e223 Block 1 processed. Values of h: h0 h1 h2 h3 h4 84ba2497 a28b8359 d9923034 ed6d15a3 155bc413 Start processing block 2. Words of block 2: W[ 0] = 00000000 W[ 1] = 00000000 W[ 2] = 00000000 W[ 3] = 00000000 W[ 4] = 00000000 W[ 5] = 00000000 W[ 6] = 00000000 W[ 7] = 00000000 W[ 8] = 00000000 W[ 9] = 00000000 W[10] = 00000000 W[11] = 00000000 W[12] = 00000000 W[13] = 00000000 W[14] = 00000000 W[15] = 000001c0 Hex values of A,B,C,D,E after pass t of the "for t = 0 to 79" loop (step (d) or (cc)) in Section 7: A B C D E t = 0: d508e54e 84ba2497 68a2e0d6 d9923034 ed6d15a3 t = 1: 42ae69cc d508e54e e12e8925 68a2e0d6 d9923034 t = 2: 738c64e9 42ae69cc b5423953 e12e8925 68a2e0d6 t = 3: d5b4a0fe 738c64e9 10ab9a73 b5423953 e12e8925 t = 4: 870f3c0b d5b4a0fe 5ce3193a 10ab9a73 b5423953 t = 5: 46574e97 870f3c0b b56d283f 5ce3193a 10ab9a73 t = 6: 1405102f 46574e97 e1c3cf02 b56d283f 5ce3193a t = 7: 297306df 1405102f d195d3a5 e1c3cf02 b56d283f t = 8: 30185ce2 297306df c501440b d195d3a5 e1c3cf02 t = 9: 10d7ba0c 30185ce2 ca5cc1b7 c501440b d195d3a5 t = 10: 0c28cf6b 10d7ba0c 8c061738 ca5cc1b7 c501440b t = 11: 6eabfec0 0c28cf6b 0435ee83 8c061738 ca5cc1b7 t = 12: 7e85f170 6eabfec0 c30a33da 0435ee83 8c061738 t = 13: f964f1a3 7e85f170 1baaffb0 c30a33da 0435ee83 t = 14: 26e19055 f964f1a3 1fa17c5c 1baaffb0 c30a33da t = 15: 156937e7 26e19055 fe593c68 1fa17c5c 1baaffb0 t = 16: 6295f273 156937e7 49b86415 fe593c68 1fa17c5c t = 17: b81a706e 6295f273 c55a4df9 49b86415 fe593c68 t = 18: a5620a0d b81a706e d8a57c9c c55a4df9 49b86415 t = 19: 2dbc9cff a5620a0d ae069c1b d8a57c9c c55a4df9 t = 20: bf89c409 2dbc9cff 69588283 ae069c1b d8a57c9c t = 21: 239a6d9b bf89c409 cb6f273f 69588283 ae069c1b t = 22: adec9cd5 239a6d9b 6fe27102 cb6f273f 69588283 t = 23: 1cdd463f adec9cd5 c8e69b66 6fe27102 cb6f273f t = 24: e0da5334 1cdd463f 6b7b2735 c8e69b66 6fe27102 t = 25: b947bdab e0da5334 c737518f 6b7b2735 c8e69b66 t = 26: ad4e620c b947bdab 383694cd c737518f 6b7b2735 t = 27: ca67cf14 ad4e620c ee51ef6a 383694cd c737518f t = 28: fe343974 ca67cf14 2b539883 ee51ef6a 383694cd t = 29: 7cfd680a fe343974 3299f3c5 2b539883 ee51ef6a t = 30: e4d7304c 7cfd680a 3f8d0e5d 3299f3c5 2b539883 t = 31: a6fd2352 e4d7304c 9f3f5a02 3f8d0e5d 3299f3c5 t = 32: c57dadcd a6fd2352 3935cc13 9f3f5a02 3f8d0e5d t = 33: 5f146ab9 c57dadcd a9bf48d4 3935cc13 9f3f5a02 t = 34: 469dc798 5f146ab9 715f6b73 a9bf48d4 3935cc13 t = 35: 03bcf3da 469dc798 57c51aae 715f6b73 a9bf48d4 t = 36: f03f67ba 03bcf3da 11a771e6 57c51aae 715f6b73 t = 37: 2e04e8c4 f03f67ba 80ef3cf6 11a771e6 57c51aae t = 38: e8b3497e 2e04e8c4 bc0fd9ee 80ef3cf6 11a771e6 t = 39: a9ce9b40 e8b3497e 0b813a31 bc0fd9ee 80ef3cf6 t = 40: f261bb65 a9ce9b40 ba2cd25f 0b813a31 bc0fd9ee t = 41: 42ef9dd9 f261bb65 2a73a6d0 ba2cd25f 0b813a31 t = 42: b2f2664a 42ef9dd9 7c986ed9 2a73a6d0 ba2cd25f t = 43: 1291092a b2f2664a 50bbe776 7c986ed9 2a73a6d0 t = 44: 7c6aef48 1291092a acbc9992 50bbe776 7c986ed9 t = 45: a9cb9df6 7c6aef48 84a4424a acbc9992 50bbe776 t = 46: c5f82e71 a9cb9df6 1f1abbd2 84a4424a acbc9992 t = 47: 8868c238 c5f82e71 aa72e77d 1f1abbd2 84a4424a t = 48: b052f768 8868c238 717e0b9c aa72e77d 1f1abbd2 t = 49: 61102ac0 b052f768 221a308e 717e0b9c aa72e77d t = 50: 8bee2ff1 61102ac0 2c14bdda 221a308e 717e0b9c t = 51: 9e700133 8bee2ff1 18440ab0 2c14bdda 221a308e t = 52: 877a43cd 9e700133 62fb8bfc 18440ab0 2c14bdda t = 53: c4e901d6 877a43cd e79c004c 62fb8bfc 18440ab0 t = 54: 2c7a07f0 c4e901d6 61de90f3 e79c004c 62fb8bfc t = 55: 67344973 2c7a07f0 b13a4075 61de90f3 e79c004c t = 56: 7ebaee45 67344973 0b1e81fc b13a4075 61de90f3 t = 57: eb9659b3 7ebaee45 d9cd125c 0b1e81fc b13a4075 t = 58: 0ebfb62a eb9659b3 5faebb91 d9cd125c 0b1e81fc t = 59: 4dbf216a 0ebfb62a fae5966c 5faebb91 d9cd125c t = 60: 08089f12 4dbf216a 83afed8a fae5966c 5faebb91 t = 61: 601aba34 08089f12 936fc85a 83afed8a fae5966c t = 62: e1685b50 601aba34 820227c4 936fc85a 83afed8a t = 63: ec956f26 e1685b50 1806ae8d 820227c4 936fc85a t = 64: 6bed4126 ec956f26 385a16d4 1806ae8d 820227c4 t = 65: 96d6e5e6 6bed4126 bb255bc9 385a16d4 1806ae8d t = 66: a5d83970 96d6e5e6 9afb5049 bb255bc9 385a16d4 t = 67: 74ccf6e4 a5d83970 a5b5b979 9afb5049 bb255bc9 t = 68: b9bdca6d 74ccf6e4 29760e5c a5b5b979 9afb5049 t = 69: 9526a197 b9bdca6d 1d333db9 29760e5c a5b5b979 t = 70: a2e5a7c9 9526a197 6e6f729b 1d333db9 29760e5c t = 71: 3708b81b a2e5a7c9 e549a865 6e6f729b 1d333db9 t = 72: f27081ec 3708b81b 68b969f2 e549a865 6e6f729b t = 73: 41daeb9b f27081ec cdc22e06 68b969f2 e549a865 t = 74: 4215a57b 41daeb9b 3c9c207b cdc22e06 68b969f2 t = 75: 2655c2d6 4215a57b d076bae6 3c9c207b cdc22e06 t = 76: 11dc8a86 2655c2d6 d085695e d076bae6 3c9c207b t = 77: 69364641 11dc8a86 899570b5 d085695e d076bae6 t = 78: 0a6ed856 69364641 847722a1 899570b5 d085695e t = 79: 4d974a4a 0a6ed856 5a4d9190 847722a1 899570b5 Block 2 processed. Values of h: h0 h1 h2 h3 h4 d2516ee1 acfa5baf 33dfc1c4 71e43844 9ef134c8 Message digest = d2516ee1 acfa5baf 33dfc1c4 71e43844 9ef134c8 APPENDIX C. A THIRD SAMPLE MESSAGE AND ITS MESSAGE DIGEST This appendix is for informational purposes only and is not required to meet the standard. Let the message be the binary-coded form of the ASCII string which consists of 1,000,000 repetitions of 'a'. Message digest = 3232affa 48628a26 653b5aaa 44541fd9 0d690603 trf2.1.4/generic/sha/fip180-1.pdf0000644000175000017500000042302311216343142015602 0ustar sergeisergei%PDF-1.1 %âãÏÓ 1 0 obj [/CalRGB << /WhitePoint [0.9505 1 1.089] /Gamma [1.8 1.8 1.8] /Matrix [0.4497 0.2446 0.02518 0.3163 0.672 0.1412 0.1845 0.08334 0.9227] >> ] endobj 3 0 obj << /Length 581 /Filter /LZWDecode >> stream € ph(b 4ˆBP‚j‡ †CAÞ &ˆ eØ’ 3ÁFð±¸Àj.cQȸo)…ÙIÈË3  ¤"¤^FŠAʆh(ÆSQ„1ÚG.…• ±ñPåT*ॱAT\S E£1˜ÐPD"”%"¡4ŠN*X¬–byåeÉäÛqH†E—J„ª ´b.Œ†µR%lPT2˜Íãy°Þg<ÝìÄ!´Òn4œÎ‡# ÐÒo7`ppR¤è\'itæã ³4($›´F“¡ÔèeÛ›ÌÛr™ÐÂn2NFCžßŽdÛä2YL¶cU„ ©èT ˜5aé•,q’P)ÝÆb‚T…ê G 7^ Ež‚»ãQ¤¢(¾LB`*lœ5Éâ|  ˆƒ1nØbŻᤇ ª¦×…0Š´ B˜»†MÀœ# âš Š‚Hž'D`¤'¯â˜¦$‰Â> /Font << /F4 5 0 R >> >> endobj 8 0 obj << /Length 802 /Filter /LZWDecode >> stream €Š€ÐP¼Œ4 DC4d0D"ñÜd  †¢á€âm‚D ‡)€Ï%*à…±A’P)ŠE£9   U!L¦ƒ1@Äp0ŒE%Ò¡*E‚¢x$(Ò ‹’¢"TD\2„êh€¶]ˆ ‘hÄø@5ŒѰ€[j²Œ°C0ª ‚A¡¨e4kSˆ oöA°Àf.’T°ŒE"JDdèf2IÄbyHšA*Iäì¶` R'È¥2žh¥Ê„q‚R"Lfyy´à˜I!è4ZJ%•n‹†9xYV(.lN§)Èæe2N{ tÃa7œîóá†À[°ŽG#=4Âyô K‚š‰T0qq ähå1LbX)ˆ¢ª)¬°h ¦$AM‹fÚ¶â#êã(Có ¢¨¸fápk¹î¨"ˆìè²B"ž&¦ñ8¥À0¤$Š‚Ì.£©+$>ä‡(ºÐµ-‹rà‹®K¢ì/*„¡hh´°J!NJÈÅÄ£xÚ8££ªË͈ò9ÌCk¶ÝÌ¢`Â1 ãÂ:N/ƒŠ’¨*»šç‰Ó˜Ò7ÃÙ23#tÐ4Ž“ËB ã5)ŽƒÜ2 #É5¦“-$2P‚ Ê1pÞ6 ã<ìûB¤––ã 4:£˜Ä:ŽC8YB °´Ø!áÃÕ¸ákþ ŽsÌŽc˜êìP‚à9 4v†õ½¦õ¶s*Ûk bÄÄHûž*…˜\Ë'‚ Ê8R£ Ú2Ã¥ÐQ·˜‡/]ãÇEÎö ’"ö+ž)P8ݧ‚EÏ„ä7Žãu¬¶4úåHŽU;Œˆ¡\!OTIS^bÈ6#pÓ4NC¤þ7Xåÿ€ØÉcÝŒÞbfŠãxÞ2bi¨«IÌx`§‹ ¸ÃᆠÓç’T5KOöA=Øóîe‚ÚX “CfTLÅyÞºU#IÒ´¾j'nB¯œ9ôÞ§Oê¹>°-û‚i¹`âX æ#Mæ(NCÐ0t®‹t+Ç:V‚ endstream endobj 9 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F4 5 0 R >> >> endobj 11 0 obj << /Length 2137 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b0D"ñÈp4¨äb. †Ø$@¨r’ˆ ò’¡Ž(#ÎFS¼ÈÈ)* a¤& FâBØÄj5 FQÁ°ä\2¥Èà…±APÐe‹FC1”ÀÊd2œŒ&ÊÍlf($›ŒÓ#i„èi7›¬£;9@äo1™Ng3I¸Ïs³”ΆqÂr2îuÒÔÄl4˜í× •jè()ØM7¬X ÞfÀ •|é;'q±èm';yÐêt¬J„¨ ¶>4ží©ãA¬,‰SÏh»ÁÆc…Ãâk;Á€£ 7áy¥C)ŒÐn7› æsÏ,kÅ. Ä’™P¸)ïsM8®7GXèø&l‰§Sí1Ù •¾âô… ˜ØÉ¯Îóä: ðXç¹/c˜ç0¡KdÚB Tà ã¨Ò°2s8®Â2 ãƒ`èD0„P¾C‚î6Ž£`η+êÊèæŽ¬*Ãn+ßE«¸ìõ²bèâ³ò0ê¿Ì¬Ž2‹Â2<òT“osI,>B2¾°µ0š 8 ´J°ŽŽê´£ÅK,Ø ŒƒjúõŽ‹Þ;>”ØÌŽRòöOA¨P Œc¤ÝAJô  †ÍçP`Â6Œ±Ó¡E SPd,ñü×AcxÚý6•ÌŒc¨ä4Í4} CLP¬.*”Hr®†!Èp…‘°`汬{#_9¢`Â;¬µ¼¡_²ÊEˆªªã›á,¹«kØHÕøP4 3Å’®ŒãLñ'[TðeeU ›9MV£ƒgÔ#m(9/6{Ÿ 6sfªá°jYËK-©5ü?P™“ù|@ µüœdô`*À?m9&¾÷þø ŠùFèÜtúMèT7í;´†t¥¸4zhD­B¦¤z1…'41'hˆƒ d&eíÂÓÜ‚aó †Ç4"’f¡I“Œ‡¾özúNhSp-X²Âç âBì‰G4Ó$ÔÚ T5f¶'=÷šïÌ9O 6ÆÃ¨çŽÉÛqo|#†XUÃs J¨3·pB#ßb`à”åð…7ÀÀ„ \£_[B JMì»ðÚc`BUEÜ;‡8üïâ,G‹2”Á÷Õ¨0‘`À²\Тj¥_àäÌE7¿ÊìWNÎ*R Š@ÀQä8’*Q¨ˆ›°@æ8Ml.‘ÈA™`䤢96Áp7‘²¨”²fA2³ D샓âCŠ"ZEÐf dQ!d’`Êâ^C¬,Jœ¢ ‰é åeŠQÊIK.…"…O¨UZyæÄESäÃÕ 'щ)(ªqUBªO)°$>&í N(AFDÊ;†ÕxB˜H&Ù*ÂÓäÜÁÖQæI”¦ÈkIÁ@uZJ]ÎDÒ|™ŠNÐe AÇÎná #*„²ƒ…üËn©uuA4\^³®+UywÖµW Ð78ªP½³ó[IRõ²¸e]v¬€ 2–bk$Äø:l†¶Sšv l­Ì$8¡¢fMÝ‹BbÇ-]Ô—¼pìèwŽöq¥¸–qb*á0m‚Ó™‹ ‹u*´Š™ª³GM­Í'꨾ŽzÚá»;íˆxB .aüu^qÙ ié[‰`ÐlÝŸµÂ eåÈ:<­Ó±uóí,+×%·°ž(NÍ]Š… B¡eœ¼xÌs"ýIfÚáX í}D ¬‚±Óà(€€ endstream endobj 12 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F4 5 0 R /F6 13 0 R >> >> endobj 15 0 obj << /Length 2511 /Filter /LZWDecode >> stream €Š€ÐP¼Œ4 DC4b0D"ñÐl4aa¸Ø\4„ °HPå$åC¶(#J1H´f3 RÖo9Žш¤ºT%A ÃhL. Œ¢5:ˆ€d5‹†!°Ú²3…ÈÁRò1”Èe9M“á˜ÔPI7ç#i„èi7›¨Ôˆ ¶01ˆ(‚áˆØk "K§G#yŒÊs9šMÆ{e¸¦t0›Œ†‘ç•LFÃIŽíx½M­¢Š ‹G¤‚†¸HP´d.›â1CÈäk  œF›^ªÝ€½ìF«Ûq`*blb‚ ¸Üo:›Œy,§Pt4y0èDJ c!¬^Ê)‘HeR‘Ø4%2GÜP)Š‚œ""ˆñ ¢2¤…!ˆr¤ó*¡»Øô…Áª¤‘1K*δ¸¡˜b·. ’èÓ¯)òű¬{"ÉÄ̳0Í3ŒôZдm,H73é´N.& ’i-ÉØ„)‹LfÎæ®Nš |ù+ãf¦†‚k†™³5Ûhf‚ƒK:j̈g–©žp¸ÆK×É ödïWøò¶Ø%e•Kl1ª2ìÿXš¼´f®Æ™‹[¬“i.å5Þ÷ÁEk/ÍiäˆOõJMöò;G‹lÊW¸4ð0×û†’Ø}ǸDÚཚÝO¹ñT3UòMÊ‹júÝÀc%gî |OI.¢])iZsSKÏq0[‡¢•®/(Ê­ûÈUì]ý á¥tUËÙè&2¼lj0T¦¿®ÅnßÐèïý(‘ô¬´>¶%‚ª%:¾eUJnã*°ÂÒ«VÚÁe¨õ‘¤â£I MP’߃Dø$´üfh&4¿Äú”GÌ…{I¶=Џñ*–”qtrJKç6EŒ•”àþQ]md§Fë–JRáˆ0ÄcH¶r²K¿!Ô6Fü”d¤ªþÈ’ *7Ùœñ–AÃXØ:EŒ‹…Kmƒ&Ô¢ØÎ¯J2œwϘ0œLñ„´[-<À n‰Ï後F)–×k âÚ}OèÙÒ…F»LŠ%¬'Mf,•¦jJ<&$ΤšÙòMA«¬2Ÿ%°äÒ|ÔÁP!HTšãa°þJ ë]sŠ“\*L}u$0†BÏurUÃ: lº×_a‘³îÄYÂþ»…ƒ³µY/cÌÒLä©'"ìÍÖ/tFALFzÍ¥ƒXP’>€u‘†Pâp!jÃÈÏroíÌû‘˜8Þ%»v¥tNøœcÞ‡#5æë7â35²,Û—F¾±ŠÔé7gäOH½#MèƒGnîXz§ÞTˆ4í~f§9Ô©Š|Úª¶ ÉÁWäÉ«LEþtú$œ_, ›AsSÔN’;n9w¸¶ ÞÈl4ú~³l÷b´&¬(˺d-BôH¼–«?ÉBd [aKT…šÚXM !RÍ@îÄYíŒþîU˜·Ј ;íëØ2½Ç¹vðåô%„åLˆB¢®ai ÆÜ”Èhk!Âó„%ƒR0ark$„±ø°jÓ¹ Ó¦¬1¨p,Å–¬wxö¤*Í¢.ËãË×khA)e €#à@J° EL5]ÿ٠ €-…Ò !éj ÌÛ”@X¢1ý†ÂÈ!r­µ–yãÌóÀrý¢(/6ô⊉(tõbª7Ï¿b²“Hˆ%àD·E¶ñÏ ;ÀšÁ”•¬ø8šx€XC€ …2;Gf[n5`†TÀàW¥Pc@£@`¤   €ž4N.:jc)@‰ëêf"^í¤R,øon2β2bР¬- ð–5ƒz0ªRÎô5h²dt{†v!.*Ì"b! ¨N!n#,ˆQ¢ ‚ endstream endobj 16 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R >> >> endobj 19 0 obj << /Length 67338 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€Þ 3Œ ‡HY¶ *£â<Œ¨c‚ÅÀäo;MÆqH¶05•N†ƒyÈÒt<ŠK¥BT …C ƒ‘pÄl9‰•’‘@êk7̦3‘”èa9PfÃ9Á¼ÍW² fói´Êr1™EÔ*$‹Dˆðá¤A%DÍQpÊ8w¿ˆ ¢Ùv$d‡ †bè@Øq“Â#À¨~N6 Ëf!̈Ð\0h2ø]N“9†Óêt:x溦Ä2Ã!p×G¥ÞåGÍ@ƒl2í5C§#Éî‡È;^6ÂÇ2ÃÖ·#Ø‹j»ƒŽö¼n.v‡?,?Î9és{ýxâ›Âæ}!ÿoVórë?oCTÞ=¡“ì§5L˜`Ú²/;-·¨ƒŽóºMäÌËTÓ+“CpÌ$ç¹L³L¿Mƒ|ÕCð»pé9/L\ØÅsá ³ÏS±5웄ì<‘ÚË<ϲϳþã´Î+,¦Aq›d)ÓŽäÃJz$ã¼ Ðrî0м(ÐKîÌÅKÒÛ"þ5R¬RûH2|3©Ž¬å+2*d-Bêd‘/ϨÓÔóº®<ôáP‘êîµRU½R„x÷2’š™K‘ÛÂî˜èÂKÃÍeT1+ÈIq$£"PUMAXHÒ¼æÕQ4ëÑ)È,^>ð¼ØË91»ŽûÏS“ÐÊl`ôRa•Ñö”†ÓVl‘lL-°fîIÍ]Ao\œhÏÏìifÏnY7²SÙ3ÆîÜL¼7µ¢ìL7ÕS,½w¼I_ÒeQ{Y1œW„Z1{ÅxÆw ¹„¸ñÎb¶»¹Œ21ô!<C0T‡#0{-^„ Øc’Ên#Û–9w|˜2Î¥ŒÞ¸ ƒoC˜~)’g¸.HæUø &è—–!o9˜&u—¹•žŸ™¹˜mªVù®e¦k7sõ¤k¹v±€EºæÉJë•‹›é¶8Îl,w¬nTe½XÚ9ä›ÃU”eY£‡uï»FµZð¹5ÝBð¹Íçž@Xfg èÛ¦•£é9÷1S^ÛÖᨺ\~‡®êû3ñ­ôz³›Ó@|'?®ì½K…eêå‰4ks±·å|ÎOuû¯=•ïÝÿ<4q4³•À²q”“VfíåóU¸¶óy~ú®Gm.”áîÓr޹©Sûf³@zÓ4µ3}7ÌËnääQ2L?ší}M7qÿS—ÄA$; 8”ÄnàNJí;ä§f¦· iñu Áe³>· -uÌ­ :ÔW¡³ðQk™7ù t YÈ„ðÁdíÖd„ á¹­ãÎÝYûp>Ïa”-ãìüÞ3/):7b ’?ˆÆr$BðpÚÐ4hÕcDv&²›A¶ŠLAÛ¨ø¶œVÃó‹KÍ+¸£â“‹l$Ù²cÏT&‹Ìlá.vfSRŽæ5óìôÍädjA7)!ü7]Jµ¸AÖµÙ$Šf2%Î.瑳§’ì®A'"»xq6E8µM‹1TiUš¼®ñÍFK(Íâà7=±mJãÏœC;@ÜóÂvW,åLÅfòüÊÌE9\ΘőXËåo “ܺ}Œ’Ê™‘ “´ÚŒSrʤe ¦lxeðfTÉÓ¬ß$l!•Pr@§€ÊæëeóæK5ø+#Ú<ì7plù°w!`ä3ŽÓ¡M9ù ¡JÙž®ÎUÏà dŠª;æc¾¨ŠðÁœ?‰T‚a7ø—åm—t¦(Kˆ±e\‰ôV7Ê»å¬a?Q})¡Éw 3ð¦1°ÕÆèáCe¤½5pŽN8g£å¡…MU(ýYœ‡«ÙUæo#—tʨüÕ™+*!ô™f2n`»†µ'é­2tQ2X¹YO9gTQ•²¾½B¹m b´µ›HvœFÉuN%ìΘ–kM9‘cf[YšU|àÌ™Ÿ9EŠŸÓ–Ñu6¬(³ô‰™À™Ò´-*C•PÆ‹)梞DñµÕåÀƒÿ+”»3¶ÖމOo`ç[°õq‚Y¦ggl´À´“ZŸk†É't¶°’âÄÚE½tg3G·6âš9™;n쎵g–xP˜ ; DN”Ó’RÒy©«DätõŠóA§« ¤Eº¡G*†:_¯¥ï:FšÐψœí/Õž÷z4¹G¡îˆª=ÄL#]"v¥ÜRè©-*&—†>KˆÀ‰éÝ@–öͺ‡f½Æ^G[ùt*tzºõFƒÇê«n=[£-:@ÉF‹W¯ÒS9˜I5©(Ó¯Œ˜ÂyF¦³—K`j%sÃw¶5Wºó]æÍ¹®ó†oâË\)ü¹Í6&ïã·dî=UÎq,ç8e4fU©³9¶‰Íì]³%½ÐòqÂLÃj/íãÁ6ÏKcBtb¶¯BðYK™mõ¼ºwâoVk‹Ÿ$Âý¸Õ¦ jºÓRàud"hö<Õ©Œ%®UjŒºo)QIσޛ»ÇÐó¬ 9ƒ•¬né`ÕÆ‹ˆ¨ËEÅ›qiåÌ©ªãR¡r_h)õ&H,¨ôÆha.÷¿w€Ñ£¬"„AŠ4oJ5sÀ¢ÒE‰Tpu·Á"‰öÁQ©îoªwÅi¬üc~ñ)t/ãîûÄÎ1•í•­ñyïϨ¢¤œ×/UW¯€TîiðC’‹\€ðÍ¥(¥ÛsåÑk¡8¸½ÑyGÉÜ™6.‰L°'G¦\w§ÅŽ4 9û·¦â·S>·¿*u-ˆè·­EíóÆwÆö¦}›µtè¼\=;ê,Ƹo\'–»¡ßýr"Jwj[|Þ&ø>ö :ˆù#¡ø¾Uüs èÑG"Öºwº\Zó’]ù·c<õ4ñ?±zGÏüÔ3ÛXo‡Ï Á{M„á‘™ÀjÇ£*ae^Ýk÷3mïã÷þã´ x»}A:4çˆ{óy¿¨à5?+Iý/]çÖˆž”ýg¸=±Ìg=Så~%ž£þõ=Å~Øîa:ƒõ_ª!ÙŸt‰Sü{/Æ;›F{þšLú#x¨Œ4øêF= jI­¬ú£LòOV£’n¯²Cä¦üºTDBä0vÇ‘+JÊ÷ð,î/ŒKN®$Êïl“Cô7Ê=:` µ&¤ïÏ•ç.øÐ8Noègo‰Ïx½§†ùl²ïo¬qÏú9Žúÿ¯öïOà£ÐhýŽè‹ÄÜ’nd`ÜýŠ<ò¯îíMÖü,xŽOŒúf?cx©Oª@ŠzøÏˆýéÞùPÚLÏw, ø/o‰¤Ï³ Oÿ '"ˆ¯£ ‡~ú°”ßϳì? n¦ŽYíŸ ÆÄ¯Ê©Íã ¯ÜÏàjÿ°þq6Zô£Ï¹l± QJOoföÐðpñðÐùp$F®5L­PAL‘¦¥ðkÈ'ðJýŽøÐUPZ…q{W.zú±hð/»&Pzÿ°ÐàÀc&•n»qÑHzpw¢þ§ çN§pª nJþ¶²°ºöJ—вðÀqD,ùÅ‚DÏÒøozÅÍÈÚ3O• ÅÄýžB ŒöÐÎÆÊ™íÚ÷ñOñ*(7#O3!ñÊ‚‚I7!ŠÂú¯‰ /hùD»v<èˆW/~=ã¤AÏŒ@ã„{~N•"¯ºZdå(@k(Œ(6Àl;¤ò—MºùRù/m)³(e¯$ÅÓò”;‹nŸ¤)ï%*àlwÒW,2™2»o¢³'jse†®Ï•'c&ï¯h=L–ú²÷±˜ÿ³&'~‡-Þ)Ã&g'!Àm1#¥#Ã91®»/²Â4ʔʅ“$±½2#LŒ\ËLòÒÂ9%·2’•4ˆ°Qó@š¯‹4óXû“V‰E'5hõsh:L4•Æ»7+¾ p97GT¾‡3í‚ò#8±ÚqS’Ï/2,›.“";$æóVðÇy:²ù³bèG ï3&•:óbãõ2P—:çåS¾zNô£€lùä¦ËSߪá>g±S"‚S…1í))OÏ,%žãSßr”j¨•:ç@¤Ófm´,4³ë¬/0â,õEeT*\/È3”+)§xèí0¥'D4Ã@nöDîÕDÎÎù¢îȈ´GF/¹EL&óàcEG°øT^=TyCÄvñ#G#&iÐ)D¾¦”+mEïítRñ%°À´3 cmJ§[´±T¯JP]B²¾ËT;=J9IrïIÊ :‹:Ms’¯/2+£8ÔÛ2s7G(é4T¯O2GC”øó”SOôpõ¦‚žë³aN±<´×6Õ¤ô·)2_C’u!¦SEõ+tRáÉQé´\2®›R¿?rå²ÁJåIOT_uN!Æ>çWUÈÉEb6ÆÂs %Ý?‘ê`'§Ã×Lô9U1¬›S¦žé=TFéTéFì?U$ Yȉ%Ô8ç4§Sγ5´_YWY1aJãí)§†•G„=©TÛ.÷X1 @IŽ·WÑ Run¢…^¯ä=µñRÔ¯S5¬¼µÁRÔ1_ÌoR“YW5>¾ÕÐäõcC•Lʉ_V‰6•GT“u_;#õ]è-^Ú8UsWt³_P›+•eXTsX”ÙXÕ•Sf5Y™LNyT•¢¿4®ãµùEõ°÷Õ» u¹C•½Y3EÖ*Êæ!]3q]oëFUÝVt VLCuuc±AVÖ¨ÙvDÙJ‹Zd ™ÅÚÞ41e/Ui+GöN’´hÕE5M[õÆátFâO©e[Cõ3jVÀø/×0ãàÇðÜeVþzvÊ3€s9‘:=·PÜ6ÄP ×!×òE'qò¿ W·d ©—,ïG†)ù s2ÖWqÇï-÷=—QrT uw èÏöþˆßr´‹{ª…z‡‹{WÌ­×Ñtjr|¤t }ן÷kzóQ|—* WÃ}êRW ~Œ5~Û'WæÀ9}ó:JwŸpÃL¨‡¿q×H|7Ä©ÕSu6µ~W%{„ä˜Æsƒ A2‹qRÌæ-%OqR¼{ÓûrXRTñëz¥qa·¨\­å_R·]µm†öÛ‡3^¦—j[tq† üQäË+õs{ ɸ‘?uS›}0—sóÆåxg•I}—xƒx±#+‚8‡}ø¦¾€st÷‡}óÒD7Ëpqv¨MÞ@aOä,3xÝŽ Žq2쨳ŽÓ=a¸Ü¥,£óY aIùósñÔC,ã]‘Q}…`‘аuÙÊ7Ï+9¹ðÄyL¸:Øì©Nn4ܤàrؘ¯8·{pË‘fùXíVu•ç§™Húíµ”6å”`®¬/P —T¥hY1*:ô¹+I‘#‘ÆÕ™#˜Æ»p¹$Ùé—Ë ùŸŽ„5ŽXßg¿ŽÕ;—JmP›¸ûš¹wvÈ'“s²’ù‡Tyת ‘9 h³L ™™?‰švC—T‹V‰?˜uއ9ÙuÙ= ÙÅg™G”·?•e”îÛ%•¶·}ó‹–7¨Ø™iQù‹Où…3j‰y}†¹BÚ žR›˜¹ŽÑ¹ŸŸäk™y¡™¥Ÿ–±ŸÆ»ZÙ­•Ëc§7RùŸJY¥žEÃGù‡CJ+ ®-—Jˇñ¤“¤ùÇ–ù»ÑPºaO÷  `àì)›š¸üÝh2£™öé\:›n:Iœ¶Ù— a}ÑZ@ciy…®, ßúáiÚ™’:é0Y«¯t<ºïkT7°12л cÙ)®Œ§{-Yð&›;™²¯ :áû-²“”xÜãi³®G²ÃPñêç´ã¤ZÛ‰:µ9íž6Ùž–Ù{YGË{ÖÙ°{GI‹Y´%™G+û}¬¯óœ¸¸zšáQq°¶À?¬,¶Z¹›£’û–žÇ=¹Ï ¤û‹:Üî¸AnÕ´NçN;»k[Jcݽ9ã½™ÑF;eF™½ly¬ѾºY¼¬'*›ËZ¥»ÚÙ«”&öºàaÖ±ü S['}¦hÞ Øöû¸“¯±¥3/±„wbZú;¯¤Æ AG/¯Dg<#x»Ô)̳7K±ñnð< ´;8ekÕ¤B¦YÆåÔºá"ù¯²r&Œ«CÇ®§¨ühùgôEÄ1«ÚášÓ±åøú;ÅOùʼ>ëÜx»ÄO¿¾|¼ýM™®•ÜcrìbIáÌä*VøåÁüЄ|c,y!Æ6Éœ'σÃU¯\3ϺáÑãÄ<³žúõx¼IyyɱüQ’ü­=¼«ÅºõÅû¹Î²c'ºÛÆê‰Ç<‚È›ÜÓÈ›iÈ}8êÝ7Ó3eÄ<•ñ\üð`{ÅM© A»'Ë9‘ÄO·I½¼·Ï×ÌŠ§-ÇíÁgl\¥_lŒùæÑUʲç–þmEUÜè—¤ –åãš/¶¾Ã^8¾)¢›øS{ßþ8«\—à¥Õ~èôý¬^ëà½ÛïmïÞŠÁ°~ô ÞïÚ{àÀ¤6Áá ù™0õ¾¬…íÓwÞó‹ßK—îÓ£éN{ø[ñ¬I¶› ôç[ŸUO£%œyô;’ÿIºl áfÀ]»Õö»Oºÿey;ô™E³…­³~»{¹ì.ïøÍ‰²ÞÏ fiÞYq ¬?ðtÃø×éû7C®ßú]é¶1üjsä‰ù•}Û~™¿û\Ú„þú Úqó Ëàßà~ʨ\×ú8Ð#˜äB8 °àh.Œ„Àh(d2A Ðpäm ‡ÄbpX8Ô]D"BáÒ*6 c0é ރʆ҉tFa”Èfѱ”¨k2J§²IPÎ3•ËgÔ €s ›ÏÅÔ¬‚ES•G‡¥#[«É¤v­ ©È!XLžÊ2 i1kTú8®H*SëÖ¡}’[%«R¹4ÃÌô*ܧޮ0(ÄîkqÀð´8j/u•K,£1†~?!ÈFôÚˆ¶^o­ÎŒ…Ô.Ÿ:1íç‘]ÐΙÖæ`û«¦ó)Å•à†C>5×ÁæôwܾEsO”ØéøƒŽåƒ[¤ƒî4/~§›ºù21z²}…Å{ùXsŸ•ú »Sé€jõ·ªÓøý°ê<ë*â¿¿lʦ¼¿´ Þ¹N’Nþ+ `Õ°n²Ú*Ë[vƒ†apa6«¬M.+J˜®)„P·FQŠòQÂL¢‹îŠÄÌh@6¾2 ªæIʹ'JœfÙÀ5éÄNÜ·r|ê¸Ó•/=¨£”¶ÌRdb— ÁSXÝ1ÍìŠá6²˜8í‹h®&g&«ˆlس¯T¬­ôMBP̬10ËKF§m%RSÝJ­*Ó L-b˹S³X¯K4ó…HÓ0å к³-HÎ:µP²<ð}>…AÜØÏµãYæIÐtsF*Q¥U3gƒÊ¢°ÖbQ"Ÿ/èsB04Â1¹E0&1¥3”ìÊ™0dR‘¦R’YL {%Ü<”‘ÚdÓÕEMM;þ¢•MH rv(1'&mÿÁÊ£Ae@4OU9í“ ÙRI9òaÅ?ô|Ø] WNîJP,o¢â¢úX`¬jn(¶&EMK’È©0T÷|Чû½Šã¿ºó-wI ½”=DÙÞ9ïݽ5ÞÆ[rë|íÒÏÀ×Ý:‡|š0 vΛÛ—]m° 8aX*9Þt'ƒÖ}ìÀ Îø[:áƒcMÉ¿.éøÜTuƒq]É´ ÙÄnãPî4hØ‚ÌcR`«ñ†½7)1áŒ;Œ"}¸'’r`;}],ÊôãR[µ“ðc»Ó:EAü³&Û´ÉëMÜÅoìž’S×0Ô3†£ý¯ÉUO+gò>r¾¹ZEï(cHÆþ]º— ï,’4ëFÄÈm}!õ†ÁÀ)àÚɇ_lAAĹ«Jb[e¦ʳÓt¾äöÒð[¡¶³T^Äгޭ@:qQ=R h*쵊bCÜuuÌÏÓºõükûC¦µ´ÏºÛ˜Rm•M-³yÑZÎð[dXh¨5¬Ú¬¾àé[Cྛ¬2ëíÍ·4ëP×ÚcQk0Üô6ªc[¼꽩Cö¾°jy> jlŸ­ñ¾Ç´6¿aj©¯§­]lmu²xEqÙû!¸ð¨epwÜ¥âÓ.Vo®5¨÷+$n M¨ti¥ÚƒŠ¶Ûs`5RãlØ5c[¾Ç5–uÖ#áø»›?<¿r=ÿ¸<Ç rÈKÐõ%pç¼Ð\NÉ­‚µœ s6È4¹Ñ›ßïëmÖ×¶Ä “Vu)'¿Ý >‹?²"lÏÚ–]¿ÅûÃjμŽînÙK·BíïÙæåáÐ;kkï!À7UKÃh’,`66›‡dMƒ<_•Ùt¶Áù±“Žªn§ÍÇêKw¼¥GwOÑú‚íý<QVCÓ¶«‘çØÖÙöIâÉxܰ}‘º–_Çø”£ÚN‚íÓÀü›mß ƒõµŸ;+Ü m}’óg¾þÏ•r/¶ÍþOÌgÒjåz¦Ìü®·óúoÇÔí-£õäÈ™/eè7óþ4Ùßó\?Û¦:6ëͼl*ŽȹúÂËÂÏ<á¹Ãû8„.2ˆ²C0´$óǽ"=t6²ûÀC"ßÀsÕ½¤C =È×=ô)¾ š©AÓ㢴A¾YL¾0¾rܾ¢e¾›¾ª9>Sì>ãøBºÙ<âØ¾ûø§ô.0c=¿LÁ×$,QCD6@ƒù©ÕœÌU!ËÛóüCØâ@kî¿òèÄ´EÃ럜DiÜÅó» ZºìT±ŒbÀ¤U·„d½S¹ ,;ÂD:¨Á9E"#ó‰K™ãõÀ\À¬HœWAÄ`=sìF$^ t˜óGcÍ£\Y<{ý?¤y™UFlLÆzÔ¼à LmG<^ÅæÆÌ‰tF¡VÁ[¬ÂO¸óyÂ;|GÁÜÈ!¡D$ÃÔa;|²|Hl ÆT$Â<ÂK¾5cç&DBB{ÂB‹ÇB´*<\+¼\-B“Õ¼³ñBû‰ÇƒÎÉäX= 7½cdÄãÔ¾T8=køJCØÅD;ì <=Ñ#»l,Ãá)CòzD˜Ä­Éd­>4C£|‹ÊÓèFÁ¡H£è±©‰<|JDÄK³l{DÓPJ,É‚¼R¿¼ƒ<|½:šüÄôgÇ VFLW½œ½sý?ä=`ÊägÅܶÅìȲ|̤œwÆt @”‘$UB,ˆFd EL~AìËäŠËüžF»¿H ̬qÌŽG‘ÆìzÍŒs?„tL\ÉG\ÞÉŒwN«LþŤÜJ°äÇÄ[E¤Ó>ÒsÍ|^@4ÔËQuNˆ‡¹’¡šÍð¡;d~•ªß±›ÆB£ÚÏ"©.d@¶\Ï#k4S¦»kÎÒ̒иÛ㸬q3½KQ£'Œ‚OôÝ£D€­ ïÍÚÊÃI:ƒ©Ï q<Øœ‹Ðb(+»Ç«l•ˆ9»DÚ¬ÄëǪãX¼A¿"PRCÍÔB¦KëB¼˜4G©]+ áN¾UJ¸KÍÔµ½•M«uN®«ôTô0Tƒh>UEÏ»ò»ãÂSÊò4˜Æ¥!E,EX$3.QJ¤íÕÅ3ÑHÂQa„‰µHŒúQj~™5KÉ4Ub1+ÏVr°Ñ…d'mÖ£dÖŒ5Ex¦ù䳄’mo/…¢´ôÑj1ÕÊúW#!ÖÂiƒÍW™6½gÍV -Ñí]É„ŠucJìVMÅÃ%Ñj_A üJ5’£èXDIXS`K‚ ›_MŒ/L娱„±jÕÅS€ÖþTM©[=¿ýH×~Ù X$SwÕ¡ 5R"ÕëxÖ‚3ín'½’&Ô¼QJk}a×uŒ×Y WUtQÍÙóæQ¥p‘„ªÙÂvHñ„Ö£ÚÖpî×{‘­WЋ3oÙmqM…~UŒeZý„ÚÒ6e˜PýfÚÿֱ¬QjO½lÕýºSe·Ö•´Ö¹XÖRXÅ=c±-sWŠ(JeÚe®W ‘ÝmÚ5³ZB ×j+V…«Õ·×­«½cÃÛ,,Uƒ¾Q5€8Å8ífØ3ØlÿÑ¥…®õ†Ëe‰- ÙG%¡?}X‘æØ¥Ñc·å‘5¥q¬Í”Ý’YCBÝRÑäAdäSäaÒÁÊ„THd•ÝR·zÿÝÛÝî c=ãÈý´VPݦ8c^Iã„ âTeªâF/±.Wá«–å˜â68Oý™a}[d~\"¶7Â"ŒaÆ^aö f#dæ ^eÝÉIü¤Ø&\\®]ɾ8­W:€ÕAG¬Flc½¾,`Ôö—@4•ˆÂgä9÷<Í9ç5@[ºÈgl*6NsžmÔfþuLfç:ÐÑž|æVoç"’ÁpU æâ_.önõ[g•E¯† Mh“¯èzI5öƒTŽBTöL¡ŽKhûH#ŽzéËfi¶xæú7g”¼–ˆÇöhæþ¢×ÞŠÉà—ÓÁñ“†¦ÈíòV©ö-ê¨*>‰©þ¬©›ëyyR ‹ yk ‘ë5‰ØŽ´ÞÁü•ÃȦ·Â¦¬k”?¤¦¹(ÁYëK=(n±1ªkõ“kF­Af’ÐåŸä DÖš«lAʶ½®ÇÜ elîÏàì>£jòR&FÀäëörµ´Ï¶¾…Å]¬Ü;'k’©gþÕ>Úëk•—m™âk.Âj|: ¾©mØŒêŽÝ_¶ê¶®®â龩Z&Áë‹kÓîv¬ÞÒ¡kbŒmθböçÞžbí°_5=nîìkÖÓ ›Cm ŸŠ.Ͼ©HfElÎ]fþÅi¦Ell¯l’°ìжèvøÓNžo~ÔïaGFõI†óɾÒ\¾ÁíCëÃgozföØ"†Ùnóí×6Û¢ÞÜêuñéÁp 7M†³qî®–ÜÊæ1®ëñð¨7b¶ôì$”l Ñg©î«ýsj`¡Mꈯ@¡:öÛrÊØr(¡9G"eSî'"£û³ò&0r–°‰`×r®ªò»ë@»óžòCçrÏ0™Ç1‹²/"c£¥ò|ò_+e9É;O$Aw!ò¶\âo.¹§<ò ê`£rBßs-©ÉmâFì±PÁ—FsåçHæ'3;òClôo.áŸ'oHôÓtâe¹_-8¿;r×»€Áj`jFqˆ±-m·YŽãõ¶äõ–Åë@æà'^¢UÚ"d¿c°Æ9kq —@ ’•ë§fš35"eR¨·a»~óuöôuì©ÔJ&u~ÀutðªJ&"Ö°j¨D¤w' õìJoßs÷-:mp¶¶ô÷ vlïYšò"g`¯k%ξö;iõ¯ji÷sÕöšeí—fš øwk/{ø‘˜v7Wß§sɵ¦÷³Þœwcxö»õÞùõ¬9î§lî€cgZÔ]Öö·e÷µOv~õ׃-–v¿w÷pvã9vö’w¶JË·rkW‰÷O#÷Gvu¯wE_¢Wb“yÿzõïW÷Ïž÷ç”p) xøÍx]Iç…î×øZ”[ÿ²¨úûG¥xºã´x§j_;žÚö3ö‰ûýwégñW_VŽÛ‡jõ•fxŸWû'¸ÜYõm34·c|…jõ¬q¨ÖúÞômUíçÇ~|÷`cïŠFtqoÓç÷°©¿³üñÞçÆªüñ¿ýÒjÚìü×C.°üÅÒõïËq¿cS,uïÉ÷z&~7âšÇi )¹ù?É£Ê&oÿq—àb7éBl ܇w±òÙçZþó|¢b·çñ¢·ê QæÿC;þˆª]¶µÿrÏv7ôêç‘§â;ûçøðwù¢°¸b6 ¡ Èl.aÄ,iƒÂac(œB%„B…ш|D\8‡A££‰:5)Ž…QQ˜Ö2Âä‚lÂd1šDBá„–u3ŒEÃ8$˜i1¢D(ÓÈå.eˆ %”ª`â28« ¢u‰•jCV¯Ì'ðÛ2¢3³Ê«‚êõ®~9ª[æõœ~Ów˜^g£Š|Òñz§Qé7Ü&ák¿Hgôf&e‚Ä_êt(@Ï™r™›Ö¹C-ѺŶkW¡Ô%wÀQÏ[›C§9™Ýÿ˜©SqT‹^æ‹D°bêºÍÄŽ·]²òl\~m/UÐÒÚ8÷Hºé{Þf±5m…/7Ѝ`ïôn›‡‡Ìø÷yµëÕœ¸w|yÜÿKµ¢{?N²Dè­3Vð©rDØ €ˆ*&Û·°jH‘¸-òP¶-a¢à­¥ ‚±4ˆ„>û!òŽü»Ëü@OÅKÈhŒ‡!ƒ"Ï!ñº?DJ¤xD0ìv«HMœ‹ ‘ŒT™Ip‚Z—¡¢­­ðŠ`…ÃN¢±-/îbÖ…†«¬Á.ÂÎ< ÊC»5EÎʘMÊÛÐÿsPd·(Ó´ð·=êÄúÕ´“4¶‘PrÌSͨûNä)t !5=3•Ä«]! ÌtÀ]$1l5묘µ¥ Tu5UUS´žÆë\ˆI*T¨µÕpÀÓõz¢Nµüó`Ït´-^°ÖD@Š×)½"åX2ªëK«|uSµƒ´¿¥ ås+T›ûb\¥OWESUÚöíw&|ktÅUîß&ÌßpMÏ]`"¶ÑÛ¥Ëw·JôÄØxTá{Äîåix:îÃ2H—]Ë. éuœ¼Õm{mØ ö`äK®“do#óǸ¥q@-›-Ë%Œßg–TœJvÙžãO …i0³Ž‡¥7ïö’ç±Z‚©Oövª­²yî¤ËëšÕáe?”>›5Ã|ÚåY>“6RžWE'rë«îf[»åõök™è»îoç0&=²ËëVûD(ð\>ÿ´j[ç%:YvW&Åó Þíë)·Íô®¿ÑÇ[ªm0r2›ä8vÕÄf‡/b4¡BòócKuxÑJÀ¸€›Ì*ýF°õ¼ÇöðåášFrÇú>ÕšŸL/&Qò ’ß#ÊÜF* ÖJFøÙ äÉôVÏÑ(Ø@ Pâ……°Ü¼ÅÇú‹Ë®†ïQH‰Z|]<3–nŽOËe—åD»ŠäËx‹!™gï~§²ÜΤ¹FN†̧M0&4U’åå Jy/)XAá“ ­¶ÉÅ:Â!tT@2\‰KÐ~åÁ¼Ls²aÉ·ÔBàˆ8'ð>yÏõ ÓÁÃÀÖ~´¹€š S”}Q}=HJÅŸ»ô ‡-GP¿*áy ‡oöu¿f8™}}DÉO@ ¾±X¼—“´6¡ÉÌã¦ÜWhP¾l1©^K)?JÔzdºJJý&s–i”ä󹩢ÄÙD‹§*Ù”)·éM‹¬s¦k@A9LI q~…äºÃy¹i4àC}·Èê¼Ìäc¢ïғƹIã#ê”.¦–Êj)0ZtڪΪî‚Ä×7Õ¶˜Kèm_¤Ð•‘ªb>©«$a¼Ò˜pþ¡ÌóåPêDP–¶)EÛ6k[…3ŠH;)ÅHbÄ7?–™Â(i=#¤~–²MZ¹õ=æ°0²"€´ù/nh4/¡ìFÝÓ«uC¨e½¢P*–\Gj(½""ôB“*;+¤§×:Oq©SGÈpÈS¹tãn¢2¦‰^KÔÊ1O./´öà^ʃ"/…EÖ:{=j–Çj‹ç˜·ž©XJš°+½Y®%þèÖ7¾í+n/¾îÕYÇ_š“ÝÀ¦9dÞ8íQ«£,¨Uº+ÈHõ£íkœ~´N ¬ÇÒ”/% Zm>õ¾[£sôAèR/ÉtÔÉùÅZs+yâ^B*9FžlOßµ¢!-¿Z¬Žx+JÉb£b$$ZÂt #Ôý”³Ê\—|sQFºp»/RKÑ•²2ÇM:ëãv59Pz¸ØÍùC}äF/Œ_C¸G#A±SnHKFœkó–tv%È冟câxK¶CKŧ8&,ötA¶¢½y¨Ðê|ŸªoOVÚ™;^éYÂlsVÚmZCmfmµ—tÆlÉúo[ièó¬56­×»·9ê‰õN2„õÖ¾Šk«£µöéØúîŸïÙü¸·ßöW3l‹ ¯xU®Í\6ËðÍŸ¶‰«ÚsêÍoSù’¶ñÈÁšE©;}ºÓŸæVÛX÷K¡ˆï“Ðáq[Yd¼­”+>8••\{;›a=œ¶UæjfÏ{RrÔm!¹I®{|¥ðòžCιKŽ’3ƒdç„•^ês³æ¤Õi,VTðÆ1EºìÛqi_¸]â¿"½°·uÞßS£}!ÝîÁ.™Ýû¤?=²slÞò4éQý§x÷~ͽ FöºŠoη|ò?W¿5+­b¬AëRó]WÌÉ -•¼›£?¯å\ÕãOçkìÛcÃÂ#£Û4çnîïÓ{>û¼7y¿°R-{»iá‰ÿÃñkÂ\žßâ)Çe¿ž3yøÿRþµï¥àÞ’p|^ å±X ãþ²®iÁÞ——¨ŸX[ÕÛ<3ù§¯ÚÈëÿ4äÿá¯Û8™©zk<†¶._†ñnÈL¨ùÊ ·¯bÏÍyƨÏbBÜ)PÀo bðÏÙ®ß-« ø®Ïð¸N2_ïlׯƗ샚‘¥FHˆLBPTåÍ’7€nÍðÌríOfîÎèžö Œ³î:!¸ÑC¢-욺„®¯B+ IÚ*0š—ž}()P Òcy É /ïb¬ñÃÂ1Oû ¢Œpïf‹k¡¬ðìrùNîåŠl<§ðvÄ‹†íðâ=o  íPêôpï®å Èò°èÓ.îðΚpÒµ®#KŠ.îmI=)´ØÐЮðÑ20\Ó0Ò€cÃëÈíhÄÕHµ ¢Ö«ïôðÉ™I,ÌT~--‹šŸnïQ5ãâïñw±1Pµ0DèböhcQ2ÉÇÒ lê!êèSÃn bŒ¤"~"L iB%Q¤3âݱ¼#‘À„ªèéâÒ±Ì9¢æ"z×¥B¼¦‘ÞŸ·h^ZQâÍ©æ âÍ?-d!ñéí"5ÑÕl½åD=‘ªMh´ó`ç¥!Q´¢P#2 `jÇr7 Qÿ#Æ•±Öè#$²: 29#Ô[2Y$Ek.é# "òE&Ì1 Ñ²tÅ‘þö1øP1¨ö‚U"E‹P&+ÍM)0&(þ²^ܱâürS2 ­Ñ!bm++õíJÄ’$‚‘ÈŠ‘°ë2 êàhV£0 o¬~F r5¦ò oó/"œ#+ß2€rù!îØKrøi€bî¢]’÷¼ü,"Q,òÛ"3! òÓ+®Ëò%ï!$½*÷)òêbÓC/Rºóòí1ß-’ƒ ¥mÒü8ÒŽd²òyer•óO0Ò$3?4r§+ò«8ÐdñÞ‘qÉ(Ò™+íÛ,R9“)!rÓ-s¢ËòßnÄ:Òø_³Dw36æxѯã0Òÿ/ øsà “ÌLçàl“Õ(Ó(Ý1‘³+òÓ:0’$ü³%!«ý*§72þ²¾ÿ’»³K)s=óIÓç20‰>g¿G$p+ÏKOæGAôÿ?3{0Çÿ8ÓWr­(=SóMó‡0ËAséá4ŠÕ4Ó70Ò7SÕF:Õ(e?UQT“WTÕR²“TaSŠu@4Õ4s•/55RQ5ÓIR•ЉOêI3Q×J33Q”›33WѱQé,´;)4õ>õ3u¿Xeu,ÔSNuËX ‘ åSê‰BÏO]³»Mµz©§NÔI.•Œ'³½O”_ JÑ´$H#aTr4Ë;b#fR—öfl#= ‚ô^hTr•2÷^v$–CG+Á(Ôëè/i+'HK¥Ivf ]vm%ucÕ}\V³%ïSe–GWÇe5}+–X¶ÓCf•CHªÞ+Õ<‚ä·UKú9ö⪖ÕkòZЖOnâ~åÖâ½VÛ`Tršµyp‘ï2ö–˜Níh•5×—w ¿±ùXV‰nw+mô ¨¡R4 HW)sÖ¦¹µ™irVêv¿]Õ§dUÝH¶®Ž?±±qˆ¡QÖ·s’7vÖu]Yi vÖƒwÔýr]ö/n´aeбc6ײéfôËfËŸL´ƒtU÷6újƒX§JuaZk~ó¢Újï±ð=šk1qðiš•,9$Ú†nª aB7몳S„z«)Í…«™§«×Ç.½¬7Ù:ɋҫÆúÆe~úÕCàsC¢½ªÇ*º©¬UÝ­zhØfFɦªY®ˆe¯š®€š¥®a©ÒË‹š«>Z#›“‡©Ø^‘{+„‚¨Ò#Ÿû%†ÎŸ¦§—W›CAÓ{°5É‚ÚÇ¢Ø!¬ô%®Æý[ß¶[µ¸&_yï…Ù¨[}{IEoã©Ó¸a>[{¨t±/6¤š„À8ɲ;CF…¨o`Fߺxç§4w¸{¸¡[§;&ó¹X_4û7?-±Ú*8[Ó,ºë¯“k¯ 6:÷´•«{µ«®·:Á¿X!µZ˵—c¾úÍ º÷‚Û¾;YÀºã®fe.åTœ;U¾šûš|+°Zÿ©:­¾{¸˜s›Ù²{¿ÃûÃû=pTƒ³s»Z—X[Í#{;IJ…?Û}3£1¾¹I¹óÁ”[U•û[ \UcÔ¶—c¶Ã ·OMÅÂÅ¡¸Ç—§œ?¸VŌQ`œ¹¸é³{¢•{¯b#šv›Ooò¹}§—÷ý49ÂGkÛ_%[¶ö‡ÂxÕº\-bª ´™ Ä›‹Ï›¹|ó˵ç³q¯™%o=»r=k¦½Ã¼¾ÜžGà5ݨ½ÙtqãÕq)̽aŠÔ/»PmyÁ°ÛÕ;—ÏÓŒú“Ów³©½7^¾¡Ù”ÑÐÞ»j>uá9“Ï*šlSrˆï¾Ñ03ϸôÇíËÕ)'—ÃóÛEB3Ãô¡î‰oîf•íôL8Ûð¸÷©"¦ÕE?5eÙñ’_ :úçðS¨d{0¯<¤>ó:ï­Ã”ãC>ξ¨pœ9 úÇÂÕÙA_S0;õ” )¼-22•Â×5Œ~èžú9úûöÅ#ÅK÷B'÷øo5’<åú*<Ç2š-_•=/êVÒ<ÉÔ@¥CîÄ;­E®Ä¢ÿµ-“9ú¸ûoKûÓ¨Mÿó-MùÓ·,!ùÔÜ¿Ë8¹þR¾ÑßzŽAø\ï3m?ø`d ° †Âá˜È@5ŽÐ($ †C¢¸ FÔr*5CG#xˆÒ7• %éTž'•  S(TÒI*ÉçC9äR 2˜ÊgrØ8ä\4£Ê¨T¡¸À]”J‡É­N#9‡ÅªC¬\sL˜XlrŠ`Ö[± aƒa€Â¥T@®UJ5Öš ¼‹¯sQµ0sq¹ÓdqJe:ý‡b`ñ ~6¨7¶É/|µ(m*¶eÚÛ™±c0RùeÊÅ…Îj±£+î§KÚv“ý´¯9’Ì$9 7W0I¯œ^"Ýi¹rôc{ŸŸ`æÖq¼ Ke¹mû½—#«Ì‚™…QÉýW©Æí›}C^&ƒER¦N>š1ÅÓ«Û­¬ÎS‚û6¯+ôé·î< ù¿¬ƒöÄ;0¶ˆ+ʃôº(.Š˜Ý!ÈJî©B©D:Èñ0©#+$@ÿÀŒÓ.ƒï“ ÊÅÁˆnà2q2¶ù1‘ËâùÊ븈Ä2 ¶Û¬ñì^§©1Ð\AóÔà3pb¥)°Î„>¤À²ÒáJ1z«J¨›ÐŽK'.>0p™Â’dÎÉ*óŒÚˆ*Ò<š‡“?<Á¯”6¤*3Úo:P“:Í¡Ë\h6òõãÑÐ=ýRLêÑëLþ¥AÑÃE"Ìê¥CLë3DM³ì±Ìí»ÚíAµŒ óM³L[ŽtL5Ìó}-OÎrM7;¨õ3Õ²%•VÔO6ÐÖ,Ñh,”m?L-T?JÚ¶ÝÁNÙ0mJ¯DTýÍaOuM×eÛ³%a'Kõ¥ç.OuÍl¡KvìM”Ý[RÚçO½¯´ó½(3\¿¾¸ràÎ*¨ú¦¸”ŠÁøÂÄÝ/ìž14*͆±n+n¨Í`îÕÕ¾ZñÖPJ[–ª˜¥Üe²<—Uç‰ tc õ‘¡£ŠE£:æïfu–¬NÅã“Áa…·Œe ÝW“!›äì»y€(RÀ±,é¨hªO ÂŽš‚c¶áH6áyì•VíRñMoºÇãJVùÚb3`‚°˜Û¡¸S㪋…0ù¤çI \+ß’°F6nj!¢‘ͺØ~!|¤°6EH‰ +Èû«tðõËÆ— £„MFñ^(Ç#ÿ¥ûî“ú&Å©|^|$µ~@k ûãPÉÁy ò â×…²Š)LYA1bé}œ3y½’¥# dó¯šÏ¶OÊÙfŒðEÍm°É 4ÀC`“DÖ{Á™µ?” 6FŽ6‘ ¨1¡ ÈÙ¹üóaj4rSÎP¹š+,àÜþa0¶IPvU@'6Q²H™ Zü!L敨òAj»e,צ3RаcK[“4t¥Õ)ãC œ6[´rÊÙUAÒÌ©¥Ê„ËŒ]!TVôæ©DxCbÝ8}ãPÊBÿ¨Á²pïÚƒ­øéYéµi¡ˆÎ±§Vþjû{CE¶WEºþ¡5u«uÁ ËJPº¢¬§6 2×é¹2h£®Ï²¸S*ç+aT®aQŠÃe(Œ¤‰”¢¥ÅöõEe¼‚©M•Õ‘«7>Ý]U…-}ÕÒŠ†è µ•z²¶ S['m¨Á§§rºµSók?«t 7W ÄÎÛ}g [ôžÚ7(?E,ÍåYÂF›ji–¡•:èBªmg »°bìG†¶  Üüi¬õB«Ùuo}¹ $’õЧ3{ÝU¿3jRÑICÝUõ"ÒQs9(ñ§˜,ÎC|`ª¥"¼”æ]úY.%-0ÂÊväOâ™:pV ˜7 JÊ€´†šX«ÔÌêA‘°êßKýjÍú«çجc\žV¼Nü•J½Y¨dͯUÃÇ ª r{®öÍPrTü+¸5%Hó-å—“ë†`¶V)NK•g%‡ŸÙN/̪c£nNuöG Ùs9’#„¿Åy!˜)w"} Çx ã)ž±Š8ÇX'2àÈ`ÎЇôc;é\èTtÆ$8C6¾©[qh>SÃú¾Î¬é…4¼“Þ} ¬4^Õ¸’BÛ¸AðEã8WÞ~°²H‡puî3ØZ™í8uÊOÖ÷ǵœg #ª×è½µÁªYÅß×%r]Ñ:pAÍÓZ£rPI¸sqv+{_<Ûá7ŸsÍ…vd”é»#«öÓHŸº'KÖ˜«¤ûð3ý•½? ®6ȉ´·´Íßu¯}t'9˜·ôÆ8]+ñ¤‘\È®IïdSƒGã„öü6;þQ~‘Xc„þf6¶ÿ&à8Ëd$£W¾êà=c’@ž)Sйƒê I­¹l¶P†:Ó³•#¾,/3^:h¬ì*ó2’Î2éÌ‘"ŸKACÀ©"ñ|ŠÚdJœ‚øð©ÙàŽŠœ”„Á©ä¼REŸKº‘¬!œC4AT6L$¡,Iô©¡ÁÔ %1“»B)0£$ ÙòÂhõ Áà– 2ALÃ<²Q¥C„A#ƒ¬t*ó‰Cq¯´!.¼L3[?‘òÉ«œ*œä;’#›Ð¥Ó2­@õDc’²=¹%=3š‘ò—@Ô/5Ä*'C°.¬6ð‘zT:ÀõDN@òÕ@Ñ º9¨KÝTÅ3§E“ª7 ,dT“Ü]@é¦Ê‘Å$Äà‚º|¾«²fÌïÑkL"NsxÍòï$×  ÍÄÛM¡`M´”ÜÜÌìý­¬û”Üü³M £dâÜãL,ô;ôÔ¼„ÑçÎ< Ë£‡•Ãf³`‚¾”ßʼ ÎPtâ›»sP V'5> —ÍÍd & Ú©uP”ª,áQ‘î`šKʉaˆ·áЯº¹éŠU+žÓÍš}؉™’DS‚ÓÒ8U0š«H›¡šåRÍ4Òã8l«.Â(Ó£6­<4c¶Óܶ;­<:¹S¤Þ™µ5>SESJ=Qq™tÎF¤¯ÒóÀLA¦GÕK tóCÖÈ9¤8½Oh„§Ú¹Òƒ¿:}S,¥)¹í8@¢Òá½RÙÐS%HÒý.ÔrYÕ¥3Uš0S-5(M4Uô‘UmFÓ•AŽ3«˜™ºSôšUô•R gDµ@VB‡T2Þ­½7KˆëVÈNµF™›ÌUõIHÝJOC ´„×<‹®¨²·´8öWeQÒ-+¿>•YUUNMµbRò ×í\U€&«ËÔSªVUC$|›Sj„ºmB:U8ÄššHV<’±¹ (MDÕò!TeW ZÈ¡gT»øWQàÑ-v²Õ”U{¿1–«ä – Æ¿hŠáÔœB³%lzYèYý›„ˆ× JTl™ÚI–Ú\ZY|E¢1Z„` u™ÅCóÙ½œ×%Èê!Â{1eú?MýÞEõbKü™®[*" âÖHÞç©}Ú©SdÆPV ã«4d“RQµ›µ&F`«2™ÎÄ;Þ¤Ë]®"3zz˜eǺL¿ÜYËI›•y¿&q¿­K“ËÕ Ç¤Öv\}÷ß-Çç50Üdçã¾{d]Œgœý\[C`öqµÝ´Š3›áCÎÓÖr:·“óf>ײ™áþ†ZŒÜ~ˆP¦:ûÜ{,0hãAßh/ôè\^wTž‚TÅ›gQ»é.ÕmgoVõ©èJÑÛ¾‹2.‘g+~Ü^tg–uÛ‚;կ焿gN:a+å­Å±~Œa*ýçæ€¹%‡h#nT–X^™hV­hm>èŠÞn±gÓŒéÊHhÞx:¾µhí h̨^‘«]øjzg©æ¥õeêÞz\^˜T†n›-F[žµÒa–g‚Jff¹ÄÍáá)ÅvzÒͦhLᶉá>¯¸ÞÅg Hç®·I5—s®¯m2r•SÖÑ.ýAíL”VYæ9m{Ôã1í}m]:Ö†Ú®ýÉœ‘Xvß\m¶üíë¾íÖ‘‹zýľÚ×E‰aøîr›ís¹½q›šBdaßåÖÕØ¾³í~¶.ÒŽ­hÙ×Vјï;CÓÛ8u9žc¿iEÔ±ßî7îÄõï¾é[èÎú7u¬“ÂéENê~p3íÑ]ÇÔî·îlàf‘ðoío~ý߆üH¥;ïÆ»í*>ïŽàÎg ØV¾íÜ)_n×ë‰ëégÉëíËFïg8®ö$[Ïq«XÇT.ön¬Ýprh¯ n¶ö9SRðvQm_[Nâ65·îJmGäÎöq…Çol]í*)òd–¶­—å,2›âJU×0jÉ›"J£Üw5ao1«þà\hÓiÅå•.œ^0qG9iîÚÙ…Ió>ø›äÂS¹¾j=›´d"ð­AóQÜVð£˜ÓEô ´T·B¸6ôÁó§?Yï ‘Ò:›XñMoÀ–BŸp2Ñl!pY‚ÈH÷ø†Ý÷‹‹ÁNMå_Ü÷½Õ{Om¾ÀÃÑ•ô‡Ävm·Þ%ô’8Q³’3Û&“Zsäf‚ã ¥þ§‡Dw:9Dé-ð6;-ï>@¾„ÿ&»âû¥Î!ZÙÎúÏyöJø²aÎîM7îïg.¾3¦Ëxdçal&§ º3¶¦ãaŽt¥V¹¤÷Y8£äÁ§IFÌïm¾`»­î0°n8â׬,&Ô UÛ’’ÏÒ²8p¤¯*nŽ)+æÛ*,ó´ïÎ&¸ê›W Tù.Î3;ó7«ò|úå^lªMb¹k¹ {Ãe[¼é8ì¨üÇÀåòUW³l9ÎwÉj±AªÁz»¡Au/‰§[¶øé–û±¤=ÚÊI—>>ŽËšè¶1˜ÌÛWežh;—]Ø{Ý †å¸žùô$¹2{zd¿2aûÌ–5‰íøvÅнÖÀ±‹Põå¦$¿Qbð[dº­¶º¸ªâG y¬£ða{yaª¬ž 8rëY,‰¶.sfîVúW-d±?FÎPÄ…ë|õÁw!VÔ6/ê.ÒÈN ÉƒnÑœ“H=ü l€æ©Lý ä*ƒµ’C6³ ar0ÕøCv½¢éYPUýA•"EÔºç„64³“þ£tp[¨ì#ø°‘D?YÄ;GŠÉ!¼}hqTþÇb>õ$!>ŽÄ!¶‰ p~1òH;h4Ž#³„'p¨‰Çe&Њ‚RòÉEL¡¬N-Ÿ)TX!Œª-EÞXÉFRNåL¶’GªÒdyŒDvZÒýöʧÓ(Æ}³—K&¶heܯ—’‰ƒM9T•æ„Í’’~bHù4`â´™K† ʨÒâç4–›ÓªΓ²ÕÜìu’¦å^Iâ¼ëØÜv”ñ"y ó}&$K¬”E¼á;ù”°Ì‰´ è îÌdÿÙ½^¨dÊhe#æ«ðœ³n{éDRXô€/ó‰ Ѫ$`½žD ¬E™DÝà» •TÁöQYäGèE"PÒRœG˜1%#ñÒRŠ ÑyE!êÛ¦deHNÙ)J'%'’Ñ €Mù¡M§´$˜Šl™K?Sl­gšʉ]E«5# 2¶µKzÍXç“3˜•~a4™™C¦БóbUŠ]êÜÎwÓBºD:½F‡«ŠzlÐé¹^¨üão3†y—ÚUI£z©óªÈ©H-;Ž=3Òµ!‰ñC§Üg•å9OÇifiœÙ¼«ß[m¾#»1ß&kù·”¦Ý©Ék.×Ú;ߎìF¶à݆¿åÛqê=˹ø›¶Ýq[ø=¼5ñ$3ûÓ[om½ÈH.ú0[ñjN }o¨æ< õ­Ÿ‚÷okZñNO®~äC2î8áøôÏä›gZY­Û²u‡0•œ+ªåž_Ý ³'ÛœßmîwÎ;g?îÝ—¡qþGyç‹áŠÇÄ$~µ¼/Zq\Ëzõ¾±¨·kØî¬5gƒV+Õëï„ïhWžLžy/!ﱫmsÉú 6A[BY(M—B&X¯ô'¾|⃪@{½Í™âͺâð6hþGÜúþ†šý_Ô꾟¤k¹·µ‰IÜã¸_]³/û ãôê?EúO0ó}«½/ÙY÷ièÿ·Ðß_`ÀíÚøïþ¦ÌwOjûÆÇâ&àOM-`ô¯¸ôOÔ—oþå€lõæ¾Mof-nò-ËÊÙ£Pˆð:"}£žBMÔøcE Jøï‚Lo”?Žù°<énz0 öè(úÐtõP(úðÚoýÏüéFüMÕòѯî4OÖÿŒvýïîz–µ¦Øný ÌÝð´ûæ¿€kÇvÖÐ p£Î ˆÇ æØenºÿ¢°.ÇòÖФb°& ®V9í›cD^ïþMd „-oWí¦ë‘ «ä(ì¾þÆø5Ÿ C(æ#DúoºöLò-ãððÏ/+Ûð‰ °\ôX®Îp2ÅžZ¦Æü…¨¡­îTÉÇâŽW´Eí磠x1l84J¶éçH) CQ ïâ~æð$Dï„ØtðÌç2÷b®ÐGŠå ã&(±Žw¦¯†çqÃñ€þÑÐ ÃÀ摊ªŽhB êqg,Ë@sÇ ÎqÒnÇW.'̈óVê~å” 8ÜèðTsR.‹Ï9)æ.üò*r3ªsÏ0©Æ8ãïÀmLË*F@ÏS¤eNÕBæ8Ý2ªÞ pÑô$d!+†åEò@l¢ßÆmFS,g,’òc'CÒþiæäÛ³“>ާg<ótq çIgJåÓsÏ)8ÔŸJgÃIŽ¿A “=´7>´¹>)ŸKãzçs»<Ð@´K7&Õ<ñ þóÐóÕG“xeSß?“å?4ºqÔõIíUO²¿0³ï?ÎÉ3'@sy”MGÅ"’Tl¯õ/ã?R4ñt#;ÌH´*qGAÔ2î»C³Ý(²%Le‡DÔÍzQDÕE•1F2) f9FN;U“FæåG1Gq_J&9CôŠmT‰IÓ±“I”•HT˜éuŒäÔ|pU¡J“ûô¯J²íKKËLL×Pô‡L)‹TpñMÏS[&'M“Në5šùò=NýFmèéçSC”aK¨7Õ‚ðñ==q÷¯E&'W”[GjbôjÛT5F“^NÍ@Ô×±×_Õ{>•ó(ˆd±pU»³ïYu¥I¤¹0%¾Øî9…É@-Ži§E ËPHS”Êã5×d­KWF³Ò hN§V†½(óq=f•]d®]"H™"–>“˜h¬q G`­ŽhècTF³iöš‰õþÞ6’5õ7göŽå •Uµ‘ðkQ}hp÷_F¼Ö˜€13!¦…,ôgmŸgÀÕSWñnbïeÐý>‰f–H·µOëÐZR·ëƒ_7d—lRkçNìŽÃ©`©(UVg*–ú‰/!&ëmpðF‡—Goì‘q2k)r)rþè—+S¦srws5bžW9ow=s·CwOf¼b0Ø#7q1º÷×Z,”—Pñew6ã G(è«5Ü~×›ñ˜œRç¬=•¦é—tL=4¬Va„ôY;¬;a-ÿRmù1Ñ}R)Œ…}ž¶,= ×3Õ6ÑÃI±øœP’±u5$­L"WLE54ø÷³³{‚ï{ÊW\©3^“Ë3÷Ï@7€Äòá-×Úù4ÅwÝ~–½~×é44Ò÷ùràaØŽóžÝ˜ ¸ ²¶­r“¯·‰9$³r·Ix{|Wõ©Uƒ—Ù†ô½|8hpM„”ì]%/?~ò)~x¸ÝXao) XhójÕ‡ ƒ€—‡êasIå1i€Ön¶©*üqÐÃŒÉ7È·ÒÎSU‹Ì¶ïpæùƒ¬LüóìÄR„ E ÔôïO|ß@Y'\ª°ŽÖeŠHù“ÕNlË”XÀÇPëŒ9-€—/”×Y”/×€D‘;Xy–nq†Ë"7.kÑU‰™y‰Ô¯•rm” „5½˜«%K™t9”Ën¾« ·oY ^؞î7w,;c¹q›Yk`—þÄw—tEŽ™³\ +®Ý}˜ÿ0G<­Ü&.b±Œ4 ZÎCî@Ê €¦# hT—ö/-øZS7Ÿô €fÝü+è@Qšfb¾±B'¡+_¢.Á¢ƒ¶+éjZZÚ4ÿ:škf.Ã7¤c¤¢-¢Ê¿¤¨A¥ƒû¥Â{£âÿ¤«¦‚}¦ÉC¦rƒ¬y¢zL4¢¬ÅZ/:‹|:U¨ÒÝš:>B¬Îš§zšŠÚ¦8Z£?ú0aº²Ð0Dz“¦:šAz’¦Ú1¬o¥ºÆ#b¬gº­z˜Uº'ªºVá”­éo¤m±£šÓ¥mô½úŸ¡mô1y°:Ù°pߪe‡¨:ߢ i¢[£ i£zž>úq®zE±„úQ§ºý²9±´:_²zA±éw²úŽ«{G¤ºµº†!zóڙ¨ÛC®º¥ú™·)«:¬Öú±©º½¸BE«¤q«úë¶ÚÏ­›¦ºá©:ÔºÚÛJû—®7Ṙ$šï¯šòßZ÷±Zý*šç[;]šež n"Úݱ¶zç·»Ó§;㬻œ¢{¡¬[í½›¯.Y:¯¶O/¾[às;ÆOzõ¥;u¤iã°Ú€ß\¿»Â´ZÞs<¦:L2Ü+§¥q½Ï@"-0+ñá¡Ñ9ÃQ¦0/Á«­ó7£êá¡3iÁ») {-´Ûœ¥U¯‰?µ®l@-¬DµÄ ƒ¡<¤ÇÈJ;¤{ £h*ÄÁ­ó ºkyÅÛS¿[åÅ{u¢q9©©ËÑÉ•˜".¸»½¥/¤P¢¾ÃZ̼yÈœ}ÈüÙ¾S—È U¡*A¶[Q¬Ðª;1êû)êzÉÓü±íÂ"Ì]/ÌŽÕÈ­é[ÛÚÜÓï^‹Í>íÖþ*:¹ç­ºÝ,Û­Ýžcã~[ßý‹ãUñœÒëžwóf“âÂ}âd’eÜ€ôšI;?©D“èœS£…óþ±¢dzI]DñϺk‘ö?O|Pø{²RQ§1]ÐcõÆäŸˆ^þ ù~µó_\‰¿÷"£¡)ô{™òàg7Ì‘ó¿]µþö_ÁÍ¿²_û“ð_‘êž™ùÂùíNØ_¥¿mâyõÐYê¿Oú»Ý^4 †ƒapÔl 6AC1¼f2âá„  9Ã!Ñ”+cñpâ'”Fc±iD= ’EÃ8Lh8ŒIF‚è$Ni – ÆséxÒƒ2†ÆBá¥s;¥Œ`ñø,Ö%Cª ¨ñZå*[£Ž)Ò¹-RÓªPêhÊ6Œ)Ö `¸s7Õ5™-s½ÍhS1uöƒÂÒæ7*¤Úí!¸Üäöj\TkVµàr5X’™¯Á,”ûµ¢oO²éÅÖ™z‡o¸ÕájmæS.»`*Õ´ö8“ÛFóLDÃuCßr6´ù5©Ëw>ÃU÷ð#âë&ZAŠéNO=ÏÇÛÉØ½cGYŸ„«“tŸ§Å§w¸½îÜíÖc4fmȵÆÉŽ1½qk0ò».x_ë›6ìÁ¹1x"¾ØáEogê ²heK&8 ù\,Â’ÅZ\LÍ-þ0†–Ce¯1“9§¥ßyFPFÁñ!ƒ&QTl3‡¨Œ£õ˜ûSæ}è©DX‚êÙ3ó*ï¹ÈEÆä´½ýEfèLY4(‰Ì^EXHìß»k¶%ƒ¼Ì5å}“GëØÿƒp5åÁæ—^”#•†Å÷q Ì+1O­a¾³W ¡ÛªŽäµ®xsáÛ‡În##¥ É¤5kJ6C…þæÓ±úd \õ ÄÂîd¼bñ€Á¸Gö¿œœ0‰¯& .ÆõäÜu‘F¾KEÅâUØáùÐá´×æc¹”ñ†4JF”î`Á³tr;Ì”ã‘tpIù}- d¥Š³-d ɸC˜ä²Á‘^‹X8ô gLõjÓ¤ž»¶rÖ'T]€@Ò«(È ŽÛfŸÔiP"zÖ§ìém†&{NéÌÓ¦b-Æ‹ÍùfgÊË%£ÐùÜxé£2ÍB ,JT.ÈX£<–r¢n0«NA¥;–ɦtÎõPˆcáq„F&»ÇʲêSª˜Íb~4ÖB ܬjªEÑE‰½$étîvbt‘Y>ÖܼïC :vÍéá(µ¬†Î^ÏâÈúTÄK+:YÖw£ ª“Fð&¥05€ *Tá–&6¼YSb«L dµ:ÅΉÜëf啚“fÌ)y«:[ ñUzT–¥3ê­€~5YœÆ%`æÃOˆu8Ù?š›RJmP?5U¶¹{UA&]U«HŠÚcW(amVb²Åë0Ôàl±ö^èVZçgŒ:^¯ŠKJ»2ëõ§iòÝK› aÖM’º'z©Y6ozR·O+-f®…œ…YqRK»p™í†´¶ŽÃZŠj•mù¶U,ÿ;ëâçNÅ`ºò¢³Ý§¥^+ì·À Yç×ûW†*QÜ—X&¨^«ÇT-cš˜ž£¨Vö˜ä2Ò§ízD²™^¥n4ÅÏJc‚ê¿ñÚËÆ­ú8Ìk]Œ¡?ª·ªGTšç’ì2T¯uJåªESéîªGû'i ˆjIÏÄ•;00 «2-¼…orÖËøiUR¡ª²93ÞÜxlï†-L¦‘¬cUÄÿ3«¦µ²N“Å,Ÿ{po“..‹ZsôTýÐð–šÕ"h·tU™ÑžÃGí4 ôÍ©Ú~ûXm%¨ôõÅÁz†ïj ¾ÓfNb¦—òÃeªÅS¢½É©0ÇKÔè¡s3•òª9%å ×a²QÐ-; Î-f…{ân©q*·Œï¢ÕÒ°Ù›jœüÛªšKðÓ¯0êÕm‘â^‹L×sYáÛË /¼±øÏx_)"L‹ÇˆÏ,cÃÙ»ÀUHotЍ¬‰O84-nKä–±ªwz =–F)$q¢µ•‰—T†‚ÝãÊût¹r¯¾ž4(7o’/XÿÃÉìzÙ=a,÷ÌãÄKoz3ç¾Y(îD ÕÛ8rNEd:&«Û¹ŠNwCÒ©§Y«¨jíXÞém ä­ŠßäiYc'9ª}(i®½Öò$™~6€hNÕµúú]«ýžðõ^Ûkè¿j˜º¼\è¶ÞÓätíï±Önk#uÞD'® ZäN»Ö¯ùW}¼?¢øN7ªíÏ [©µ¬¬ÄŽƒIòQ˜Õ!œiÐ^¤ë“o;óŸêùL­üåâtŸ~¹'æ˜Ñ¿dŽe¡²§©Þ–¬ð|€EyÏ|rÀ¸þ«·¯NT<ŸÌBçÁ‹  Ë Jro™8¾{ü¹#?¹é¿êޏ\@±{ÂKÃBD›ÃY@QøÄkM?s· L')<§ÚÝ¿$¼X¤{F?!M® ¤"\,)3@ASÃ3ô A[=?l:4O³Ë5DÊâÂð¼Ì\À’­Åä:¹Ü &,_­\[BHý1ûþ°¬%°ì-'\1ÅÓúA„7ƒôCc–Å£~°Ä/”0>¹Ã®á6ùРíFxè(¼ ‹¾À’©Á8¢šL >òÁ$4¼tRÅ ¿DY<<0®ŒyE{`Åqƒ¼Ô¯|ƒ6[¦Äáç:[½:B‹ª=¤uA|fDˆBbºK€#<˜ii°ÆÃÜ–Ã ’3I24À It>d–&ÚUšÄ˜ ²S™-¼š°Œ›­˜‚,›@‰Él™ªºkÉšàÊ2@¾»R<¿An L¡¿jÏÉñãJ›ˆ ž²¤J£œÆñ¢œ›JZâÊщ°ºÔŸ–\³°Óµ,h‚Š¢bËQÆIÂ¥Ë,™Ḛ́¸Ôµ£¢gIºÅ´¬³Lɤ},£5|ºJ8–´º¼SËË í©9ÿ´ ¨\Ê»œFJdyKä@‹ {dÀÄÐHköÌë@‹ ¹ŒºJDhLÁxÉÉ?8‚£„9Ì*ïË\ÅÉƨ‚Ë»'Hé¿"\ŽÃQ¨K£NHüµÉÂÉ#r¿Ä“•Ü@L;aÉ\Å•t—ÌCœ¡Û¹ÌáË̬Éܾ*\¹Ë„bÊ”µÊ,¥MbšJ4Ó5\öËKO;ôJìòªºL»Ê¹q#ô÷<î¿"Ñ9Ì­Ëd´Ê´µžÜòMx«PTžÐ³Nü¯Nô‚KôÜ®ŒÀÉœÁÌ »4é®ZªP³`ElÈÈ$ÈM£ÃI\ËGìÌ6¼Í<µJ{ÑQ4ûÈcο$ÒHœÓÄM¸ìÕˆ,Ö½üºK‰ÇP‚Ž¿dñ' #ÌSxÎdÝRj=Í쎲4禋/MôqQaÛ¬0 QŠ 6(Ê„OsK1U+•ÏYê›üôô“Ií ΘñN”˜7¥R”#Óe+º4Λ`6• .r‹Ëª¨5M!F+TUÂnˆ ¦¼á§–»ªÝ¹ ¹ÿTËÑ5ÀŠ»M³&®1sª]O³4É[ZQ‚µ£;ÕL ÏP‚¸Ìá·u:URCرt9‹»r¬(»Âák !º7ŠLY™ b¶½X"½gÃQ¶FU£5•\¶OÕãÄÝmÀÓYTëÀ•_ÇX©"%r-£‚T‹X¨ùÆTìxÑ€Š2ÃVÜIR#%S)UÕ‰YU[¹ÕmXÖl…UŒaÕ<Ó|ºU½(¸”ÜWu^ÒUuÖðVlV]d¬aËÖ,‹³d;h&-T)ËÖGË[wQ]†ÖíPÙ\†Wä-a¬WB-$ìºVyàÙ:¥Ö=S,E„ˆ-†°Åm¹3uW ‹X»¸­Tµ>K}йô³Y»ŸªA¡h‹ÁáOÀÚ±·Z¢R%îZêO„|œƒÛðE³DéãœQœy¡?ô³Àµ²êQš |u«"‘¡F}½ÄKÚÔx,¥³Û]¹>‘Gǵ­(9M3ÉŽÆI¡\9ŽÊq¡\$”úBšcŸÛác8Û…­ ¥Ð¸Üù™$i¦µ¸41fÛ`„Ó!bÝx]ŠçÝ`ÜS#[(ÐÝÊ]a Ó"–›™FÞ ÄšõÝ¡ƒÅãÅ2 U¿ÕçDË&]é?åê …ë-ÅÞÑrGÍé^YJ¡ÅâÛñ•âÛxÁ]Tß|_Yr»1¡_‹„˜,QˆÚ¢Ù¡_Å争J_íÞÛÝñ ÍâÛ¼^-Ã0ô`Uüß•ôÛ]òœ `‘r?6q}`IÒà|íÿWmßàsƒ[¦À] ÛȺ=A»¦amæuÕÅ˺mê=ÓÞõÇÜÁQ¨Q“áÚ»\|G̳Ün1í¯—ÉÛ™T)¿`µÍ\áˆý«>ZÓó]Þ*â™›[l*;Û±‚Ú®-1YÊö1×Q¦ažœ‚hÜÙ¥´Î5!¬c¢UbN.œ‚dZÙÍãåÁ%rïc¾7à^ã‘ÙàÆ:e÷£xÕäb9¯nD£ÒJd–B]4Tž½ÍdÁ®Ý†CÕæäöL®G•¬å!Ÿd+ã<°d©k‰~A®AdÙ>>ähîe¶H[®YãFåã±`Ù†[1@åh»Fc“NS©úVæaó’þcŠigæ•èšç¢eàf»b€ÿei ¢o¢6f$ )g ßfø˜æ:VÜBÿçÕd&býxæ'ãÒ"g¨›æ"f6P©dçòf]å¶h þg“j榀©ýI EÚææqæÙŽfö†gmeRFfÕçäNèâežtšnuÜ~_¢fxi6pg™ÿgÎ,Ñ„qg©nãQóTÕäÝ’ ]ækÍÖA¸˜aÌÜXÅH9.3¦ô)[q".UÓcÒ¸Zö§§äèÊëNV«Î«è"„掭§IHß>†'ýâk¶çˆ¸\Õµ§ÕÍFºn‰¶_Ë÷j`†ÌÅó°HîQë–¼`ûô¢¨›kë÷[“Šþ¿^5<]¡ºëÆ ìP–Hîj‚Ɖ¶lˆ÷ÌÆJlhŽI€Ä?)Ÿìuäl6ÁŠÞÄžŽÇ]óž) Ó!í÷Ñ¡$ìí„´ñFmFÏæÕÞ&Ê‹ûh>Ý cûd^̈h©nØ‹nÕì.Áms¨ínÝîf½í6pž) ´¿,° ѧíëÖÞÈZÎÇ*óòœ6¼,þóS`›+ŽÄïÍ?öï‹l’^kæé¦ÇN»JÇ'ƒôËÎÇe2q\­\ìâq\mí‚ql•NîLù‹uÚ'þM—6x’ð¨Áߨ»3ôïÎødŽ»ïÖHíNùïùâìóï–ôfŽá ¶òñwhxÕojmåðwÓ*ØŠž n¾¹íq@þ-GŠÒí‹!ñ~smöÍoO&ë¦öòIÉ'ñ¦ùëîûqàq]àÁéÞö+O ]Sj¿ožVp@ôñ— Kžêè5·7+HØärasŠÔs·òîºoß pÿ@q&Òì×îçCž7#rwí¶ºq‡Gˆt´qšÏò9«q¿6í¡y6ì+¿I‘}Xà/± cTèÌnùŽÅâq÷È~½$´ÃÇ7)Õò3u¼Îóú*%æ†9Æ c:ËÍ»Q°³Çõl%^'‡Œî/5ˆ>£I^ -:û`(Ì*‹ŽqÚÝ ÛÍÇl,[Ýβ›·ìÆb›>HÌsàõÅÛNlìgÐóøG3»Ç›Ñ Ðò^mõ[ë4ãêJ*ó=Ê\Ì<íÅ0èzn ¿p *ý> zŒ¤4é„"*Ãæñ'n46öÁÏS‰+OÓz¦%0r¨©ŒíF :ç(é´8÷,jO¿A‚˜§ ° +È, «t€±,\˜ž5¬s$ý1ÍóþE´³¹®óÊ=Ï"ß1Dk+&KÏ¢v´ÌÏû/.ÀsŒ×Έz÷ "Ï(<ξ”8P²2°µÑ¼·Ï’´EEº‰¤ ÓÑet}(éQîµü¹¨}N»­ÛÁL•,õ?Pñ¬'T9¯²ÞìC2ÓðìÀdç$±p=g]A•´ÔÖ½Õl0ýBŠá$†‘ÌÏ veSªs“ÅoÔZ¢£Ñõ>¬Â–…ÒYñ~£ÛVô™ ¯2JHÉ”‘ IqûµÊ+ܳ*ÑòÀjç»6ÌÓ:¼u$åS Ó-ƒfÍØLõ…àU†9¾ø|ï)Lïí‡{Oô%«CÒ¯ LÑ5!FS‰$çÒ1ŽU¤#CÓ=߬»§6MW–…+u$QjÄÖ¢Ã"ßê]­ :·j—F\P­ï¤BÑÝÏk¹«#%+1Òh›^zÍzÊêìèóMôúd3JKƒL2Özòæ{M£²BÓnä¹hXh9àAšï*¿Z¤;þ C¹;ÊwÑÀVòÏXîÚWÆâ×=ÆüCÃòúÊ"¥O;À`ÇYKs ¼ßÜï9Ȇ ;ÁõxÐi ?H+ËØ°Ðu¦ˆöNj=E‘˜©LÓš¬D½$¬Kýxý[p§<÷w©·‘ÙêýGˆúvž§SÐ.þ‡»Ëtþ»Õt_%Ð31ÅÕ}q+Éj¶]Éõk±ëAÉGŠ6¥ËO IA>ç8Õ‘; LÍ×:ÅŠ÷“D {O^<æˆÏÞJ-H€ý<ÞvJbzIq]¹øÛŽŒ fíñó0“äæaóGõø¹µð¨sŽPn¹”8¶ó `óuMíÁµ.å¢4oÀÁÀÃüè"I¨sN&%BÅy_²ø~ÅÌ.8¤üÞ‹®|î¡–ÒùËyNþ'çl^³µwp= ÆóÄôÝlQ¯1ìž'ËÊ(¥)ôŸGžê!s;o’0œ×s³Û{æ3By•£Ì‘/‰Û¾IüŸb•“ÁÒ¹·æ¸ó÷(ËrR¿¸é¢³[”¯ÍÜ”‰*àbç’½g4ǬÐe¤‚‚rÅâÁbÉ& œtðH·Áô]d(9‘̹Õ=øQ¡R«…ŠºTà Bÿ朥Bìz[× DÌsQY¶`å’{HEÌÔñ$¸ 2Š”w’µ5ùî¨f<Š‚ î<Ìæs9¡1ñœrÉ‘@&«Aß´ß›ýHCØÊÞ¨Œ†®N|Ŷµ=¤Äc‚“EØ.ãÝÜ`11ΉöýI™ôÀ¤¦ ¨ÉbYT§ À‚´¹HÞHôV§`À¬,ª~TSª)Qª—7’•.duF¦"§Ph¾êŠÃ¡î€þÉãᣪ ¬úÒS¡§Kx*•=”9ΪŸ}j!ê©*S*Þk]eQ0õÕУâDŽ TN4}ÐTÿiã“—N‚œ“e‘Y©¥ƒ¦E‘ßR'K)A;ñ ³RvqJ¬Í-zõª˜"«ºî±(ÑÍSÔKOì¨uÕT§aRA…Kžµö¼Ôúðå«Ók–ŠÂ*y ÝQ›õ•ËUøZáéed‰t”‡¬êtÕ®WV¸Ù:æØm|’ªæ½ÔÛ€}ì–µ±QËZª‹b'-‡¥ö‘þZ;"m«Ušgv\…λdÂÛLGxÆuðÜ8{&êÝÇd·²°Iêg+Mp*îMÒÆÝ[lënŸ¶ñ™azH ‘¦¥¿$RXŠq˜v|bWŠ C ÈÃâçŒ(Æ2r Ê=âFxÞ1Äå,XïÁ¬UŒà龘ò:"w$ . ¬8rÉC¬›2ÕÜ—Êâ©ä†‰wò ÂMܬ4»-‹ä]øáئ“Õ¥ÆåHm¦ØÏ8.yQ‡3¦}Æh|¢Ó°eŸív7Ú–ÇaüÖ¯Ö,ÍJk¢Bù¨ô¦ãÑù£î|9˜K~¦ÆpkUk75µ[$“Ù6d¼Üµ¾c.MÞyg.©ËwºñôÃÔúb”æH°s|™¾;"JËݘžïwV/鉆ÁœPoøõØn0 žC¶<–lìo3ùV<圿>a5x3€üכ܎IÇ¢ мvÒDfñÈb·0äÜW”4¥Ë:]é¿“óLã9´Õê|“œÜþwÐnEújËYΩj#‘èS²ô2w‹r$ì»ÇÉ$ÏBîeÑ’?l®ŸêøsŠq/^ã÷}»qkÃgˆºäA¡Žv¯U¼xÖ $ƒyK‘£Æ#·u­z\(±¿’\d)èl¦ ÎóùGê$¯ê…a"f_Wá÷C½R!Òž*#ê»7ž‘ý÷ÍI?XÞ;åò)]ÔI¿.wg‰ùkÀFªwôZFËú–‹ÄÏWóò箌òT£ÁY ¿ð/‡0ô_c³éaºˆjõ×~…´{ŸÕ2}\ªýSßM#ðjïÇp¦öøjÞðïúîb Îtî†&„¯3ˆœï£XOjîbZ‰G*ЮèWEdoÇlïÏ Î ñ†Hpï¦/ð ðçé«¢ö‹„òOøÎæ¾Ï„ÿo.ûo‚oNÿ0vþ¬øô‚pïVõ-†ìËþˆ…G˜“oÚ|‹„ô¨¬õÎH ¯ŠŒ¯typ縌¯$h0¦òGÐûp\D)<û‰@ñ/¤Éï®ÍÏ#oE¦w lð©/¾±ÏȾo*±­ˆô-€âOJým È.þOâþªpïJ¡Ð) ƒRÿNæÿ°ÿÈI p PçKmìò°‡NèBî.°,›«ôòÍ´ï:½ª“ (ôð„kÑD²nlþÌ "ÀðhÿçÛ ÊÑâë* Æ+ £"ao뼯œûNúø†vûÐö$ìÎÃfÞ¾â*oÆfyj’-LøâBÔæEÐñ…ØÚ¯"#ÐR…ÇèüÐò#d½ê)Jj•Ñìè.’ÄÒ·îæ,'Îú]ɺv$›‡Ž{!†Æ‡EvÞl)!_)!"Jî׿Ÿø)G|¼Næ-­§”ýØ’N*"LâÛr$ò,ŽŠÈò÷lÆÐ†ñ!®o²pJïºpñÇç#ÌÔúÑÔΰK¥¿ b±/­Žñ‘îg·*K¹*,¶àë $ p²P›G,i°v&[Òʂί#$ Œ²×"òÅ"̹EC#ɯ+$iæï²M¢Œ¯nG%im,D›*q&)Üt²s&ÉÕ#‰øKP;+j$ò²er fNþ^+‰0Ê1-CÓèm(R{-’14Qm’?ªFîGb™íèoÀm(W,S[4q6“fp²&ÈzÊÀj‘l  jÕÒÔȲԃR¿!›çbÓ Á,H£,Eo+’~Ù3G:%hfqþv,Úfd×9ˆ¢Ò„Ól.v(4»2„É&fl³Xp®7Æ;2„žB%83vá’pÉ.*¯ ²y:ê„Éì~£ÊvÇëÈÎRpX“ôÜKbÈÏž…Å;rÚ˜ÌçcB¦¬·)%2CC:í¬Œ\ô/@O(S¥AÍ(Sÿ?S•?I³….ÑÄÊ3é,M\àÔn„ã?ö„óÄ¢©¥Egï.J =Ó¹Hó±<ôÃ&IŒ-¦ Àsƒ;“‘;èfçS÷Òv4aK”dT4³7ôÄc´­=ñ,>l6%-ÆðÎLÇçóMtÂëCq<t_ޝMpHp`líôxq”ý­-PQÂÝU DÔÜçŽ+NoÆr4Ö™u‰«bËm%ç~¶ïP/`€ |Õ9BÇKR¯%µF—4P5&åµÝÔQõ§uEô䇕‡3 P(m5EWRuQõoCÕÓõwîxÕàmWUŽœTñXÕ™MŽâ"âzs‚$ àè€#p(õ ¸,bvµ¤_‘ïQRÂÇ"¬%Ä÷\CÂð‘[­ô!•Ú…U²/P$Õ³[ñk[(òïn¢‘ÿ^Ȧ¢‘`$.scs_¶ •Ñ_Ëía‡îuâ‘_ @ }]AZ•àõ ª!2’õÈ^Õ¨( n(c‚ ‹[] edï9^-Ýedêî=eõØ»6gdvj6}öD³ãgvs'uã[½]•¹_Šru×duËiUж›Z5Ý^„^DjvG^ö‰k 0%_ÑMaö öÂ%ökv au£a¬`$yb6±bŠr¶6a63^µä2V=a Ž'ÖyZ6Kc seþPVW`b6Öm]epT^6qTÑguZv1–|bÖEZÍU]õ¿i–µiÕÕt£^l—a³kfª¢–a_Q™kvÝW_^ïkÈt6ÙbbÆóV/n¶åob!nÖ©o–ãVRg63_ˆ›y%e×-Z-Uo×0/w¢¤‚’ö”ž¾‚ $SP FËzÂ9l¼5c|bæQ¶7 q|·¿lÐ:×Á}—Ók£Tœµ³c÷ç|×L4¶“tbuv×þ#i×v5Þ qv—Ýe‚ùÇu½ç6/$ g6×b€÷oCxjÏ+×ø,x@/öa×Ñ|ØN$Nñ{ñ«|‘uìÎ(WÒüWí~0÷…ãab«Ÿ†c}x7ío¶r|"— AFv÷&P%n7#‰c/‰BE8£ƒVCq¤ëW ŠãË"µˆÂó†·¢!°÷yvF¹X›qÏP´ø¨øÏoXÌDXwn`póXvC¸è)xvcøñp/Î+ØëˆI Wø-‹Ø…+íŒX³d׊X­}x™‘wë¸J4ø…øƒbØQ{÷w„µÂ´8CvØ]‰ø>Üøª>7nÓ¸ªYÙUˆø'„‚E¸1}qª,wc×Í‚"e–wß–X/~¢½ƒx‰¬4Ø„W¹†wÍ\÷ÐK¯‡7÷[Bžh˜ 67¯™£”îCÄãUÌR à`y;-ÅŒCߊ؜>“EŠ„m‡Ùd¯œ¦wQä$P«^øp&S)‘yíx…ÖKX©š™ ‹y¯ W×)‚+œ³KhùüI:Hé3™C´QW¸ˆy¹›¾P9ÄO¸ƒœyÏ9Ø$×YÜ`yhi–uéP!¹ùžzU{Z5¡æÓŸyÿ ck YÑzÚ 7åI¡8a˜“3s¸¹¨#›·¸z,qY­œäuçû¥u熥°´™¬%l7\CË¡hŽ··ˆÀ,¢wþo+O¨+M†²ñ¯{šÎºÁÖˬ kxj·$AŠ',:Ør×9¯šºÌ¨ ¯Ö9{úßpŒ62·‡êW$Ö2¸Daq9¦R«‹êÕ…šê8‹®JKû*¬Ë·ŒªÜMv¹Éžk¯•8Tñ·]–åì­WÅ—jK˜øÏ}¸!qÏ27Ô²c‹^ðâ­BÿÚïåQ!¯±„ÿÓ¬Ñw°Ð¡¬S×á=å^uâ—ÅÝQl¾~µ»¶òÚtó<}¿NQ‘»ûéXû ZeÙ•õèDãÎXŒ}áàÖ“ÃŒ6ï}c£e¾b%jÝÕ/ÞƒÉâë ûq¶²ç“7\=Õ,{[œlÒ~5žëÈN •-w23ì¾òÉÞäï»a×Qõ©<ìyš“ìCñ«›wc¢¢6×7ÇÀq$/Qy@r·vAÀ¤ßZ*ˆ ’)^ÖâÖVÕÜ#µ[øÜ;WóŒ8ï‘Dm~_kG8,;ân²Xÿq7µŽx뚟^5"oj‹Ô&ó«a–(&v°Bnn—d×ç|Ižçf¡š–?qf&ï›qxóó Ï¢¿-ù‹%óY ó†sxßwôŸôZBFÖaôõ_ŸåõuâüÿO[XÛÜ d á à@l‚†c€¸l4 #(,1 ÆÐñÌXaƒBhÄj0‚Gâ±xÌ p.Iâ©t7†L$¸t l.Ä¥qÌÞ8ŒÐe³ú(Ô\2œ ÆóAÀÒ]„ æÑÚ-Rž7¦TébêÕ˜1‰@éƒZPoTÑ UÚ ÆV8› #ÖËu[/«/S;æÛl¦Hàt;{&’Uq•X„ZÕV¨M†ò¸ŽZ£>³Äi·š½ m4ÍÊ&S¸Ø»+¨…ߢü´Ë`8Åh¡:ú•öŸ©¢Í´¹Í%J{J¤ ‡7Z=²¥iµÕë6úe;9æë9õ ?+9\âg»°Ëå‚–`£æaTƨ2Õl°² }G¨·i¤»Þž(Kç.>Òl"ý)¯äM3ðDóMMìI@ÁÓlý ¬SÔ1 Ò ü9FB ƒ’ÙÑIå7GQd.º©‘ƒÿ@FqÄó>ªuL¿ÌQòÑG”¢xÐÍ“4·%¾U\Ã>N¡Ä°Ù¡hl®ô&2Ò_&2òße¤4…×-DÑiMv­DFµ¼ì¿È5ŒNÍÏ|º¥¶-=WuU5G5 cƒZ”5‹DÎË¥µÌ,Ŧ0}Ïc¤ *Óà ¿MA(bŠžÈ­D ë̘EP6jbñ‹ÏˆÚ8u`ÊÖØ]Á‘ÜN{ÔŠ*dÉ[c³Ã“nÈÆYp¹Ì°sVQÞVª1ÕBžǰƃœÈñvŒ”5qM_¥¡jU;§Õn+³5j9Fr…ÝÐô©•¢×“m†ér;ßles “M „fÙtÕéiî;wåzªŠ¡Ò[ÃÀóÅÛ¦ý¬éh´R›`û ‡<"èøµe mú&š¦èQí]ËítlUYåu~¥Ð\Ü^:Î{~[fí‡æ¹Ç%«g|ö{·çê”i¥ò±¾…¤.½Ö¿Söº¡ÄSVì¸8Ù_ƒjÚÞ¯q*$-äl·Ös´î^FÙkè]UÀîÓT%¾ëÞ­¼ïþG×Áø\5-Æøüg…t[{TþyÌã¤æÚ[Þm-ДfrøYy80Q’ÒÌ[R>\7¨ÿ Bj^ŽÝ5¶¨ æ×›êƒ ý·ºø0»’À‚ åÅsDÊ€P4QBSã ,Od:Eüh¡¢GN°pçÄ4ú÷ ´H]ËlÃD{ ÉÄPz±:z€b´3#°]oDøº½¢Ü4/pŽ%ÅÖ“£¥”ôxt.°ª·ƒ,b¬TYO al´4¢"‡×Ç—>(¡u¢ÑžŒ¶-.YœŒ¤o tPzIKgmE¤¶î–[zyL-¤É¦fš˜ŠoO)Óc®n¨TEP¦ý¼©5‘y]Yúˆfµ—©õê+Õ(ƒkª¬Ž[÷þµ˜sPý¥h•&Ùí §ËŽ,,R¥]«'l–£ 6nþZùCi “ž¾ÔMÎÙ ß®*V¶¨®;lžQ-pÕû¡ì+Y'¶ºnG aÕí‡î ñqÊb“i˜ÙS¼À_$CM¼Q¢X2yÓCD›ÉOñÛ˜­ÕJ±ª~‹]]8ÈT:`cåeqí,°s'¿ìaM­1%­âM²û€A‰Cdò ºëß±¥õ›óèëÏÌ©€ä¶XµgÓlÜ])fqȶ~v¨670‰×Yï2M¼ü­˜†zz¶§@Y$O2<ǪÓ'@èÙ‹£ë1=­u§'šLAñ02nµçÃ0eòh4G“ê[é±›úÕQ<=‹ó˜¦£Ó˜ð9™IÏu|Œzs#б¯Ÿ!ðÌZ‰Ïê M¬vF©sÓÃWáì׫µ…†ÕÚÏcêJ™®µÆ¶w»aië˶Ô|ço‘¤zpuu­"¦)ë蛹5qšÞZjX@gy ª–‡;çÎ(ž ä=}à;’»Càgj6øŒ±Œ¯F ý>á® 7ÈgĨ«òâ¶¡¼ð þ8fL€\#w;Ø–™œnàVo–J<óÆn–FæVðôûÀUXßÓ¢NïÓdyäO-£2”ðm!ÂU=Ø|6bpúåÓ(L7|Üg‹!n1¾:¿:ë\{ïŽCi¸ATÄ6¥6YÑO/åÒó–¤>ÍÌù=~—³º<ýÃÛÐÚãáÝr’- %?×ýW|p®ÆKš×¬þô’¿bÊÜŽål#Â<‹‹d¼dí¸½â¹&Jìùž)ò¦¹Ù§/€„]‹š°©޻įá'C˜i£¹i-Š?{š‚ÙáœÅê<Î'êN'17µ÷höYüª¿ ‹Ä·Ç0ûéì;½ðѵáøÿo£}ÕW!¥_-“ê?¯Ÿ"?鱿jêß­ûö§ÖHPH|¹p>; àŸÒ 8£á¢Š¼¼kä@é+Ã…¾"ç>¼#É9Jz‘KÁ½ªü?›á­ä @kh,S„0ø8Ì@È„•[Q¤Ú²Àd£Ãê¸ËÛ+ ƒ©/˜‘²Œ‹Íƒ2ˆ8)ˆ È¦1"‘8Œh30Aä:¡#Ø:û”Љ˜Ós9b³¤L´.ÒŸ³À†£b;¼2¸â.7$0˜M•|6ž›%´*B²úBÉ+CŠœC$.ÃÜ0>YÄ"A"ÃL@£Ü4CêœÜ=”)ÂÀ‹r³-pþ‰±]´‰KDª´tLžL3’,G¬bJEDÜ7œÜMÜ9«Ä{~D‘+EJo³ÄY48ÍÅ "»rEƒÅÜR¡QWÅ©ÓÄhBìCÁbÂÃL²ÚæDä[À*=EÜiDüJFqäF l ´U®Ôc ¼dF¼e´$[ÆÜfF‰aEJF¬uF,sêFTgA›G‹9 Pø™Ñ6Ânˆù™ T~>É™ì!·H« ¿H,gÈ@‚H ªÇÐÇHpœ„!B샠 µt}Hh$<$èµHðƒÊàI ’€P¤,“,”’ä•–È©·& :ÈÉ6ˆüš\›:¬œ•ÌyÜžˆ”!¼°Ï³L˜%!¼Ì”%<¥¯¤'§Ž|’ ¼!‰ëΤäf¹¼”A¼«°YMJú‰G¬†Ç¸ç@BŒ‘ÆÑ¼ÇÌŒŒ~ɼȔƒ´ìwH4…ô†Gt¸ÉCnˤ ›HœŒH´¤“´­E¼ŽÉ<ªÆLÇÌd•L|–JtËJI†Ì(«J4Ž>0ƒÊ b±¼ž‚òIøÿM¡˜ÏGráÉh°JyÄIh‘Ê{EID©ŒÊŒ«3”¬É³H<¯N BâK\TN8 jĤ‹GËSLäÞNtI,ÄIÊÈÔÌM¦ÌÜÒHœ¥FrM„qDÜòMqÉŒôLÔÚ³K ʬ„ÍТMädÏ”ÛÊ©JœáFlÝÉáÏì”!DýLäÐæÍ·!’`‹ÜÔDŒ¢£DãJeÅ‹4©2`‹,¡FsŒP¼—Ft ƒÍÐlœ- £Ç¸´yMJÐË-& QLίèÊÑ…Ñ{4ž¤ÕÑÅÏEA‰ÅMÒLÝ ÄÕÒR0Æ»QO‘ÄPœüÏ“uM ,Oá@Q…L-8…0P}1Cµ ”½Ñ4Kƒì¦ µKõ6ÒÜrÊ%7½ ÑŒ]ÐõRœ €UCµÓÕ&TSeµCSd‚S5©4ÑGSdž)Í8T™)Ñõ!/ULLíMQÐÔ ÓéÔ&SçU .B&íDÔEITÍVKÅ-TXP}HËúe&•DÔ½;ÉÅNÒ-NÕOJ-PGu> mRQÔÌÔ;G‹g´Ía€µ1}^Ns˜UãúÍj·µO²Í;ÕDg%C5½Ó£gÒ½rÅ`‹4ÅTœ5ܲ×#mÕÜгGÔû.PÍY¦Q~PÍ:O”ö×ìKN5>‹0…ÅvWœ´×•aVå_=¤¢·]…ßÝ•Ø\.ÙuZÑPÝç`mÅ¡mˆÜ]É×%ËMeÏ?ÕëÛ=ψýc`LwKmàR#&Û¥$_5¼6ÇÏæÛŽÚU6_T €ÚEÐ× ¹ÞöÞ-°ÞÕ£ÜYœH !Z@ß5í_M÷3 É[\å^õ°]ûF¼®a5ýbžK¹á,FâXB²†Ì[OâôLÁâýØÂ°¡˜Õ“ãM(Mc¨R%–PÆÞïGu¯:…ýZ&åDÞäuÙRžeŒÞá.UÏ­Þ¼ýÛå^6ÑÆ[Ï, :…Úf/ã&.M1õò”¥TfHÁbÎæu+åndÌkÞžd ¤€e ¸§¾E”ÞÝ%>%¡Þ„N5¯g>âT¸&¬ÛgÄWä\Ê+åǵÈË…hc8Ý‘K†egÓݸÌÙ[žÒF)è>'Û+âR%öfFwBùɈxÓ…!>]¬Se¤cVBg¦mcå6çÞ&f¦zE¦ÍNgF¾YÕ”ã¶ffA‰h¶h².è6ke5¦>žm×ËüN6ž¶œg\hÖƒ..e¶vÐî‡ç¦ˆ°vdh­&æŒ`†hçÍéSiF꾀ܦzh%*h6°hN±çf†â–³h޾FPZ&Œ^ösk„žiÖkž~j&hé6XgöZÀäåê}¿_}AçÃVnÎM¾ƒS¦¬j¤œf”ãlcJcnqêí h>*®ÖÇÔ,ßõ?Àp‡ŒèÇUBù—¶çe6®ÑTΩè*íaXŒíñ3‘¤í”ÔÂùí]N ¡wmÕ^&–é½k¨¦•i–îâÆ}CîB¶ÕåKèæÔú¶èÞQV6m Q±n†å+8•îNë,–äÐÚþ¨ÎñÛžò‰¦ðQŠmãTúÞmõ-nÞùP~ú.ß«®ÛTæàoªem×>ÍLžÐꉠŸÞƒíî÷Ø}‚‰ÞäÊgÃm”o Íe,m VÉïuÑí¦ïÀE^3ÆÔ½^3¨¶Ôã$m=´Ï‘¢ŠôùÔùN Îy×ÐÉqµ 3év¡Z°‹mË"×kXq•Åò=«5gò1ȾìÔÿè(ðòc‰ù&V˜ñ=6ðÞîm¹‚îç BW1_L´òý°±¯,Içrâ°\ï p5yðG.a±èñ3ng׿p×0ðÍr÷@TÏ)ðŽÛñWTÿrÇBr}%[&Ðî­N2RÍaq«Uã,ñí—ØFÐñ÷9•? Û!‹?Yfíýòwr_G[&r¯-r¿Y3‘{tg75ÔËï_MpÂâÕç2t74óÇ4›÷]õ'Qjr—+“…oXU_•…«çR­ôúØ×² qµ«sW"õ ûö½Åó§$vVÜ“‡öy[Øu¯¡o]nåî)ßNZ²àw½°÷Ïeó˜tæ_:xÙ‚:÷Õ® ÒìÕyʇøM´¶y{¶ëø9x”¨^¿`rx5y¶ßŽX{nø!÷Ÿ~ùätÍyÖЄ!¨¢x‘5zòBAVt&T€W~Á”™_š ß›ùÌ'ˆ”)]’9ŒÓ‹Xš zjPQ¾å-1xÒÞ‰ßTbúÆ Z¢w Å=G¥o¦,ÜtùJÍúª¿Sû\‚zæÚ§¸Wmí МKDµCR«•¹<>Awh9vi•ûëкk² ßà Ã釾Ös¦º¿ÇŠ~g‡ÅŒ¶‘_ˉFzˆ~g›¦Óx¼t—ÎC7ÑøW½}6º|àý_Îwûé¼ïÐ–ïØ‘äÏü¢VçßüÇüØŠ>! üŸÌzO¾{·â¯Çà{гþ\ûèØ|#O¸zâ‹Ã? Gè ¦ÆþÂÞ}wà©#ö|æíÿàþÖüÄ~ßàä7ëCWÈŒ—ÜÿAZèWùp¾¦ª÷Ï2Ïñ/Àˆp€ ‚`43EÑ€i  ‡H0Ìj0"pøT )ŒEÃhpÐp.É ² Ⓦ"r¸´¶^4‹†0Ù¤†37FfqYÄF64 Æ£ð‰ÌJKAʨ“‘¬65CérhŒÞ±<¢IÇ2HxÒRƒÄ+V[=n ’×éqzÍÆ³žÆ)Uy sŠÝ/cJÀÚ&mÀȆvL%öçz£Ü¯3¬e˜o`´Â°Ò[4š·bÊÖoЊ>[1L£]´ôˆÍÚá4ÖQé::,z9´jøÉ8ÏW'MäûM–;x¢[êÑ vOǹȷ’Ìú]%˜èúÓyÌï£?§Ð«tÝ—‹aäðÔ|rŽ]bµ°àW¢9ûm²Çn»ç-»V«º¯{È.ÌÚV4*obJBÒœ·p[Àø4Nèú>éƒZþ!n[ É†Î6ħNZN”»ì\$맬S=j¬$ï%c0TÀ§.º8ÔÁȳ²ã5)ìsEÀÛÂqÀ]Id•&+òçCR+ Ä0³´¬.Ú<ž½É¼>À¬Ðʸí3ª;zÓ†«3ƒ &KœÜîI)M EIìËÄ«› £Æ êƒ:F’S½$P©s(6ršFð¹U¾5ò{ÉJïìêª =0>ke?2Ì»õQÎÊëõSOU\ØÁTÚçX)Õ´5µµfÔ¯•}xÖ=Iía¡ôíwb1°3aÒï[YOP­¡RTÖš@¹ZÈ´¸åÏkÿPTÓRT;JÜ®]p°vý $t´ÇX·ŒýP¶3EKu<Õ#=z©VŒßDM“£«N8‰ƒßr¾ÀÛcµcGnm3,â¸Å1ÒR†8‹7ÕbHülІÉÊÖ¢ºñèlÍEw–_%Ï“ÎP¦Ï ÎRüÉ´ŽNƒ‡bºTÑìtºUžƒX¢Ši¥ÆPÓG¥¶Ó:—ªLPVŸXj¨VœŠ‡ÄPÂ#~ž›h{-ä$T:é³lÂ^‹©a»ûÆI¦íz"z½³r«s½Ë²‹NnS†§f:¾ÑžêõÄ¥ÈiûøÜì5Ê‹›håá€ìõ!ÈóSÿIɱ¼?‡¿{¶U›Å4êèÃÕ]oLÓK ÷7Äï½8¶Èn“ßýNêøÔí‡äøõTyxv“Yè$ö¯§æúÝ7€úøÝí¹ÖïèVWn÷¼/ÉÙ&ÿ>¶ûï¾Ï#û»$ö±Ü¬/zØ?—ï|ô“ŒçQÒg.9>¿÷0âRCƒnå7ĆÝ_yD)!w¼Ãž„H } ;bÈÛÛZlŽñ×$vˆáß›ia¯Ø´†¦­!kjjêÁ¨·F¶©`ùv )Ÿ´¤~ÆAFJޱ÷6†~¢+@ˆîÁçx˜ÕâtDs aô¾”ÈZ“W[l‰§±FJÓáü_ Æ%çüÉbŠM^%ƸÀæû`Š1Å G8¬"¤Hsa«4ø·bé”H Z2Æx(_C@‹º ÄhÍ N“SDð~HÆÄ–U¤cO‘mÈ¿CÐrVD‡‘¤±½ÉDM%*fˆò éš9?‘§%™Ý´™fþ×”·uÒYhÏ X9V1ÑJ…`”&)!‹‰\JåpMælÁ$NhÊ‚DÊæL¤# š`J‰8IeäÁ›sM&x ' Öo“¦e+‡o: í^Ä>nÌ©9$ 3˜OÂvJI|QÚ¨,Ρ9ÌÌØÝd¶ æ†Ϫ¸&T´5ÒöK—eÉ>•ƒ$S’{Ç©ƒ3]ÜIŸS¹fË)®|–T¤$KñüÒ¥ð fU'qT~A8*hså„Á£-f|ËzÇå{U•s(¯¦¨-Qbk˜2€ÆJxÇR% <™E3TéIU%lÁ«2 ¬5Z7C£„$ŸÒâƒQYèÖ¨ŒœÆŽ)9àߨÃ4­uÂe˜9«<¦‚#¥ÓR½OªeYë¤ã­töoÖvó2¬gƒ•úsÏÛàg…‡””’ÁÌéç<)í¬öf~VŠÇ/ç-¬Î±¸V:í-§…u¦„UùndPíeu †? ]f£tò0oª‘ÓWãK™[Ú¦+áuÜ3—L.¦“¾IÓrP)܃•Ô=/Kšºˆ¥uEBÉZR†¢áª\åˆÝ[´f\ï¸Uíú.‹yeÌ•`“™ÂÀùQ3îÙ¹Ÿkš¡ÖÖIP.¤}© £ÝÕ}ªBµ(ª&}]wGh­±˜ÕºõÛÓmª7”†âçÕ)HB—5VŸG£%)PB’…ý€ÀŒHjrJñY§õ³’&»"ª-û«†€€V=y׃ |Áˆþ5i«!<\™‘²tÆ5ª'äR1AJj¹?9|“ŽoD Ù)db¬ÁwØæZk8ó?¼Ó›c=ýŸX éâi•‰)œ¨'/š+œð¶só³µu]†åZ§¡mÎo–ó@±Œ>°ä\™ZFñfŠË6Žˆè;•†=‹ó0+ÿQU±YIºY|ª!ìq‡scȦÙY2Å#ŠõmÖK'¼GwõÅ9ÐÙ‚ùJuKû£{&3å-E\Æ¡–’Ô¿i‹}³¦!-­X\ó‘véò]q¾GœŠgQ™˜Ó±©Eí°`Pc;!Ⱥšã¨ýææ·–¡'-WvêÆ™¿r*f»»8Þ˜jW»ù›c7Ýo»óv Ø›ÃXpýGv2þž«{Iq\ÝÏeïìdÚÚhÖéÍŸ§ógÕ{ßSêW5ª6+LæW/ë^=¨u®Øšåkb½}®¹Æ¼Ð{-ô>c‚¯^ɵ«;PñE]Æv… Ú¤ A*­;öÆ‹Ë ÃpÑn×T¦ê뛕{qõ ØŠÂæà7*@Ì¿½–îÕP'oÊå·«œØ+#µó¼ÃλÞuì\ó l›Ê3Í:êõI™¸Ö’Ø›Nüåý3Æ/'~»èÓpØ·Áêóõí-rlËaÚ+vOò<÷ª[¾¶Y¯WLØŠÁÂùþ9;×wÑÊ7"ú¼ؼg¿íïîäl•Ÿx> ø¼ÇÍü-†¡;¬Ò3N}&Ç&sÒå²è­Ý+AÞð¿j íPc—ªYÆŸ¨ûoÀë×·ý”—$þÆI“?'@ü[ý}Dç bœ%zþ£äô¯ÂÑ“çŠÙoÂÿ°Én‡îŠêϬSÏÌW š¬O¢ýXØØJð}Š ýèÔóMŽüÐPX ·ãÜÐN~ Tý‹ø¯P6MPþÊy鍊ì2û(”Oªß¥êþPˆY/ÍððŒ0š— ²)EoÖkÅšô d†NÂÉ0²{ŒU /$ºÇíPJþŒLƒ ¬œË0ÌwÐØ¥nžÆÀØpÅ Oâþ¢»ïð:è+šÚ/Á Ð40ŽÊB¢ÐH’ú(ó ³pîýqýÑ\Orüùq /0‚­.K´ˆ 9 „+†ÌqHál J™ d(0ÈâPÄPl:û‘^”ÌhFUp¸ÒÑ Q} ñwÆpP('­ ñi滑Xá +QBÖи¢H ®ÚÉ‘nÇñµªØd¿é$Ñ0ĺ.z8'5 ëqŠÝ ±¦ªÍ.eh@£ÌqèoŽ“'èÝC|èM€Ë¬jVÚŒ’l®{ñÀf ,@½­ÔR<'A!΢ß,ƒ!Úá1ðÆN7#2 ƒÈîWêñ¬a' æò2ö§òZ·ÏŠ! |÷‘Q!‡ùRp¸²,£M¿#­”öIÑ$.zËð(Qþ{2#2O >äQùÉF ³*’S)í—) Ç¿ rˆêR!0ã&ì)(R%¬%,ÅÍ&Ò,J0 Zıý#Ðà …~Í1ÿ/¹*rQ$ËbÖqñ%Ìó0rdùÒb÷û"Ð_1pÅ'i'Km)²å(1ý,,™(Í·+Fq)K/Ò ó3~9( âN³*¨Ñ/ ÅRöÍmoéUÑòerY*È5Qò²‹-&H¹ .³bUM8žÉ„„kJrULaˆTêËÀ„s¨©S˜ÖîÝ;,’|n†²2ÝPÄW(A;°18³›ã« W?‘‚´V±‹UTq? öÕÌx¢NíQXÑ6Æ€k"o¾0ŒéNU LUYTMÕ”ó05E1WW‰Ï#“ñVÇ)A1—ô¹µXoû\ ù@©ÿ,³ñ^5»ÇÛCuÏTLX# 5™\ÐÒäCNŒ<)q@ì³`o]6+¬’Òí– ¬63õïaò¯_€mTìacu¥`u­ŽEdF)Í9cg¸É–ÿ¶WbV#­Õbmµaö-e–2ð¶=cT@Ú¶INU.Ö2úŒÇhR6xò憒¶:Ý­g–ƒ>xúggrªffWSÖ:wS¦Ú nƒÈU6ºžtâÆnuöÆÌvÊ„Ðál“Ïi2„2çïlìƒn‹lùi¬“n&„öòqöùlÑKW€·m0c nv¼„m€fd»<¶³[–±hvµYöàÅϹm/Æf² T0ÍÉ–Ãam·tvc­÷öcu6XÖ¶T‚Ãs×8Ö­QjtäÒãwYvMmLç o Œ³wî¢Ê@o>¶ao7tF#tE¿_€nŠ,UyíÕrÑʬäW«8÷{×…HWK®‡x¥x—“x7—x7šð·¥0m}¶©l‘ªÕ/w3ÞB··vo0‰vÈJ“Ø'›=.ir|3m8%ËFé8 H¬`ieÌÊG2ÑÔ¼$ÕMKlÆqRèx4Çí–oe‘XA1²*$À`î,“ƒWÜÎÌ‚m…ðÅX\p¬Òs*pû˜$XÀ3sJExxÝ8SÕƒ§>Ú¸‰FøST5'…Ô{ø.ç¸&б‚›ƒ+q‰qÑ4jŸ…¸³?x2 gèÙoLx©^BMU˜1…¸Ÿ,X±7¬‡ƒõ= vÉŽx‡„îéŽVÝX™ 8cXo†‘kˆØ³†xuxL˜ˆO‹‘8îÈteˆó‰'¥‰pጘÖɘ¢ÿ¸ËŒ˜¯2˜Ç‹@Rø4x³O…¨tÞµ]‚ÕÑ«†íT‚L˜xý^•}…¸ÀàØ¾´yT3„ús,”®>m8,»mÍÕ˜+FÉ™¹˜Æ×U…"þTËJbM' –#MØ¸Š®¬}‚¨ñƒy½Ó: '…8IˆÕòðÅ…ù]™e›˜kˆÒpÕ¬æŒa™GQ79”¡Ÿ²‰q"˜Z ŸÉ1mx· ï§‹˜ù‡™9…Ùšè±¢ù£ù§£lÇŸr±ƒ9µ(Yítø2x˜Ò$ÙÇYËaÏŽ:HY­ÇTi‡¥ž{‡yéC¸Ïñ~òÆšA–ZS샠2^Ú¹šVº¡ Ÿº¡™Gƒ5òQ¸W9u…µ€ÌZµ[˜a§Øg' U¨z¹¡ÇPð‹¦º í²y›/Û”OJXù§y5W¹·«uú«2:¨zRÜÒîÆK³h$ŽM0“tÜoZ#rhýMBåIÐí/€W",îíô¼['EâdZ[áçª*ÒTì[:!Ûæ»4ð{-$-ï±Y ñÂ_#N¦ò’‡N¨vó\êoi³ÎŶûE`âÐä[·Û°ªk³ï,S[7µ›E²‡±O"à割ûA³V×e«¸›©¸³%ÿ…´[Pí›U¶[µÛŠ/rðÍ› ¶¬¿·S=½s´sHê›[·’ªê†1ºÛÚhâÄ&˜Jâ™1 ‚j;üême¿{I»{t×f¾q·s¡²¼ ˜ûS»Ìq¼{V÷¨ ½NÍÂÈ8êâÉ6;‹¾gÀÒð+¹*äú¨Rýi£ÅŽÊû/ÿÀ¯ë[¡Æ»-¹¯² »²À‰Û&ïPC<ƒ¯½Æï×È•É;5É|vyÜ‘Æ[,òׯܩÊCm¸ü]²MÑËfÇ&ŠZú¦]•\AÙZQ V”ùýf¯¢Gä{ÓÝTÎPp0¤³Ò °ÐÁÕa }3±ÐÕÓ®çÝÝBçαq¼]ήòXü­]PØÝò€#q±‚ç'Ù¾õ}‹Ô6ú=Yc=^½ÝÅØ‘+ ½ß,Ô] x·ãM ßäãÜ;éÛêûܾ Gž ¦½×ÑÚ†]QÞ¡ çæ]Þ×'á. ú&?ß½ÇàrWž7> ãcá.á}!Õä™áýØž~¡Ñž(ýÞDC1Ó>6¹EÖþAª~$þIþÂgÿÓ» Üë%Ý%5ÞþæBñ=Uçr už}ÝòV¾ÏÞ¾‰ëþêØ^84þ×ðaá¥'ážØc+ð[Ùñ-~Ó>Åëãþ…j"+H ßbG²ÓïF?-#mßë¸7ÅåKóEó†LÃBì@G©àp=®(’O ª<}?„ãaÛÞ^-?}æ³ÇÔzž(’IÛOd!%Ôݨ(œáù .Ål© £NŸE'÷«Z0ëÂ"úޟîjØ!çØ†?ú^Vâ_”V>÷÷½ˆÎSÆ`ÛøÅ¥ôƒsø-&ë|}ÿêÂ.Àh(f4ƒ°¸iƒÂF"á¬.5aphD4\0ˆÆEÃh$z0‹ ¡ƒÔš%Ž`R9t–O™‹†rÉ$ÂP3@ ’HäÄgB’Í£Tz -‡Ôh#xÜbo@U¦ùÌÊ­G†Ãâ5Z¼¶­=¤R¦ÕË]mÛéu(…ÒçcU'SAb§, Í'ÓztLi*QpÑÜD«MÇGâ±{µ—€ºÊ!Bá•¶y‚Ìç¦Ô<]"@7ÂÐÆy8¦{Cè£ù nËi)ìev¼&Þ¾ÐËf’.ÿ‰°¼c&š®\0d0ãÆ:"Ὰv8‘Œ¢ºìNöf2‘n¤VµóÎ5(…¹ìÎ{ºý’îϾ=áš í½ øÌ1 ³œ…%Lø@6±{f»/ˆúàÆ0-D(–¥êú/l,4ÔC«Œ<Ô!íl"܆аdø:Lâ^èEÌB4íF-#Q¿SÈ9ÀδuÁ¨üÂÂÌä0½BHL¬ÃoH¯D+¼“ÄÌÔ•9PKQKqzkAläs0¼ƒD}>Ïd„„ªÌ²÷ÏÀh¡Ásƒ6Ä>q->/L‰†¨Ó©Á” 9LªCfºËÔ AG!¬:úÊ”\DȾT ;;&íu&–Ò”ûÿ4ÅÿÍ(m8ü¯ûUÆéB.ðTÔ[ÜÓÕt[ÑP×kÚ±VQiUXÌT T¨Ö3¥…)ÔÈÛr² eE_-VT6¢±­¯[§–ßT$)µOY¿ó}œúܱýCgÒðÌKÆòg`¨Ôýê‡D—¥À†ªÎEè»Q7Uβ\5…ó%V…-Y׋Õ[i.Ëga´ V)F†-e>йji4á³?uÖovêØÔ•ÍB\Üí”Õ¶¥"ÒwnHç_oÛ’ËVtG´–È4=˜ÑtC·hofi›R¸E¡SÞtÝåO]ÕÓ@ÔŒ-É®ËVvUšÕ÷e@äúý»\ÖÙבcÛ!ŒØ8Å“gYxÆÏã ÍÑŽ8væEmï6ÃÝð{°eo5Ù®qÕ,;¾Ów{ÇxÓ±^¦,üäQxÙwí­_8Â.÷V#m5¯[Ia×Îé¿®VÆ*´8xʼn[Õöå[ÒlæÚVÔe»Ö¯˜P·Ý*èÞ9ÞqªfáŠižÑì÷Lô—‡ÐÝŽGÓU¨­¬ßÜä·n*Æ7j°®-[\9œ~Làú— ßèóÿÒûtO]ûµv¤ü׋R~Æ>×,è×ûaUO•n°·fLT’-)¦ÀjPÑkhRFáž)ø Ô+Ü'ª¢¼² ‰SÐ%P²³s« ±÷…ݧ¿Ò'‹g0ôŠÃ÷‚R!Ñ]w¨n%ss¢dFˆeaͨNÕ””UjqÄòQœÁ „Qv2FC—ƒÿ‡¤©éÃÈ[ QlZF*-ìˆN¬á,{0…ß2CŒ¬Ës P0Š@G¨)Ô“ŠÌÖDE˜üà¤dq±šÁ˜ã#V³I#Ð\ž¡×ôS`6#JÂLCÒ4ÿt=HزAùU #tF*Ñ~QÂÒ¹âéaŽŒ–˃“e£O‰2ÁíÈ2zT*ú—ežDƒbÔ¤1=!ïN EÒ§]=#J”ÉDiBçOL›i6#ô>¦¡iÿ}\öäÁbìì+ªqÈâ¬bêm°&¡Óx„"ìÙ5föj ý*ã½ °¶f¾ú2he '²ÄÒœoྡྷ3 DÙ¢Ž¢4Õi“qu³I@ŸZlà–ÓîpÇZU'ZkBœ¹ñM…Åe+-l“1J×E bU§q*‰C™k%fLD—Rþ¤Q€mQc¡Î‚.Ìj¥Qâ”æšZ«Íù˜õš]kª€.ó fêï«’r­Ä©ÉZ+dŽSÀËÏ7Øé'|ôLÜÝœO^§ìM¬u>ˆS«G(øŠñÁ®é’ßßÄêçqÉCšS\“H¿4ðy4‡ù„‡q“ &N¾™ã-€pÇtωBGç¶#14KÆ™þ·Œç2³µêd´”<'›ôžeÉs‹P0|az’&šJÕÎþj’õm怜}5Û/«\šmô’Ë”ËUÉOz²ËÜ“GjW4löÕhºØSJ–g¶‰$¿>em¿ öDòÚÅ IM³¡6ÆÎ¶ŒÐH6ãF̘,¡¬ëöÓ”~T×BlkžÚö-ÚPþkïš×¶Ÿ®ŸÑÿG2ÍðÕvsf´E TÁöɲ`Ñä“Dp¢ffk–­?IÞMpsk!®ã´Zgƒ˜·À3ÜXÔ¥ ;àì÷Ìå¸úêí¨ïË´$XÝÄ£’^úOÎã^½&|{n‘>$^oǹÔl¤t‡ ¹Ñÿp¼Ï›¶.¥¢"-Ïên§Ws¹­2G>œ¸sç^SÈw×^&xËUtCÜíx›AíœL½4ÙÒ'jxë鍮͆ùcÔ]’ÈqÊ0Ç…·Øÿ˜äŽ`P¹uO¼ý[Äóo$©yÏ‚ç.5pþ—Щ÷Kí¼3ŒÖÝÎLúƒÄÞ]ÓÞm‘ÕÝï‘äø Y{µÆaV‹&~oùÞE†;î-âHŒú(G­Wˆ‚/Á6x-êzÿ·òÿ=ën®BWd—Á´¦ç»K˜óé¤wNõR:îr®¨ï¯A1'èþC„„bOþuv'1Ÿ0GŒJ4@+ÃûðšHÄ“Òs@5?«ôƒ3@ ò?r`$4·ëý±”À( Jÿ?[ý@4 ?ð¯ÀX±/€˜ÀèõÀ›ô¡¢?< ‰á¸£ö‹úpªûûAIò?Œ›“Rˆk>¼ ƒA94´ Z°±3SX¹€ÄÂ+ªÁÐÞ@ä  *ÁÓL”ˆÄÁᢙT»“ÏÁ„B´Aj 6X†»hä£ëôAhÞ=„ì%CPÐB< ­›¼B¢?Œ´´Š½Ü4kEˆió±TAŠä;xƒš?Á“‰ÁaÄ ÒÛÄDB”DA« BÁÞ@l;!üK³ƒ°Œœ6»\"-Ë=BBí«ÛýÂdBsîDì;-CýªYÂã%|-™XBûx¬´11óðAD1¼„&³kÖED`ºÄdÀ4)CôL;ôACÓ5Ã4>Áœ@DüG‘!žìc,9ß?lTÃ$C³v„9ªD\ÃÌ,šlDEÀÚEѶ¾Œ]JC,^®£óFҮ⠸ÁEAa #$ “s»›'KµéѼä9›¡ÁCÇÂÔ3!,‡Èiü£b­_È»XÇ\A6ã¥Aƒl#ÄNÈ yBô(Dv »ø:ô„0ü‚§+ÿ‹‚"°†·ºA‰".C4H©ÀHËxä}Âê /H…=!¤¿h;Ô–Œù×É\¥ÇŒšL™ÊŒ?JAf¿ˆ'B?´œ®E„¬.rYÄ<°<ä£ÊL›JZ JºÒJ“ÛʃÛÊ»µKD¬È¼¯GL»!¢K ^žô½$ºö?D²„¤ÊܶJ¬GJY\Àü­Ë ð§4}dt6 … ñ–œ¬ šKüLÌZtH˜•$ëµ?°°LÁÂM3%ʬMZÎM#ô j÷ÍŒ MšžÌüvM™˜ÜÒZ²ÍPÊÍüNÍZÏÍÌM ŠN<ÒÍêN\À‰¡mŒàLì ÁÎÈ1vÊÜÍHLÙ@Ô Í,áK¬îKªªI´äËT•ÏD—Àà(\Ïr­JR^KBH *tŠÏÃiÈ<ÈÅ’GОµäÉ™ª¸OTO8«5$Mši@m¦<Ð'ãMþ˜„’œŠÐÁ¦KÍ)rD=2ÓöÐ*tÐ:ÞQ=¿ýAíO= ÉmΔtÐ܋ѬðM“V%œ¾ÐÅLÛQÔÂM•Ý!RŠMí«ÜÇ2³ôzž¥{ö’zù!`ñ¶40Ò|S¿³:¼¤ G_šÈõ'8\‹Œé”GHHÝ-ÃìwŽù¼RìÕB«×Àà³ËÙd&5ŽÙ ½Ò“×EwdBÒòA4½ŠmJÍÇeµDåB×í´¤]Ý4U¹4µ²X];Â=›Âé] ŒÃeÛ/ X­ˆWª ^uÃ[í>MéÜ’Ö¡™²NÑý‚. ¿ýí´< cŸËÍòÜÝòL4t•s¤Þ5öŸDQ_…=ÀUöÄ û_lHGeñT õ¬xD¦°ýß½qÏ|ÁFCúݦ©½þÞó@mþIû`•ö»½u¸»ÅX&Ôò`íùa/aZßc‹È® _áEóÌ5$Ö,¡¡Õ_ Ûô!u{G`@Œ–áâƒà¬óTâÊ´•áÍCâ0îÈ ý¨ÎB¾ÎèD>)Gæ U³aÞɶ±œb!¼b"ÄŽ#ÉÄ "^%ânâ|ŸâµZKî4ÀÝŸ¡ÑþR5c°µ"Öc›ûc•&^ÎQ„Œ?j’žçV= ]®½*m§V “O•ZV=S>ÎGU’dÂ`C`d´—dtM®^PÂ2ÐEN*êá?ú’ݾ?Ó»ÀQ9ÌQe‘¿ÂV*ä:c¦W¥ÌyäIòCFcs5U¾I/–(äþEäÌ^d®NE.fJJcöQGÞiå.å<åLödq.×Î4eäjå‘Þe¦\ÂV8çBaÆoSŠ®Çtqædzÿå"æ eG~OUJ¨cDedîj[¾z±Ggžãó1æýcˆ}Øâ0Q6‚gN€åu›eÔ‘UOJ3ô/vF¿²÷Cq»„Bžä„¼¯«žv[é=óR¨ÛœXi‚ÇN™Ç,vi²\Ó™Õf~Q¢CöœÉn¡Iž’&Ôj6ƒiVIê »Xž™Òüj…©éÄŸiaÁúȾ’\š¤‘V‘I¬ÄdoêÉÙ?ŽjT kD±êoj”gê Oj±éŒi®»P¡¼Eð#ö¼AôCÛnÀÏ$ÇAqÀL6’æcm¨ÖƬ}Ðlv›ìVÈÛÓô7ël¼ lr†@æÅÒÖÌ^ü–ìD›m-NÄÆíFÕ?‹abDH¶‘þA6ÑRD lâÐäÅc^GÓÕÍŸ¹@S‰l¼¾ ¦?³‰it:CëV ±LŸî… ÇNéÙίn³ÔS騞æ1d›n?GfìÁë¤@{ô:D•DvåkMlcÎ nnnLÓÉ›Ê|9Þ†m†6Û¡:oæ‰o@Å2B{p ™^›Þª„ïq¬X›‰,Wo2‚o÷¨Ÿúðnè×.äðÓcÁ¤l¦äð¤‹ïgbäŠÀöêÏ)íöªpþú#dCñj8¿nøî–÷ä¦ãª¿WñšiL n™dņîq"ýd¿Íqrï[Œ•ï o$o«rº‹['ïhOo®úTæûo?!pÒoýJêÅnôq_s0ñ™HËï^Æànÿsì:]gš—-âæ;1r 0ˆ4k%‡)ϡ͎Š¡Ã¸ÇpÅ…h6Ô=©dÈUŒöÛLÄ»2×(Uw^Ó!ÍoÖ$ífJ¶ýÛfÚ¶clÚÎ}&Û7]•CÛ¶ùmÖ×Ïr Hý|ˆ]6gR]ÖFxÝá¤Ø½Ï·ÔÐâ‘~/lâ8½þ£5®õÃ\`¶º\ø^D‰a×–ZÚYy†7‹[ÎkTãÆcRù>†Ö᢭¨øÖ]_>llV-2Ú ¨útÐêH nöjÓ±­j:àiªjPfÌí¦Ã§®9.‰…†šCi ixFÓªê*b ±.:¸i¬ÊºÚ¿DÀV‰©íI¦Ë³ðÛ³3/£¸jL€Rµ¤†Û4k²³m`9 ¨nKʶœ¾OÍ"œåÿÏ!¢š´ÜÓÌ!]0AÔN½P’õ݇I̲½²¡Üu› `ѧ}ïf›tüï?ÜÒAŸŠ™ù&¡y}O›á®ó<éú®o€÷esîö^§•Úù\Ë% a°o6'p×w*þ’â†hõ·û¦mÉq¦—âµÀSÃO팃¸E£š:쵸GTE°M]'Cш)3(ÆŽ ºÓæg ù¤&„ý¦.BÞ\Iúl* ¶3–˜ »@ͤÁÄÎÏ ä7‡M$ÿ3`OÜS(>ÐüÚe Õ< 9Å6CrzÑ¡<2!ç’˜Õ·á44e ‡À¸ªhÕ;(ˆ±x÷Fs‹JÁLÊ6Fh×ÁšWçzÇh‚`¼‡‘‰€ `äl~`ÑŠ¢¼b£ìYÒ2ÀˆU Á?xÒN.Â#O a L…0â('XaX¬†’ÂÈá!Û"0úDXƒ e’>7ÒÆ #ä"t…²¦)¬9)YDXбh‘ÅÉ;%“lj‚0Š2L˜÷*æbÞšqá¢EHïdÛ‚QÖQMy#¤…[1îg€¤)$trAOÑ¢C‰Ó3 ܘð’HAÉ>ÏeA{e­Ž_¬â¹ bŒÒ"*z_Å$|À¡ˆÑ.€²‚_f/˜3b}˸G4Ž´Ø’óLÄÉ£¡‰i9±ª’ꩄ fí+’3¶g"×t]ØD³WÄþ'Îèk+æ”剔ò9MFß ¦ô"<Æ*–juHôÒˆðˆõD©oôÖ/PÔûSiOêÉ\/sœԈ9P+"¬“ŠsÑQbeG¥Ðr¥VX™Sh}S'õF[CªÊ*½L¦µyκ¸”åð«&š*™R6+죃òd²hîz1¯ˆ½ú,÷­eâ®#Ôž¼ÂuŸ]aa‹WQîÒ‘x+覉)¬ÎA+M!txWs”ÚR?˜= ˆm ºóOl“<Ò1²ì©y­qà½É)7ˆk7pŒõ²1¥®ê[ç\Ì-Í¢ºóJb]jUmnõÓ»¶É6F[³%nt`··±3Å»ßh­Ý“öȃЫÂëm›¡ÖÈ‹Úù[h° ÖŒ÷óÒL )ƒuÄ^ ðg)E¢`²\HI[ïå駨ÖñFâ™iL»¹¸•”>œC5©Íè(úö\«/BEò¯¸N\.q¾´ôÛú×hm‘f`ÕÓ"Ùj´Ð¯á/ö›Ù«AmýŸ U?*ÚL†-N V·÷å‚í¢¿—æèWkoo&F¯÷þ\VQs-2º—#g;¢cmp·÷=]¢»ï=üЉŽhkÇ™³ýæ¾øvçèc3ož¾Y· æÆ„ïÖ‰·øBÿJœw€œf—8Oê|A­\ÆÇxDµ[¬)j3uÁÖÿ9W']žp®+¤FŸ„£x¶ÌÄô«é ­’4…îÈ»iç\N¬½ÍÌ9CÊíýrX~¥N%^ÌU´õ‚irY—ñ¯í*lšÚ»EZ}{3å©X»&Ü]{¬†Ð©Úo3Ñb¹5ZÛ4?Ad)¤KÒe¿áTH÷px¦_±ö°ÁÙ®a,ã†ëRàR@ÈníµWÝjs4û&{±­ùMA¶ÄFõV‹ùÌ0üóMZÏ”rlÀ"TÖÛ{›Âý±ÉyœEªßtZlý94Ã<—•sX/|µC®æœºÑu}uÍè9iœ’§Žw]ºä³¼‡Xôbi`¹Ô ¦ý£pXˆ%û—D]öK¹õûè8û—í2p‘ôÉÃ$¤'ïÛƒ¡Ä4?†ò 2ñd¢©BÎý·yç ¦Àüw2=k÷‡=ó{¿´ù¬½­=æÈÓu?®••K‚JÊ•2^hýËgúRŽÂo=I—¶öž¹Öû ‹Õ}n_ò^¢9Pið¢Ô“Såôîm9ý—%%ô+Žøo¯º6 ûx7©ÎsÕé{=ûþGí[òùªïðk|²Šƒôrƹ^WþkÚ3÷Jâ oþƒÐõîìÈ.c ÚF0Ú*c~ò°çkµJ—p*I%ðñÄPõŸ©ÂøŠÂæOÍÙL Õo¯ˆ˜ÏŒ÷O浈XéjøŠõŒÆ™I*€n2oïƒÏ1HÄŠcšõïrI(ðr­Š¢pt}$’¢ƒ n! ðIp¢õð8H®Ž÷P¶H5*P¼ÛÅ\ÙͶUÍÉÏúàpÞoÊñÐŒÈ䨊P`Ùê¶þì†Ùïí¯ñÐÞÉpT¥Lu _Ш÷‘ñÐKp6ñ߯é Jÿ ªºß°¯Ê!¿P°åüèQCÐG°/pô1ehç-ù°èÈqfñPi¡QC{Qzó¯ïÆø0„ØÐ^ÉP²÷Jñ σ ¤‰ qNæ1›F ‘ ò•Nâ/ƒ Í’ñPȺ±¼ÃpËÐÛìg Ñ oPË3SËc²}/íñ‚UÎb÷/_ï³ BàÁR åo«déòñCÒ ÕP‚.5ò+².µðß°ê¯r:ÉìUÒ pòE ‰­%N÷’W*%t Üð„ª~€p¾²jÁÒg)¬Ðø‡'qpðªØ)²Žå’y æ\i0û pÞ²k*2h„§w@f(¦ò´>ú.i"MƒÊUÈúMƒ®o¥Ø›äØ=Ò_¨èè¦ú%ë:HM.MD£ARÁf4ho/‰¨zèc-2¶Zˆ$Eé.è/1m#-Êí1èË-É+1ã’þî€åfkt…’üN¦û3É#/ò¶ ñ¢5Æ“4M"›òô'ï5¿5hñ.²Ûk7-rí6鄲Ù+n£,Su,hû6Hû³Rm3óJk0Eþo³˜›âÒ[s£/‡1â‡:Éa;{;s,mÏ › Æû9Èð*sÍ'ÏJ³¾„óÙ=/o;ƒLvÔ…“Ù,“‡=â<-fû<¾€dDu³É?³>óù+n¿1Jš$žsÈ9³Ôš“p3Ï=óñs 8”36“¡C“H•3ì’4,o³}DlD²2€ó\k ‹3ãGý7 xÓ;¨éC¤’396t.&sW4)FÐ5B^:söŠ“+I"r³%;ÒËGÓµ0³hìF°©¿9’ùEóU+“ZF²øžrë>/?82Ðgs?1S+2Ã.ï꣑9²ú=”%6=ɾLô™:I O3_BɾJôè¥ô¹-I 8RÜ»G«:¥\¡ $k®«uM¢´áPI¿Nt?S -Nôø³u:Ž”ûN3P54œÕ -èPç+Q%ÙRuAµ !«’¨M‡´íWI"ùÀ‘´¹Jîø„P£Uë 0•d®s P¨˜§5’¦ÃI4†£ÕT ï@F³¦Âkª­3Úö ´¨sã0èªdæû3ˆjb#3Hl(ý]«Èl5Ø£§] „cäøHÇGõÃZ(¾p5¼“C=^õÄ“ö Z)‰^öD5ö‡ò÷aÊŒí6Нs:Ê[“­Z¦±Oj©[3¯[ F õ@Xƒ•­@)±5ôM[óãdÉqA´þ—cTÈ™aU¨žõe–_SôŸT6Lóx“Õí67*£J2(bŒU_[ôÍ.u«@•[ƒihª}5 ©$IikXÕ;Îo³!l n¦„Wl«Y•Sls1Y¶«B²}ZD>U£ ó­[s_`JÛ\©Z#ÁauÍKï`£H‹^mô¡´C^ ±^Wg2·]6yoQƤUûoÕùJVö… _Éïm.¢£yb6maµËa÷'oö's¶žp%ÿdö8¶*¡vçZT c¶CA-Kv·ržvçA²ÏeF±gvùeÖå\öj—–ifWItV_hvt¤77g´U_3_h5ëQsOhÇHê a¢.®È›b¨¨v ÚWwQí·ZV­I¶II–ßlw¹_¿YK‰³’ëéàÌtR™hGmqô[sÔzéQhóF¢³k·bápÛk±~ ÷-Ê5k/ïU¥I˜ dóËx#E4x—z7ïn&Öãàh¨Ž¿iV-¶Ðsm{«D^V´¼T j‹¥I–¢Î¶É‡öp8~ãr·‡+ã+wÀ´¬/‚UR¸;.7mŽÃX¢—Ìk4Ôn×dÛRîh÷–uØ•Zë¥n—oŒVc 3¼Üôl¶Ìå5s5t•ˆ–ÍLójëÅ}ï*ºT míLØf¶EC5p4L$Ñ‹k~ð¹»suvêiQyß¹…Cÿy ‰ÖÙ…uYZ93YK)>¸ ³4},hÊÙFåø|ÚEy‹E\ìõË.ù[h–¨ì¹LðÕµ5ø‘–¹)mi+—˜Þh¯ J¹æø‹Ù+wnj•õ™—/‹Ù^”âžyUn+[”XÓøÈáóÔÌQ’¬DMFp8Çv!8 “>88¿”E´f·ôŸGKeCææyWžÎ{•Ïï˜9‹6ðˆä´=TNçG3Y 3CnçŸÙwš!ž™W—2šµ?“KEØlɵÁ‰î£Žxé +,™q”8=‡9KiÙï¢x…ž9W¥ŽAŸz^j•–T=¦¤_Žú–õS˜Z:äk˜sHÚ ŸS ™4³y•vy}G–똖‰xn­•wªY®´¹³©Ì“,™¹7VFÁv!YÅ9L99ÌÕ—¬>Õ€ˆ¨¶Z3Ÿë›žX±•S1Ÿ:¥JZêj˜¯Ÿ³  zhúúçº 9g‚®§¡zy¡º#žô¥±Z[¢{³Ú-ºÝ¹?§ÚE§j¦í™ý€®™¡ºÍ¨·¦ûºçŒËKIú¨³WÙµÝY?µ·UµómµÁxW¢´ØI„M¹7ëE“ô]£šZp;ƒªS1¸™UJ[‰¯9ßhZa¯šÙXŽ{†u€íõ\cmºvÒäµ»N{»™w»9w{XîtuE/ºÛÇœnK½Vq¼º§ù_Y“ºÙ“T»íaº¨ùwñ.@<ò¶è¯É=O§Ú“RÓÄòUK™•W™”ZûÓlš½½öâúEÀn§ÂÚÆî|3ª$…¢Û@ä̓ûßmÚy€º4ç¼3–\»®A»5†yς͸XñV¼ƒÆÛÏ\sÃ\es˜½9XÌšˆy±rÀ|.÷Wª9ù·݉p(ûÝy^‚ýAˆý-&œ¥ÓXò»];Љ+ÓXùÒ×åÖGÒ©wÒ3ãŠG[Ò3myÑÙ‡ÒGúñY3‹Ò¥ThñÙU¯,´͵ŸËJû‘@qØ>ݱY=9Ñy:ãåACnŠ~ÁÀ¢ZÔ¥ª…­ªÈN#8=vàq›v@ UOÍK(y‘'Ò‡t\A(zÐó=y(ÖÅy›º)(X^¡Û‡}?šzRˆ}ÁQvÞ]Ø—Þ+¸{¡â;9ãSãÿ(^6þA'öߎ ½r…¶œïàÕÁÙ:±åú-Ý41AG[ÜD..‘æöVí=ÇŸz£Üöã)ÛOÞÚ±Ýýã>}çœåä<Ó)Òs„=˜Ú”eäïŠñ£éS“ಅàû!m©á“_¥þƒ–ˆ%â]N»^1HhYíTe¹½Ám‰î×ê¾E·Ý!ä^OÀ¾kåWÝ;](¾að>eß>i¿¾w¶­€°^•f•E&ýéí}ØÈÙ{Ý™/ÕºQá›C)©º}ìÿ#ìÚ°›åÞ²gžn¤WÒý( ì#rý‰_\!¿`¦¯àq;&©;/ÙDðo”®ölƒíß^ hT”ÿ‰šiùõâß*ùuËc]úßúQʉ«…ñ/ß’6…ûm"‹‡÷kÍ ŸfGÒ!²üv ÙýNÿrý¶ŸØ6ž;Òý*ßÞ¶b§ßiõIÿ€@ QˆÐ\5  ÐPÌb5‚¨Èaƒ›!PÈ àqŠE„ˆ\‰ŒEÃŒŠ&J%RÈÄp.K¦¹œÔs‰Åc²Áˆä\2P&R: Ú]ƒRa”AÍ~.Ñ¥‘ñŒú‡BãñgŒØbSI-BÑšÖí‘[Än.¦T+µ;HØ\7¬LèƒKœ8of‘Ï+é j2¹Á)ô+®Ó«Þ.£)4“/B¾fò×ùó/ÐÞt\­[E Ôàµyœ ‘6v½4‚£ÖQöÓ<œú?²ÃÍ©¼Vª«ÀM¬Qñ…Ÿw±Ý¯*¥tc­¼öæ£jýD]z· ®.Õ¦ë°õt/wÞõ·†–ü­0èã7Šñ®ˆ+¶³ +@‡¯ ûbû+mûvã#MÒHã ÁR·;k"Þªí¬/‹„ûHsÌÎ5©z¬®4êÊP²ÁKcRýÄKb¿-)ª8¶P;Ï+-JbëÅêÌ.´Ã*Hç 9Šì_ ±Ñ‚³EnR¯ÀMü[5nrÁJôe,CѳÀµ«1ã7º‹‚¹É,™8!MÂÁ2¸ìŸ#"qD®O«³“6C«6BˆÈfÔ¢<· †p»79¡t„ LôJéÒñýÔ»­]«Â4ÕEÖÔq »LR‰C­YU b&GfŠÆèxôÑ(¬¡`½‰ÖVÀ¢HU“ÆÍ$=p³¦´ÝN¬ «Jµ2%¯ÛïDPú3sM(Œ¥«^Ø«Ow¼ªåä¨WUµÓ{¥5ÁUוJ½{à Ý7\ÞÍÜ»Ea %M°—úlüÒÕÍkTIDÇU®P4=vJ—UžÁâ—žDi®M'«fDöP9lKÞv3¹W¢¹d‡Ußñƒ®Ó|·\ÕÔmA¡ËqõEUfw½ Ü T•JiÔlDÒ:­W¬i7½KNiW-CÔ‰NT Z^Vì9ýc}b¹…Ý}×x•s_»v6¢Þ6Fceï9¡€+9Më -–ÅÑYªöë·qˆ¬ÜëNÞ³ãü¯»o|Í­Jg7=EbÜͷѼ¼v…Dà—%µ5x7WÃá5~çñÒˆly5¹ÖݽŒÊ6#‘âYËîAÀ÷·W ½òRù–riJ溮þ¥–šæšâç2nwÔQ¸ŽÏðé» ¯ïjzBÕÓQNÃÏ^ê™Ò“:Ñ[¾&˜Ñá†'ß=G|îžKË>)B³2ߎÙu/Nmšžæø[¿RM±Ù8&ÑÕçtOÁ(«Ü| 5NàÍ—È Ø™”n Ù¬9µ€C^©IQ P¥µ’¢^ÛÇ`Ч&íj'^îíÚDXÌ!‡€Ì¢A·Ü¨ K\‰iÉÕCgâùÉRQPÝú¨øwˆÌBeFB ‘U¼‹¼IˆŠæ#!%W#XŠeDÅ8¢½ã“‹±eI¿xœúHúyQ)!>„iA’¯(Š1C/xžU$4B¤,è>Š_Üc!Ò:M9/¢¼=&°Æ>w$ãíŽÒX‚>bøMäA´…qW¼ÉfìØlˆ!ÑB3KÇÛ/Éd¡‘ÑÂDF5" ªÐx2Xº¬³ý" k#?s þÃ9†fXìAA1ȧ` å Tv2Z^¥‰Ëeº\5¦ ‰G9ÔßMÜâ ŠÆhÌ9êbY$®žPÊF9hÉÞ4øB2¶x« ;•Œ§œðâaɃˆNd¡ O¥›C’Ef,|"kR-QDÜù €5LTˆ–V‚}©Cœ~´;ÒÚ(A‘¤iî<Òzm)ªL-ôª›=uJ٬¢„8ØOkQ« ¤‘²5Q™qIÍL—t4ÎÊFÉ$4VÕÊ‚E_5ORUXÔI,zà‹ŒuªRªÌW%aB/J•‰‹j²ã=§Ž¦ÕJûHé,$=ÔÅ—ØZ¡*P­¥pƽS €ņ0î—Xª PžíŒ°t^©C7Õcã*³5â 8º¼W)Õ'%BšEº)kYê Cti§Ò«FW(å!:ôªÎÃz]I¬ƒ5£”¾Øšg¨Í9µ1ÑTšxßiÂL¨Œ‚T4«t*<ƺwn²TÕÛl4ôKO:²¸îýZ@Õu/ÎGXª]Œ®0ðVéï[_ŸôfúÐ)eIÊ'^”ŽÓ2ûE_…Ÿ°.ó,»pl%~6"ÙH…ìMŽf^Ê·[!,¥U‰¸—)H[üMSV…¯¢–å¯àfˆÔ…úÙ4SDýé^"ehjá²;û‰ãaú³—žVÊ3UïE{(Öc¹lf ÙÀpðß&Å€§|2¼·û-»¼µ,æO«åñäù‹]¯Nzwšªf«>²ó…ãÇ·ZÅg0 T‚Ê’D Ê!°lé <¤îbxh÷”H^ˆD×|ºËä³E ­_­í™hw‡ òî–€(§Mƒ\øG³ñ†ÏJÉ(@nËÚ²Fú¡—$y©Á¹uuÄÌ£jƒ> Á‰(?záÅ븪¹xךܸˆ¥µCÙ$Çe¥PcÁÏ×DUMíB  FÏAçMÃìö "fÂ`D³q3 ÈúÕõÕ×΋o |³Uõ:Õ ûsC}êøÊhØÄ:É’2‘¾wù ¢\ ]1’;¾lGf[äïl]¦ é’ â£ ì{ĶK¾Õ—} ~;6 žüâ8»{P7 4å:D…íâ#ËgNç.üÉAî}Êh0Í\·n×>K“ˆÏ¹¨ÿ_7è¾ë·óõ·Q†Àó [r€†><Œ1ûcº‘ÊŒ@Z‰¹þŒciÄ Ž†½ØÏ=´ =!ñÀl “ä¿y¿+ô7Q›ëð“‹œº;:ëæ§HÇÃT©ž4±3Y2© @ë,BÝ ‘½´$CÙ¼%‹<5D'’ñ°Â“ $B±ÑûˆÂ³Âȯx¬²¬Ár÷±ÓIFBÑi9Ô.œÐ³© 6Œ"[YC³¸¼µ¬¥“£ É;¿Ü@AÓæ—SÀ¹ ÁÌ?;³MÔ½ìBãÝ?²E‰м(ÄŒ1ÀDFS,8³«ÂÃo¼‘C#ÍD3½6»ŒÃŒ ½DDs`½Aº“ôE¬BALA™dA””ë<ô4¼»ˆ¥ˆ¶ô^ˆR.A#´Eƒå ¼ÆH°AdV‹)Åüc½ «Å؃Ãü<Ä$DE±¼@C|4©,9Â3ºÂ˜«ª¼+E[ÃÂt+ÄÔG‘i1¼w‹‰‰GHçÆl/E¦CÄQÔ2ÅC×ÇüzC\yJÇŒ"Ås¼Èy6ì4È QÄSº°d¢E[ºÊä!Êd CÔaIªËÌ«¼³}[~°ÑBJ¬[Js¦KlW8Ì›Âcº»›<¤©ÆBl’yÌF«µ v—|bœY_EÊQ•Ô`ÊZA,Zä[› J™E$jÍœ¹KáO=|c ÔĸV>ñôK«û ô™ÉïÎ+—ÄNžNŸÉëÆ!4Ñ·‘QÉìÂ|Ú•ÔfÊÉá?ìîüBMÁÏ͆£x™DKIrNqËÉlãF´NO|hK”J6D˜™tÚ–›æNüÌÇŒ©³ÔºÁaGºÌ#ÓÐÍ·Ö•ËÕÍR>Ë|±$,zÏâ@ÈTñ!ëkKÜ8$µ Κ3ÅcÉMó–ORa¹$K¤L˜P¼ŒùQ\›;½7„š£ÓÑkžÁ¹Q:„o£"?Â$;Ìá¥û¯í!;³ ”«¼¸º7E›À•ÍW#[ŒÑjhĺÏLËU"Ì…E}%#\HRiDÒ}0Ñ£ÌÒåRå,<-E/Ë•gË«ÂÓÃQzÍÝ K­9ÔSuT<£Ò¤íÓu9Sµ:Ÿ};νaÖø$0< GÑ^VlžºÝ+ÕE\Ó|¯FÝ*I<Ä$áÓ¼áºEU•~R[ÝU5^Ø;BX#¨Å EI™;Õ{ªÖcR”ÅQ1ؽe•z Å6¢ÄºØ£='tžµRUЃW¨QÍ“TE–u'ŒžÏà LfÕúKTÊØ]œ¼Í„!í›X-•Q•N']¿=¨…O!è¾>e}$°¾ }!¦T–×¢Àd³%¨ÎA¥¦Èá…% áHí•JX§ãí[%žÆlùY«ÌÔãìÉZD*›¹=Å·:Ñ™&º8µ¹¿íœ(==15»Ù·MJQ¨UÀÀU’:e”Ì»)P„ͨ¤0LmÉWµ¼Ü¬Ç½Ã+Åû-M¥­µÏÉ…T«ý´ü•DB•Lþ*kŒÝ\tPŠä\MÔÜüCØ ÑK"ÄœäÝe¼]4WÚyHCtA2”ä/tú[R²ÇÛæÛõÑ8¥Èâq^}º´ÚûÙõž!íæº´ÞM™ÜéM­êÊôÙ(­È"»=5–ÜŠŒÏÃÏ7•ô8Ít4YþµñÓ±xYûTû4EAßÜæ·%ýœ ƒFTu4Eñ13D\6üÍúüµ•ø‹-ùÓ;BÅK(¤ÐK¶E}L¨Ì 3ÂmˆãDåÆF:þG]ÖWb¡åe¥æ=´à–MdnPܽuæÔ&’3@cF4^a`®)à¡Åä¾bÅcËÈç¶$f†jV„Åc$ÄŠp 03³s„‰ë¸Úb9ˆUÃX#äJ¸NŒÈ»%…\蘉i»$è±=rþß<›¯½¯Àž‘ ¾‹'6]hìXÇvšIyé#¯é+é“iÌ-€V6yMî]Øk¿j3Û½Ód p>µj›ˆžv©@ÔjÀ…@¶­ê¬ j¾ªÓ>j“Ö>dpêî§ÈÉŸkUöG&µ6‚ŠK|Ù¾?ëTÀUæ/AøÃXô™ëN§]®¸jt´Ã å?Þ¾k¦$ìN³]®¨ëUÓë96[ãßlTÂl®³l¾ÉlSÆjAC¤¨›ä§êPf.+ë XÀ ¾+H›äL‰¹¥ÃFÉè¬Qíˆ$š€›žêöJÁ¦àX†Ô D`ئÞÒ«êîÛJlj0cøí{ÛOÐÏ ¯í `Þè=%b‰¾ïnÎÜÛöâäÆáo¶k{lfæmžÃmàˆBn×mLWí^úUž°mÖí?¨ÞnfÓO~ÖEžûmj+žÙG®Üo\yÞäÊöùíõmFe®æp»½nfã:fäoDÞí©}cNÔn• î¥ p†ÒîÆÔQ¾îoÐÖžî½ñpë¨ï,`Ú~äïJré„Qï¶÷ožDïŸkîûÁŸí.q@w<Ë‹í&<’Äqô f‡д+ñGjÍn~þ¼\Ãî…bR¶íXšòl¯Y¯½ñ&¥Ë„8ŒjèÚ6 s¥¸ñ&©ÍT~ÉÎŸàŽºt]s¾£t&fòÎŽÃ^"Xÿ>·Fò3²c×)èìnô¦ìËÁï3rðŽDçObFës„–õ¾r÷MT¬+èH‚èXj-¯ãVÊeˆŽ¥G“xnŽÃõÄnõOóã°õ÷?Û¦žÙä+’/ïcŠáüÁзY5¿Z!Ÿ[¯¯Ÿ_e¶Ÿat½öß=ö'dëï^i½wvnOê7h‰êUþ/nÉåÊïj¯y^¾ß@®N®ßBbšö©_Ïxk§h%JI÷ûˆ$ƒ4»OwŠu´×xÚW‡xŸ´$Zö–ø¦ì♓x.®â˜äŽ5¯u¨àqî} ®Þy+÷ÿ‘—ZÙ—¼ßu' ø“(,uxƒ:÷ûó¨CÚõ ÷`Ñu‹ùç ÷_¢H…j'ލüww8˜/xÛ¨x©'{¢÷«k§~ ¯’ G©÷ù^x?ŽwW²sŸ…ù¢LûGŽøšOùk¸øÇ¹xؤwúnŽ.¾ä¹!—x¾:˜wWÀ)¿ŽùXµxÏ—!'˜x²!°·ù« Z÷œ3ůyÙyî\‘5{¡ü¿¢úfC“¯¡ÊI÷r€û/É$»üxâ}_›±Ôb™lû×¹$UûÂTwÜQIübÒpW-W,â™o<¯øšÉxyöüwu|·›|ª]~̰ÏÏüïé5‰ë|ý'×s^=1$wpúŒAýxÏñ£¯ ®lŸs+Å2¯¯ëTVÓ²^È-dö§IS € ÆBáÀ€j1A ¦Àh(i‚A†#‘pÌl †C†ãApÒ ŠE£ØxÌ\0D£ƒ\’6.J`ò¹lj91‰I¢ñ˜| kƒÎ¤q¨|cšÏdôhàÌeC‡Œb´Œ˜q)ž Æá´Ê«\¨V…Ã¥ x6Š ¨Öi%¢a9°Yá#›,±m„À¥Tº…ª;LOï°˜õî“~ÂÁƳ =柊 çvØ Ò½ cfxVÿäáÖáÎ>'S¡™…RèNj2§›eÃ{d°ÂiÑ,Å$o”h5˜¦K…¢Vñ:~@â¥jáH§ƒˆr»PêW+ÛN‡N׃³ýëS¯ìT²ØnÅnõ3¾tÆFþO^¶F·ZoÌ?¸½¥‹ h´Êjž¬¼LÊ$Ÿ0C´ú,(âé+0’¨š,/pø@*ʵê“ÑAQ ¥ÐJ>Ø7, ##›Y Ñcd?í³Ë·qÔâ>î‹ê⪋KÚϤ ŠHç+Š3Bì:­äò<‹¸¤»2«Ä¼ØbóÅt˜õ¾Ãݾ2[æ ÉHÓ€üM¨{÷ 6mª4Ç ÐÝÄŠ4»£Oªþ¥ðœØúÂÐ} BóÄä¾DÑRÎÒ3 F´°nÖÅóÑ% rô¶‚ÆèóŸ?2.j¤ÓOò;ß;°R7Ó}ļù:Ñ­ôVDðPð¼uâ$ÚSPúŒÚ4±jŒ„ºòÑLÌÛ…=+}©lÙ±ÕT*£hõ˪¥FÔµsÄœ5팖ÞÓ.ÃÅCNðì—'ÖŽÂ)lPî­89°ÅòéÜøßÒ·•­„à˜\`†µI"芴Ò}J© ì‡6F4¤ã² úž*•f¯¹íë#Šô1’1j¥á’$Ó"Îæ’l„¨bqëNé!±–8ñgض%ŒÖù&=¤âM£ƒ‘âY2ë”ÍØiŒ#ºf9˜ÊQþ%š³šö8IÎ%¢b»0Oëk´j©88»Å6.9§&[¬¹³Æ‘4‰1j¾ß £8ˆ†ÛŽFüE1$´\v³Z(o$í£´ÅåW4s3oÈôÌ¥Êðý/EœrÉ@]zf}n[²Ûϯ_s“iù¾ÅÄ yõ¡Ï¹ò“qÛ •ù+tÞB·-nÜGž¯L ¥JNé¯â¾ßRŸQ¸ßvÆk_O—öREuÝuOgÅæÕoß>ÓWýLáÁy 0dZÓkÀo¬¡ë<•†Wßã­9Eíï=t¼bßü+j‰èƒ¦±Þk­yN­Ï5rî`+¼w ©Û°³™Hâ¯HÏÍ´´RÌ]£ìQuí8—' Ü*é+or ¼ ­]¼8È~ £‚#Äš(Ûš¹[cdĤ¢ž"¡|ÆŠ'D’d 1Æ#1u·tκ!üA|‘ £xÉÄL‹‘>%˜¤MbÌCŽÑ`ËE¨ÀªJo‹ñ†9Åâ%щ AP†‚ðŒEÁˆ ˜†­ƒæ|ÖÁzeˆèDn|áð ` #ÎCe ´ƒ0j ˆ:•q €ªÃHn ò®VÊðè%T¬•À )„€‚ AŒ¼˜aÜ4Ëù•/¦Ï)„RB J!§Ì¿ $l£ ¡†\‡@ʃn s3€‚ç8c3^lÈÐŒS䌓!¤P9"|¤à”@¢YMÐc-B¨. `ºUÎЈC€aAÐ6ÎpéC]( ᚆÐpPÃxm¢¡Êu‚Ê;-Bpa¤7΀ÙIÁ@I ÁΕ‡@ë9¨Ä¯£tÀ)‡IÒ(dtŸÏI´lüŸÀ‚dPk7ç( ”1†€ÜÃ`o áæ“L)_Hhp¦á”9M ¦i e µ¯€˜CoTª¹š6*<Ž’JJ©¸ðAPS¸8ØCp 6:O0¨§´ø¯ŽXÀƒPn(”t×ËP¨Ml5ò¾šSúƒCA”¯´6¢Z† aìHb “²Ô‚€èí`( !²—ÍÛjƒ(d¬–îÔJû…Dh ÁÒÑ+Zƒ%Å·SÂuËsexf®WJ_ʪðCf핲õ4²TúTC€r ó˜1Òº[*ÉŒµ§`´˜Êðë:ƒ`arà3]k£}¤µ—7h9ÚUKuð“B•`¬[/¨(ªô_KPæCjª˜SÛ| žÁ*WÏÔ¿‡ïž “6ÙáúWpˆU Ó6àâI‰O§5C»à(*.™GH.0ŽÔj²ßL‡ˆon#ÈÒÖWdFO7Ã!✇ŠÃ¦-¾€âW™l…B1œæ¿àË!ÓÚUuò¤µÈ–†MÐqg­ÈôúèZ|– -^w•!Ä:†™S˜ò¾p\CšADÌ™ØïÕ»¢$¦™·;…9M:)´©Ñ6zå3C@mÑBj¹”ò4¯¿Z 9‡ ¨oî5ÎòçDhüï¤C>“·¹’Zé`Ϧ%DÁטÞÓ-+õ S zŸDT]´LÀ Á”;VIys­Ö×ÂÕS`í P/Ðh—‰~ÝiÝ?/õ¬Ûä§K\÷ŸsþÞÐ[ªZÜ …\íîí·V¾Ä`zZóh6˜a@9í™öõEÞ€ 1ÒFÃMÄÙõF¹yÒCÖþ¦sJ‰Lz 'ˆo•†x_þ?‡«ha ¼8aN?¸þ†ãÓ_îɇis®Æ®óÔW A>kí"¶óØ0ƒ¿,Mîãv>Èóû&áȨ9³ Íßgœ6W˜“duik§ôëA‹¬Ë^e˜úÖŠÜ]ŠhvY§5zöxÁ=ŠZ†[g{oV3 }ÇX¼aÖ»¶ï6#¸†kïP»ˆt®tÌ3VJMŽï3êW^k5ˆ(Øtüv^QÉh|Pi TßUÞ¯q©Paó¶’Û×9áé µºº®]Ü‹é÷݆߽*¶uyjíUö›¿?qï=ê}¤å ¡Ÿ‚Øß;koß#W{žhÚ°@§ØÛOëžç„C 7ÚT¯¤àŒÛj”ÑÀ¾bÌy“úÁG`ÆÖì9ÛáÙ/ƒˆÐ¸‡1རœí¨ÚÏà™¬lÏ,"ÚiÖ¿j$ì,:þÌ"º‹†§&úé¤á« œïøšMªIp½êÚ¾n^šJ+IàçjòÂRè *’à@êçü%"^‚.“ÂÊ R逩B endstream endobj 20 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R >> >> endobj 22 0 obj << /Length 2005 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€Þ 6ÅÃ8PÛ‰RžHT1Á“iÀØe6™MÇC ÐÒo7Å%CT …C ‘¡•&T"A bФZ4 CA–œ4E2AZ1«ÔEÓ æ¯YªÔûA¦[/˜Ì̦K HÒn³ÖŽfó1Ðîa9E—QA˜Òr6ßð8;ehÑ€2b°XCyÊò(0›¬ÅÒ¡*-¢Q«âáˆØk ¤‚©f3y´ÅwšÍïј޴tªào‚êvÚ¤O7,ÛM°¢Ý.˜L¦“iÄë‰Z¾S¶»z¯K‹\¯X9âÄ×­ZÀZúbƒ±„Øi2Mn}ûOÆN$”Ê!ÅHîi6=–¡Ns< R”5‰ËÐ2°+£h*C œÁ#Z—+¸ÎéŠÓîÜC “p4Áðˆæš ÏHä27hl+BHÜ32«#˜ÙÂhÄ7Ž£¤:î:°Z¤ÀŽ#«ä¦q ¥2ÑóÈó= ˆÝ ¿È$¸ëƒ”ع®“L:.$<4DÒõDÐSj© lÌÄ´¼Aº¤7ŒI¢îõ¶’ØÌ95®´¿6ªBt°7<Ó\]#¤s>Kƒ4Ö)ÌŒ„73+úÎÊPT©Œ£Ð7 ã`Þ3,`f«B'CÉ5´)1aÔ@˜0Æã’jÊÔ.•b Žƒ Ü¦¶•Џ)×JЭ&=1EXˆã ÜŽcê9 öZ´&ˆ–(P¨‡ÈrÞJ(*„¡hh‰¡’6µŠ< ¬tÆ…2gœBÚKX¼ WF†‘ ÏĨ˜ „8{ìýð…6–ÚhiM(Ì=ˆ €Tp u‚EV›(l¨1„½Cä£âOÌ9‡4,UÝ"ŒhžP ¸ 0I L.™O©_1’d)©—q)A@HAÍø§Ê)!<Š‘­ŸQ)à ` !à¹ÊØdöa«ê\ìíï.ÈøRÂx“«i5ÐðÍžËé_±À¢ƒIøJl†)à¸)ͦ³ñ (¤¦àm*%RÄ‹!@*„%´ ²éš†´CpcAä8#5µ(¢º'Ž'ýÆ”°Å= 1R•2­mOÉýA¸3!5Ó΃,]I>[% {•Š]ŠN¼8*…´C.M¶‰©V='´ø£“î~­ bƒ%•, kN—­¦ÐR ¥O2,ÍšÈÃ:¶ €1­ šÃ$Dtõ)b–Š s=£SæŽÔX² AÀ6 p‘B²˜¤á"€PƇËúÐôPe¨Â{ÉÈ{rHFFÈú&Ð^Öœœ=4̆Îý¬h(m ©¶HK3)åHR ¡JVžÆ8Cˆ³%F%•6 )àKªwĶ{ŠÝ~mËi‹­«Oj]±µ„moƒ›,5vXVê²G9m&¤9€ '±èÄ˃œé†aq.hàiA¼ç)ePñS¬çã)[TÉX±;}_­å|‹,Œ¦Âph œážâyÖšƒš`f=ÊAÿ' Péjˆ1áÎ^3ÌÌªÏ ¸ $(*—Œ-TLà :àŒ †ðnG§Œ"WBhÙpÝx„¤Ö[አÆ ´gvÚMyP§ÔR®ÚÒÅ’î¶°,Y²ô¡[Pè³obÌ2ÆE›ØVƒ&&¹Eê¼âÃÁݲ‡¾jÛŠ/ZhÉ[í4áƒ[Œ X5r8”ìÌT°\¼Íæ`6a \n0˜-Îl7fx#œðêtÎaܪ҈)›³]ÏYŸT»åœóŽ}A¹×ç$qœ\FÆSÜaT†™•+‹7'+ÃNO>L9¹g#©(O¦òî6 v{ЃX´ì±â€™¢ ÐÈènMzï$l2¥ uëû×yc`|ÆÓ“3úѸ·féi±4¦w çfÁ}’)qåq;&Þã]m_lÅhµØÈ ¦—¡™ !êž[" 9¤EÆ"dK}9wÙ;Üä  fùˆ E `(€€ endstream endobj 23 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R >> >> endobj 25 0 obj << /Length 2541 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€Þ 6ÅÃ8PÛ‰RžHT1Á©„Øi3Lf¡¤Þn9Ž…%CT …C ƒapàh9‰•BØ ®h4› ¢‘hÔb5N•Jµ`Òs® Fƒ¡¢§U«ÖMÇC-®ÃX7™­öJ…‚ÑX9 &ã!„äd°ØÎ†û™Ìàe1Ì73PsÄNVzè Ða9š1†Ã9¼åZ4E‚’éP•Ñ(ÔhÄ\1 at°U4Ç73g·³œf9Áa»üÖ©¿¼^¯—ì€(2Ì·n  Üo­ó«ƒžK}ϲÍ8üüo:Æp¿MLgSeûÇ^6œ*FÛmêk7ñØëÿœ~G&*¸p¬ ‹3HÓ ‚ T¦ › ›ŽcHÄ©8áªÆ0Ž«+<­1nh¯ ЪÆ2Œ#4áÂÁ@Â3­£:ÃáC=:+Ð9¢Ý/ ¸Ø6FŽã¼ãÆ/ ²Å+܈¸Ã(ä—HCôø¾oªh›D-+NAP`à9 ã°Ò2:j d»q[3»cz8/PšÎË¥&Ê3dd¹MsCúõ³ã ó.áD ýÏ®Jö¾¯ó4ü;ª3Ìü1Nsó'1 £¸ÊæÏC,š9C³¢Æ˜É´r°<ă’í= 3TôÏLƒ”-Ë­ªÈárDT9²ã]+N¥t0̃Š[@Ò|ƒ¡(Z"SZ6¶p`®04ûŽ´Šz2HvR #(r!h¤¶Šjtá­"ªù'[jÃ{[Pf´Œ£ÄÞûÉuê1#“Ö6¯-ã¦ÑÞ ÂÊß-+5ˆê-+Ž#Srv†Æ±¼rú¬[t]AZ×¶6­mEª a Ńs2»ACw‡.Øá/Ì.ú°;Ûû©œÖùn^cŽ6äHÜÜŽMÞ÷…èÞÞוhϪ nU2.ÙrÆ.iH )‹M¹ð*§qVªn$æ†a‚á>n«Àë8û´U˜ÅÖÚÇ›ïªÃ'2*C:hßoÎîøáïÐÄ5@Åëd7 ‘~üÁð±W:È ÉµeÈné‹¥ïÓ$"3à+féË “º½«{„[sŽtÈ zŸt¬I€m² [M»øô2µ wá@ha•ʱy+Tß“®ñv°!ó%ë¯lÞžk3(y4§’3Éë_­æ¦üÏ’;¬ÃruqriW9RšT 1| Ø=ĨXQÇ6 ¡HX…àRŠ9j4áÀ°îÏctk¡WåNØf Æ!#§Rèo Ún ðÌ£¨Jò!'‚,د¡ð¸.]lœØ"”ƒ±©|(©}+ ÞaÒyƒtoI=¼“ËKJ10ÛŸ2ùb`s%ä2†ÐvòQ›"‡0î¿Ø~­ƒ6%Ž(Ì”©c¨uµXØLSˆ¦ Á”ÌŒI˜u2ÝÏ'×CR3MhÆ$é!A1`,Ê)$¦zì„?-‡ i!ØÔJVd1²c]_ô *>&(ˆ˜uÒKäꃊo¬€b3ºÈN -*‰•޲äáÙWDŽ=ngÏ›¹idí˜pÁ•c—jJÄ’¨“²6ÒÚÓðA”irÂÔ á[á+’VU;WÒÃѪqο3ÅO­~tDš×K”Œ¢]p gµ¬“ Tæú8¨Õúñª˜?wÓõ&¥MÝ$zú² ¬/<¼]ZóÎ ï¿€ 'Oæ”pM'Ô:EvZŒb {é°ÈÂùƒËT1 ë†ÀÞÃÌ_¿èÄ …@¨°g͘)àò°øÖÖ#,aÄ] hïʶÃH›áùpVu*6ì3½tƒ|+y!ÖƒW òB:Øaê¨1,ŠòBhDy5XsB‰#ü™Ë·$´T*#z(ÆX#}„Åg¹–9ΜbŒ Ãìv” 7Lä‰s¥ƒÁ•Å;ìñQâ*C!¡ ¨,ÌîQ‚®L÷3gipèc(‡Ù‘ó£ò¨ ¡5aÔõêΘˆtƒú¢š˜i54…tð:ÂÏ«$Þ±—J~^ßíXâF.ÚÆ êÍa ‚D‘úà¹c’š‘²J×uš%‡…ä]—ñ³Y•­m¶Ü¾à×i;^ÏDóY "[ «pDÕ¶¶È( eµÅîY¼tî築γ»&WË1€ÙÀ¡žj›Þ°"-±y1E'Å<¡ ùlYhLŧ*J}*‚»ÀÀºtÔUnû‡×ø-Kb]%gd½šqÓƒ í'.à‹xïBîGxí˶¡Ã›rU ê\&2É15Œq2t̨¡ô™æÓ{&“âgÞJ»c©Çéã­K6È*@ŠkTßļ̾õX«‘M¤êú0hâ 2  ÇMU¢ˆ¶ ÿT3¦sÓpêO8H²yàc±›³7‚/¼—˜“íÖôKPñ0‹Kèžp’WÔŒ vÖîy g³Y^o§Âg^Q™ºÇ!ÐÈÆW#\Ûì" !›‰<š€ózq¾Xk‚]ÿÙC&F–Øý# ÉÏbfwmîÇ+¯sŌ͕7 )\d^Ÿ¼¿ úºX9=ü^þ»zgfz¨5´Q@Z¸u…ÁÏïqÄütX=þI éžLOÍüê§…ûˆU4·O¾ à LÓIRD¨ª=žÊÚ:Òýkìƒ@»O˜«ç©ëÖ®®ö®®b® NfK+*ðBíC`ô¼ïú¯ËžuJ¾Ò ¦7`Ööh¸ ê^h–hàjŸ@Pz‡]°-ƒ¨h縵ê ÞgzóÐl dx†Òz&Žß0p¬* cÐpçŽæ&ŽºÎjþFŽþÔÚpŒBì.àc& næn…t¯§šæ%†šN( ÅÖ(%ž,B&"Pän fÆJàh‡B#ÂT‚v' ¢B endstream endobj 26 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R >> >> endobj 30 0 obj << /Length 719 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€Þ 6ÅÃ8PÛ‰RžHT1Á b‚¹ Êr2ŠE£AÀÀPt7̦ƒQA<Ät0šMÓ©¨ †o8L§:$ðÞf¢MŽ’êˆ §@7 '# ¤ºT%A ÑT28 †Ãˆ™P‰*©´jE*™3¢Óêµ3MÞv(8LFÃIŒÂt4›èw‰µncŒç+™ÌÂlÇÍ&Æ#Íî©_°‚…£EªÙ£ FÃX]¼+'añ&ì¼Èe« ¦3A» µŒ†óbI»$r6ì±[mÁN^v™E›n ª.)‹¹“Â!”á[:L¦ã§Rmzàî(æßÈÇÒóUŽ*œÍJ6:~™áX‚ø†A“T»M*K‚Zñ¦AÀdó«‰{êý‡Šx˜ É|¦éÈ[&Â0Ê2%î@8®;’Ä9pü, Þ÷Žc›ë ¦Ê¸Â¬«c"ïŠ ÃEŒ\*ž4ƒF¯,<×…àP# "€¦( ¢’Ñ‹Kö·Úº†n¨Ó<ƒHÌÎ̦Ç̪Ò:3ÐZ†iäÅÌ àÚÂÆO»y8L˼úD‘²`ý&SŠn4/´kª9xêüÑ­ÀÅB&ØàÝÍJPÉÉ T¸F.Šî(¬sl¢°,ú—Luc76VÁ@œ* "^›(UøP1Ž£’`òXR#.7Œõ]Z¬ØC|ÞÊ8**ú9ޱÜi;¡²l( #ËÅdZ©³“\(´Ý„äÄ–9&45<¡AŒc\¿<…k2ÍðÉă•îžDƒ€ß<³%ð0Œc-r_Êu©ˆØcB¶3ÄtmðœcIàÃŽØt\ç0ÊæA†=ã€éŒáIåß–×Uã³x,B0h„¡hh¢Yê‰a€fY¸nÁ¢ @jŠƒR" `R endstream endobj 31 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R >> >> endobj 33 0 obj << /Length 2513 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€Èj3 "qˆÄ\3…›`‘"¡ÊF 3Éʆ8!lPF2™ §# °R-ŒÆ¢‚I¸Ìo9L'CI¼Ü).• PAhÐ\1ˆ±áˆØk "KE‘¼Æe9œÍ&ã<Þs;) &ã!„äd9Ù§U³©ˆØi1Ðè´yÅÌb8Té¨ Ô\6… FQùR² — G#‘­ÊvA83kì¥‚ªx|N.sX­ÎS¤Íx½Q®9ÑDüå– ]8i‰ wã(è¸qÄD ’,€ ¦E!•JD[ÐPH ”É^qP‚N"JDMè*ÀŠ"Ñá¬@j8ŒUùu¨öà’N*‰äB© ¨$‰âsʃ"R¦8Apr„1LcPæŠÚÌsX:ŽMãh$ #˜Ñ ¢Ø3¨Kt6·ãœì*bàR›†Áºv4¶aœ(C#ˆê4Ã##pÛD@ê9ÃK8P;ÄÐúq·R*æ" #¤´" T­&±#5/§ Q,ÁÂwÇqís Ȫv3&)œ©Z£à8.ëʈÙɸn«%ês7×á@Ú°cÏ"×A@Þ3[#`ʲ7V¸P[!“Ê…È‚$‰^„܉"ì[äæ°hŠƒRy"o8hÄ8Ïpex=é ´1DØYl϶V °Ub˜±a¥t©*Š´—3#xÈ:«íž=l)¡Ì*ª°8€è›åa@Æ£&Ct‰Gf°Ë2°\ëUž¾f·ipâ¹­¶°ÛÐÖj¼—6y—TjmÃ¥Û¶þŽŒ’ŠÀ:Z!hr°‹yUrµ¬i©¸dBºí¾9ælVá[¶{|+!Îû¶ã ,k.ü[ôòi¡íÛ¾»e›ÐP± òÀéSðvŠñÛe¿°½»,%Á»XÀcĵÇšŽcI!go.ÔæŽRš¹¸Ú8£¦Új·½µnmªm/¹kù§y`÷ÚM/ «ãMAžw•ä±(Þ4+Åù<øiKó]ÞþÍ,ž³síw™.S•Rú6Ñ×¥Þ“\<ð0œùÏÆÉß!ÉK[lÊÜ_“6U%‘"©wbYã~®ý¦5¤–ž`B„Ñ"h’‹é$ÁPô  E%¤*ÉCabÜ:–&úÕyÍC!Ì:†Æê‘‹¸ &ᮆeˆ†Ct7.ov5æé’2™7(¹¿u–àãQGá„ÍÄ·d‘Ÿpf+E´&LcS((lŘ¡WB`‰Äeo‘¸–®ßAœj€ñ¥ ª•AEDý¨†ôøc (d¦¬9BÀ£Ä.š8»PÞíÝɱK Fƒ0`žV" %Ú=A(¯Ë>‹¬€§²#¬sde 0´*§ ÂJmä훇(fÃy•QÎW5Yz”•|—±Æ‡‰åK×6æ*]»)zkËdÉ7!Þg-H{Ú Ò{²êWÂ0ƪÌ#i†,®²r¿ߤM +lÜLD1Û ä$…ÓÌG¹ '¸FF Y¸A$*€¦~O¸G fàïžCh} Eá)P¶Ð'¢4G|•(¿?ã´²??hîŠ c ô3ÉRæ†CaCŽÎ9¤fdn£à èԹģhXÝÒßzfâ Êmàd‘tÃÑâ>›z˜Z,‘pz}V! «Éb0 ÎRü,PUÐ4ö#Äh‰ÊsšnÃÃn Îc%-EÂ2ž¤Œ€bH $atÀȃ…10«˜( «™mÄåaœ]„®Žb¸ðÊÌëÄe£5©‚*qÌ9:xVsCØ0ƒD\ÏZ²æ ­‚l.v¹ ƒR…mq—¶à¢Ü‚‹`ç-²'a݇Ùå^¨Ð10Èīشçåc1Oò¸``Ükµ˜œ$ààjb%"cŸò2šN•vYúDˆ2HÜ8´b²MÀ4´ÜÚS—' !¤‡eâ ¬Q¡âu¬ÉY!³Wðãásgø7F\Ü&…Atm£VØÃ›‚!ÂøWÆXËqìÙ!8[ìh‘²ñ°µ9OðÄØS"¯¢½€¢0 -6,HåUJÍr'³#¸x­Ttê ô;'Ô±Ëç"¡3‚t˜¹a7àA;(RUÞ$‹•Åè†m8;Äá”ÙfYHˆésÎ|ท&wzêçväÄoÁ¡Ÿlz}2ÈV‚¤W.lÜ7=(…| ¤Ô-ñXÜg²ûC-q6™ü:SÂvC`6—Êú”+}¤8§’;F“7t£’55.lDÜgÝMb‘ÓÎ&³dÚ'`V‰s fk3k f_2* *V$† Þ¨4 žx22ÚPa€kp(ÀxsHŒ‚Ž= ám|i¦ŽëáÙ»wyĸkyâp[ˆAE×ÞÛã}Zñ’ 2)ÅŸ&Ü,m ea"ƒ fyLV䵘ÐßÖâ\ñÃdÏô£ã¼SƒHË à¤º Z„Í#VfÜ2®vi%÷Ï(Y3D¦Æ¥ÜÚ©èç$Zî½²Õa €¡ŽbóμÏKo_D$¯lB™Í¼È:2›Ì c ‰ ç6{ó^xý˯ümB 9KNæ û5ÄûÚK*æK¸d2ÞØkñ;¤=Õs!Ûµ ‹üü]1JhÂýÍq°±ÜEa†ô0Û•³2o+†È«g0­¹/'ñŠaDq+ÛnQÀÉp†(Cé “Ÿõâ@ZC{tòï>ú½9ä¾yôÎV«m%(§ ¯Í7¥ É*§Yo׿Øm¶íöî/£0§d W?àSwó*„œ-K Õ›wàÿ„óyÃÎzG9',0„¦Óбn{ÈÝ‚‘lULý´¶œµÜÈÏÐ"oÔ"㌭ÜÏà*þk:="t^<ÿ rÿn¢ÿ¯þ¬°^…â´fÉk”)Ðÿ‡GаþÉò8Ð%…øÿÌ_ @ýK@a°>ýïøÝpHéÎ`r)®8P&*.¢%ÏÆû˾f8ÿÀVü´F¥¨ô ÔÕî áÃŒFKÂðÆ¥ÏxÖ­2¨ŒˆÄ TÝ­õ Iä7í¨é‚"KHàP^ú® _€lÅàŠ ` endstream endobj 34 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F8 35 0 R /F10 36 0 R >> >> endobj 38 0 obj << /Length 2646 /Filter /LZWDecode >> stream €Š€ÐP¼Œ2 DC4c"0øHÀp Fâᜠ¨m‚DJ‡)€Ï%*à…±A$Ì)ŒÇ#Aê`3 E‘LÐç7™Š 3ÑAº44›Ž†S9”ä,£Š’éP•ƒ aP¨dp.âò"$P\ b’¡ª±„Âá ¡€¸s2‰Bì·Hàæ*MGƒ+e¸ˆ^q Hä\6ãºÓ ]/öa°Ó ÄÄá!¨Ø\8ÈÆcqÜĬQP˜ÐN†ƒ-c4›Lg"íG U«áòטŽ,f1ÄEòy\¼~ÍÏ‚¢‘‚:4 "ú¨ä{3,¸,¦¨rí7‰€lÉ…€éÝÚ)ׯ €Î_§¢ fÄÙ›SnnMÙ´š—\Àkd±„ƒŒ{¦dÉ—S¦[KIk,¦“Q‚æ€cˆ‰g©Ê1Ä!í¢´ÎKN`̇zÞbö•X=ƒ\ñ\’³y$ÝôC‚Ô 1¢ï‘æO3…) Œã'jŠ‹†@ÊŠK¢£@à¡RHBàÜ(oBMMcÕ„0 B;A)c9R¥*œ’–SC•. Cªp®'ˆ-1Ì.!§æG¦è)Ê>‹£#‚VQ©ôš€ÚNA$|“Í{æœ>"ëA ŠJAÐTÃ$óŠpç1Ž&DŽœÊâfRÉÏ®“Ò{!">Ld¯#‡XäPÄYS©YRž5‚:7šøâ?‚ÑкƒŠÚíëx4®)i&X3„‰ X2G'¾™jþJÒ\°…/™YíjŠú8ç&DZ²2M2Ÿ¢”°8ø^¬Õ­E)E0§RJX¯¨½<¨ Å\ÑyDĬЄ!´7©‡ÐiÀb(•r–- ¢ NĦu•XUƒ\z™‘I¤Ë]nBëqUóY^*Ð4†G}J*Í„7ˆš3F³vÊ%¾2 !ÈàJ\ñ2 å½™PbiZÝo“ˆ|–+»ôÂp9g§‡€Vyq 漄7âKôŒ ¡¿jÙ š3ðiÍ NH.À´Ai¬=…¶¶ ÒS(c#áÃLà¡ØDàœSjck’‘P{ójò4Ž“P"Yìs`vv†Öâ9†ÒÐzIµÔá¡#9¦¡÷1‘Ù9%Œ|–ò¶¶†ŠÄ#¨‡ jr;ƹ¯_¬•¨r»‡B$M1n(x¦ª¼•ÍúºX¾“”™ãzp7™›ãâXBÐ= ­òb&—QØb޲MÙtí`Zàc Vþƒ8%H8¤1ä1­`ÆC`a¾‹:Ê Í¢ß@s §gÜ0QD=²-ÏæÔ hÁ¹¦G.¡|å’Ê2"È9î|[}Dc÷"~Cw†_fÞ©–ˆ–+” *ÑêÚÔZ–Â}µ´žÌà „F«§t8)D¹Å¢qwrêA7ßîÙíl²ÔcqsGZ„Áf«MMfXµ¤àœ¯m"Êà `,ñ¦a UæÔš”êUˆCåXøO ÙZY›RNÛÕ݃RëHL Ô8ð³n”»ž§¾ë!9ÐÖ‚¿Õ æ¥Ã˜‹BKŠAO6ÄéqvUIÍq<(Ý¢ÉÀÊÂ\ÌEŸz/jÙO+9y6ÔÛ×›à}͈è- Ë›W·‰êÞ“|›Ê‘ä$«àe£œ }§aˆ7«UsåéÌææ…šù¬é¸3BPð„7† èµyò˜ôLøŽÒ÷á©§¦¿ÁÍE*oè¯7¦ÙÁÐÝÆ-êý?µŠaÑQz(Íè!Ç §†t‚… Q–;Ͻ—¹®-E Á—Öó1<‚…)².Çàà D4ÉéÿPz)Á½W~àaùv×ïø?©ŒpÐý/îÄO÷/Î ü'0~ÏÞbÀÒs ZýG6ýã¡ð}Àæñ‚` LOÔðâhðð(ü£lýïRyf Ž¸õ¯^¥/¿¦h‚¿oxÙKü ÀÎýÐcoÊÿ¯þø«Œý0cp*b%9†Ð§’úðpü/½°o/ÄO“°ü®8ý°)ã :þoê]BîÚãlJo0O„¦¥†cgÌú§…Âa PÛƒ‚Æ‹RLO!.Z,ÀÀ-Ôë ëÒuf¦"É~ŸíêeðÈç%9 `P ¦ˆV‡êRÐç §I ŠXÒpèØ äØí’¾‘ ÚM¨»è†Ðè€ À… ¯O ЏçyQ.ÑÍ# Ìy„8z¤$"b"``Ë„8ã°´Mè㢢B endstream endobj 39 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F8 35 0 R /F10 36 0 R /F11 40 0 R >> >> endobj 42 0 obj << /Length 2291 /Filter /LZWDecode >> stream €Š€ÐP¼Œ2 DC4b2 „R‰Bc#qˆÄ\2BͰH©På$åCPl2™Ž‚áIPÕƒ ¡0¸h*ŠÏätül8ÇâeI(¶(M£1˜ÔPM"”Êd9SSªŠ !’N#ŠK¥BTâ;†A£ˆÂ-ˆU!dH%<¨h2×ê£ALA¹à†¸CIÏ„:œÌ¦Lx èoÁ *Æ3y´àu:`jx±A‡*m2œÎf>‹(2u§3¦TÌo9etÚ<&£U¬×f…Œ©ÂtÝëÌÆ™†Tèhãåq¹SÈÞv4™2yš±‡k¶‚¢·:(Øk{¾Š &ìüξ8Õ¯ú! Ê­¾ÕëkãAžˆ¾ª³Œä?oèPå¹°ìc@Þ:Œ¤ O¤ΠÛ²2ŽNÜ«2ð+ ¿p[vþDcKkÁƒ äõŒê“àù0*¬˜ Ã;Ÿ8c4lËF¯*OKðà0AЬéªrT€×L Ü:°«s&ªÃ|},TÇ*r‹Ô7I1k.HïÔ ’|Ê ¬ðè<ÍóL Â:g'GÐÑ7†àR©Ë“-Ïs4îJr¬8µ-’ЧG¬mŽ“Õ/1ÒÌ#’óµ:õSTõF6 Ò8A!A-TaÀYQ¶ò½\Â3ŒðÂ1ŽƒsSM*û]MŒc È©ÓpëªÔŒ£tWWQU=$Y eh ðšH@Tˆô¾lÏŽC€ÞÉ0P5a0¾öœÔÜcÈØÇ7K=Aq ÀÞŒ#\¡hßl°Þä —ofÏØ5+€¹7ç^kwÀØkïTÕumÕ[¶ý(¡êjø ðªÌ3«á–Q £ˆëfÕCØ6N™;êã~Ôå¹xÄ6g£\Á—K2Þd–‚«KÔ΂Âì¥×/la§ÍÙ>$ü´Z[bÙ½Øí&¿Lá–HÛæãxï­çP`à2ŒcK— /$;å¹#Ÿ&mJ°áy^ƒ>ú«A¹¶ ¸Ä›ÏV­@É‘ì ƒ£‡57JƒhÂ95Ÿ6ÝåÌ D„\<7í¶%À˳¦Í#uA`háà ¶hvûç=‡Iݰhê=SÖе²¾ÕOC½PÂ8ncsµ×ø—×`çì>%›ìi=þ»çÔ7w»3Îvë ƒ®}é|\Ê[¯<†ï8¨¾R•¦Ë×X3eéõ¿óÓL/ €À8”I„*@Ý̲TÏŒ#Æyª¤µœ^lTŠ@ðb&B‹ˆ Dx2Jÿ y5&ä·Â‚zQ7…Ç¡J:(À Á/a°¸Š÷!¸6G­›A×ÊÄÃ,d‹…n—‚< A‘:<€ÄóCžüžºékëP9XFXR×,,ñŸ¦ XC9*‘°²£ *z,1¨«4Ø6³ãƒD mn)Ä À.d…ýž¦^¢ç8.jEÆ5Þ ÁÞ;‘ £µ» ‹=d Ýãi¡‰6-Ä"@\ 3”Ïð¢H²Ke@P¾!€‚àhDÌX6#ä ¦¹pñA¤2!Ä Š”† fQG,K)š¥#$DÄÜ–³äÄg’©Œö™“¾§\H*s¦;|p§”‹7¯šM¤Éô #ÛŠ©*E™ýâì§)á¾>5Øæ xg îÇ¢¬ïpsP’WE¢ó7ŸáO %Iül ;©7“¨Ò=7ªõä,%ÄêV€©Š¼³%Á<{Ä [d³ë€3§Yë9×µ¹þµXžª,™"‡Êò‚š—0k"µ·žTéý+° ù”ðá”Kr].ºt˜§³ÊBO©E‘…4’ÌõáÓ‰üÕ"þ ‚CáfÌ)¥=î5v_<šYËW9¸ó°äëÙ{€eî)®¤8ÍK"dfú…ˆšXtçmLz`ÈæC\ô ¾€ú‰÷91ò÷¯y,lJI ˜5MðP:pE `(€€ endstream endobj 43 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F8 35 0 R /F10 36 0 R >> >> endobj 45 0 obj << /Length 2634 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€Ä`8 Æ#pÆ0T6Á"EC”ˆ@g“ pAAða6œ †QФ¨j‚A¢°¸h(h.ŽaR2$¶()NyÌÊ)Œ‡AÐÑO¨ÔÅó‘¤Îi7M• •PÚe9œÌ&zÅ”Pi9ÙãQA†ãYªX,•¢à Ä\‹¯uB¥\Ü).• S’4b ‡hq¤L©E ,s|dï  †£Qž[1GàÅAMPaª¾›çKmj¬a:b1XÌtò6 ¨:ifnq#g§ºb‰F·ÝÆW1AŒß1:í ›¬X(Z3ŽFÆ¢o„mãËô FS5skT0›7+¡ÀÂd2X ø àP½ê¨î7…°äí¿ÃÊ8AJpÜ:7HÞÿÃxÌÕ{ü¸5J¸ðî1ˆ²ßAj<î £†l]ª¬ZEñj¥9RШh[00Lã¼Äë›Èó= 8P$ £pƬr"ª«ªŠè3, «)>ÏÀËJÁBδ­r„¥;ò”= Ñž´ªŠ;G΀l†Ál†Í`ZFo:§ª]ÆügDF Kº‰<³¬WQ”-JÑT=KSQ¬p*N… PÔ¥7LÔÔõQQÓõ 'VUtÅKXVqª¤ÁQÌìFÏÏï dà†K¡Kj¤º2KòÚé1­KeŠãHرÍ*£­Œ+ÔÒºO¤¢ª@Ã"ïo…håe›¯3*–ðfª×CCBÐü©m…=“jÌKE›3.“EÉ ã d×-ŽŽÅ/M&»J¡“ሪŠpâ:ɲ~(­Âîþ$[ØøÄ6 ã×qãâlp¸(š%–"’ 2¡¨nE ª@–)³Ž‡åÈ A™2Y¸@‡⤅¤-€ˆ%I`Y•HY†ƒ«8YcK›gYòˆ"H–€C!ps£é. ?¦¨ácãûžë©åynʌ实p…k™Î¾Ì°ò½ìûho¶i[zR•Òaf6;ªðV62Œ#ÑåXN­½êÒ&ÿšæüvÌ;âzøŸ††‘Æðj=¯,B©Õг*¸xÄ„&òOÁ© ;ทÖQÑ:èÁT'0¨BxN k *…0ŠaÉWdôòÁ$¯ÒŠ’(á*£6,Æqm‚Ìr•FHWÃZ*0ì3Tœ“⇫•¼½f^ßRˆ.B “÷œàÑ£ªu™˜ƒ6X " 9‹î Ѓ(,BÜ€(ˆ]ª·§’ßA£,$b*‚è®ôž£?‰Í Æ ¬ctäÈ7– ¤Ad‡nHï£4.ç£tOf-´™XëÚh(àæ-G¶ÎUùŠ ;S£éNA™€­äg¢t a ¾”cÂ+™sr4ªH÷Œò$”€Oj:˜¬B‘¹z­ @fÎ2–AœÎÔLÈ,5é 6¨êÙ¡ã9æd.6€fê‰Ô+$QHYÆUg@F#s©§5ÄT ',Ξ(駈*Ф!Гr2V°àC‘¸-àï“ò’D2+r¸ºd”›t¯ùù®òè¸WÁ.¡¹0#4à uIô„º—F¨ä5£îú%± ]yÙdþ¨¯Z»-‹ÇÍ"§œq™™Qêf ž¯ÓԀΠ5á)åà(Y `7/º<]i ½ ëL7‡pæMiºå•f9&TQ884l-Gµ¼<>×¶«e8Ê=* ñXLÝž†I6»‰9®åÈŠSú{Ù‘uŽZ(7.ÂÏ™Ïoî…ó×0ƒ›jqʉ?y†U9C <Ào„U™»E¯“¶HÉköhª±Ð³@²ÎYäÃh ÔOàܪ€žŠ¤A¢Ò鋱åÆÀ¢ÐrEï1}bV–ÜôLÃuÌ¿×ÄÏš}n®E¿)Þþ#ü—€.îOåB²ö§þ °ˆÿL%bp­NŠm«Ô¬6â0¡•™èž¢Ùšï‰eâ]¡)Z"©u/M·ž–¡ßÛY“/ͱÉ6Ú^;”ˆr(qwÞè"tò©,³YFzÄ­v­j9À:*{ç­§c²tÒÓKN 1jF4ÔóO$MA«m…ߢY訃(ÍyÐÎDž„þ =kû|2ÅòËW2û^«»•-VÈ8ó§,ßIÞ p6ŽÁí¶¼Ås3+Ç’8NÉØ°@‘6$È“7Ú-´,;¹Ù²(ÎÖo<âd¥Ÿ ¦*ÆXßã\g¿·æ9¯¸ð¨cö“yÔ›ùíê©k±À]…0¨BpT„kâÂxS?!l¥Ûì:®ˆnÆ_t~ˆMù:”©è uÐE~er{[¨–Mº™œÃ’½E–8¹«§æÄjév ³k$Ñ<Ñ‹‡v¶sG¼Š—]”ÍȦæ”p,érBÄ7Ò„PARí=Q…v7›Þ¾çv&ˆŒwí)˜R•5y3®ê*½Ó ³–¤qtŸ, Zø}¥9t0gÜWòM§Î·§ƒ‚ O;Gýî<ÑÉ ª&e†?uøˆ¸E:{CÛÙI“Sq›5¹a˜ƒPƒäØ9“œhž²Æ“8²TYÖ)i™ÉÄ5Õùˆÿfè.-÷§ÇàÚœKñ³Í²ê¹É#È–{LÍí™i÷ 3ߊ%Ø“Â*×Ï8B8hǤøí¦žO’ºï–žàl„àr „-Býc>úÏ`Ö †ûpÀláÍ4ýHTüL¡̦âëÞã0ŸŒœâk Ë´ËË(8#HW€ÌoêuLÎÿ/\kÆ$<*’ž –ëø&$ªˆ¦‹D0'£Ìý£2 ä@„`ˆÖPZž4û ú5n¬D- œAO¿Ž"ãm–°¯Ê¿ ÖÚV¿ð·Í®ýçɤL°Pr¹ìÜNúÂö+„8,ÛŽ®ñ0Žññ®/š¾ðžÒ$ñ Mb$ò`b€lÕ°ºÖ # ®1PÒ¿0ÖüŽ*¾PàÉPIÎ8î<0)â2­hofÌ"EÞª†Ð#"~‘úcŽ¢B endstream endobj 46 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F8 35 0 R /F10 36 0 R /F11 40 0 R >> >> endobj 48 0 obj << /Length 3219 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€Är0qˆÄ\3…›`‘"¡ÊF 3Éʆ8!lP7 E£1˜ÔPC'“JR¡$œG™M&ÅBAƒ5H¥2™F™Ò„šyL¨).• PH4V  G"áÈ€Z2È „Ih ¨h2ÐG3ci”æs0™î3;˜ Èi½Η)±¤ç„ÍæÓÔèe2b§3I¸Ïˆ:\1l©„Ùˆ8L†L†"ëw¼™f"Ѽ^Ýš¾M±XÌq„èi7›²G;¶`îo¬V¤âØðÄl5…ÛRãÔÌf2œŽbÉÈq62˜LfŽ®»nÊ`²¹{?\Po3u|Ùõìe®Œ…¦#NË6ßœŒ>èÀP0Ì‹îÿ½I³x8Ž£(Ü1½ÍsÑ…+4ƒÌ ø¾o«ú?/ÛV†ê`ë?{ôë*Ø*Kl™¸áC2½†a»üÎ:O°g†¡l: Æ.kžèÈ °Â9F‘°P6 #Ê64±‚l …‚X!…‚ X"µaº·Æ‘Œ:ærT_¦Ñšƒ%7Žü4ì) 9MoôޏÅ($X¶É’t¡7†©°àÅI‚ ‰"TR‹Áª4aÀ\¡¢D€R* Hu‰¡è f4˜h‰ FШZYN”=@‚QÔb6"¡šÆRt­/LÓa@cOÔ UK]T¡ˆh´ÕUYWV•µ“\¢tpcIÁµ[JRÔŨVED‰¢Vhl´VýVU´ÒV·0lQµâÒÖpApXwg{Yu"*#Á½ÝiÞV­í|Wh¨r˜÷ý…qa¡@i‚TwJ òAoa”ÚIY¥Òí¶×Æ”,9?j]3åÓRg—„}˜fP0ËAPfzÿÉ'Ê)ªl+ÑÅõ]QÁ¥¼ŒØ7 ‰yÓÕ½•Ž¢¥K–•áj#Uey…šfµˆj!Â`"1bØúÖ kȽ»¸Ý÷ŽMXS9E蘦¡°Q¼0]´é·¾ŸlßA«ÞŒâڶɳÓn9tk¡¬kï·c­&w âU;’¶ˆ*< ñÊv^ývS´ˆ¨¨b*uÙ0Ý“<9¸Ä"Æ ƒxòÈ&3è‰,ëOVå­Þ *›/Cs¢ÛF™ÌdØR¯óN¼/J´¿°#£©Ò¿Ù·»cÙßiôN¾(Æ5ÌŸX›Æí—Ðg©r¨r ˆÉc-Õd·vºMH­Å©6B>F‰[h~í­Ç¯’ ŽÔ²Þúˆ±W+vkŠ•®È`cWz±Â=¨Zœ[÷yOäˆ*²Ór8¸á §äR €h—©µ«^­T³‹¨êó§! „@†Š5H«$*¥Òª½>«ó¬SšVV¼ 80‘ qÃÙ[(}’KF¹X*éa w£=cã3ÅX¤å‚ÃZ¿i,]"´Ö *¹$°²ÓH‡ÖÖ¼ X¥¨ÕÎ¥Z›^TàCaPbˆÅª®¶„´[‰ ­À7‚õZ¸°Ò\ƒxw(à̤¿‹@hº¼»lV±Ë°F®½¸#ªž+)ì›eŸjÍzA5¯yÕì7UªVöB Ýu˜5ï!$Õ^`;¹®óƒ$Òò8BháÁd}Q8}ªr!Þ¾&ù3•/vïׂ/B,É,ã£È&@Û=Æ 1wÆøjÓ7õP«Ž c2*`«âFŒÅvJ¯Loxô±ÅñF{Èdåä3®vÅ–AM˜¬©™2¬ÿš³Œk‚ iÁ¤Òc»ÍlˆJ…È+rƒ®<‰Bò6$#G_`lG¨–2¡Ñéas“Ù†Y 2bçÛ$œ•öΗ …*,òǰRí,p“?©ŠZKUüqSGFå#€ô<ÄTÿL‘ÅQ€ôîɰ³ á|-…\fÇÒ6 Á}RÃb2œ[z¯#ßjkQÞ€…Dº_ápî\&îÑy¿]çå,2F¿XºU­ér)‚‘¬9'O-I-¢¦ äJ˜:ÐÚ̈?R‘y›ŸÈVb‹ç*ýjÚµ®&@Æ‘‚€ÀO?AЬ}¤ ŒÒ àß„“?´‹ŽÒ0gûFGêÆ ²úþ&„bj®3‘pF˜·‚r"i$è˜Saøqvª{µ}– ½¼£ò¢4»Iñç °â«ø6ž¤Úµ´0®qÉ,š2&{=L…øÀp§0Â!`'…,gxîÎÇ›tùÉh8êœûœD‘Ëú/[ë½}ÃvzÔÔÕÄý›’±Ú³»^ß·ÒÉüÜ$¡mëxãNëµ;Ä5§ ó·õÑ¡ùæ¬ð`Û’޳ÜV(\.d“=UnúyûõÌàÇÂ315à &pŽ3…àA³aÃpp`,gný½ñ¯“S²WØI+'³1¸B÷~AÈ1ða¬‚鵞üŽ{à¹ýé$ çnl‹‰¿Ó×^FiÙöëGûÓNÈßË„vm䟫ÞèèP,‚þ2²¬ðå/Àù…N™˜þífÆàŠÿŽÄÚ§ö³o™EŠ·P ûïæbÆþÆÆc/H¥.@V òŸLÆŸ‚\2-¤ö&BàÎ8 ¤á`z"Âî&â°UÇ’Dvõ0LßbTp@¨w@ Æê(ýdýoª!&&`)’¨+„¯äº®~dv™&]¨ÂZáZÚODcÓ H,™j»]ªäЦÓ%|»ZÓLèÅæé¬Kˆ^ÂÐÛʹXÅp¼ V VmKþìl€°Ø[°Üó-Š&‚Ѳê V nfìg$»>ŠŠäð2óM³q*\`v^Èè.JõPPm¥ïÐÿ`†ádÚ@†°’ÿ®–Ñ8™ €_Í€sPPÞålh½Q€®ïÍEO…Ìnu§”™ª¬9 %ÑnÂçZýŽÚP†'QNž¬¾F¬ÃìÈ5NÃ\ €ÊGL.÷"ýŽƒ¢"Ï€\o‹ ‘D! h™®Š"Ë"ñ'–Ôˆún•Ï”U±ô^£¯Ë€†ñò2 üÀW ,.ÿ*`úÎKÒ§r -U«$E,RP™#&3!Qée„_ÒJê/»ÍŠÑæ Œ Wm¥#Ñèîð–:Ò"ñöc*ÒÒÐ þcß"’1'¥‹&‰ àf#ªã&¯ã%Ù*ð;"ò\É W²‚Æò†¦OØöBÉ ’’X° )5ÄЛ[*Eç*’Ñ g¦ÁRµqŽÉ Ròê·};,Ò@˜ë º²‘" s/æ½+9'“ *kbÚªC²oRLc01.þjQñ0r %Ñ ö²>%ºmÊZ´ïW  ‚݇nÚLr–¬Ý ÉŽ8Â`õ]b>¨¨y-‹"­O7¨¿¯ÐÝ P{ãRÆçÈ.Ñ伇{9'¸ÐÏ8C3¢CÆÆäŒBìACMì. ItãSª¼¤ýÆ‹)$¨S[êÃ-ª SàŠƒ Å;2 z#åz Ë…2ñìåëäo)$ó„꥜#+âÉ@3éÏ'!Ô :Ò·A.Ø[fß?ô\t h¼Rì÷B³õ-í»)²(®)@=B4@Â?3Óø:óîGt; ±!ʶ®…˜"I" aHˆ§¸¢B endstream endobj 49 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F10 36 0 R >> >> endobj 52 0 obj << /Length 2688 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 „R‰BFã1pÊ&7Œc£HY¶ *¤â<¬¨c‚Åp¤Z3œ $¡¤N ÏfÓ˜ šE* äJäžF¦ÑHdòi@ªT ’IäáIt¨J‚A†P˜\4-š ÇAl@f2ÂÈ“APÐe¨Š &#yÚñ7^Žg3©´Ês¡àN†ƒ Òó‹¿Ûǃ™”âu2›ŒyÉ^»_‚ ã±h®ŠÆ2Ä$ƒaÀÀ\5±•$À¡@ÀRT5C£8¬V‰ê!ÈàÆ²º 191w7–(åMó¹û+M¤uÆc ¸iÃÖëö;1@Üs·Ü‚·ñì_€ ·EÃk]Æ’Ý 8ŒLÒ6Ž`Êà àÊ29ã ø¢/Ct9Cò¼ã3ž2#8Ð:BoèP·…£ÒÇ+ΪÚ×!Êâ¤N3b¹Iî7ŽC æš…¡Èl.£Cö›ÀdGálƒ!Œ£0Ì4ŒcK2ÇHÒP3CxÛ JL„±!Žc Â7 ƒ€Þ4À²ØQ ÌÃlÈÿ#Ó4ðt£!͘P2(Æ:Ž“„å#…ë èМÈÍÌÒÔJ‚ Rè0Œƒ äò¯àhó<-#SC=EºÍÚë†!«\µmƒ¼’9  è›½ ÓÞö½hJš¨˜l¾HÍZ×RẘF.‚k`…=:”ûAP¬uF eTµUcf”X” XV/SvìV¡d¦ˆðA]רZ™L’;.Œ£…åL‹@Ä.7ºõIßÃ,4í/!Œr°á>@ñÀpÇ‚M7dc€ÃDS”Ì‹d1·ðÜÔÂДì¾ê ‘b †ÈA>ï¢åG0ä7Mëòl?Ïâ<¢Žƒ~v2t˜Î0ƺ&=èj-œêºö“N>UÒÔï?5uÃrÖ—Ïk8a¢D[K û¥/AH`Êi»JÛ¢hå=šFÐËŒ¬Ã£Ÿ…¼|1@Û m£ÿžH@ÐFÞ¢Ž´0Ü3í>ÞÉéŒ;¾MX‘6žafv- <@ÌÌ€Ó1E(”‡Æ´·YO a€»BvîlqØÈb¸·R‹¸pgˆÏý•vÔÈÇ ´'•xÈݺîx×Ïý¥ …Äá•Ì üý ¬ê-­ŒÊ(—C²€ò¸‚¡ €AЃN½2åS‡Ê|‹d£t¦P˜éÔA‰ é,Ó\‚PŒ@\'z§¿Ê¤IçÔ(ªä¹n½çÀ× 7>ó)—Ô©J~˜›,«*òÕÿªœ1…•¼ÚɱBêëý,µ2êÆ±N2üupá9õ[[ä² )Ë™Ø´Ò "j`šK÷éWL.˜åÀ‘4@@¦ã²k$É|¼%òí›X+um®Ø¥A]ªø ©ÖÃTº´v× b·-Ž‘jøL«0K±í‰µ…€ž­›¸µö,[+&UY_¶Ýó×{z¨k¸ÕbßÚ÷`Ÿýĉ–ä=û•tnuÐsË ŽÛÆ^‹`…ǺM²:Ýi=[]¶Yöâ¼I¶µoļ·¯`PŠ+¹6<{›sɶmv4.¯ÊÑ|çx3Õ¹"zUcÅ’UPP5HMÜ•TÑ¿@kHš›c!Ík.å·ˉ/.‹æ¡„¿ZÅ´f‚|hl-=Gp¦§ZuCA“W¸ìíÙ¦²·0P(SœÉÔD%½¯’žÊšú AXE¶S¨Ž6*÷)³q2ÑâÿC—Ã’ò¹ÚgÍöå&ÊÖ§U¢œÀ̹aMh¥WÒ&D¢pésfAX„Ê‹ÉèC¨@îtbÅŸ‹–š¦£ Ð‰<¿›ù¶Ñ9^D°µaž ÿ gšçP‚G_º~häm?-¢Ü3€Y¯Xbp¡¤Im#KJLJ $é68ʘÀÊ”$¸Ð]þãCX| H.50§YehÒw'~èŒÏLë /:Ú”ÈÝDîÖý7kë˜î°‘U]å ç™2{È€Q¸µ>L°™Tn‚!¿Ï%æ\Q¥sÙÒ¿wœ)Þú£'.?¿£,vÇ šÒÇÈ8E«º»@pî Ô8•™;ó”B™ë¬øà9༟¿NGÎy|&"{÷‹òž»¦9Û&ŽÇƒðeßuu5ÞŒhGâ;âÛ«”Ø¡¢ê«ïèœÇ£K‰ÕÉ…âé’…r¼DH™—0êÑÆêéîÖì¶ùÆtCžtØSHzÇÆe§µ÷¹‰Ñúóíœ€ã“øjAÊÎýHét·¶wÌãP¤ö ö傿Ëóª*Óø£‰TʨA A$)•¸ðSãÁG)%/S[…ƒœüú­´¾ýc"µA†1a¾=“uJ¦ŒKk ié>§ò*΀é}Çö×v>Ð()86}ß‘$åy” &èü•(C?Çma‘ ˜péë¾xAf¡ 7‡T4ý§"‚â†ùïÐù”ÿºùç:Yâ*ì‚Úï¦ oªNC¶ûðm`æ "üAožtä8¨z åä>DBDpH“8mh6®DºFàz0€ðPùÆÖ’*ä €Ò `Ê`°Hh0H@G&2(®DðODøOÐfP#þ2*ä ƒ1æ„T.‰&Wh3E&zËfÖa'OFC°°ú[ Ç–/ðÊR$R‚m °Àad½cù ¨{pΗ°Ó åxöx@è ¦Ï0nNPÊ^…í ðú_ Æ_ˆž$( ã!p¨QÅ‹$øMäâgjýÏ–ù dEFúoç-±: èªpñDŠäžI€Â ‘8me&0†jgÑ:pg7G '@$I䳆 Ðîpc5FÖäG±B€åYðª6„ºû†Û*º$Œ}h" f~ü,i”£î2ãB ‚ endstream endobj 53 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F10 36 0 R /F11 40 0 R >> >> endobj 55 0 obj << /Length 1560 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€Äb7 âx°¸g 6Á"EC”ˆ@g“ pBØ ‚P(IÄBI`R-ŒÆ²átÜl7K¦ó™ÙL‚M(´9РšE)шô¹Å4ƒ3¦NÉ%BfP©U(‚‰¥L¦T—J„¨$+ †‚§áÄ(Z2GÊ„I` ¨h4œëÆÀÊn2Oì xÌo9c Øó‘´Ât4›ÍÆexàu9 ç3. «;Í8»¯(Zø%¡‚,CÒn‡ÃD5Ct>D1:Ž­+\·Â+”&¼a¤,¾¯ìjî§næï< ¸e@ÂÓHiØØÃŒî4Zé Á¸!Á€\‹‡(šö‚ è¨5Eòœc+¡º>‘Âéh{!Hhž…¡¨r ‰#tعC(á;…àP0‹LøþÏ‚˜Ê1³ Ôø@±Úv;¼2Lþ°ïÅ$!á9N“µO3Ý?? T ùHOŒ# ÖÁk”Œ†¨€ZÊá°kÃ@hj`„A€D9ε~Nµôð:OUòƒ? u2qcÕšƒUR¶TŠ2±uj LKˆb…Õào-M1;u¦á¨h Ýq(q'Ì0…Å+1´Ð¾Ñ¡ŽóYÁ@dŽìƒñ'm¨àÚ´ƒs—DÓØ@QBZØßz.A•Ȇ÷=gZÖòÝr¿Ž­}Æâ»iÄ Ï{8¡äã€Â2>Ø>WH&Nú Û:dÊ(äìÖt ŒC`Þ1wîN9·ÙRvã2ù‚ƒˆäó^T †9‚v4…:¾­”gIÛc‡³:Æ„ÿjAE Dm;/V¢K˜iW jþóëãpÒÌeî#ŽÅ¸ƒ³8:´¯æØ±bF0Œ"’%È’:ˆV!²èK›¾‡r(šʆ!œ¯)V!È\F¢C\¬kŒ[ð|©WV½lB’pqÜøÊrA(õH†ïÕ¨G].O…Ñø½æŒóÐ\ùÝ|ÔŸD)øiXßÚí[ù½â!‘x”ÁáܨŸ'øùˆhÜŸOžï¦èPyzäh?r0÷â¹kK „PŒ A@ేÐB »¿x/½â7Žò`(5Vé×°'Üè‘ åWMÛß°0p‚Da¥¾xGZ}¯ ¿27Ù„‰q^¿øRõ’´Wnª=àQÑ liûƒh-ßT„ïÂÎÚ3;èäét´¶{ÃJaJ¨ìë¤ôF‘OH×4 ÙxƒptfÙn\$™ H–ò_™L['n ¦ A¯cLMÅÕ°‚ ,`°"ÂÅVÃfY†Dª”dÊ[‘õlß¿›%qXR½ZúÖ‰Êð¯¦Í¡W׫ëJ êŠÀ§Õ@³,e[OÁ‘iU*¹_[{ª  ×Úê ŒÂcòí®•BW–…•”5Ü¢¨{4qŪ'g:TÔŒ—²U‰äI%evñ“x4ŽÏð‡Æ0Š@ÀQ endstream endobj 56 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F8 35 0 R /F10 36 0 R >> >> endobj 58 0 obj << /Length 2043 /Filter /LZWDecode >> stream €Š€ÐP¼Œ1"¡š1!0˜„(j8 aÈÜ\8†`’¡ÊF 3ÁÂá´0ÇHD2!RT5A±èˆ¶"T"IÊ’ðQlPt‹FÀ {IˆSÕ&—M F#b1 f3¤Œ†•!°Üh5 ë64nB# ÆÄ(ÊÙRŽD! 6Ÿ[E˜Èj4…%Ò¡*N-…Ð ”jE*¥OÈ ªC®Zš8ŽF[‘ïX­W+Ö Hj9" Fƒ‚ÃN(·Ünw]½æ÷}¿âñ°B «'G«eêªhË;W˜ŒFz"0Àq·Ðh´ƒm6¶›µ³Ü=¾¿c³Úí÷7+¥ÛŽqxù^†b£MóêSB àŠ­M¸‚é:޳nA°hÙ ¼<«ÄòAï3dÚ6Ï{ˆã(®C<§9jhý;â0ˆ4)«nþ?Ðn ŠbíÁT,OØ`ðº¯$4øÃŒ£’¦¾Î`PÄ@f®†â‚±Åq4PØ0ꚸ±!œbÅAñ„eFÐ<†k„ø>Pëèå3+$šÐ†b*Ô!†-¼ž!Ê2›mˆRzв†í¼¸KÁ¤Á-g½ÎˆùÈñâ·Nb,0Äíès:ÎóÌÈ8Œ4M½#Pa½ ÐôK!Ͳ4?$ªAÄšMÛ ëÁáÍ4ÚӤ͢ÔÛÔ•5Q?Ñ•][BÖ’,<úÄ*hs&‡˜jˆÁÍPÛוôa†â Õp¶8id«ÖƒfÜ|× Ò•½*„I¢0„"6@ì[×Ķè†!6‚ Ñu+5eÝxYv­ólCêÔ›D!Àp¿ØÕ…ÿ€ÓXDpDá¼g‡AøRe†á÷^%‹MÔ«0è"Ú–·†ÐTã¸üfõ¢2çtÆôb—”åxHe…æ¥mŒgÍ*¢ú9vÁôPažgÙkiIù5•h‘å F›©Zó†qßaÈl!¢-\Þë:0s®QŠÐpˆ¢#C„ìkMâm;^á7ÉÜ™J³Wø‰ØNí¼oU~”—VÀ0\ ÃlÝ/²Þôžk}c!µv"ÜHºÓ†·1†Á¨ƒ6?AÑ=#7Žôü?›_a½¸" Ësë½£ vðx‡ìÁº/0B{߈^ qá†}[Zî<Ž3]R«ìÑ.íìz>Fœ¦Ý3Ú{x½;Ç|ð 3Ëv ám©TL°Ÿªœ6ïÉ—ì`ŒÓÑ4)J ¿äPRßÛá€o}õ­g ¥ŽšI ÅuóÆËd?á õ\ WcsÐ`A s{ýð‚±väT‘œR¥| –’à… -P¼õ4`nó™†ÀÞ#Øw!ë‡ì:5Hsœ£YfÍE˜(™ŠéØÀàš•æ’`¼V‹Ö-6x¹ZüEuñ˜æµd> :àaH¾5FŘÔÑþT±Ê:XíK,{s1–#œÖè‡Óà5,¯Ê È’ÓÎÂ1,¢$Èù"Ñcé‚Î:˜YÔäêrh|Ù °f^Ù Œ”2ñ j ZøCW’¥ÐÊÅD£¯’rq÷B—d¥[ÂÞ_Ò!r#¥0Sõ5ïvglj2fZcÓ4"JÙ© "CÎR®„ £ ÊlÙ‹ýãÒ B“´œ2 ÎI2ŒËìÞ$?>·A»¹- dÁOIìGP:Ɇ~˜8’ÛË©*A qPX¹-ßlð9°6PO·~ `º¹tD!Q8&ôr£¥r:6Š;?é¡q,ª/´[áÒ+¥Ê²˜”ÙV_Z|é”àé;Ú3Ohå(„ô0üD¤?/Ñ0+í8²„*“ ‹*«þ|P‘;à*SµèÕUÛPêühCèü®=zž˜ag¦²a%w ZëEj­ˆ ·Õ^_I ÈÚÖ´ñ9J•|Õú>òV‹4P|6"X†ÏZ[Í‹²J5Ù:ÒÝ‹äÁƒT™•£°€,õŽçîÏÖihݤ-v¬üK³ _BÉ> /Font << /F4 5 0 R /F10 36 0 R >> >> endobj 61 0 obj << /Length 2046 /Filter /LZWDecode >> stream €Š€ÐP¼Œ1"¡š1!0˜€€oŒF"á¸âm‚BJ‡)€Ï%*à…±AÐR- ì¾c3Si „A# Ç#1˜Þ^2OHDR `2!hô™˜Èp0cD*œôqGFä:ìÌj0ÔFc¤ºT%IE°²¡W-žLæ³ èÐs;¾Lâ¸ÌbCÙgÔ Œ-¤Oh$…mÈUjÅhc\Ì׬+%¾â * ®òì Òò(³à&â°ÐbDËȸ¬‰ÐÌȤRèhC"b²yQ†_œ¬Öí×&§W¯½ìÆ£”ö×a¦†Ø­®ßs»àŠ“œ93ŠáñH¼~O§—–¶éºº T³XÙ»)èj;®ü˜lú²)›¾¼/Ò‡, l!ˆA›õ‡kÞô¾.3é´î³ú¼5° ÌÀ¬Øn"‡(8ˆ><±AÃ<â¡Ë BÐÄ4ôÃðc?n¼R׆¡¤ZˆHÈŒÇHeÆ-¼hô†áÊ„7Ìv!G±ü+*HRCPþ?ÎĘÅ¡¨ŠÚ†¡²€ÅJ”©3A„b ¬r¤ñ/6Á„ÂôÇHÔy?S\•I´Z!‡¢b¡ˆÌTå:NÔËÓ9p‰CÁ¡Dü#Pt%R˲ý ®Q±4Û%µ¡¨oˆlÂ2ÎÅR”´üÓÕ(‰.‡!ˆjÊSB-BÔmKSÕ4c6E…j5óõŽ¢4øž×5Ý{_½"0d-¥ŠÍXð¥•fSöuE0Úôz{6 û_b@b ‹e±Vò;pÜprüWhÅ]Wb‘wÜ–EçX:”tNÿßmzc\󨆬,V`X$‰+ÎAˆoŠaA·bXcvÓ7Î775¡³¹&'"s 36C äŒ}JaÒˆsU³A¦X­eù6†ˆ˜~uYÛMwˆO†§¹´Öƒ¡¹×Hj"¢`íÇ:l»¨/ºž]œã5•³Žç±f=°°áÊ´Ål0¾Éi3AÌÊê†!µí»|DnZ|Õ½c‹Ö='5áˆr"U‚Èô†Ü…ÁÄ s· dÅñ½K_m›vá­ï|Ö{8s¡€b· |ôóÝ öLÕ—¢èëáÕut'Ø"í.óls-v{I[¢gÐL«yßx òÉM)ªü¯-Ô¶wV™uÝdz~}xqQ†•ÏOAƒÞ|‰"”z­BÓ}©ÿ–gÚóQ£ögynÒü ÖcOí¬¿æ Á‚S*,$õ@g‹ß;éF® +F¼¿jÄ@Ô€†ÑZˆ9ƒ –QA¨3…Hô–ˆBXÊj„Ð!˽ˆ&O`“sÈÆ4£5 ¡¤6‡ôˆXn»Š‡ì†!DE§!I…­v(3øbÌ‘ëŠÄõ‘¡@[‹BWp€ÞC8¾£ >±2ÄÕôî™E«8ʲƒæÉ£ƒŸ±Ì™ÈÄ‹Ì4yiàÊ>ašÀGÍq@ÐP ç|Ñ›s (+s^ й=§*~%Ušc NБc„*Be ŒaÄéîLÈêq0¯í–£š2ºÂÉ u9Ò*@¸‚5# ´špК&¿ê-jI4σ3€©U±kmŽ¡R®°qŠúCT³˜ÓÚƒOéMɨƒèC€Q 2¹Âì‰Âl áŒ5’òˆ AC“®à 4ç]ªp( A”2†ë^€r®a”9‡0Ê+-¯aP4[ °a ÖÆYpÞ¬¸{ ¨‚â"Dȵ¦€§[VDqâ#äRQ´äH…@ ÁrMµàÔ;f‰Ãí— !ÊË(Ò BQ ­ÌÚg+X25ºÚZ;pA--»!7„‹]R"U®#R¸êšÛÛEmAB¤ró•ð\[.9,ÞuKç&`ɘ+%øõC3l†N/x ¡B‡ Ï.w]‚"]níí¼ªÔ^D»j•ѽAPªó†¯}â· ‚ù‘p@®®øÄ…Ý~Yy8BÈÀ`Èžà"ç 53ªwÿ =¬XJÂNÉ« Úã!w15޽דÚ¬?yÊ(.Äx”Íâ‹áo/0¾˜¼¡_|/‰oѯfDýP„cÑ1öªÕ`Âã¶ù ø3°Ì÷á+[…r~Ê8£*[Ì=y±x1¸nÚ!«¿Šmá"8¶ó¬¬Í~h¡‚-Acü{‰\«ÈKjPÁà ºzÆŸ&è /[ÁFRÃx«CÚ¦outf&aú?/é,Y˜±sž#xË4iQ‘Z›8äTgP*žwX¡”äfçëÎ]WD†M[…«`4ʰ&ØÀæC=–²E$@ÓºC™¬¯d×m] φÌ-»ÐD³¡Lô‚‰åxÉs%“bóÖ|rdƼjˆn…ø(Úªdµ¸·½ïµP„ Åz¯æZ¸Ï2LPH endstream endobj 62 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F10 36 0 R >> >> endobj 64 0 obj << /Length 1669 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€äf.B㈸g 6Á"EC”ˆ@g“ pBØ ‚P(IÄBI`R-ŒÆ¢‚ºo9gó¡ALŠC'Ìès²™šP&ib‚i§M#Ô§B *·;$• u:­\ƒY©Í+%2 ¤ºT%A ÑT2-ŽÆ£Q´e•’ÁAPÐi9ÔÌ'”Üd4ž*xŠ™˜ÞrÉ›²Ç#i„èi7›Œ&Ê™Àêr8Îf\M|Q¡6qXüž¶€(7Ε3‘”âu4ïL•3¡¾¦m2™wzã¡ ËS9 8ó ÈÉ>·ÜAEAV™Êâs¸úÙ„ÏÏ×½~o®ˆb4èŽG‘iŒÞd2ðõÙ³mL¸ c2|×,cÈ2P ¸ªcxÌð½Ê¦!‰"K :OˆÎ·."þ!Kó…°`PP #Æ2EOÄV2ŒÏÀÌóÆcDj4Œì8Õ cHÔ5‘øØ6ÈhÝ!·20Þ87#€â' ԻÃñ þ†‘#)¾#" £Æ4(aƒ_¹\†Ó,4:³è2ŽM²ˆÊ+s3ì7Ó¤æý=Ž3\MÏ€è9…‚¦61Ã;›7AÔS\äo+Ï72ŽÊä#J†RÀ\ˆ‚G… $¥M®”úDÁŠ?S°ê¦ÄËÝ;IÀh Úúކ5ì´%®ˆÊ8'á¬ÌÿŒ0]£3R)Ť¢Œ£>ÐÚá@iDÛS0îõÛl[Ú\±8c(&á¸a3 5ýÛgZkþ1Z×mÏpÝP=£—DCœy^—²u3_ þ1߸xQݸ iM;ní˜=ª˜dŽì½¢7£ƒzÕΕ¿‡(–Ëo\#n4…Ã(]›(Žs%Ž ÁŠ$ºÔˆoX!Ê&Á0—ž§&áµæiñ†Xe<»ZG¥Ä©mwy0¬<ìŒãLû¬Vô¾V€P`À/‰S9Áèd¶îÄ:' øjË1se¤i^>ÃKïˆÒÏ´jž|©ŽÍêÖA³Cn=‰fS"|ø@#šøjna½:*$10ÒÕzïA¡¢".Ó½:/R¤ úÅ7»fƒ¡ÕÜJÙQe¥i‘7;ØôH’%ÑáÏMYÝ?{kЉösÔ¢ j2ÏYZê:˜m¡gm‹Ç²„/ÖXQçÊ`W¢èZûÕkêåë=§Ö‰‹°¯}éGÄù4$uô½²Z­kRLÁ#0ˆB8/ÔŽ¦ÂúDkûDÿ½8õˆ€4W¯eõ:ÐPÞÞó³ÏŒxbûßD5}e©ƒp‚Da©1Çí ŸÌ)±¯Àש ˆ4„± 8VìŸ;‚ à‹ÁXßjfh@Ì:w‘ ¼'QMÿEXD 1hÐÑí®(¿›ß‡ú´˜ƒDƒ@ !ƒ0ˆ ‚(1ÍÍáeZ×"{øCï©°”S¤ŽY·eA½/)T4TÃl”¬©‘Ҧ㠛%:Í3ʉTåa®&¸êœö€š[TIå<É:ÂØ0 ¤Ü‡µ9û–H2ÀÌFÙ1 ¬Ç `Æe—€e3£H(ÓJjC jÛá„™ÊnÌÔÍ3Ó4Óšªõ^N†{‚‰ ¨¤‰ŸÏ Q lP¨åô†xN*Ji86Tˆ…°qK'õ04È:i>Ø9§Z˜„*z ‚%?£ÓneN[OHÑ5¿Ñ €G&ì‹©õD"U0lªTÈ!õf„Hº¤júò¬3n}TéýZ2ò#u¬ÐjÝEÃU^uÒ‰×y^—›~;EÎadD $á„–¹; ¨lræÚ6ËTòK`B @XV£a; !™9™‹ •'öVP¿3^ S3šµ‰ªÐ¢s6Û"Ä@ݰ*øØB³€ô»~kèÇ„w6ÇÎ Aªn.$ÂJ¤—jÉÙÿb6\ÿ†F+eY•• ku—Ý€Q@¬¹ÆLÆb'M'бV8.Y-ÖNݳnÄØ«1sEñ­ã@Ì Ø8¿6‰àËô²Ñt hdIù·7xát2·B/„Rˆ endstream endobj 65 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F8 35 0 R /F10 36 0 R >> >> endobj 67 0 obj << /Length 2113 /Filter /LZWDecode >> stream €Š€ÐP¼Œ1"¡š1!0˜„(j1DFãÀÜq 6Á!%C”ˆ@g‚ …ÃhaŽ[E"ѰÀ`(!È„QIt¨J‚M%blD¨D“%À©Òg5›fq ° `:§ÕFÁ±†1ÌÆCJ¨Øn4Œ†u»’n7!†cb emªŽG" †FžQmˆ@Ìd5 ÆÓÙü˜[ £ËÅé¥V¥UF5Œ¬Ü‹q­|j¹^°^&ãQÉb4Æ¡EÂåt»m/WËö@Y,¥@Q—ªMÆYÎ4\`9ŒFs-.{A¢´í6V‹ˆÀk´Ök¶-¦Úçu»Ï¸.%f£SÌÍÆ|ʨȆ4# ˆ¤‚è:N¢Æª¯ŠðŠñ;Aƒ¸#;ÏZ×¶-›Ô‚=Šc&÷8>f#‹¨j!6³ðý?ÐhA´VÀÀi¼ !Àí|Á°›‚áÂÎ+- 5pèP†Âp‹‡ËhÃñ‹¶€„é‹äHêÈq\[¶‘œj7ð¤x¦ÃCâÒ«bj7R,ŽÉ.Òþ"B‰(Êaœª ÊñŒ³EÁ¢yB³#; ³ ¨o!-Ä™ͤÖM³{h««^4”‡;Ï3ܱ)J’´Ã½´\̪‡†Ó‚fÆ #I†¬°¹«ì0ˆÅËå<T°ehGÏ}éHL0ŒÄ2;iœ†ØqžË¹Êà3„±¢¿@‰¥dún#yZZ¼9 AŠí"|kZæÒïË éƒ39t ³o;N‰-èúNçEfº¸kHE¡˜n"†rT±¼ï{îÿLoËO ÚpÁÇqQ—´NžiêóL1"†·TØ6”'5ÎsÔù=?a•}At’~Ðõ<ñÖjx—iŠÑðÅ =VÜ%ÜwPVÕA®~J#ÿ‡Œã¾=u6ù]?eªÑ˜­c k¤¦!5Ýì[ìVí bù[cÅUð— ˆù2m}è·G*ÅAÊÕ>å¡N@2ný_»ùKºµý <оXå™õ*ïÑ7—6öŒçEjÐì¬R.}Šê`ƒg>°h>Wá „îÍ«`dfÐÁÏ"äq‘¥€s A´/7ILŽÈtöá¸C‡0ŒÃÖÞûך‹LÝE—dôºOºQ‰äp°:ÔЭ0BÏÁƒ˜¨Óâ¼1‹1n07XŒ|ÐÂËŒe Ã«Ìh%T!˜tVZ|6&©V9Å8Ù¢ðb‡Õ»ÆS>L]6’±ƒY ’ÁÁu~ÄlíHèg$bÄ“ŽI*>ÀóêåÐÂ5çÙÿ´I?(X oD %Ë åHE•o1,HÓ+äÌaˆÎÚ15Œ Ân—H² %ÒøR6e& Ì3¢ f1U™¨!JÉk NSÕQa´—E ‰f°F›¹"$t¤îfñuœ3GNi‹4cñõ~q”ŽH8Ž¥§¨Ažó4 ƒTÛæb‚Ÿ¯„!P?7è–Ç*Ä”G!ËD¡¥Ž‡«óPÚ¢´\ƒ§ýGVrðfri ´„Ò8~Ìi(ÒyMJRÁEi$=ùKÚAѦTYüSYßgTHQe¥ÎòlÜ(9¨5 þ¥†ÇXD©5Øšš’ê…1ªïÆuFCš¶L4Ü< èÕâj‰YGxʃЮ+*‚©U¶·×96‡šÈ1›*Ѥ ñK,Iƒ5él„Jœ}l ÖXXc]b)ðptãXºËÔØIvJB—Hèf’*£­Ö›Ù³b ìõ€ö ÑÚš°|¥Â‹P`ÃVÿkå±³(nlƒèÇõ¹¶ Iÿ?kplu=š‡5|!ûamɽËVÍé¿4Š‹j󽺷^`˜Kµnî5t>SÈãD>å®AÊNóº‚úƒm¼pI¼ƒkâ–Á¾—æÇ¸ ¤Oœ±ÞßüzB´S#"Ü ØXBÁW»ß¢Üí?'s´ÄÙó•†e6%‚Ø…^®Ó?}qÄ´ôà|R‰1}ý…sÍ‚¤ò·X3,äy¯Èj Jö6džž—ÃÀ‹²&É(n­`o‹ýËLdâ‰gi}5Íý$˜|±Pa\ÇøQëWbªÖÉÊF'g—4Z:ßK•³\AYÁ¾Lç•s¶YÏŠ.ÿ-T™k•¥0z6²VþÏJêù‘µÃD–Ir³ŽŽl™Œ›¢´„^ŠùûEÊoKÄü—B)]¯‘»P&5ŽÕ¾¥Ñz°…dŠ d‰ÆÅžÑ-OˆM‹GÊùi¿k§9¯5ξÔ{dSöÐÉf;‹Ol¥æ]eQ<FŠ©§?¶uÞ“¿·òFJ˜æsòƒc¥ôü výÛMnÛ¡¾ Ö_÷k±§MRi!¼.¬–å*k{VêÜê%Jng‘σùS8ÖÝ<nRUæê]ÝÊq M’\c‹¨³g¶• xÞù`\*² Q !À(„.ÑKX0Ȱ~–K¡!WØ…@ÔA)D endstream endobj 68 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F4 5 0 R /F10 36 0 R >> >> endobj 71 0 obj << /Length 2040 /Filter /LZWDecode >> stream €Š€ÐP¼Œ1"¡š1!0˜€€oŒF"á¸âm‚BJ‡)€Ï%*à…±AÐR- ì¾c3ŒSi p6"ŒÆ£‚^2OFäQÀÐlF¡Ñé31È`DPÆ)èΪ9 )É™pA! Fd:Ùt¨J’‹aeB$®[<™ÍfѨÆw{™Žƒ"(ÜlCY'Ô Œ-¤OF$b h„DbªµzÈâ·©Š+Ã+ˆh)·\EAUÚ]€š^Q•þn(!Ó8HF+„Ãb1YRm„Ådò£¾gA=ÍÖ+Z‹|Y®Ù^¶ö­´ôŠD"G#RǹnÈ»Þ}Pf4!H„!—™Æä{E¬¶c¨Õ:àRX×¶îÒø;©˜fˆ€f1ìŠfï¼/ÊÅa˜‚¤8­;ô=ï‹æú¿N#ð"¿î³[.í„ œ°HP¸!˜röBMB Pn!â‚°ðÄ5)¬ÔBù>‘KWÀnËe"FBl9ˆ¸gF±»?°BhIÇò ‡"¿PÌ6øI-LTìEÒ˜o*­‚n†‚3‡+Ë1’">a€‹1·ÏœÇ2Ìí Ó!H‚Ê3«`¡ÆB0`ˆš;F§¢ ó=ϬPаc„ý4 …CQÔÃEÌÔœ¡À²˜s"(¢¶ýSTå<T^Ò«UMTULMYWV <å'ΕË`˜ÆPXd¾‡×µøo`Üm„¶Á£Á/´"-—^ÙÏÕN Õ"#…kÒ•Â{…²üÙ),ð‰wRSkp<·K½Ђ ox'·XavÝõ5çfËwåo_í“B)_¬ÌV «á8ˆô¶‚=°¬½ ‰±X¶0"­®­±d ÎDÆKèf#"ðÍdÂQiG(B¬¡SÙv`fU6!›ç°?)[pCefæ CÌýhÚF•Š&p€y<‹C©SkPo«så4˜)*dºúé`·¶¼î$IJs¦È¬0xØ 2¬•*Ÿ †ÁßÚiK)«5ä> /Font << /F2 17 0 R /F4 5 0 R /F10 36 0 R >> >> endobj 74 0 obj << /Length 1987 /Filter /LZWDecode >> stream €Š€ÐP¼Œ1"¡š1!0˜€€oŒF"á¸âm‚BJ‡)€Ï%*à…±A\¶6.ŠE±€ÀP=™ ¦¢‰¬öz).• RYœ0‰+––Æó˜Êw8ΦÓéõ…* ©áÅ2i6¨T§•I­Z† ¬ÖËcšõ:Á9Ù,´=¤,—B)–+ Æåf¬V®ô˜ÕîŸp©ßî˜TC o¨ß¬˜ F ð[Œñó|E'‹ÊãF™»î'?WÐàï#]&v¨1!ŒÙH4F ¢ …Ã¥T4fC1ÔQÁ•Ÿè:‹‹c…«mÚùXk«…¨iš10‡‡kZä$ç®"iˆ>ɳmÕÂíˆÎÜÐ`>ª&Á¶ð"†øÀ`ëÚVõ¾oÙð`ŽéȉzabqZVÊ"lûNå€î™Rvï°seÖZ&•ÎsÝ `ÄÈ@Š]7Pu]gÄØü¦M©SÙXq¼Ü@ŠÑü}ƒßx Íè#"0ŠW]^•ä†_›µôáÇSÕúÚ/O‡;À„•˜8! ¤¸Wºø_ ç^Õ§GÎú_[í^Áù!·òÜÙJÛ! à ‚ïÂ3niOüÀV Y âÀ ƒŒiO¡õ>Çíܳ¹ƒKdγ@‚‚AÈ2\m*Áöœ+h Ð"° dÙ‘…°ÎÀØpö ä`¦uõ(ànÂâ…‡Ñ!3æÑ Öú´iQ*&Dè¡ álwd±–ñÉÐ4€‘ª2 ‰ÂaX-1õ«Ðh¾\„g„¡>,ÙBOŽPæ:¸–Þ(8W0z¸ðo#ÛçÁ 16M!^\ˆr*4Åw/[¹€åfƒ fN—¤™“aN®Pp”ÌÈ2—  #J9JÌe<¿•2ºGW4gA¨5tá!cÄÚå¡–àÁzKðl ‚2³ W̉0æ,¤²šIŃJ ‹¼3°¼„$N£W¤ÑšsVk¸Yn Wö‘«$ÍùÃ8åÌ¿x3 fIRl¬ÝìâbBAIè=¤ÓiM¬Â¨Æ’Í‘“v‚Î ÄÆgl¯’ÏöYKø‚‰ž… ôMôË—~ ‚$ߢ¤ÚŽ=*—e!t †µ2ÄS›Ã Yñ ‹³ê\¡+çyp šl²éÌe£mêŸS…Jfi;@Îmõ¶Z¦û§ó3A ÌI¾ –{zªURp¼zÅMêÊã¬8(¶¶ÁÈA€Õß„%Ô°Y„,&®¹z(àˆSuv&Ð…Weª‚®µÈTvZgV$œ¶zXal;»ƒÆÀUªdâ,„|õ¾ËYȳQÚµ ´(fMÙG/-©s0t¥™ÄÙ-Y±µÏŽØVx,j¬îTRÅm³ ÛâY6íXY PÐÙ„šËÐ\K?aMɵµêè=zT¹fzÛšJ5嵯¾È¦•ÙkòØ"Ócp®ø3¼4ô»Ë=¯=¶è%¼P†ÖiÀA­·Ì!ß[/zBK‰t ›Dܰàœx*'¶¨•p9A¦º,Ђ&‚j¸#0r®®Fk+>ýáðmñ*ÛT±m®è…†A†¯¸§â× FnÄÕ¨?clpì˜^Ç•î£.À`Þ'ŠS›òÙzdiFB2R¼]ÀÙô]èþB-Æq +?‹Úþ« 6pñmÀ&ÏVTùŠ¿SƒkdÓ"UÖ7„Ù-öPÎ5;ÁŒ»ž«ùbƒ³|éÝ ²B€8\®‹ÁƩ̪¿àøžÒ³VŽÍ¹±&¸‰‚1¼Æ·’jä==.r ·iœÎ½QªšVˆÕº/.YÕÙnrGs†ÑÀ¦/®´ù6Æ23GW o¦Ä›c­PAé·O©è‰¢v ’®"ÀÐ,²>¢•˜)R$"0@@ endstream endobj 75 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F10 36 0 R >> >> endobj 77 0 obj << /Length 1922 /Filter /LZWDecode >> stream €Š€ÐP¼Œ1"¡š1!0˜€€oŒF"á¸âm‚BJ‡)€Ï%*à…±AÐR- ì¾c3GSi l9#A€Ò^2¢LÆC‘© †2¨ô‘A†5Æ#2N{B"#aµ[HžŒ©c" Š1—J„©(¶T"Jå³ÉœÖa=§wù¸Œ5 ÛÆUéœþƒC¢ã2 `f0 dªÕŠÕs%`±Y(×+ (¨*½K°“Kà f7ÁÍŹ¢8WlõL6#’åHSñ…Ãw=Êe³lÕ^³[®é š}N¶ý²Ž63ÑÀЊ2Ê‘±|yžÓlBÜn­2Ì„Dz,Þ±G£Äã}9#|¾g¤Ó5RXÕ6N»»i˜`÷8ašÉ;®ûÂñ¾bÆÂ,É=¯{âî¸ð¸®nœºÍj‰²a’Â#ᨌÉAb¼@‚­¬AʲÉBÐÄ4ÃsàùD+©/m\ ™†ŒX! †ÁÃ$§ÅñŒg¦B(аˆoš©»" |õ*’k Ãoü—IÑPeAÀj!ˆk *’¤¬¬K,Ðaˆ‚ oÉ3'³D{ÎQ<›ÅAœX"«B fø?3lõ>OÔÒ#SŠb…CQUG,“:³«V‘b¸ÄÑB ¾úS=PBØl¤´‚•TuPƒVÔý]JÖ´Ån5¢?†b-Ÿ×so_2A¸„á£-G+cc†–LfYÕœj§²xP0Mkùw†}¾ý[a»·lˆª”ss]T÷bÝöCGÞòd |ÅM„TÁËÝBáðrcC€Œ¢b6äaB‡>˜…ÓuÞÓ/ŽVîÓZ"aÀмNds~d9Øú*t÷?eïfU–eÒÞc™ç4¶6¾ÅPC[=$¢ÍŠþƒ¡è®b!®õW骸q¨e9[sªÚ˜ÔRÕ†¡„Xí¡².!††û±#[+Ø‹†aʬí[fݨ…ŽžÄk7ƹ¾JZÿ÷Ê"%ËÀð|,s ‰Ê‹EÇ"ÇY¼ŽÛ1ÙûÌék6SüX†ñó¿<ÂÿÑG0¼û¦ÜòcÔï¡§XúuÁ—Çó;ÕmÜÓTÍ„*·‚ e™Ò^fŸ8攲p³iúCW²jͱE À¶¢È' Ê °ƒX}+¢ÜèRàž„YÛ3”üh”0ÕûAP`šŠÇ3ï6}ÏÕÁ@ š ´PZ9å- ¢RøÆÁCd´nnBÑpsFc‘‡J%¡Ê)ø²Y5#-4•=Ry顬.6Q¹nϵ´„)‰}sŒ°_=§D@¢SÚAPG‰°Ö'›(vZŠTF€â¦›”‰ Ñr;CT0™ÕЬOêÉ3«tò•ͳÏZXp‰¼÷OêС ÈL¨¡™x \Asª•Þ¬WÙêcZôÁOŠ%wƒUË Ñ™U“bL-‹eΦjÍÂ…dg]b_@Ý¿5ô­OåT¦áΙ÷òqSØE3E…>Zt·j¬ló‰Mj‰“23"Kyèhs*˜+q[Ï¡d@ÝtÆk|¹ÓóB¸v–ã[%ý7MY”'u°Ü(«tZæ’÷ZS›g½v®âñ¦’rßÞ…y¬ ÷6K¼#éM2¯Uì—¹`„2ãpd¹¾‹¦ÀgËw\†6K¥DòXA˜A¨Q`dl‡ÌÃAt"9àè{$F幪Çs©t5-³ð"*ƒ?‡ëf"Kou1œQÈA¯’ø»Yj‘sªQ_Ä(fíÙèOŽÑv>aàÐ ˜‚2"ÞÂ$õ+dŒW“±¸(»˜u5G`iULþS;èÆq«âdë­FjË™y†ä2Û‘oþ5zÕû5Xr¬h¼éµ±o6¬œá–èqè¦ùÔ#gvˆ¹sÙ1ϸhž»ÔY>éÇ{ÉíÂR •ŽÖ/Li7¥4°FËØƒBCp !K^k³. p4#Ó`ƒb>A« ¨‚Rˆ endstream endobj 78 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F4 5 0 R /F10 36 0 R >> >> endobj 80 0 obj << /Length 686 /Filter /LZWDecode >> stream €Š€ÐP¼Œ2 DC4c"0ñÞ7ŒEÃ8Y¶ *£â<Œ¨c‚Å#a¼Æk‹Fc1¨ e1™ÍMœâh(1L¦éôÔàr—Ng3)]E ZØÂl:Òªó5@öH—J„¨ Ü]‰Elâ˜Â45EFpÚâT…‘IPÕ´Dáј¸j4ŠÆcqÙH ûP0œª–+$Œ1‰Âá ¡hÄsgDѺ¢* ‚‹úËkˆÄlÑ|ü l8Ââ/±…öþ Šla0ÈÀ]mÆ¢áÆ0*ÌFÀ Œ46ãÄÆÔ ûÃ/lF" †D?ƒ£òuGAÎàŠ4XlpLîâÒ!mRôÖ·íšÒÙ-a»j䆬ût¼…‹|À@î@â¸í°l9­Ûž=!†a¸„âŠöº¯àð¡À†" gDÀcB dEl£ø·¿èCRÕÀ{µ6‹XlšÐ{V›µÎ–ŠCDž³C«Ë é<€h¹ˆÑŒ%űÀ„!¬ÜòG{¾êˆQ«ïÂR9"4r4ÖB`T á@ÐTœÅJKÐg@¸+L°ãKA‹ .±± Àù†Áº0;³CÃá ŠˆAÀr"N1ÀŒÐ¡áÈŠ¿L«ú¸O° ‘@ÐkM Æ+5?2­ÁBô‚³ô¤?K:¡¤Ú»¨´qNa@r ˆÎ „ˆÕM=W†”È`Ë©óÒ „!Hd†ÿO«8`Ô@IPš¥cΪ&IøÈ4Þã˜è¨:73.ÌÝT2´Hðûæú†o»òÄPŒyHé;Y ψÕa­[WâÁEÁq2õŠƒ1K6ÌB¹bÚã;¨i(®ð„á*ˆ¨€€ endstream endobj 81 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F10 36 0 R >> >> endobj 83 0 obj << /Length 523 /Filter /LZWDecode >> stream €Š€ÐP¼Œ6 DC4b2 "0˜€äh.D㈸g 6Á"EC”ˆ@g“ pBØ ‚P(IÄBI`R-ŒÆ¢‚ºn1 'd¼ævT$JDJ,èPS “JÂ-6vM"”êz¬âœA™Õ…’¡NÅX­k–)¥p¦T—J„¨$! †A±ÑÄè@-G£åB$°PT4Nv# Ààe7 '‹*Äf7œ²¦ìÁÈÚa:Mæã ²Äp:œŽó™—^è͇œfG+¯£ Æó¥ˆäe8M;ó%ˆèo±L¦]îÀPt4lG3¡‡"a9'×+ (¨*Ã9“q ÒwÐé |ÃG(æs0™ý>±A‹æ5öz<žo©§H9!hÆ7Œƒ+Šõ?C:6¼HÞ3A¯Ë£¥Â˜†$‰0£¨9?Ã;öŽìHÆ4BÜ9±C£^úAð b(!„` ®+šL½…Áˆl¡l(–·ì{Bдm¹ÁÂ;q°‰0 zà ­sàù,L“äê,Aìjî Ê…¡ Pná’ ‘ÇÉhf"r†bn(!@ˆa ‰8†“¼òƒ†"(Š!Bö‚‚"S cE…ÜÞGB4¾ºˆÁ¤Æ¼S$‰LAš‚ˆÒ.!¢B•&* H ŠH endstream endobj 84 0 obj << /ProcSet [/PDF /Text] /ColorSpace <> /Font << /F2 17 0 R /F4 5 0 R /F6 13 0 R /F10 36 0 R >> >> endobj 17 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /Encoding 85 0 R /BaseFont /Times-Roman >> endobj 5 0 obj << /Type /Font /Subtype /Type1 /Name /F4 /Encoding 85 0 R /BaseFont /Helvetica >> endobj 13 0 obj << /Type /Font /Subtype /Type1 /Name /F6 /Encoding 85 0 R /BaseFont /Times-Bold >> endobj 35 0 obj << /Type /Font /Subtype /Type1 /Name /F8 /Encoding 85 0 R /BaseFont /Times-Italic >> endobj 36 0 obj << /Type /Font /Subtype /Type1 /Name /F10 /Encoding 85 0 R /BaseFont /Courier >> endobj 40 0 obj << /Type /Font /Subtype /Type1 /Name /F11 /BaseFont /Symbol >> endobj 85 0 obj << /Type /Encoding /Differences [ 1/minus/mu/multiply/ntilde/oacute/ocircumflex/odieresis/ograve /onehalf/onequarter/onesuperior/otilde/plusminus/registered/scaron/thorn /threequarters/threesuperior/trademark/twosuperior/uacute/ucircumflex/udieresis/ugrave /yacute/ydieresis/zcaron 127/Aacute/Acircumflex/Adieresis/Agrave/Aring /Atilde/Ccedilla/Delta/Eacute/Ecircumflex/Edieresis/Egrave/Eth /Gamma/Iacute/Icircumflex/Idieresis/Igrave/Lambda/Ntilde/Oacute /Ocircumflex/Odieresis/Ograve/Omega/Otilde/Phi/Pi/Psi /Scaron/Sigma/TeXtext32/Theta/Thorn 209/Uacute/Ucircumflex/Udieresis /Ugrave/Upsilon/Xi/Yacute/Ydieresis/Zcaron/aacute/acircumflex /adieresis/agrave/aring/atilde/brokenbar 228/ccedilla/copyright/degree /divide 236/dotlessj/eacute/ecircumflex/edieresis/egrave 242/eth/ff /ffi 246/ffl/iacute 252/icircumflex/idieresis/igrave/logicalnot ] >> endobj 2 0 obj << /Type /Page /Parent 6 0 R /Resources 4 0 R /Contents 3 0 R >> endobj 7 0 obj << /Type /Page /Parent 6 0 R /Resources 9 0 R /Contents 8 0 R >> endobj 10 0 obj << /Type /Page /Parent 6 0 R /Resources 12 0 R /Contents 11 0 R >> endobj 14 0 obj << /Type /Page /Parent 6 0 R /Resources 16 0 R /Contents 15 0 R >> endobj 18 0 obj << /Type /Page /Parent 6 0 R /Resources 20 0 R /Contents 19 0 R >> endobj 21 0 obj << /Type /Page /Parent 6 0 R /Resources 23 0 R /Contents 22 0 R >> endobj 24 0 obj << /Type /Page /Parent 28 0 R /Resources 26 0 R /Contents 25 0 R >> endobj 29 0 obj << /Type /Page /Parent 28 0 R /Resources 31 0 R /Contents 30 0 R >> endobj 32 0 obj << /Type /Page /Parent 28 0 R /Resources 34 0 R /Contents 33 0 R >> endobj 37 0 obj << /Type /Page /Parent 28 0 R /Resources 39 0 R /Contents 38 0 R >> endobj 41 0 obj << /Type /Page /Parent 28 0 R /Resources 43 0 R /Contents 42 0 R >> endobj 44 0 obj << /Type /Page /Parent 28 0 R /Resources 46 0 R /Contents 45 0 R >> endobj 47 0 obj << /Type /Page /Parent 50 0 R /Resources 49 0 R /Contents 48 0 R >> endobj 51 0 obj << /Type /Page /Parent 50 0 R /Resources 53 0 R /Contents 52 0 R >> endobj 54 0 obj << /Type /Page /Parent 50 0 R /Resources 56 0 R /Contents 55 0 R >> endobj 57 0 obj << /Type /Page /Parent 50 0 R /Resources 59 0 R /Contents 58 0 R >> endobj 60 0 obj << /Type /Page /Parent 50 0 R /Resources 62 0 R /Contents 61 0 R >> endobj 63 0 obj << /Type /Page /Parent 50 0 R /Resources 65 0 R /Contents 64 0 R >> endobj 66 0 obj << /Type /Page /Parent 69 0 R /Resources 68 0 R /Contents 67 0 R >> endobj 70 0 obj << /Type /Page /Parent 69 0 R /Resources 72 0 R /Contents 71 0 R >> endobj 73 0 obj << /Type /Page /Parent 69 0 R /Resources 75 0 R /Contents 74 0 R >> endobj 76 0 obj << /Type /Page /Parent 69 0 R /Resources 78 0 R /Contents 77 0 R >> endobj 79 0 obj << /Type /Page /Parent 69 0 R /Resources 81 0 R /Contents 80 0 R >> endobj 82 0 obj << /Type /Page /Parent 69 0 R /Resources 84 0 R /Contents 83 0 R >> endobj 6 0 obj << /Type /Pages /Kids [2 0 R 7 0 R 10 0 R 14 0 R 18 0 R 21 0 R ] /Count 6 /Parent 27 0 R >> endobj 28 0 obj << /Type /Pages /Kids [24 0 R 29 0 R 32 0 R 37 0 R 41 0 R 44 0 R ] /Count 6 /Parent 27 0 R >> endobj 50 0 obj << /Type /Pages /Kids [47 0 R 51 0 R 54 0 R 57 0 R 60 0 R 63 0 R ] /Count 6 /Parent 27 0 R >> endobj 69 0 obj << /Type /Pages /Kids [66 0 R 70 0 R 73 0 R 76 0 R 79 0 R 82 0 R ] /Count 6 /Parent 27 0 R >> endobj 27 0 obj << /Type /Pages /Kids [6 0 R 28 0 R 50 0 R 69 0 R ] /Count 24 /MediaBox [0 0 612 792 ] >> endobj 86 0 obj << /Type /Catalog /Pages 27 0 R >> endobj 87 0 obj << /CreationDate (D:19970331114224) /Producer (Acrobat Distiller 2.1 for Windows) >> endobj xref 0 88 0000000000 65535 f 0000000017 00000 n 0000118125 00000 n 0000000182 00000 n 0000000840 00000 n 0000116724 00000 n 0000120321 00000 n 0000118213 00000 n 0000000948 00000 n 0000001827 00000 n 0000118301 00000 n 0000001935 00000 n 0000004151 00000 n 0000116830 00000 n 0000118392 00000 n 0000004272 00000 n 0000006862 00000 n 0000116615 00000 n 0000118483 00000 n 0000006995 00000 n 0000074413 00000 n 0000118574 00000 n 0000074546 00000 n 0000076630 00000 n 0000118665 00000 n 0000076763 00000 n 0000079383 00000 n 0000120790 00000 n 0000120436 00000 n 0000118757 00000 n 0000079516 00000 n 0000080313 00000 n 0000118849 00000 n 0000080446 00000 n 0000083038 00000 n 0000116938 00000 n 0000117048 00000 n 0000118941 00000 n 0000083196 00000 n 0000085921 00000 n 0000117154 00000 n 0000119033 00000 n 0000086092 00000 n 0000088462 00000 n 0000119125 00000 n 0000088620 00000 n 0000091333 00000 n 0000119217 00000 n 0000091504 00000 n 0000094802 00000 n 0000120554 00000 n 0000119309 00000 n 0000094948 00000 n 0000097715 00000 n 0000119401 00000 n 0000097874 00000 n 0000099513 00000 n 0000119493 00000 n 0000099671 00000 n 0000101793 00000 n 0000119585 00000 n 0000101915 00000 n 0000104040 00000 n 0000119677 00000 n 0000104174 00000 n 0000105922 00000 n 0000119769 00000 n 0000106080 00000 n 0000108272 00000 n 0000120672 00000 n 0000119861 00000 n 0000108394 00000 n 0000110513 00000 n 0000119953 00000 n 0000110647 00000 n 0000112713 00000 n 0000120045 00000 n 0000112847 00000 n 0000114848 00000 n 0000120137 00000 n 0000114970 00000 n 0000115734 00000 n 0000120229 00000 n 0000115868 00000 n 0000116469 00000 n 0000117241 00000 n 0000120904 00000 n 0000120961 00000 n trailer << /Size 88 /Root 86 0 R /Info 87 0 R /ID [<854ab977fcb2c3db01e0830125426569><854ab977fcb2c3db01e0830125426569>] >> startxref 121068 %%EOF 2 0 obj << /Type /Page /Parent 6 0 R /Resources 4 0 R /Contents 3 0 R /Thumb 92 0 R >> endobj 7 0 obj << /Type /Page /Parent 6 0 R /Resources 9 0 R /Contents 8 0 R /Thumb 94 0 R >> endobj 10 0 obj << /Type /Page /Parent 6 0 R /Resources 12 0 R /Contents 11 0 R /Thumb 96 0 R >> endobj 14 0 obj << /Type /Page /Parent 6 0 R /Resources 16 0 R /Contents 15 0 R /Thumb 98 0 R >> endobj 18 0 obj << /Type /Page /Parent 6 0 R /Resources 20 0 R /Contents 19 0 R /Thumb 100 0 R >> endobj 21 0 obj << /Type /Page /Parent 6 0 R /Resources 23 0 R /Contents 22 0 R /Thumb 102 0 R >> endobj 24 0 obj << /Type /Page /Parent 28 0 R /Resources 26 0 R /Contents 25 0 R /Thumb 104 0 R >> endobj 29 0 obj << /Type /Page /Parent 28 0 R /Resources 31 0 R /Contents 30 0 R /Thumb 106 0 R >> endobj 32 0 obj << /Type /Page /Parent 28 0 R /Resources 34 0 R /Contents 33 0 R /Thumb 108 0 R >> endobj 37 0 obj << /Type /Page /Parent 28 0 R /Resources 39 0 R /Contents 38 0 R /Thumb 110 0 R >> endobj 41 0 obj << /Type /Page /Parent 28 0 R /Resources 43 0 R /Contents 42 0 R /Thumb 112 0 R >> endobj 44 0 obj << /Type /Page /Parent 28 0 R /Resources 46 0 R /Contents 45 0 R /Thumb 114 0 R >> endobj 47 0 obj << /Type /Page /Parent 50 0 R /Resources 49 0 R /Contents 48 0 R /Thumb 116 0 R >> endobj 51 0 obj << /Type /Page /Parent 50 0 R /Resources 53 0 R /Contents 52 0 R /Thumb 118 0 R >> endobj 54 0 obj << /Type /Page /Parent 50 0 R /Resources 56 0 R /Contents 55 0 R /Thumb 120 0 R >> endobj 57 0 obj << /Type /Page /Parent 50 0 R /Resources 59 0 R /Contents 58 0 R /Thumb 122 0 R >> endobj 60 0 obj << /Type /Page /Parent 50 0 R /Resources 62 0 R /Contents 61 0 R /Thumb 124 0 R >> endobj 63 0 obj << /Type /Page /Parent 50 0 R /Resources 65 0 R /Contents 64 0 R /Thumb 126 0 R >> endobj 66 0 obj << /Type /Page /Parent 69 0 R /Resources 68 0 R /Contents 67 0 R /Thumb 128 0 R >> endobj 70 0 obj << /Type /Page /Parent 69 0 R /Resources 72 0 R /Contents 71 0 R /Thumb 130 0 R >> endobj 73 0 obj << /Type /Page /Parent 69 0 R /Resources 75 0 R /Contents 74 0 R /Thumb 132 0 R >> endobj 76 0 obj << /Type /Page /Parent 69 0 R /Resources 78 0 R /Contents 77 0 R /Thumb 134 0 R >> endobj 79 0 obj << /Type /Page /Parent 69 0 R /Resources 81 0 R /Contents 80 0 R /Thumb 136 0 R >> endobj 82 0 obj << /Type /Page /Parent 69 0 R /Resources 84 0 R /Contents 83 0 R /Thumb 138 0 R >> endobj 86 0 obj << /Type /Catalog /Pages 27 0 R /Outlines 88 0 R >> endobj 87 0 obj << /CreationDate (D:19970331114224) /Producer (Acrobat Distiller 2.1 for Windows) /ModDate (D:19970331114427) >> endobj 88 0 obj << /Count 0 /Type /Outlines >> endobj 89 0 obj [ /Indexed /DeviceRGB 255 90 0 R ] endobj 90 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Length 91 0 R >> stream J,g]g+e/h_!_gCtO=0f)$P%cIi8Zdfc5&3j_8$7g.@L`YKUJNGBP\poR=_;Dl'P(T (7Boo^^S:71(MN]ZQX/+Cbu.lK"p74pe1T%s.DY%&\1TdJhr54.M9au6>79n6`Q:4 PbLSZTLEE(8E@'*1mg_*eTnN*;*'V3+gm-EEetX%;Bo$ur2ss*N`.-!.kG_q6GDD' dKoL!8Ka#EV,@V!\j8ZFbp6EE<9cn=N6j0nf;(&;QU6bUD')c@\ 9-d\DA=cZ0Q>gIM$$;cd2O@&a;X,Nn_aP(]I1aRc(K1^ue> gF/(+GaKo$qneLWDrQ#;5\S(\$q'4Q,85`-8;S(=Z"WSBOV*FM)4,?B],R endstream endobj 91 0 obj 488 endobj 92 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 93 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb)urTB;Rp>H >q_R8jqBbNel=)f:1mF'%/,*6TMT<$);Q&m6_mPWe@@.XSPQ%[.TJO+*DsX]O^$\[@aJB9tsOioWjnAY&^dE",4:W/:LW!YA =M/6)*KS9PE-3'VUFhh$>,aM%k'&t\ctIN)4XQLiVpoI(>.nOW?*DmsG$@,,f57mFJ,~> endstream endobj 93 0 obj 270 endobj 94 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 95 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^757;Rp>H >q_R=AlC^ceguBB:1mM9eCk-iTMHr^+9`O?8#0$s<4ZX!R1,bioWjnAY&^gLbU.L`nZLW!YA 3%SZ"d9FY%ACZX)="TcY endstream endobj 95 0 obj 267 endobj 96 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 97 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^757;Rp>H >q_R=AlC^cenm@9:1mM9jEUhlT?h1M32H\98#0$s<15*kSPO%Ll;]m8Ni?*]+Cpb+ jY!66RFc7SMRAJV.'m'X(:eRbQ#*rrC6om9f'R[>J1k!9jnAY&^gM+`44W@#LW!YA =M/4Rh.O%RlT![s~> endstream endobj 97 0 obj 289 endobj 98 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 99 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^757;Rp>H >q_KdAlC^cc=&Yoc"BtcjPkSPTKsr])@[IA8#/N9F@o7cSKF]XAlK,&7\?*@>?rSmcCZet7R9B@Z/LSeKg \;WU$*K7gBEYj[X5:;]<__IRLjF]+QcGDC6%1F%CF4.nsp?776dAbZ3X]l,Jb/q$2 CA/[\#QoLii,Eo[ac>)%`7&4A*4[[LREt)=H endstream endobj 99 0 obj 313 endobj 100 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 101 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^757;'6"M >q_R=AlC^celrdf3%%H-[*EkXT?h+K)8urB8#&g(?j^0h2,'psT^t-C63g&^5cZU8 g_-RmXk"W&fPQelB!K6#p8XC0d9a4blLrr$EP$7,gjg2V`T!d$Rb04@//5DkH'hoW \,8spr_R+Pu%[c24(LED)Q\U6T[fm D'urd5&XN(c>5)f*X;Te9UkT&f=cN?cOX7"lr/P&-YH8MZ7$,t[[/XXhMVS@'rlP2rj0bHgcT1!GHL __]OMSB?pf1Mki3c"R%43Qrn9kr['eMEO'tP)T$n:U=%#6-Ag/%6.1?bn!(e1fY>U ;7) endstream endobj 101 0 obj 635 endobj 102 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 103 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^7(s1:^r( >q_R=AlC^#VJQ^0:1mM9PX]p_TM6d*3&Lo"7mPHN:c_$'G>"l6@s%"4$Df\]en-db [;*B,Y"E:A)^Ufp9X!(7nk!u,h/B,nBK$ endstream endobj 103 0 obj 292 endobj 104 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 105 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^7(s1:^r( >q_R=AlC^#VJQ^0:1mM9PX]p_TM6d*3&Lo"8!VIN:at3QSPQ1Q.2=lA7Vu,+:o_s4 c$!N"Y#h[4$RM)R@^K:9c\YAa&qnQ>2&BcKFg<4"bkKUke35)N0?MX/q':FrNF7\p:Z; D5k.,jYCtli,EpG4sq/+a5fc&4J$1ES^6MAA8i(~> endstream endobj 105 0 obj 309 endobj 106 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 107 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^7(s1:^r( >q_R=AlC^+VJQ[/:1mM9PX]p_TM4M?3'@J*7mPHN:c_$'InQV:W`*)TioWjnAY&^gM+`4=1jRLW!YA =M/6)*KS9PE`kN# endstream endobj 107 0 obj 232 endobj 108 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 109 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'n/JWrc<;OKAM >n<4EAlC^;enm@4bg8/&jS"!dTL%a=\d]F77\S7A'T,m#O&)]L.C6UF`,>NZ@qlU8`KXkNd 2I'9A*KS90D4)B@<_%tKjg/(!*M2)?c.B&AHZ"U5-^e[))4`lO='sP&1H'ZAek*'q D)U.]V%U1L`,?f&rIe3c`74:M(!]l>S^6MAB_>,e=0:*@G'd(G#Q~> endstream endobj 109 0 obj 322 endobj 110 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 111 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^7,_1:^r( =P&m5:brEBceXi0S\0K'~> endstream endobj 111 0 obj 305 endobj 112 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 113 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'.WJWe/e;Rp>H >q(u]AlC]P^25g!6=uFljS"!dSk`nI$7-II18.P.oX\S],u(=:BeoOE3@C]s`>+YhlTd4="tG>JeGM om?(l.t>LuE`kA-3ldK/;K6gFc?DF/[qG>79\f),VoRM5\fF1#&Zs\i/K5QR[eH-B 8>uEVjEF['hSQA+qWA*Ca5h8d;0bYbS^6MAH endstream endobj 113 0 obj 312 endobj 114 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 115 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'.X-^757;Rp>H >qV;a@e0>jenm",:1A9iI-Q,ETM0!_3XlRE6)7#Lds1",Y"XE`;5B57a'rb:skCSp!bd_di#cm3\/oVpEgL)S"V;_k=g22Hmd/_?lXS m.XC/->RO]c>ND^3,\H_S'g_MS@RM9;[(h3[!^/s=0:*@G'dN/jB&88n9B=e5:7'F~> endstream endobj 115 0 obj 335 endobj 116 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 117 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'mtJWrc<;Rp>G ""'C/AlC^c7U7sC:1mJgPjWraTM9)tH3G(D/>:KqoQk'-QTV*=Bse;--Ns43&U^:KZ%*X Fh93-8MA$CDY&6ds!obAjKh]Uc*gWDcfd!(CkNHpVUO_7HFTP*.BM/ko%P1^en(D: mC-"7:@EVG_U9r:lXplD^uTN]>e",VQd=(N3aFqI=037pp%r%/kBFV@J:I~> endstream endobj 117 0 obj 328 endobj 118 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 119 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'mpJWrc<;Rp>H =!j;.AlC^c5$^+;8t,@>jQ^MFTL`]/\U=+17\J*VoX\TDPi]iVQZ4X.8Jk4a;=i,EpG4sq/+a5h8cHS/AYS^6MAFH@%~> endstream endobj 119 0 obj 309 endobj 120 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 121 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@':\-^757;Rp>H >pkfZAlC^cef?E6:1mK#[.\o(S^;#5qBZo:7ukrpFGaWfAP/n#AQ7rC8HRME:?n*J c$"/4YZP^B3;k>30X=l!;+eL4f5J/fXg6]@f'NpWb:`P$j:_&7^>No'r!!NMs`5&R?kc;?D9M:REPUS_c_dp6!u9<4k(B[e&Wf,]_' @e&Pl~> endstream endobj 121 0 obj 300 endobj 122 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 123 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'nb-^7161:^r( >q_R=AlC-Penl_$c=^(de4P!NTMFYA3%Y>o8!_K#'Y4G\SCaW;BMf\5 endstream endobj 123 0 obj 352 endobj 124 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 125 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@&GD-^757;Rp>H >q_F6Al1RAenm@3`2=9ZjM#7kLX0X51^rZ+8"7jS:qB(R@7I.oAQ67:*i2r*`+p*F X`aqRX4/[7g@]d4;6a9fQj@Z5*N&X(]i)'*g\),LJY6GL G[+52&O4:n+rM9,59Z9/jRX&O[*(Cuc"H.+h"HXrGLK0+P$Lbb=0KPEp)?/j2N)5% mWVBR^<:`8fC*Mq%OQCR>N53m4FTdNSSb!+3W2.>=0:*@G'dN/jAq2pn9B=e5:;fB%"Nj~> endstream endobj 125 0 obj 339 endobj 126 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 127 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@&kP-^757;Rp>H >qM5`AlC^cee^!0:1mK#[.\o(S^;%JRJdn\8#/POFLbBuSPP9p.TIsOb,8=7e&Pl~> endstream endobj 127 0 obj 300 endobj 128 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 129 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@'jl-^757;Rp>H >q_AbAlCZ_^25g!:$.YL>ipH!S4':i3[CSJ7t]3'm)q)\$8mAYn&D(5ikrfh]"QmI]^-cC&[Ch5OI[eE6:H^9)7BHXKY,/W 'Ds]5(I#[qj`oIE8qV$)@<.NIbel0+QKIe-$"c[nU694I3W2qs;'OTPopZm!^-f9Z @^ctu[bl;:h/;tm%K?JO`Snl5)a06/4j2dO3RQ]=++Mb"F^a+/`*9b\n+U:?*uC75 `q+M)?GC-^h=(,6i#i~> endstream endobj 129 0 obj 355 endobj 130 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 131 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@&GD-^757;Rp>H >q_F6Al1RAenm@3`2=9ZjM#7kLX0X51^rZ+8"7jS:qB(R@7I.oAQ67:*i2r*`+p*F X`aqRX4/[7g@]d4;6a9fQj@Z5*N&X(]i)'*g\),LJY6GL G[+52&O4:n+rM9,59Z9/jRX&O[*(Cuc"H.+h"HXrUsro@HC\ZW-J,Ti[Tb^;(Lsi- CNeFFcM'oBY]%$TXbP_ga0ShB*56"M-)p)!FWDM%=/E"`B6udjkBE=_ms'4d5:;fB kGgd4~> endstream endobj 131 0 obj 342 endobj 132 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 133 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@&GD-^75710J.r 0e/P_-.-Fc`b.6#6RK,GbY!(/T$V.Lq-==J7%$oO;X-ZAQTD"ml;BZ[3i?&\;X1[$ j[LJ!XOq>i4!Z;fB=(fY<6I_=cT\gCC::YNb3_U,?11`#UiuK^Ur4r($gmfrHbA>* fN@8cong^nZ'&p_b9<.[jPr7YNaFeSbtI[%Rf8@(Tpf\r\ag$e4\h@C!P^Z%ZV>4'ooH-,4?W44IH5G8VQot)69T3`Jlma:qP54q:` jn*k0#Tm-Wh=(,dIU>)$"9~> endstream endobj 133 0 obj 359 endobj 134 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 135 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@&GD-^757;Rp>H >q_F6Al1RAenm@3`2=9ZjM#7kLX0X51^rZ+8"7jS:qB(R@7I.oAQ67:*i2r*`+p*F X`aqRX4/[7g@]d4;6a9fQj@Z5*N&X(]i)'*g\),LJY6GL G[+52&O4:n+rM9,59Z9/jRX&O[*(Cuc"H.+h"HXrGLK0+P$Lbb)5>['275S:cXS3Q lF+:[]Sgi6d-c+`*W2O:TAdjNZsDOdP98oVo6gP8=0:*@G'dN/kBFVsn6(%.+"*E" kOa(K?"aK~> endstream endobj 135 0 obj 346 endobj 136 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 137 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@&GD-^757;Rp>8 9.uZ+Akd@UdT\Z#8u?[?jRsrYSBtm^l6R4*"/&Ji;lVu=SM6kfl;[VV<^0H\;X2fD j`XukRoX?'HM*TKB=(iZioWjnAY&^gM+`4=1jRLW!YA =M/6)*KS9PE`kN%="Tc_ endstream endobj 137 0 obj 238 endobj 138 0 obj << /Filter [ /ASCII85Decode /LZWDecode ] /Width 76 /Height 99 /ColorSpace 89 0 R /BitsPerComponent 8 /Length 139 0 R >> stream J2Q7]3$]7K#D>EP:q1$o*=mro@So+\<\5,H7Uo<*jE<[.O@Wn[3@&kP-^757;Rp>H >qM5`AlC^cee^!0:1mK#[.\o(S^;%K\c!:`7ANgq;0kAXSPQ1`C/mioWjnAY&^gM+`4=1jRLW!YA =Lae))3;jLE`kB/"9~> endstream endobj 139 0 obj 220 endobj xref 0 1 0000000000 65535 f 2 1 0000122997 00000 n 7 1 0000123107 00000 n 10 1 0000123217 00000 n 14 1 0000123330 00000 n 18 1 0000123443 00000 n 21 1 0000123557 00000 n 24 1 0000123671 00000 n 29 1 0000123786 00000 n 32 1 0000123901 00000 n 37 1 0000124016 00000 n 41 1 0000124131 00000 n 44 1 0000124246 00000 n 47 1 0000124361 00000 n 51 1 0000124476 00000 n 54 1 0000124591 00000 n 57 1 0000124706 00000 n 60 1 0000124821 00000 n 63 1 0000124936 00000 n 66 1 0000125051 00000 n 70 1 0000125166 00000 n 73 1 0000125281 00000 n 76 1 0000125396 00000 n 79 1 0000125511 00000 n 82 1 0000125626 00000 n 86 54 0000125741 00000 n 0000125821 00000 n 0000125959 00000 n 0000126016 00000 n 0000126074 00000 n 0000126662 00000 n 0000126686 00000 n 0000127118 00000 n 0000127142 00000 n 0000127571 00000 n 0000127595 00000 n 0000128046 00000 n 0000128070 00000 n 0000128545 00000 n 0000128569 00000 n 0000129368 00000 n 0000129393 00000 n 0000129849 00000 n 0000129874 00000 n 0000130347 00000 n 0000130372 00000 n 0000130768 00000 n 0000130793 00000 n 0000131279 00000 n 0000131304 00000 n 0000131773 00000 n 0000131798 00000 n 0000132274 00000 n 0000132299 00000 n 0000132798 00000 n 0000132823 00000 n 0000133315 00000 n 0000133340 00000 n 0000133813 00000 n 0000133838 00000 n 0000134302 00000 n 0000134327 00000 n 0000134843 00000 n 0000134868 00000 n 0000135371 00000 n 0000135396 00000 n 0000135860 00000 n 0000135885 00000 n 0000136404 00000 n 0000136429 00000 n 0000136935 00000 n 0000136960 00000 n 0000137483 00000 n 0000137508 00000 n 0000138018 00000 n 0000138043 00000 n 0000138445 00000 n 0000138470 00000 n 0000138854 00000 n trailer << /Size 140 /Info 87 0 R /Root 86 0 R /Prev 121068 /ID[<854ab977fcb2c3db01e0830125426569><5d0d4dc6e12cdffb19fc519c593db9e8>] >> startxref 138879 %%EOF trf2.1.4/generic/sha/Makefile0000644000175000017500000000127511216343142015403 0ustar sergeisergei# By default, the code is compiled for a "big endian" machine. # To compile on a "little endian" machine set the LITTLE_ENDIAN flag. # To make smaller object code, but run a little slower, don't use UNROLL_LOOPS. # To use NIST's modified SHA of 7/11/94, define USE_MODIFIED_SHA CC = gcc CFLAGS = -O2 -ansi -Wall -pedantic -DUNROLL_LOOPS -DLITTLE_ENDIAN # -DUSE_MODIFIED_SHA all: sha sha: sha_driver.o sha.o $(CC) -o $@ sha_driver.o sha.o strip $@ test: sha appgen appgen 1 | sha appgen 2 | sha appgen 3 | sha @echo "Values should be:" @cat sha.good.outputs @echo "except if you defined USE_MODIFIED_SHA!" @echo "I have no known-good comparisons for that case!" clean: rm *.o sha appgen trf2.1.4/generic/sha/sha.h0000644000175000017500000000161511216343142014665 0ustar sergeisergei#ifndef SHA_H #define SHA_H #include /* NIST Secure Hash Algorithm */ /* heavily modified from Peter C. Gutmann's implementation */ /* Useful defines & typedefs */ #ifndef _WIN32 typedef unsigned char BYTE; #endif #if defined(__alpha) || defined(__LP64__) typedef unsigned int UINT32; #else #ifndef UINT32 #ifdef _WIN32 # pragma warning ( disable : 4142 ) #endif typedef unsigned long UINT32; #endif #endif #define SHA_BLOCKSIZE 64 #define SHA_DIGESTSIZE 20 typedef struct { UINT32 digest[5]; /* message digest */ UINT32 count_lo, count_hi; /* 64-bit bit count */ UINT32 data[16]; /* SHA data buffer */ } SHA_INFO; void sha_init _ANSI_ARGS_ ((SHA_INFO *)); void sha_update _ANSI_ARGS_ ((SHA_INFO *, BYTE *, int)); void sha_final _ANSI_ARGS_ ((SHA_INFO *)); void sha_stream _ANSI_ARGS_ ((SHA_INFO *, FILE *)); void sha_print _ANSI_ARGS_ ((SHA_INFO *)); #endif /* SHA_H */ trf2.1.4/generic/sha/sha.c0000644000175000017500000001407711216343142014666 0ustar sergeisergei/* NIST Secure Hash Algorithm */ /* heavily modified by Uwe Hollerbach uh@alumni.caltech edu */ /* from Peter C. Gutmann's implementation as found in */ /* Applied Cryptography by Bruce Schneier */ /* NIST's proposed modification to SHA of 7/11/94 may be */ /* activated by defining USE_MODIFIED_SHA */ #ifdef HAVE_STDLIB_H #include #else #include "../../compat/stdlib.h" #endif #include #include #include "sha.h" /* SHA f()-functions */ #define f1(x,y,z) ((x & y) | (~x & z)) #define f2(x,y,z) (x ^ y ^ z) #define f3(x,y,z) ((x & y) | (x & z) | (y & z)) #define f4(x,y,z) (x ^ y ^ z) /* SHA constants */ #define CONST1 0x5a827999L #define CONST2 0x6ed9eba1L #define CONST3 0x8f1bbcdcL #define CONST4 0xca62c1d6L /* 32-bit rotate */ #define ROT32(x,n) ((x << n) | (x >> (32 - n))) #define FUNC(n,i) \ temp = ROT32(A,5) + f##n(B,C,D) + E + W[i] + CONST##n; \ E = D; D = C; C = ROT32(B,30); B = A; A = temp #define FUNC1(i) \ temp = ROT32(A,5) + f1(B,C,D) + E + W[i] + CONST1; \ E = D; D = C; C = ROT32(B,30); B = A; A = temp #define FUNC2(i) \ temp = ROT32(A,5) + f2(B,C,D) + E + W[i] + CONST2; \ E = D; D = C; C = ROT32(B,30); B = A; A = temp #define FUNC3(i) \ temp = ROT32(A,5) + f3(B,C,D) + E + W[i] + CONST3; \ E = D; D = C; C = ROT32(B,30); B = A; A = temp #define FUNC4(i) \ temp = ROT32(A,5) + f4(B,C,D) + E + W[i] + CONST4; \ E = D; D = C; C = ROT32(B,30); B = A; A = temp /* do SHA transformation */ static void sha_transform(sha_info) SHA_INFO *sha_info; { int i; UINT32 temp, A, B, C, D, E, W[80]; for (i = 0; i < 16; ++i) { W[i] = sha_info->data[i]; } for (i = 16; i < 80; ++i) { W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; #ifdef USE_MODIFIED_SHA W[i] = ROT32(W[i], 1); #endif /* USE_MODIFIED_SHA */ } A = sha_info->digest[0]; B = sha_info->digest[1]; C = sha_info->digest[2]; D = sha_info->digest[3]; E = sha_info->digest[4]; #ifdef UNROLL_LOOPS FUNC1( 0); FUNC1( 1); FUNC1( 2); FUNC1( 3); FUNC1( 4); FUNC1( 5); FUNC1( 6); FUNC1( 7); FUNC1( 8); FUNC1( 9); FUNC1(10); FUNC1(11); FUNC1(12); FUNC1(13); FUNC1(14); FUNC1(15); FUNC1(16); FUNC1(17); FUNC1(18); FUNC1(19); FUNC2(20); FUNC2(21); FUNC2(22); FUNC2(23); FUNC2(24); FUNC2(25); FUNC2(26); FUNC2(27); FUNC2(28); FUNC2(29); FUNC2(30); FUNC2(31); FUNC2(32); FUNC2(33); FUNC2(34); FUNC2(35); FUNC2(36); FUNC2(37); FUNC2(38); FUNC2(39); FUNC3(40); FUNC3(41); FUNC3(42); FUNC3(43); FUNC3(44); FUNC3(45); FUNC3(46); FUNC3(47); FUNC3(48); FUNC3(49); FUNC3(50); FUNC3(51); FUNC3(52); FUNC3(53); FUNC3(54); FUNC3(55); FUNC3(56); FUNC3(57); FUNC3(58); FUNC3(59); FUNC4(60); FUNC4(61); FUNC4(62); FUNC4(63); FUNC4(64); FUNC4(65); FUNC4(66); FUNC4(67); FUNC4(68); FUNC4(69); FUNC4(70); FUNC4(71); FUNC4(72); FUNC4(73); FUNC4(74); FUNC4(75); FUNC4(76); FUNC4(77); FUNC4(78); FUNC4(79); #else /* !UNROLL_LOOPS */ for (i = 0; i < 20; ++i) { FUNC1(i); } for (i = 20; i < 40; ++i) { FUNC2(i); } for (i = 40; i < 60; ++i) { FUNC3(i); } for (i = 60; i < 80; ++i) { FUNC4(i); } #endif /* !UNROLL_LOOPS */ sha_info->digest[0] += A; sha_info->digest[1] += B; sha_info->digest[2] += C; sha_info->digest[3] += D; sha_info->digest[4] += E; } #ifdef LITTLE_ENDIAN /* change endianness of data */ static void byte_reverse(buffer, count) UINT32 *buffer; int count; { int i; BYTE ct[4], *cp; count /= sizeof(UINT32); cp = (BYTE *) buffer; for (i = 0; i < count; ++i) { ct[0] = cp[0]; ct[1] = cp[1]; ct[2] = cp[2]; ct[3] = cp[3]; cp[0] = ct[3]; cp[1] = ct[2]; cp[2] = ct[1]; cp[3] = ct[0]; cp += sizeof(UINT32); } } #endif /* LITTLE_ENDIAN */ /* initialize the SHA digest */ void sha_init(sha_info) SHA_INFO *sha_info; { sha_info->digest[0] = 0x67452301L; sha_info->digest[1] = 0xefcdab89L; sha_info->digest[2] = 0x98badcfeL; sha_info->digest[3] = 0x10325476L; sha_info->digest[4] = 0xc3d2e1f0L; sha_info->count_lo = 0L; sha_info->count_hi = 0L; } /* update the SHA digest */ void sha_update(sha_info, buffer, count) SHA_INFO *sha_info; BYTE *buffer; int count; { if ((sha_info->count_lo + ((UINT32) count << 3)) < sha_info->count_lo) { ++sha_info->count_hi; } sha_info->count_lo += (UINT32) count << 3; sha_info->count_hi += (UINT32) count >> 29; while (count >= SHA_BLOCKSIZE) { memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); #ifdef LITTLE_ENDIAN byte_reverse(sha_info->data, SHA_BLOCKSIZE); #endif /* LITTLE_ENDIAN */ sha_transform(sha_info); buffer += SHA_BLOCKSIZE; count -= SHA_BLOCKSIZE; } memcpy(sha_info->data, buffer, count); } /* finish computing the SHA digest */ void sha_final(sha_info) SHA_INFO *sha_info; { int count; UINT32 lo_bit_count, hi_bit_count; lo_bit_count = sha_info->count_lo; hi_bit_count = sha_info->count_hi; count = (int) ((lo_bit_count >> 3) & 0x3f); ((BYTE *) sha_info->data)[count++] = 0x80; if (count > 56) { memset((BYTE *) sha_info->data + count, 0, 64 - count); #ifdef LITTLE_ENDIAN byte_reverse(sha_info->data, SHA_BLOCKSIZE); #endif /* LITTLE_ENDIAN */ sha_transform(sha_info); memset(sha_info->data, 0, 56); } else { memset((BYTE *) sha_info->data + count, 0, 56 - count); } #ifdef LITTLE_ENDIAN byte_reverse(sha_info->data, SHA_BLOCKSIZE); #endif /* LITTLE_ENDIAN */ sha_info->data[14] = hi_bit_count; sha_info->data[15] = lo_bit_count; sha_transform(sha_info); } /* compute the SHA digest of a FILE stream */ #define BLOCK_SIZE 8192 void sha_stream(sha_info, fin) SHA_INFO *sha_info; FILE *fin; { int i; BYTE data[BLOCK_SIZE]; sha_init(sha_info); while ((i = fread(data, 1, BLOCK_SIZE, fin)) > 0) { sha_update(sha_info, data, i); } sha_final(sha_info); } /* print a SHA digest */ void sha_print(sha_info) SHA_INFO *sha_info; { printf("%08lx %08lx %08lx %08lx %08lx\n", sha_info->digest[0], sha_info->digest[1], sha_info->digest[2], sha_info->digest[3], sha_info->digest[4]); } trf2.1.4/generic/sha/sha.good.outputs0000644000175000017500000000026411216343142017107 0ustar sergeisergei0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880 appgen 1 | sha d2516ee1 acfa5baf 33dfc1c4 71e43844 9ef134c8 appgen 2 | sha 3232affa 48628a26 653b5aaa 44541fd9 0d690603 appgen 3 | sha trf2.1.4/generic/ripemd/0000755000175000017500000000000011216344734014453 5ustar sergeisergeitrf2.1.4/generic/ripemd/rmd128.c0000644000175000017500000001645211216343142015634 0ustar sergeisergei/********************************************************************\ * * FILE: rmd128.c * * CONTENTS: A sample C-implementation of the RIPEMD-128 * hash-function. This function is a plug-in substitute * for RIPEMD. A 160-bit hash result is obtained using * RIPEMD-160. * TARGET: any computer with an ANSI C compiler * * AUTHOR: Antoon Bosselaers, ESAT-COSIC * DATE: 1 March 1996 * VERSION: 1.0 * * Copyright (c) Katholieke Universiteit Leuven * 1996, All Rights Reserved * \********************************************************************/ /* header files */ #include #include #include #include "rmd128.h" /********************************************************************/ void ripemd128_MDinit (MDbuf) dword *MDbuf; { MDbuf[0] = 0x67452301UL; MDbuf[1] = 0xefcdab89UL; MDbuf[2] = 0x98badcfeUL; MDbuf[3] = 0x10325476UL; return; } /********************************************************************/ void ripemd128_compress (MDbuf, X) dword* MDbuf; dword* X; { dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], dd = MDbuf[3]; dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], ddd = MDbuf[3]; /* round 1 */ FF(aa, bb, cc, dd, X[ 0], 11); FF(dd, aa, bb, cc, X[ 1], 14); FF(cc, dd, aa, bb, X[ 2], 15); FF(bb, cc, dd, aa, X[ 3], 12); FF(aa, bb, cc, dd, X[ 4], 5); FF(dd, aa, bb, cc, X[ 5], 8); FF(cc, dd, aa, bb, X[ 6], 7); FF(bb, cc, dd, aa, X[ 7], 9); FF(aa, bb, cc, dd, X[ 8], 11); FF(dd, aa, bb, cc, X[ 9], 13); FF(cc, dd, aa, bb, X[10], 14); FF(bb, cc, dd, aa, X[11], 15); FF(aa, bb, cc, dd, X[12], 6); FF(dd, aa, bb, cc, X[13], 7); FF(cc, dd, aa, bb, X[14], 9); FF(bb, cc, dd, aa, X[15], 8); /* round 2 */ GG(aa, bb, cc, dd, X[ 7], 7); GG(dd, aa, bb, cc, X[ 4], 6); GG(cc, dd, aa, bb, X[13], 8); GG(bb, cc, dd, aa, X[ 1], 13); GG(aa, bb, cc, dd, X[10], 11); GG(dd, aa, bb, cc, X[ 6], 9); GG(cc, dd, aa, bb, X[15], 7); GG(bb, cc, dd, aa, X[ 3], 15); GG(aa, bb, cc, dd, X[12], 7); GG(dd, aa, bb, cc, X[ 0], 12); GG(cc, dd, aa, bb, X[ 9], 15); GG(bb, cc, dd, aa, X[ 5], 9); GG(aa, bb, cc, dd, X[ 2], 11); GG(dd, aa, bb, cc, X[14], 7); GG(cc, dd, aa, bb, X[11], 13); GG(bb, cc, dd, aa, X[ 8], 12); /* round 3 */ HH(aa, bb, cc, dd, X[ 3], 11); HH(dd, aa, bb, cc, X[10], 13); HH(cc, dd, aa, bb, X[14], 6); HH(bb, cc, dd, aa, X[ 4], 7); HH(aa, bb, cc, dd, X[ 9], 14); HH(dd, aa, bb, cc, X[15], 9); HH(cc, dd, aa, bb, X[ 8], 13); HH(bb, cc, dd, aa, X[ 1], 15); HH(aa, bb, cc, dd, X[ 2], 14); HH(dd, aa, bb, cc, X[ 7], 8); HH(cc, dd, aa, bb, X[ 0], 13); HH(bb, cc, dd, aa, X[ 6], 6); HH(aa, bb, cc, dd, X[13], 5); HH(dd, aa, bb, cc, X[11], 12); HH(cc, dd, aa, bb, X[ 5], 7); HH(bb, cc, dd, aa, X[12], 5); /* round 4 */ II(aa, bb, cc, dd, X[ 1], 11); II(dd, aa, bb, cc, X[ 9], 12); II(cc, dd, aa, bb, X[11], 14); II(bb, cc, dd, aa, X[10], 15); II(aa, bb, cc, dd, X[ 0], 14); II(dd, aa, bb, cc, X[ 8], 15); II(cc, dd, aa, bb, X[12], 9); II(bb, cc, dd, aa, X[ 4], 8); II(aa, bb, cc, dd, X[13], 9); II(dd, aa, bb, cc, X[ 3], 14); II(cc, dd, aa, bb, X[ 7], 5); II(bb, cc, dd, aa, X[15], 6); II(aa, bb, cc, dd, X[14], 8); II(dd, aa, bb, cc, X[ 5], 6); II(cc, dd, aa, bb, X[ 6], 5); II(bb, cc, dd, aa, X[ 2], 12); /* parallel round 1 */ III(aaa, bbb, ccc, ddd, X[ 5], 8); III(ddd, aaa, bbb, ccc, X[14], 9); III(ccc, ddd, aaa, bbb, X[ 7], 9); III(bbb, ccc, ddd, aaa, X[ 0], 11); III(aaa, bbb, ccc, ddd, X[ 9], 13); III(ddd, aaa, bbb, ccc, X[ 2], 15); III(ccc, ddd, aaa, bbb, X[11], 15); III(bbb, ccc, ddd, aaa, X[ 4], 5); III(aaa, bbb, ccc, ddd, X[13], 7); III(ddd, aaa, bbb, ccc, X[ 6], 7); III(ccc, ddd, aaa, bbb, X[15], 8); III(bbb, ccc, ddd, aaa, X[ 8], 11); III(aaa, bbb, ccc, ddd, X[ 1], 14); III(ddd, aaa, bbb, ccc, X[10], 14); III(ccc, ddd, aaa, bbb, X[ 3], 12); III(bbb, ccc, ddd, aaa, X[12], 6); /* parallel round 2 */ HHH(aaa, bbb, ccc, ddd, X[ 6], 9); HHH(ddd, aaa, bbb, ccc, X[11], 13); HHH(ccc, ddd, aaa, bbb, X[ 3], 15); HHH(bbb, ccc, ddd, aaa, X[ 7], 7); HHH(aaa, bbb, ccc, ddd, X[ 0], 12); HHH(ddd, aaa, bbb, ccc, X[13], 8); HHH(ccc, ddd, aaa, bbb, X[ 5], 9); HHH(bbb, ccc, ddd, aaa, X[10], 11); HHH(aaa, bbb, ccc, ddd, X[14], 7); HHH(ddd, aaa, bbb, ccc, X[15], 7); HHH(ccc, ddd, aaa, bbb, X[ 8], 12); HHH(bbb, ccc, ddd, aaa, X[12], 7); HHH(aaa, bbb, ccc, ddd, X[ 4], 6); HHH(ddd, aaa, bbb, ccc, X[ 9], 15); HHH(ccc, ddd, aaa, bbb, X[ 1], 13); HHH(bbb, ccc, ddd, aaa, X[ 2], 11); /* parallel round 3 */ GGG(aaa, bbb, ccc, ddd, X[15], 9); GGG(ddd, aaa, bbb, ccc, X[ 5], 7); GGG(ccc, ddd, aaa, bbb, X[ 1], 15); GGG(bbb, ccc, ddd, aaa, X[ 3], 11); GGG(aaa, bbb, ccc, ddd, X[ 7], 8); GGG(ddd, aaa, bbb, ccc, X[14], 6); GGG(ccc, ddd, aaa, bbb, X[ 6], 6); GGG(bbb, ccc, ddd, aaa, X[ 9], 14); GGG(aaa, bbb, ccc, ddd, X[11], 12); GGG(ddd, aaa, bbb, ccc, X[ 8], 13); GGG(ccc, ddd, aaa, bbb, X[12], 5); GGG(bbb, ccc, ddd, aaa, X[ 2], 14); GGG(aaa, bbb, ccc, ddd, X[10], 13); GGG(ddd, aaa, bbb, ccc, X[ 0], 13); GGG(ccc, ddd, aaa, bbb, X[ 4], 7); GGG(bbb, ccc, ddd, aaa, X[13], 5); /* parallel round 4 */ FFF(aaa, bbb, ccc, ddd, X[ 8], 15); FFF(ddd, aaa, bbb, ccc, X[ 6], 5); FFF(ccc, ddd, aaa, bbb, X[ 4], 8); FFF(bbb, ccc, ddd, aaa, X[ 1], 11); FFF(aaa, bbb, ccc, ddd, X[ 3], 14); FFF(ddd, aaa, bbb, ccc, X[11], 14); FFF(ccc, ddd, aaa, bbb, X[15], 6); FFF(bbb, ccc, ddd, aaa, X[ 0], 14); FFF(aaa, bbb, ccc, ddd, X[ 5], 6); FFF(ddd, aaa, bbb, ccc, X[12], 9); FFF(ccc, ddd, aaa, bbb, X[ 2], 12); FFF(bbb, ccc, ddd, aaa, X[13], 9); FFF(aaa, bbb, ccc, ddd, X[ 9], 12); FFF(ddd, aaa, bbb, ccc, X[ 7], 5); FFF(ccc, ddd, aaa, bbb, X[10], 15); FFF(bbb, ccc, ddd, aaa, X[14], 8); /* combine results */ ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ MDbuf[1] = MDbuf[2] + dd + aaa; MDbuf[2] = MDbuf[3] + aa + bbb; MDbuf[3] = MDbuf[0] + bb + ccc; MDbuf[0] = ddd; return; } /********************************************************************/ void ripemd128_MDfinish (MDbuf, strptr, lswlen, mswlen) dword* MDbuf; byte* strptr; dword lswlen; dword mswlen; { dword i; /* counter */ dword X[16]; /* message words */ memset(X, 0, 16*sizeof(dword)); /* put bytes from strptr into X */ for (i=0; i<(lswlen&63); i++) { /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ X[i>>2] ^= (dword) *strptr++ << (8 * (i&3)); } /* append the bit m_n == 1 */ X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7); if ((lswlen & 63) > 55) { /* length goes to next block */ ripemd128_compress(MDbuf, X); memset(X, 0, 16*sizeof(dword)); } /* append length in bits*/ X[14] = lswlen << 3; X[15] = (lswlen >> 29) | (mswlen << 3); ripemd128_compress(MDbuf, X); return; } /************************ end of file rmd128.c **********************/ trf2.1.4/generic/ripemd/rmd128.h0000644000175000017500000000770211216343142015637 0ustar sergeisergei/********************************************************************\ * * FILE: rmd128.h * * CONTENTS: Header file for a sample C-implementation of the * RIPEMD-128 hash-function. This function is a * plug-in substitute for RIPEMD. A 160-bit hash * result is obtained using RIPEMD-160. * TARGET: any computer with an ANSI C compiler * * AUTHOR: Antoon Bosselaers, ESAT-COSIC * DATE: 1 March 1996 * VERSION: 1.0 * * Copyright (c) Katholieke Universiteit Leuven * 1996, All Rights Reserved * \********************************************************************/ /* AKU: * <> added __alpha, * <> unique prefix for function names * <> using tcl.h, _ANSI_ARGS_ */ #ifndef RMD128H /* make sure this file is read only once */ #define RMD128H /********************************************************************/ #include /* typedef 8, 16 and 32 bit types, resp. */ /* adapt these, if necessary, for your operating system and compiler */ typedef unsigned char byte; /* unsigned 8-bit type */ typedef unsigned short word; /* unsigned 16-bit type */ #if defined(__alpha) || defined(__LP64__) typedef unsigned int dword; /* unsigned 32-bit integer (AXP) */ #else typedef unsigned long dword; /* unsigned 32-bit type */ #endif /********************************************************************/ /* macro definitions */ /* collect four bytes into one word: */ #define BYTES_TO_DWORD(strptr) \ (((dword) *((strptr)+3) << 24) | \ ((dword) *((strptr)+2) << 16) | \ ((dword) *((strptr)+1) << 8) | \ ((dword) *(strptr))) /* ROL(x, n) cyclically rotates x over n bits to the left */ /* x must be of an unsigned 32 bits type and 0 <= n < 32. */ #define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* the three basic functions F(), G() and H() */ #define F(x, y, z) ((x) ^ (y) ^ (z)) #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) #define H(x, y, z) (((x) | ~(y)) ^ (z)) #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) /* the eight basic operations FF() through III() */ #define FF(a, b, c, d, x, s) {\ (a) += F((b), (c), (d)) + (x);\ (a) = ROL((a), (s));\ } #define GG(a, b, c, d, x, s) {\ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ (a) = ROL((a), (s));\ } #define HH(a, b, c, d, x, s) {\ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ (a) = ROL((a), (s));\ } #define II(a, b, c, d, x, s) {\ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ (a) = ROL((a), (s));\ } #define FFF(a, b, c, d, x, s) {\ (a) += F((b), (c), (d)) + (x);\ (a) = ROL((a), (s));\ } #define GGG(a, b, c, d, x, s) {\ (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ (a) = ROL((a), (s));\ } #define HHH(a, b, c, d, x, s) {\ (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ (a) = ROL((a), (s));\ } #define III(a, b, c, d, x, s) {\ (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ (a) = ROL((a), (s));\ } /********************************************************************/ /* function prototypes */ void ripemd128_MDinit _ANSI_ARGS_ ((dword *MDbuf)); /* * initializes MDbuffer to "magic constants" */ void ripemd128_compress _ANSI_ARGS_ ((dword *MDbuf, dword *X)); /* * the compression function. * transforms MDbuf using message bytes X[0] through X[15] */ void ripemd128_MDfinish _ANSI_ARGS_ ((dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)); /* * puts bytes from strptr into X and pad out; appends length * and finally, compresses the last block(s) * note: length in bits == 8 * (lswlen + 2^32 mswlen). * note: there are (lswlen mod 64) bytes left in strptr. */ #endif /* RMD128H */ /*********************** end of file rmd128.h ***********************/ trf2.1.4/generic/ripemd/rmd160.c0000644000175000017500000002225011216343142015621 0ustar sergeisergei/********************************************************************\ * * FILE: rmd160.c * * CONTENTS: A sample C-implementation of the RIPEMD-160 * hash-function. * TARGET: any computer with an ANSI C compiler * * AUTHOR: Antoon Bosselaers, ESAT-COSIC * DATE: 1 March 1996 * VERSION: 1.0 * * Copyright (c) Katholieke Universiteit Leuven * 1996, All Rights Reserved * \********************************************************************/ /* header files */ #include #include #include #include "rmd160.h" /********************************************************************/ void ripemd160_MDinit (MDbuf) dword *MDbuf; { MDbuf[0] = 0x67452301UL; MDbuf[1] = 0xefcdab89UL; MDbuf[2] = 0x98badcfeUL; MDbuf[3] = 0x10325476UL; MDbuf[4] = 0xc3d2e1f0UL; return; } /********************************************************************/ void ripemd160_compress (MDbuf, X) dword* MDbuf; dword* X; { dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], dd = MDbuf[3], ee = MDbuf[4]; dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], ddd = MDbuf[3], eee = MDbuf[4]; /* round 1 */ FF(aa, bb, cc, dd, ee, X[ 0], 11); FF(ee, aa, bb, cc, dd, X[ 1], 14); FF(dd, ee, aa, bb, cc, X[ 2], 15); FF(cc, dd, ee, aa, bb, X[ 3], 12); FF(bb, cc, dd, ee, aa, X[ 4], 5); FF(aa, bb, cc, dd, ee, X[ 5], 8); FF(ee, aa, bb, cc, dd, X[ 6], 7); FF(dd, ee, aa, bb, cc, X[ 7], 9); FF(cc, dd, ee, aa, bb, X[ 8], 11); FF(bb, cc, dd, ee, aa, X[ 9], 13); FF(aa, bb, cc, dd, ee, X[10], 14); FF(ee, aa, bb, cc, dd, X[11], 15); FF(dd, ee, aa, bb, cc, X[12], 6); FF(cc, dd, ee, aa, bb, X[13], 7); FF(bb, cc, dd, ee, aa, X[14], 9); FF(aa, bb, cc, dd, ee, X[15], 8); /* round 2 */ GG(ee, aa, bb, cc, dd, X[ 7], 7); GG(dd, ee, aa, bb, cc, X[ 4], 6); GG(cc, dd, ee, aa, bb, X[13], 8); GG(bb, cc, dd, ee, aa, X[ 1], 13); GG(aa, bb, cc, dd, ee, X[10], 11); GG(ee, aa, bb, cc, dd, X[ 6], 9); GG(dd, ee, aa, bb, cc, X[15], 7); GG(cc, dd, ee, aa, bb, X[ 3], 15); GG(bb, cc, dd, ee, aa, X[12], 7); GG(aa, bb, cc, dd, ee, X[ 0], 12); GG(ee, aa, bb, cc, dd, X[ 9], 15); GG(dd, ee, aa, bb, cc, X[ 5], 9); GG(cc, dd, ee, aa, bb, X[ 2], 11); GG(bb, cc, dd, ee, aa, X[14], 7); GG(aa, bb, cc, dd, ee, X[11], 13); GG(ee, aa, bb, cc, dd, X[ 8], 12); /* round 3 */ HH(dd, ee, aa, bb, cc, X[ 3], 11); HH(cc, dd, ee, aa, bb, X[10], 13); HH(bb, cc, dd, ee, aa, X[14], 6); HH(aa, bb, cc, dd, ee, X[ 4], 7); HH(ee, aa, bb, cc, dd, X[ 9], 14); HH(dd, ee, aa, bb, cc, X[15], 9); HH(cc, dd, ee, aa, bb, X[ 8], 13); HH(bb, cc, dd, ee, aa, X[ 1], 15); HH(aa, bb, cc, dd, ee, X[ 2], 14); HH(ee, aa, bb, cc, dd, X[ 7], 8); HH(dd, ee, aa, bb, cc, X[ 0], 13); HH(cc, dd, ee, aa, bb, X[ 6], 6); HH(bb, cc, dd, ee, aa, X[13], 5); HH(aa, bb, cc, dd, ee, X[11], 12); HH(ee, aa, bb, cc, dd, X[ 5], 7); HH(dd, ee, aa, bb, cc, X[12], 5); /* round 4 */ II(cc, dd, ee, aa, bb, X[ 1], 11); II(bb, cc, dd, ee, aa, X[ 9], 12); II(aa, bb, cc, dd, ee, X[11], 14); II(ee, aa, bb, cc, dd, X[10], 15); II(dd, ee, aa, bb, cc, X[ 0], 14); II(cc, dd, ee, aa, bb, X[ 8], 15); II(bb, cc, dd, ee, aa, X[12], 9); II(aa, bb, cc, dd, ee, X[ 4], 8); II(ee, aa, bb, cc, dd, X[13], 9); II(dd, ee, aa, bb, cc, X[ 3], 14); II(cc, dd, ee, aa, bb, X[ 7], 5); II(bb, cc, dd, ee, aa, X[15], 6); II(aa, bb, cc, dd, ee, X[14], 8); II(ee, aa, bb, cc, dd, X[ 5], 6); II(dd, ee, aa, bb, cc, X[ 6], 5); II(cc, dd, ee, aa, bb, X[ 2], 12); /* round 5 */ JJ(bb, cc, dd, ee, aa, X[ 4], 9); JJ(aa, bb, cc, dd, ee, X[ 0], 15); JJ(ee, aa, bb, cc, dd, X[ 5], 5); JJ(dd, ee, aa, bb, cc, X[ 9], 11); JJ(cc, dd, ee, aa, bb, X[ 7], 6); JJ(bb, cc, dd, ee, aa, X[12], 8); JJ(aa, bb, cc, dd, ee, X[ 2], 13); JJ(ee, aa, bb, cc, dd, X[10], 12); JJ(dd, ee, aa, bb, cc, X[14], 5); JJ(cc, dd, ee, aa, bb, X[ 1], 12); JJ(bb, cc, dd, ee, aa, X[ 3], 13); JJ(aa, bb, cc, dd, ee, X[ 8], 14); JJ(ee, aa, bb, cc, dd, X[11], 11); JJ(dd, ee, aa, bb, cc, X[ 6], 8); JJ(cc, dd, ee, aa, bb, X[15], 5); JJ(bb, cc, dd, ee, aa, X[13], 6); /* parallel round 1 */ JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); /* parallel round 2 */ III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); III(ddd, eee, aaa, bbb, ccc, X[11], 13); III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); III(eee, aaa, bbb, ccc, ddd, X[13], 8); III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); III(ccc, ddd, eee, aaa, bbb, X[10], 11); III(bbb, ccc, ddd, eee, aaa, X[14], 7); III(aaa, bbb, ccc, ddd, eee, X[15], 7); III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); III(ddd, eee, aaa, bbb, ccc, X[12], 7); III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); /* parallel round 3 */ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); /* parallel round 4 */ GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); /* parallel round 5 */ FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); /* combine results */ ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ MDbuf[1] = MDbuf[2] + dd + eee; MDbuf[2] = MDbuf[3] + ee + aaa; MDbuf[3] = MDbuf[4] + aa + bbb; MDbuf[4] = MDbuf[0] + bb + ccc; MDbuf[0] = ddd; return; } /********************************************************************/ void ripemd160_MDfinish(MDbuf, strptr, lswlen, mswlen) dword *MDbuf; byte *strptr; dword lswlen; dword mswlen; { dword i; /* counter */ dword X[16]; /* message words */ memset(X, 0, 16*sizeof(dword)); /* put bytes from strptr into X */ for (i=0; i<(lswlen&63); i++) { /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ X[i>>2] ^= (dword) *strptr++ << (8 * (i&3)); } /* append the bit m_n == 1 */ X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3) + 7); if ((lswlen & 63) > 55) { /* length goes to next block */ ripemd160_compress(MDbuf, X); memset(X, 0, 16*sizeof(dword)); } /* append length in bits*/ X[14] = lswlen << 3; X[15] = (lswlen >> 29) | (mswlen << 3); ripemd160_compress(MDbuf, X); return; } /************************ end of file rmd160.c **********************/ trf2.1.4/generic/ripemd/ripemd.ps0000644000175000017500000131765711216343142016313 0ustar sergeisergei%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: ripemd5.dvi %%Pages: 13 %%PageOrder: Ascend %%BoundingBox: 0 0 596 842 %%EndComments %DVIPSCommandLine: dvips -Pul3 -oripemd5.ps ripemd5.dvi %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 1996.07.01:2101 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet TeXDict begin 39158280 55380996 1000 600 600 (ripemd5.dvi) @start /Fa 1 49 df<01E003F003F003F003F007E007E007C00FC00FC00F800F801F00 1F001E001E003E003C003C007800780078007000F000E00060000C1A7E9B12>48 D E /Fb 1 114 df<03F0000FFC001FFE003FFF007FFF807FFF80FFFFC0FFFFC0FFFFC0 FFFFC0FFFFC0FFFFC07FFF807FFF803FFF001FFE000FFC0003F0001212898811>113 D E /Fc 3 64 df<000000060000001E0000007E000001FE000007FE00003FFE0000FFFE 0007FFFE003FFFFE01FFFFFE0FFFFFFEFFFFFFFEFFFFFFFE0FFFFFFE01FFFFFE003FFFFE 0007FFFE0000FFFE00003FFE000007FE000001FE0000007E0000001E000000061F187E8B 53>27 D45 D63 D E /Fd 1 49 df<038007C007C007C00F800F800F800F001F001E001E003E003C003C00 38007800780070007000E000E0000A157D9612>48 D E /Fe 3 53 df<03FC000FFF003C0FC07003E07801F0FC00F0FC00F8FC00F8FC00787800780000F800 00F00000F00001E00003C0000780000F00001C0000380000E00001C0180380180600180C 00383FFFF07FFFF0FFFFF0FFFFF0151C7D9B1C>50 D<01FC000FFF801E07C03001E07C01 F07C00F07E00F07C01F03801E00003E00007C0001F8003FE0003FC000007800003C00001 E00000F00000F83000F87800F8FC00F8FC00F8FC00F07801F07003E03C07C00FFF0003FC 00151D7D9B1C>I<0001C00003C00007C0000FC0000FC0001BC00033C00073C000E3C001 C3C00383C00303C00603C00C03C01C03C03803C07003C0E003C0FFFFFEFFFFFE0003C000 03C00003C00003C00003C00003C0007FFE007FFE171C7E9B1C>I E /Ff 13 121 df<7FFFFFFFFFFF80FFFFFFFFFFFFC0FFFFFFFFFFFFC07FFFFFFFFFFF80 3204799641>0 D<1C007F00FF80FF80FF80FF80FF807F001C000909799917>I<000003FF 00000000003FFFF000000000FC30FC00000003C0300F0000000F003003C000003C003000 F0000070003000380000E00030001C0001C00030000E0003800030000700070000300003 80060000300001800E0000300001C01C0000300000E01800003000006038000030000070 3000003000003030000030000030700000300000386000003000001860000030000018E0 00003000001CC000003000000CC000003000000CC000003000000CC000003000000CFFFF FFFFFFFFFCFFFFFFFFFFFFFCC000003000000CC000003000000CC000003000000CC00000 3000000CE000003000001C60000030000018600000300000187000003000003830000030 0000303000003000003038000030000070180000300000601C0000300000E00E00003000 01C006000030000180070000300003800380003000070001C00030000E0000E00030001C 0000700030003800003C003000F000000F003003C0000003C0300F00000000FC30FC0000 00003FFFF00000000003FF00000036367BAF41>8 D<0000000000038000000000000FC0 00000000003FC00000000000FF800000000003FE00000000000FF800000000003FE00000 000000FF800000000003FE00000000000FF800000000003FE00000000000FF8000000000 03FE00000000000FF800000000003FE00000000000FF800000000003FE00000000000FF8 00000000003FE00000000000FF800000000003FE00000000000FF800000000003FE00000 000000FF800000000000FE000000000000FF8000000000007FE000000000000FF8000000 000003FE000000000000FF8000000000003FE000000000000FF8000000000003FE000000 000000FF8000000000003FE000000000000FF8000000000003FE000000000000FF800000 0000003FE000000000000FF8000000000003FE000000000000FF8000000000003FE00000 0000000FF8000000000003FE000000000000FF8000000000003FC000000000000FC00000 000000038000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000007FFFFFFFFFFF80FFFFFFFFFF FFC0FFFFFFFFFFFFC07FFFFFFFFFFF80324279B441>20 D<7FFFFFFFFFF8FFFFFFFFFFFC FFFFFFFFFFFC7FFFFFFFFFFC00000000003C00000000003C00000000003C00000000003C 00000000003C00000000003C00000000003C00000000003C00000000003C00000000003C 00000000003C00000000003C00000000003C00000000003C00000000003C00000000003C 00000000003C00000000003C0000000000182E177C9D37>58 D<00000300000000000780 000000000FC0000000000FC0000000001FE0000000001FE0000000001FE0000000003FF0 000000003FF0000000007CF8000000007CF800000000F87C00000000F87C00000000F03C 00000001F03E00000001F03E00000003E01F00000003E01F00000007C00F80000007C00F 8000000F8007C000000F8007C000000F0003C000001F0003E000001F0003E000003E0001 F000003E0001F000007C0000F800007C0000F80000780000780000F800007C0000F80000 7C0001F000003E0001F000003E0003E000001F0003E000001F0007C000000F8007C00000 0F800780000007800F80000007C00F80000007C01F00000003E01F00000003E03E000000 01F03E00000001F03C00000000F07C00000000F87C00000000F8F8000000007CF8000000 007CF0000000003C6000000000182E347CB137>94 D<600000000018F0000000003CF800 0000007CF8000000007C7C00000000F87C00000000F83C00000000F03E00000001F03E00 000001F01F00000003E01F00000003E00F80000007C00F80000007C007800000078007C0 00000F8007C000000F8003E000001F0003E000001F0001F000003E0001F000003E0000F8 00007C0000F800007C00007800007800007C0000F800007C0000F800003E0001F000003E 0001F000001F0003E000001F0003E000000F0003C000000F8007C000000F8007C0000007 C00F80000007C00F80000003E01F00000003E01F00000001F03E00000001F03E00000000 F03C00000000F87C00000000F87C000000007CF8000000007CF8000000003FF000000000 3FF0000000001FE0000000001FE0000000001FE0000000000FC0000000000FC000000000 078000000000030000002E347CB137>I<600000F00000F00000F00000F00000F00000F0 0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0 0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0 0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0 0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0 0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0 0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000FF FFF0FFFFF8FFFFF87FFFF0155272BD25>98 D<0000300000780000780000780000780000 780000780000780000780000780000780000780000780000780000780000780000780000 780000780000780000780000780000780000780000780000780000780000780000780000 780000780000780000780000780000780000780000780000780000780000780000780000 780000780000780000780000780000780000780000780000780000780000780000780000 780000780000780000780000780000780000780000780000780000780000780000780000 780000780000780000780000780000780000780000780000780000780000780000780000 787FFFF8FFFFF8FFFFF87FFFF015527FBD25>I<000001F800000FF800003F800000FC00 0001F8000003F0000007E0000007E000000FE000000FC000000FC000000FC000000FC000 000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 000FC000000FC000000FC000001FC000001F8000003F8000007F000000FE000003F80000 7FE00000FF0000007FE0000003F8000000FE0000007F0000003F8000001F8000001FC000 000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FE0000007E000 0007E0000003F0000001F8000000FC0000003F8000000FF8000001F81D537ABD2A>102 DI<0000000000000001800000000000000003C00000 000000000007C00000000000000007C0000000000000000F80000000000000000F800000 00000000001F00000000000000001F00000000000000003E00000000000000003E000000 00000000007C00000000000000007C0000000000000000F80000000000000000F8000000 0000000001F00000000000000001F00000000000000003E00000000000000003E0000000 0000000007C00000000000000007C0000000000000000F80000000000000000F80000000 000000000F00000000000000001F00000000000000001F00000000000000003E00000000 000000003E00000000000000007C00000000000000007C0000000000000000F800000000 00000000F80000000000000001F00000000000000001F00000000000000003E000000000 00000003E00000000000000007C00000000000000007C0000000000000000F8000000000 0000000F80000000000000001F00000000000000001F00000000300000003E00000000F0 0000003E00000001F00000007C00000007F80000007C0000000FF8000000F80000001FFC 000000F800000079FC000001F0000000E1FE000001F0000000C0FE000003E000000000FF 000003E0000000007F000007C0000000007F000007C0000000007F80000F80000000003F 80000F80000000003FC0001F00000000001FC0001F00000000001FE0003E00000000000F E0003E00000000000FF0007C000000000007F0007C000000000007F80078000000000003 F800F8000000000003F800F8000000000003FC01F0000000000001FC01F0000000000001 FE03E0000000000000FE03E0000000000000FF07C00000000000007F07C0000000000000 7F8F800000000000003F8F800000000000003F9F000000000000003FDF00000000000000 1FFE000000000000001FFE000000000000000FFC000000000000000FFC00000000000000 07F80000000000000007F80000000000000003F00000000000000003F000000000000000 01E00000000000000001C0000000000042547B8345>112 D<007E0001FFC007C1E00F00 701E00383E001C7C000C7C001E7C007EF8007EF8007EF8007EF8003CF80000F80000F800 007C00007C00007C00003E00001E00000F000007800003C00000F00000FC0003FF000F87 801F01E03E01F03E00F87C007C7C007CFC003EF8003EF8001FF8001FF8001FF8001FF800 1FF8001F7C001F7C003F3E003E3E003E1F007C0F807C0780F801E1F000FFC0003F00000F 000003C00001E00000F000007800007C00003E00003E00003E00001F00001F00001F3C00 1F7E001F7E001F7E001F7E003E78003E30003E38007C1C00780E00F00783E003FF80007E 00184C7ABA25>120 D E /Fg 3 49 df0 D<000000001C000380000000007C000F8000000000FC001F8000000003F0007E00 0000000FC001F8000000003F8007F0000000007E000FC000000001F8003F0000000007E0 00FC000000001FC003F8000000003F0007E000000000FC001F8000000003F0007E000000 000FE001FC000000001F8003F0000000007E000FC000000001F8003F0000000007F000FE 000000000FC001F8000000003F0007E000000000FC001F8000000000F8001F0000000000 FC001F80000000003F0007E0000000000FC001F80000000007F000FE0000000001F8003F 00000000007E000FC0000000001F8003F0000000000FE001FC0000000003F0007E000000 0000FC001F80000000003F0007E0000000001FC003F80000000007E000FC0000000001F8 003F00000000007E000FC0000000003F8007F0000000000FC001F80000000003F0007E00 00000000FC001F80000000007C000F80000000001C000380392B7CA342>28 D<00E001F003F803F803F807F007F007F007E007E00FE00FC00FC00FC01F801F801F001F 003F003E003E003E007C007C007C007800F800F800F00010000D1E7D9F13>48 D E /Fh 7 105 df<003FFFFFFF8000FFFFFFFFC003FFFFFFFFC007FFFFFFFF800FFFFF FFFF001F00C01800001C00C03800003801C03800007001C0300000600180300000E00380 300000000380700000000380700000000700700000000700700000000F00700000000F00 F00000000E00F00000001E00F00000001E00F00000003E00F80000003C00F80000007C00 F80000007C00F8000000FC00F8000000F800FC000000F800FC000001F800FE000001F800 FE000003F000FE000003F0007E000003F0007E000001C0003800002A217E9F2C>25 D<000001F80000000FFE0000003E0F8000007C07C00001F803E00003F003E00007E001F0 000FC001F0000F8001F0001F8001F0003F0001F8003F0001F8007E0001F8007E0001F800 7E0003F800FE0003F000FC0003F000FC0003F001FC0007F001FC0007E001F80007E001F8 0007E003F8000FC003F8000FC003F0001F8003F0001F0007F0003F0007F0007E0007F800 FC0007F801F8000FFC03E0000FEE07C0000FC7FF00000FC1F800001FC00000001FC00000 001F800000001F800000003F800000003F800000003F000000003F000000007F00000000 7F000000007E000000007E00000000FE00000000FE00000000FC00000000380000000025 327FA028>I<3C007E00FF00FF00FF80FF807F803D800180018001800180038003000300 070006000E000C001C0038007000600009177A8715>59 D<000FFFFFC000FFFF000FFFFF C000FFFF000FFFFFC000FFFF00003FE000001FE000003FC000001F0000003FC000003E00 00003F800000380000003F800000F00000007F800001C00000007F800003800000007F00 000E000000007F00001C00000000FF00003800000000FF0000E000000000FE0001C00000 0000FE00038000000001FE000E0000000001FE001C0000000001FC00380000000001FC00 F00000000003FC01F00000000003FC03F00000000003F80FF00000000003F81FF8000000 0007F83FF80000000007F8F3FC0000000007F1C3FC0000000007F381FE000000000FF701 FE000000000FFC00FF000000000FF800FF000000000FF000FF000000001FE0007F800000 001FE0007F800000001FC0003FC00000001FC0003FC00000003FC0001FE00000003FC000 1FE00000003F80000FF00000003F80000FF00000007F80000FF00000007F800007F80000 007F000007F80000007F000003FC000000FF000003FC000000FF000001FE000000FE0000 01FE000001FE000003FF0000FFFFFC003FFFF800FFFFFC007FFFF800FFFFFC007FFFF800 40337DB241>75 D<0003FFFFC007FFFC0007FFFFC007FFFC0007FFFFC007FFFC00000FFC 0000FF8000000FF80000FC00000007F80000F000000007F80000E000000003FC0001C000 000003FC00038000000001FC00070000000001FE000E0000000001FE001C0000000000FF 00380000000000FF007000000000007F806000000000007F80C000000000003F81800000 0000003FC30000000000003FC60000000000001FEC0000000000001FF80000000000000F F00000000000000FF000000000000007F000000000000007F800000000000007F8000000 00000007FC0000000000000FFC0000000000001DFE00000000000039FE00000000000070 FE000000000000E0FF000000000001C0FF000000000003807F800000000003007F800000 000006003FC0000000000C003FC00000000018001FC00000000030001FE0000000006000 1FE000000000C0000FF00000000180000FF000000003000007F800000006000007F80000 000E000003F80000003C000003FC0000007C000003FC000003FE000007FE0000FFFFC000 7FFFFC00FFFFC0007FFFFC00FFFFC0007FFFF8003E337EB23F>88 D<0000000F800000003FE00000007870000001F0F8000001E3F8000003E3F8000003E3F8 000007E3F0000007E3F000000FC1C000000FC00000000FC00000000FC00000000FC00000 001FC00000001F800000001F800000001F800000001F800000003F800000003F0000001F FFFF80003FFFFF80003FFFFF0000007F000000007E000000007E000000007E000000007E 00000000FE00000000FC00000000FC00000000FC00000000FC00000000FC00000001FC00 000001F800000001F800000001F800000001F800000003F800000003F000000003F00000 0003F000000003F000000007F000000007E000000007E000000007E000000007E0000000 0FE00000000FC00000000FC00000000FC00000000FC00000000F800000001F800000001F 800000001F0000001C1F0000007F1E0000007F3E0000007F3E000000FE3C000000FE7800 0000787800000070F00000003FC00000000F8000000025457CB425>102 D<0007E0000003FFE0000003FFE0000003FFC00000001FC00000001FC00000001FC00000 001F800000001F800000001F800000003F800000003F000000003F000000003F00000000 7F000000007E000000007E000000007E00000000FE00000000FC0FE00000FC3FF80000FC F07E0001FFC03F0001FF001F0001FE001F0001FC001F8003FC001F8003F8001F8003F000 1F8003F0003F8007F0003F0007E0003F0007E0003F0007E0007F000FE0007E000FC0007E 000FC000FE000FC000FC001FC000FC001F8001FC001F8001F8081F8001F81C3F8003F818 3F0003F0183F0003F0383F0007F0307F0007E0307E0007E0707E0003E0E07E0003E1C0FE 0001E380FC0000FF003800003C0026357DB32C>104 D E /Fi 54 122 df<03800E000FE03F801FE07F801FE07F801FE07F801FE07F801FE07F8007601D80 0060018000E0038000C0030000C0030001C007000180060003800E0007001C0006001800 0E0038001C0070003800E0007001C000E0038000C0030000191773B327>34 D<03800FE01FE01FE01FE01FE01FE00760006000E000C000C001C001800380070006000E 001C0038007000E000C0000B176FB318>39 D<00000060000001E0000003C00000070000 000E0000001C0000003C00000078000000F0000001E0000003C0000007C0000007800000 0F0000001F0000001E0000003C0000007C00000078000000F8000000F0000001F0000001 E0000003E0000003C0000007C0000007C00000078000000F8000000F8000000F0000001F 0000001F0000001E0000003E0000003E0000003E0000003C0000007C0000007C0000007C 0000007800000078000000F8000000F8000000F8000000F0000000F0000000F0000000F0 000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0 000000F0000000F000000070000000780000007800000038000000380000003C0000001C 0000001C0000000E0000000E0000000700000003800000018000001B4A75B71F>I<0000 3000000038000000380000001C0000000E0000000E0000000F0000000700000007800000 078000000380000003C0000003C0000003C0000003C0000001C0000001E0000001E00000 01E0000001E0000001E0000001E0000001E0000001E0000003E0000003E0000003E00000 03E0000003C0000003C0000003C0000007C0000007C0000007C00000078000000F800000 0F8000000F8000000F0000001F0000001F0000001F0000001E0000003E0000003E000000 3C0000007C0000007C000000F8000000F8000000F0000001F0000001E0000003E0000003 C0000007C00000078000000F8000000F0000001E0000003E0000003C00000078000000F0 000001E0000001E0000003C00000078000000F0000001E0000003C00000070000000E000 0000C00000001B4A7EB71F>I<03800FE01FE01FE01FE01FE01FE00760006000E000C000 C001C001800380070006000E001C0038007000E000C0000B177A8718>44 DI<1C7FFFFFFFFFFE380808778718> I<00001FC000007FF00001E0F80007C03C000F003C001E001E003E001E003C001F007800 1F00F8001F00F0001F01F0001F01F0001F03E0001F03E0001F07E0003F07C0003F07C000 3F0FC0003F0FC0003E0F80007E1F80007E1F80007E1F80007E3F0000FC3F0000FC3F0000 FC3F0000FC7E0001F87E0001F87E0001F87E0001F87C0003F0FC0003F0FC0003F0FC0007 E0FC0007E0F80007C0F80007C0F8000F80F8000F80F8001F00F8001F00F8001E00F8003C 0078007C007800F8007C01F0003C03E0001F0F80000FFE000003F80000203477B127>48 D<0000018000000380000003800000078000000F8000001F0000003F000000FF000001FF 00001FFE00007FBE00007E7E0000207E0000007C0000007C000000FC000000FC000000F8 000000F8000001F8000001F8000001F0000001F0000003F0000003F0000003E0000003E0 000007E0000007E0000007C0000007C000000FC000000FC000000F8000000F8000001F80 00001F8000001F0000001F0000003F0000003F0000003E0000003E0000007E0000007E00 00007C000000FC0000FFFFFC00FFFFFC00FFFFFC00193277B127>I<00000FE00000003F F8000000F03E000003C01F000007800F80000F000F80001E0007C0001C0007C000380007 C00078C007E00070E007E000F06007E000E06007E001E06007E001C06007E001C0E00FE0 03C0C00FC00380C00FC00381C00FC00381801FC00383801F800387003F80038E003F0001 FC007E0000F000FC00000001F800000003F000000007E00000000FC00000001F00000000 7E00000000F800000003E00000000FC00000001F000000003E000000007800000001F000 038003E000038003C000078007800007000F00000F001E00000F001C00001E003F00003E 003FF8007C007DFF80F800781FFFF800F00FFFF000E003FFE000E001FF8000E0007E0000 23347AB127>I<000007F00000003FFC000000F81E000003E00F000007800780000F0007 C0001E0003C0003C0003C000380003E000798003E00071C003E00070C007E000F0C007C0 00E0C007C000E0C007C000E1C00FC000E3800F80007F001F80003C001F000000003E0000 00007C00000000F800000001F00000001FE0000007FF80000007FE00000003FF00000000 07C000000003E000000003E000000001F000000001F000000001F000000001F000000001 F000000003F000180003F0007E0003F0007E0003F0007E0007F000FC0007E000F80007E0 00E0000FC000E0000FC000F0001F800070003F000070007E00007800FC00003C01F00000 1E07E0000007FF80000001FC000000233479B127>I<0000000E0000001F0000001F0000 003F0000003E0000003E0000003E0000007E0000007C0000007C000000FC000000F80000 00F8000001F8000001F0000001F0000003E0000003E0000003E0000007C0000007C00000 0F8000000F8000001F0000001F0000003E0000003E0000007C00000078000000F8000000 F0000001F0000003E0E00003C1F0000781F0000F83F0000F03E0001E03E0003C03E0007C 07E000F807C001F007C003E007C007C00FC00F800F801FFC0F803FFFCF807FFFFF82F003 FFFF60003FFF00001FF800003F0000003E0000003E0000003E0000007E0000007C000000 7C0000007C000000FC000000F8000000F8000000F8000000F8000000600020417DB127> I<00060000C0000FC00FC0000FFFFF80000FFFFF00000FFFFC00001FFFF000001FFFC000 001CFE0000001C000000003C000000003800000000380000000038000000007800000000 700000000070000000007000000000F000000000E0FE000000E3FF800000EF03C00001FC 01E00001F801F00001F000F00001E000F80003C000F800038000F800000000F800000000 F800000000F800000000F800000001F800000001F800000001F800000001F8003C0003F8 00FC0003F000FC0003F000FC0003F000FC0007E000F80007E000E0000FC000E0000FC000 E0001F8000E0003F0000F0007E00007000FC00007801F800003E07F000001FFFC000000F FF00000003F8000000223478B127>I<000001F80000000FFE0000003FFF000000FE0F00 0001F807800003E00F800007C01F80000F803F80001F003F00003E003F00007C000E0000 FC00000000F800000001F800000003F000000003F000000007E000000007E00000000FC1 F800000FC7FF00000FDE0780001FB803C0001FF003E0001FE001E0003FE001F0003FC001 F0003F8001F0003F8001F0007F0001F8007F0001F8007E0001F8007E0003F0007E0003F0 00FC0003F000FC0003F000FC0007F000FC0007E000FC0007E000F80007E000F8000FC000 F8000FC000F8000F8000F8001F8000F8003F000078003E00007C007C00007C00F800003E 01F000001F07E000001FFFC0000007FF00000001F8000000213477B127>I<00E0F80038 00E3FC003801EFFE007801FFFE00F003FFFE01E003FE0E03E007F80E03C007F0060F800F C0071F800F8003FF001F0001EF001E00001E003E00003C003C00003C0078000078007800 00F800F00000F000E00001F000E00001E000000003E000000007C000000007C00000000F 800000000F800000001F800000001F000000003F000000003E000000007E000000007E00 000000FC00000000FC00000001F800000001F800000001F800000003F000000003F00000 0007F000000007E000000007E00000000FE00000000FC00000000FC00000001FC0000000 1FC00000001F800000003F800000003F800000003F800000003F000000003F000000001C 000000253476B127>I<000007E00000003FFC0000007FFE000001F81F000003E00F8000 07800780000F0007C0001F0003C0001E0003C0003C0003C0003C0003C0003C0007C0007C 000780007C000780007C000F80007C000F00007E001E00007F003E00007F807C00003FC0 F800003FE1E000001FFBC000000FFF00000007FE00000003FF00000007FF8000001EFFC0 00007C7FE00000F01FF00001E00FF80007C007F800078003F8000F0001F8001E0000F800 3E0000F8003C000078007C0000780078000078007800007800780000F800F80000F000F0 0000F000F80001E000780003E000780003C0007C000780003C001F00003E003E00001F81 FC00000FFFF0000003FFC0000000FE000000223479B127>I<00000FC00000007FF00000 00FFFC000003F07E000007C03E00000F801F00001F001F00003E000F00007E000F8000FC 000F8000FC000F8001F8000F8001F8000F8003F0000F8003F0001F8003F0001F8007F000 1F8007E0001F8007E0001F8007E0003F0007E0003F000FC0003F000FC0007F000FC0007F 0007C000FE0007C000FE0007C001FE0007C003FE0003C003FC0003E007FC0001E00EFC00 00F03DF800007FF1F800000FC1F800000003F000000003F000000007E000000007E00000 0007C00000000F800000001F800038001F00007E003E0000FE007E0000FE00FC0000FC01 F80000F803F00000F007E00000781F8000007FFF0000001FFC00000007E0000000213478 B127>I<000000001C00000000003C00000000003C00000000007C0000000000FC000000 0000FC0000000001FC0000000001FE0000000003FE0000000003FE00000000077E000000 000F7E000000000E7E000000001C7E000000001C7E00000000387E00000000387E000000 00707E00000000F07E00000000E07E00000001C07E00000001C07E00000003807F000000 03803F00000007003F00000007003F0000000E003F0000001E003F0000001C003F000000 38003F00000038003F00000070003F00000070003F000000E0003F000001FFFFFF000001 FFFFFF000003FFFFFF00000380003F00000700001F80000700001F80000E00001F80001E 00001F80001C00001F80003C00001F80003800001F80007000001F8000F000001F8000E0 00001F8001E000001F8003E000001F800FF000003FC0FFFE0007FFFEFFFE0007FFFEFFFE 0007FFFE2F367BB539>65 D<0000001FF000C0000000FFFC01C0000003FFFF03C000000F F00F878000003F8003CF800000FE0001EF800001FC0000FF800003F00000FF00000FE000 007F00001FC000007F00003F8000003F00003F0000003E00007E0000003E0000FE000000 3E0001FC0000003E0003F80000003C0003F80000003C0007F00000003C0007F00000003C 000FE000000038000FE000000038001FC000000038001FC000000000003FC00000000000 3F8000000000003F8000000000003F8000000000007F8000000000007F0000000000007F 0000000000007F0000000000007F000000000000FE000000000000FE000000000000FE00 000003C000FE00000003C000FE0000000380007E0000000380007E0000000780007E0000 000700007E0000000F00007E0000000E00007F0000001E00003F0000003C00003F000000 7800001F8000007000001F800000F000000FC00001E0000007E00007C0000003F0000F00 000001F8003E00000000FF00FC000000007FFFF0000000001FFFC00000000003FE000000 00323775B437>67 D<0007FFFFFFC000000FFFFFFFF000000FFFFFFFFC0000003F8001FE 0000003F80007F0000003F80001F8000003F00000FC000003F000007E000007F000007E0 00007F000003F000007E000003F000007E000001F00000FE000001F80000FE000001F800 00FC000001F80000FC000001F80001FC000001F80001FC000001F80001F8000001F80001 F8000001F80003F8000001F80003F8000003F80003F0000003F80003F0000003F80007F0 000003F80007F0000003F00007E0000007F00007E0000007F0000FE0000007F0000FE000 0007E0000FC000000FE0000FC000000FC0001FC000001FC0001FC000001F80001F800000 1F80001F8000003F00003F8000003F00003F8000007E00003F000000FC00003F000000FC 00007F000001F800007F000003F000007E000007E000007E00000FC00000FE00001F8000 00FE00007E000000FC0001FC000001FC000FF800007FFFFFFFE00000FFFFFFFF000000FF FFFFF800000035337BB23A>I<0007FFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFE00000 3F80001FE000003F800007E000003F800003E000003F000003E000003F000001E000007F 000001E000007F000001C000007E000001C000007E000001C00000FE000001C00000FE00 0001C00000FC000E01C00000FC000E01C00001FC001E03C00001FC001C03800001F8001C 00000001F8003C00000003F8003C00000003F8007800000003F001F800000003FFFFF800 000007FFFFF800000007FFFFF000000007E001F000000007E000F00000000FE000F00000 000FE000E00000000FC000E00000000FC000E00700001FC001E00F00001FC001C00E0000 1F8001C01E00001F8000001C00003F8000001C00003F8000003C00003F0000003800003F 0000007800007F000000F000007F000000F000007E000001F000007E000003E00000FE00 0007E00000FE00000FC00000FC00001FC00001FC0001FF80007FFFFFFFFF8000FFFFFFFF FF8000FFFFFFFFFF000034337CB234>I<0007FFFFFFFFE0000FFFFFFFFFE0000FFFFFFF FFC000003F80003FC000003F80000FC000003F800007C000003F000007C000003F000003 C000007F000003C000007F0000038000007E0000038000007E000003800000FE00000380 0000FE000003800000FC000003800000FC001C03800001FC003C07800001FC0038070000 01F8003800000001F8003800000003F8007800000003F8007000000003F000F000000003 F003F000000007FFFFF000000007FFFFF000000007FFFFE000000007E003E00000000FE0 03E00000000FE001C00000000FC001C00000000FC001C00000001FC003C00000001FC003 800000001F8003800000001F8003800000003F8000000000003F8000000000003F000000 0000003F0000000000007F0000000000007F0000000000007E0000000000007E00000000 0000FE000000000000FE000000000000FC000000000001FC00000000007FFFFC00000000 FFFFFC00000000FFFFFC0000000033337CB232>I<0007FFFF01FFFFC0000FFFFF03FFFF C0000FFFFF03FFFFC000003FC0000FF00000003F80000FE00000003F80000FE00000003F 00000FC00000003F00000FC00000007F00001FC00000007F00001F800000007E00001F80 0000007E00001F80000000FE00003F80000000FE00003F00000000FC00003F00000000FC 00003F00000001FC00007F00000001FC00007E00000001F800007E00000001F800007E00 000003F80000FE00000003F80000FC00000003F00000FC00000003FFFFFFFC00000007FF FFFFFC00000007FFFFFFF800000007E00001F800000007E00001F80000000FE00003F800 00000FE00003F00000000FC00003F00000000FC00003F00000001FC00007F00000001FC0 0007E00000001F800007E00000001F800007E00000003F80000FE00000003F80000FC000 00003F00000FC00000003F00000FC00000007F00001FC00000007F00001F800000007E00 001F800000007E00001F80000000FE00003F80000000FE00003F00000000FC00003F0000 0001FC00007F0000007FFFF01FFFFC0000FFFFF03FFFFC0000FFFFF03FFFFC00003A337B B239>72 D<000FFFFF80000FFFFF80000FFFFF0000003FC00000003F800000003F800000 003F000000003F000000007F000000007F000000007E000000007E00000000FE00000000 FE00000000FC00000000FC00000001FC00000001FC00000001F800000001F800000003F8 00000003F800000003F000000003F000000007F000000007F000000007E000000007E000 00000FE00000000FE00000000FC00000000FC00000001FC00000001FC00000001F800000 001F800000003F800000003F800000003F000000003F000000007F000000007F00000000 7E000000007E00000000FE00000000FE00000000FC00000001FC000000FFFFF80000FFFF F80000FFFFF0000021337BB21E>I<00001FFFFE00003FFFFE00003FFFFC0000003F8000 00003F800000003F800000003F000000003F000000007F000000007E000000007E000000 007E00000000FE00000000FC00000000FC00000000FC00000001FC00000001F800000001 F800000001F800000003F800000003F000000003F000000003F000000007F000000007E0 00000007E000000007E00000000FE00000000FC00000000FC00000000FC00000001FC000 00001F800000001F800000001F800000003F800000003F000000003F00001C003F00007E 007F0000FE007E0000FE007E0000FE00FE0000FC00FC0000F801FC0000E001F80000E003 F000007007E00000780FC000003C1F0000001FFC00000007F0000000273579B228>I<00 07FFFFC000000FFFFFC000000FFFFFC00000003FC0000000003F80000000003F80000000 003F00000000003F00000000007F00000000007F00000000007E00000000007E00000000 00FE0000000000FE0000000000FC0000000000FC0000000001FC0000000001FC00000000 01F80000000001F80000000003F80000000003F80000000003F00000000003F000000000 07F00000000007F00000000007E00000000007E0000000000FE0000000000FE000000000 0FC0000000000FC00000E0001FC00001E0001FC00001C0001F800001C0001F800003C000 3F80000380003F80000780003F00000780003F00000F00007F00000F00007F00001F0000 7E00003E00007E00003E0000FE00007C0000FE0001FC0000FC0003FC0001FC001FF8007F FFFFFFF800FFFFFFFFF800FFFFFFFFF0002B337CB230>76 D<0007FFC00000007FFC000F FFC0000000FFFC000FFFE0000000FFFC00003FE0000001FF0000003FE0000001FE000000 3FE0000003FE0000003BE00000077C0000003BE00000077C0000007BE000000EFC000000 7BE000000EF800000073E000001CF800000073E0000038F8000000F1F0000039F8000000 F1F0000071F0000000E1F0000071F0000000E1F00000E1F0000001E1F00001C3F0000001 E1F00001C3E0000001C1F0000383E0000001C1F0000703E0000003C1F0000707E0000003 C1F0000E07C000000380F8000E07C000000380F8001C07C000000780F800380FC0000007 80F800380F8000000700F800700F8000000700F800700F8000000F00F800E01F8000000F 00F801C01F0000000E00F801C01F0000000E00F803801F0000001E007C03803F0000001E 007C07003E0000001C007C0E003E0000001C007C0E003E0000003C007C1C007E0000003C 007C1C007C00000038007C38007C00000038007C70007C00000078007C7000FC00000078 003EE000F800000070003EE000F800000070003FC000F8000000F0003F8001F8000000F0 003F8001F0000001F0003F0001F0000007F8003F0003F000007FFF803E00FFFFC000FFFF 803C01FFFFC000FFFF801C01FFFFC00046337BB245>I<0007FF80003FFFC0000FFFC000 7FFFC0000FFFC0007FFFC000001FC00003F80000003FE00001F00000003FE00001E00000 003FE00001C00000003BF00001C00000007BF00003C00000007BF000038000000071F800 038000000071F8000380000000F1F8000780000000F0FC000700000000E0FC0007000000 00E0FC000700000001E07E000F00000001E07E000E00000001C07E000E00000001C03F00 0E00000003C03F001E00000003C03F801C00000003801F801C00000003801F801C000000 07801FC03C00000007800FC03800000007000FC03800000007000FE0380000000F0007E0 780000000F0007E0700000000E0007F0700000000E0003F0700000001E0003F0F0000000 1E0003F8E00000001C0001F8E00000001C0001F8E00000003C0001FDE00000003C0000FD C0000000380000FDC0000000380000FFC00000007800007FC00000007800007F80000000 7000003F800000007000003F80000000F000003F80000000F000001F00000001F000001F 00000007F800001F0000007FFF80000F000000FFFF80000E000000FFFF80000E0000003A 337BB239>I<0007FFFFFFC000000FFFFFFFF800000FFFFFFFFC0000003F8001FE000000 3F80003F0000003F80001F8000003F00001FC000003F00000FC000007F00000FC000007F 00000FE000007E00000FE000007E00000FE00000FE00000FE00000FE00001FC00000FC00 001FC00000FC00001FC00001FC00001F800001FC00003F800001F800003F000001F80000 7E000003F80000FE000003F80000FC000003F00003F8000003F00007E0000007F0003FC0 000007FFFFFF00000007FFFFF800000007E000000000000FE000000000000FE000000000 000FC000000000000FC000000000001FC000000000001FC000000000001F800000000000 1F8000000000003F8000000000003F8000000000003F0000000000003F0000000000007F 0000000000007F0000000000007E0000000000007E000000000000FE000000000000FE00 0000000000FC000000000001FC00000000007FFFF000000000FFFFF000000000FFFFF000 00000033337CB234>80 D<0007FFFFFE0000000FFFFFFFC000000FFFFFFFF00000003F80 07F80000003F8001FC0000003F80007E0000003F00007F0000003F00003F0000007F0000 3F0000007F00003F8000007E00003F8000007E00003F800000FE00003F800000FE00007F 000000FC00007F000000FC00007F000001FC0000FE000001FC0000FC000001F80001FC00 0001F80001F8000003F80003F0000003F8000FC0000003F0001F80000003F000FE000000 07FFFFF000000007FFFFC000000007E003E000000007E001F80000000FE000FC0000000F E0007C0000000FC0007E0000000FC0007E0000001FC0007E0000001FC0007E0000001F80 007E0000001F80007E0000003F8000FE0000003F8000FE0000003F0000FE0000003F0000 FE0000007F0001FE0000007F0001FC0000007E0001FC0000007E0001FC01C000FE0001FC 03C000FE0001FC038000FC0001FC038001FC0001FC07807FFFF000FC0700FFFFF000FE0E 00FFFFF0007E1C00000000001FF8000000000007E00032357BB238>82 D<000001FC018000000FFF038000003FFFC78000007E07EF800001F801FF000003F000FF 000003E0007F000007C0007F00000F80003E00001F80003E00001F00003E00003F00003E 00003E00003C00003E00003C00003E00003C00007E00003C00007E00003800007E000038 00007E00000000007F00000000007F00000000003F80000000003FE0000000003FFE0000 00001FFFC00000000FFFF800000007FFFC00000001FFFE000000007FFF000000000FFF80 00000000FF80000000003F80000000001FC0000000000FC0000000000FC0000000000FC0 000000000FC0000E00000FC0000E00000FC0001E00000F80001C00000F80001C00000F80 001C00001F80003C00001F00003C00001F00003E00003E00003E00007C00007E00007C00 007F0000F800007F8001F000007FC007E00000F3F80FC00000F0FFFF000000E03FFC0000 00C00FF000000029377AB42B>I<003000C000F003C001C0070003800E0007001C000600 18000E0038001C007000180060003800E0003000C0007001C0006001800060018000E003 8000DE037800FF03FC00FF03FC00FF03FC00FF03FC00FF03FC00FE03F8003800E0001A17 6CB327>92 D<0003F000000FF800003E1C60007C0FF000F807F001F007F003E007F007E0 03E00FC003E00FC003E01F8007E01F8007C03F0007C03F0007C03F000FC07F000F807E00 0F807E000F807E001F80FE001F00FC001F00FC001F06FC003F07FC003E0FFC003E0EFC00 7E0E7C007E1E7C00FE1C7C01FC1C3C03FC3C3E07BE381F0E1E7807FC0FF001F003C02022 78A027>97 D<007E00000FFE00001FFE00001FFC000000FC000000FC000000FC000000F8 000000F8000001F8000001F8000001F0000001F0000003F0000003F0000003E0000003E0 000007E0000007E0000007C3E00007CFF8000FDC3E000FF81F000FF00F000FE00F801FC0 0F801F800F801F800FC01F000FC03F000FC03F000FC03E000FC03E000FC07E001FC07E00 1F807C001F807C001F807C003F80FC003F00F8003F00F8003F00F8007E00F8007E00F800 FC00F800FC007801F8007801F0007803E0003C07C0003C0F80001E1F00000FFC000003F0 00001A3578B323>I<0000FC000007FF00001F0780003E03C000FC01C001F803C003F007 C007E00FC007C00FC00FC00FC01F8007001F8000003F0000003F0000003F0000007F0000 007E0000007E0000007E000000FE000000FC000000FC000000FC000000FC0000007C0000 C07C0001E07C0001E07C0003C03E000F803E001F001F007C000F81F00003FFC00000FE00 001B2278A023>I<0000000FC0000003FFC0000003FFC0000003FF800000001F80000000 1F800000001F800000001F000000001F000000003F000000003F000000003E000000003E 000000007E000000007E000000007C000000007C00000000FC00000000FC000003F0F800 000FF8F800003E1DF800007C0FF80000F807F00001F007F00003E007F00007E003F0000F C003E0000FC003E0001F8007E0001F8007E0003F0007C0003F0007C0003F000FC0007F00 0FC0007E000F80007E000F80007E001F8000FE001F8000FC001F0000FC001F0600FC003F 0700FC003F0F00FC003E0E00FC007E0E007C007E1E007C00FE1C007C01FC1C003C03FC3C 003E07BE38001F0E1E780007FC0FF00001F003C000223578B327>I<0003F800000FFE00 003E0F0000F8078001F0038003E0038007C003800FC003801F8003801F8007803F000700 3F000F007E003E007E03F8007FFFE000FFFE0000FC000000FC000000FC000000FC000000 F8000000F8000000F8000000F8000000F8000180F80003C0F80003C07C0007807C001F00 3C003E001E00F8000F03E00007FF800001FC00001A2277A023>I<0000001F000000007F C0000000F0E0000001F0F0000003E3F0000003E3F0000007C3F0000007C3E0000007C1C0 00000FC00000000F800000000F800000000F800000000F800000001F800000001F000000 001F000000001F000000001F000000003F000000003E0000001FFFFE00001FFFFE00001F FFFE0000007E000000007C000000007C000000007C000000007C00000000FC00000000F8 00000000F800000000F800000000F800000000F800000001F800000001F000000001F000 000001F000000001F000000003F000000003E000000003E000000003E000000003E00000 0007E000000007C000000007C000000007C00000000FC00000000FC00000000F80000000 0F800000000F800000001F800000001F000000001F000000001F000000003F000000003E 000000383E0000007E3C0000007E3C000000FE78000000FC78000000F8F000000078E000 00003FC00000000F00000000244582B418>I<00003F000000FF800003E1E60007C0FF00 0F807F001F007F003E007F007E003F00FC003E00FC003E01F8007E01F8007E03F0007C03 F0007C03F000FC07F000FC07E000F807E000F807E001F807E001F80FC001F00FC001F00F C003F007C003F007C003E007C007E007C00FE007C01FE003E03FC001E07FC001F0FFC000 7FCFC0001F0F8000000F8000001F8000001F8000001F0000001F0000003F0000003E0038 003E007E007E007E00FC00FE00F800FC01F0007803E0007C0F80001FFF000007F8000020 317CA023>I<000FC0000003FFC0000003FFC0000003FF800000001F800000001F800000 001F800000001F000000001F000000003F000000003F000000003E000000003E00000000 7E000000007E000000007C000000007C00000000FC00000000FC00000000F83F800000F8 FFE00001FBE0F00001FF80F80001FF00780001FE007C0003FC007C0003F8007C0003F000 7C0003F0007C0007E000FC0007E000F80007C000F80007C000F8000FC001F8000FC001F0 000F8001F0000F8001F0001F8003F0001F8003E0001F0007E0001F0007C0C03F0007C1E0 3F000FC1C03E000F81C03E000F81C07E000F83C07E000F03807C000F07807C000F0700FC 000F0E00FC000F1E00F80007F800700001F00023357BB327>I<0001800007E00007E000 0FE00007C000038000000000000000000000000000000000000000000000000000000000 000000000001F00003FC000F1E000E1E001C1E003C1E00381E00783E00703E00703E0070 7E00F07C0060FC0000F80000F80001F80001F00001F00003F00003E00003E00007E0C007 C1E00FC1C00F81C00F81C00F83C00F03800F07800F07000F0E000F1E0007F80001F00013 337AB118>I<003F07FF0FFF0FFE007E007E007E007C007C00FC00FC00F800F801F801F8 01F001F003F003F003E003E007E007E007C007C00FC00FC00F800F801F801F801F001F00 3F003F003E003E007E007E007C007C18FC1CFC3CF838F838F878F870F070F0F0F8E079E0 3FC00F00103579B314>108 D<03C003F8007F00000FF00FFE01FFC0001E783C1F07C1E0 001C7CF00F8F01F0003C3DE0079E00F000383FC007FC00F800387F8007F800F800707F00 07F000F800707F0007E000F800707E0007E000F800F0FC000FC001F800E0FC000FC001F0 0060F8000F8001F00000F8000F8001F00001F8001F8003F00001F8001F8003E00001F000 1F0003E00001F0001F0003E00003F0003F0007E00003F0003F0007C00003E0003E000FC0 0003E0003E000F818007E0007E000F83C007E0007E001F838007C0007C001F038007C000 7C001F03800FC000FC001F07800FC000FC003E07000F8000F8003E0F000F8000F8001E0E 001F8001F8001E1C001F8001F8001E3C001F0001F0000FF0000E0000E00003E0003A227A A03F>I<03C007F0000FF01FFC001E787C1E001C7CF01F003C3DE00F00383FC00F80387F 800F80787F000F80707E000F80707E000F80F0FC001F80E0FC001F0060F8001F0000F800 1F0001F8003F0001F8003E0001F0003E0001F0003E0003F0007E0003F0007C0003E000FC 0003E000F81807E000F83C07E001F83807C001F03807C001F0380FC001F0780FC001E070 0F8001E0F00F8001E0E01F8001E1C01F8001E3C01F0000FF000E00003E0026227AA02B> I<0000FC000007FF00001F07C0003E03E000FC01F001F801F003F000F807E000F807C000 F80FC000F81F8000FC1F8000FC3F0000FC3F0000FC3F0001FC7F0001F87E0001F87E0001 F87E0003F8FE0003F0FC0003F0FC0003F0FC0007E0FC0007E07C000FC07C000F807C001F 807C003F003E007E003E00FC001F01F0000F83E00003FF800000FC00001E2278A027>I< 001E007C00007F81FF0000F3C387C000E3EF03E001E1FE01E001C1FC01F001C3F801F003 C3F001F00383F001F80383E001F80787E001F80707E001F80307C001F80007C001F8000F C003F8000FC003F0000F8003F0000F8003F0001F8007F0001F8007E0001F0007E0001F00 07E0003F000FC0003F000FC0003E001F80003E001F80007E003F00007F003E00007F007C 00007F00F80000FF81F00000FDC3E00000F8FF800000F87E000001F800000001F8000000 01F000000001F000000003F000000003F000000003E000000003E000000007E000000007 E000000007C0000000FFFF000000FFFF000000FFFF00000025307FA027>I<0003F01800 0FF838003E1C78007C0EF800F807F001F007F003E007F007E003F00FC003E00FC003E01F 8003E01F8007E03F0007C03F0007C03F0007C07F000FC07E000F807E000F807E000F80FE 001F80FC001F00FC001F00FC001F00FC003F00FC003E00FC007E007C007E007C00FE007C 01FC003C03FC003E07FC001F0EFC0007FCF80001F0F8000000F8000001F8000001F00000 01F0000001F0000003F0000003E0000003E0000007E0000007E0000007C00001FFFF0001 FFFF0001FFFE001D3078A023>I<03C00FC00FF03FF01E78F0781C7DE03C3C3FC0FC383F 80FC387F00FC787F00F8707E0070707E0000F0FC0000E0FC000060F8000000F8000001F8 000001F8000001F0000001F0000003F0000003F0000003E0000003E0000007E0000007E0 000007C0000007C000000FC000000FC000000F8000000F8000001F8000001F8000001F00 00000E0000001E227AA020>I<0003F0001FFC003C1E00780F00F00701E00701E00F03E0 1F03C01F03C01F03E00403E00003F00003FF8003FFE001FFF000FFF8007FFC0007FC0000 FE00007E00003E38003EFC003CFC003CFC003CFC007CF00078E000F0F001F07803E03C0F 801FFE0003F80018227AA01F>I<000300000F80000F80000F80001F80001F80001F0000 1F00003F00003F00003E00003E00007E00007E00007C007FFFF87FFFF8FFFFF800F80000 F80001F80001F80001F00001F00003F00003F00003E00003E00007E00007E00007C00007 C0000FC0000FC0000F80000F80601F80F01F80E01F00E01F01E01F01C01F03C01E03801E 07001E0F000F1E0007F80001E00015307AAE19>I<01F000000003FC0007000F1E000F00 0E1E001F001C1E001F003C1E001F00381E003F00783E003E00703E003E00703E003E0070 7E007E00F07C007C0060FC007C0000F8007C0000F800FC0001F800F80001F000F80001F0 00F80001F001F80003F001F00003E001F00003E001F06003E003F07003E003E0F007C003 E0E007C003E0E003C007E1E003C007E1C003E00FC1C003E01FC3C001E03FE38001F071E7 80007FE0FF00001F803C0024227AA029>I<00F0003803FC00FC0F1E00FC0E1E00FC1C1E 00FC3C1E00FC381E007C783E007C703E003C703E003C707E003CF07C003860FC003800F8 003800F8007801F8007001F0007001F0007001F000F003F000E003E000E003E000E003E0 01C003E001C003C003C003C0038003C0078003C0070003E00E0003E00E0001F01C0000F8 7800007FE000001F80001E227AA023>I<01F00000003803FC000E00FC0F1E001E00FC0E 1E003E00FC1C1E003E00FC3C1E003E00FC381E007E007C783E007C007C703E007C003C70 3E007C003C707E00FC003CF07C00F8003860FC00F8003800F800F8003800F801F8007801 F801F0007001F001F0007001F001F0007001F003F000F003F003F000E003E003E000E003 E003E000E003E003E001E003E003E001C003C003C001C003C007C0038003C007C0038003 E00FE0078003E00FE0070003E01FE00E0001F03DF01E0000F878F83C00003FF03FF00000 0FC00FC0002E227AA033>I<00F0000003FC00070F1E000F0E1E001F1C1E001F3C1E001F 381E003F783E003E703E003E703E003E707E007EF07C007C60FC007C00F8007C00F800FC 01F800F801F000F801F000F801F001F803F001F003E001F003E001F003E003F003E003E0 07C003E007C003E003C007E003C007C003E00FC003E01FC001E03FC001F07F80007FEF80 001F8F8000001F8000001F0000001F0000003F003E003E007E007E007E007C007E00F800 7C00F0007001F0007003E000380780003C1F00000FFC000007F0000020317AA025>121 D E /Fj 4 106 df<03FFFFFC0FFFFFFC1FFFFFFC3FFFFFF878181800E0183800C03038 000030300000303000007030000060300000E0700000E0700000E0780001C0780001C078 0003C0780003807C0007803C0007803E000F003C00060018001E167D9424>25 D<0003F000000FFC00001E1E0000780F0000F00F0000E00F8001C0078003C00F8003C00F 8007800F8007800F8007800F800F001F000F001F000F001F000F003E001E003C001E007C 001F0078001F00F0003DC3C0003CFF80003C7E00003C0000007800000078000000780000 0078000000F0000000F0000000F0000000F0000000E000000019217D9520>I<00080000 000800000008000000080000001C0000001C0000001C0000001C0000001C0000C01C0180 7FBEFF001FFFFC0007FFF00001FFC000007F0000007F000000FF800000F7800001E3C000 01C1C0000380E0000300600006003000040010000800080019197D9820>63 D<0038007C007C00780070000000000000000000000000000007801FC038E030E060F0C1 E0C1E0C1E003C003C003C0078007800F000F040F061E0C1E0C1E181C181E700FE007800F 237DA116>105 D E /Fk 45 124 df<000003FFC00000007FFFF0000003FFFFFC00000F FF00FE00003FF8003F00007FE000FF8000FFC001FF8001FFC001FF8001FF8001FF8003FF 8003FFC003FF0001FF8003FF0001FF8003FF0001FF8003FF0000FF0003FF00007E0003FF 0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF003FFFC0FFFF FFFFFFC0FFFFFFFFFFC0FFFFFFFFFFC0FFFFFFFFFFC003FF0000FFC003FF0000FFC003FF 0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF 0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF 0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF 0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF 0000FFC003FF0000FFC003FF0000FFC0FFFFFC3FFFFFFFFFFC3FFFFFFFFFFC3FFFFFFFFF FC3FFFFF303A7EB935>12 D45 D<0F803FE07FF07FF0FFF8FFF8FFF8FFF8FFF87FF0 7FF03FE00F800D0D798C1B>I<0001FF0000000FFFE000007FFFFC0000FF83FE0001FE00 FF0003FC007F8007F8003FC00FF0001FE00FF0001FE01FF0001FF01FF0001FF03FE0000F F83FE0000FF83FE0000FF87FE0000FFC7FE0000FFC7FE0000FFC7FE0000FFC7FE0000FFC FFE0000FFEFFE0000FFEFFE0000FFEFFE0000FFEFFE0000FFEFFE0000FFEFFE0000FFEFF E0000FFEFFE0000FFEFFE0000FFEFFE0000FFEFFE0000FFEFFE0000FFEFFE0000FFEFFE0 000FFEFFE0000FFEFFE0000FFEFFE0000FFEFFE0000FFE7FE0000FFC7FE0000FFC7FE000 0FFC7FE0000FFC3FE0000FF83FE0000FF83FF0001FF81FF0001FF01FF0001FF00FF0001F E00FF8003FE007F8003FC003FC007F8001FE00FF0000FF83FE00007FFFFC00001FFFF000 0001FF000027387CB630>48 D<00001E000000003E00000000FE00000007FE0000003FFE 0000FFFFFE0000FFFFFE0000FFFFFE0000FFCFFE0000000FFE0000000FFE0000000FFE00 00000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000 000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE000000 0FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000F FE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE 0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00 00000FFE0000000FFE0000000FFE00007FFFFFFF807FFFFFFF807FFFFFFF807FFFFFFF80 213779B630>I<000FFC0000007FFFC00001FFFFF00007FFFFFC000FF03FFF001F800FFF 803F0003FFC07F0003FFC07FC001FFE0FFE000FFF0FFF000FFF0FFF000FFF0FFF0007FF8 FFF0007FF8FFF0007FF8FFF0007FF87FE0007FF83FC0007FF80F00007FF80000007FF800 0000FFF0000000FFF0000000FFE0000001FFE0000001FFC0000003FF80000003FF000000 07FE00000007FC0000000FF80000001FF00000003FE00000007F800000007F00000000FE 00000001F800000003F000780007E00078000FC00078001F800078003E0000F8007C0000 F000F80000F001F00001F003FFFFFFF003FFFFFFF007FFFFFFF00FFFFFFFF01FFFFFFFF0 3FFFFFFFF07FFFFFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE025377BB630> I<0003FF0000001FFFF000007FFFFC0001FC07FF0003F003FF8007E001FFC007C000FFE0 0FF000FFE00FFC00FFF01FFC00FFF01FFE00FFF01FFE00FFF01FFE00FFF01FFE00FFF01F FE00FFF00FFC00FFE00FFC00FFE003F001FFE0000001FFC0000003FF80000003FF000000 07FE0000000FFC0000003FF000000FFFC000000FFF0000000FFFF000000007FE00000001 FF80000000FFC0000000FFE00000007FF00000007FF80000007FFC0000003FFC0000003F FC0000003FFE1FC0003FFE3FE0003FFE7FF0003FFEFFF8003FFEFFF8003FFEFFF8003FFE FFF8003FFEFFF8003FFCFFF8003FFCFFF0007FF87FF0007FF87FC000FFF03F8000FFE01F C001FFC00FFC07FF8007FFFFFF0001FFFFFC00007FFFF0000007FF000027387CB630>I< 1C000000C01F800007C01FF8007FC01FFFFFFF801FFFFFFF801FFFFFFF001FFFFFFE001F FFFFFC001FFFFFF0001FFFFFE0001FFFFF80001FFFFE00001FFFF000001F000000001F00 0000001F000000001F000000001F000000001F000000001F000000001F000000001F07FE 00001F3FFFE0001FFFFFF8001FFC07FC001FE003FF001F8001FF801F0000FFC00E0000FF C0000000FFE00000007FE00000007FF00000007FF00000007FF80000007FF80600007FF8 3F80007FF87FE0007FF8FFE0007FF8FFF0007FF8FFF0007FF8FFF0007FF8FFF0007FF8FF E0007FF0FFE0007FF07FC000FFF07F0000FFE07C0000FFC03E0001FFC01F0003FF801FC0 07FF000FF01FFE0007FFFFF80001FFFFE000007FFF8000000FF8000025387BB630>53 D<00000FF8000000FFFE000003FFFF80000FF80FC0003FE003E0007FC001F000FF000FF0 01FF001FF803FE003FF807FC003FF80FFC003FF80FF8003FF81FF8003FF81FF8003FF83F F8001FF03FF8000FE03FF00000007FF00000007FF00000007FF00800007FF07FF000FFF1 FFFC00FFF3FFFF00FFF780FF80FFFF007FC0FFFE003FE0FFFC003FF0FFFC001FF8FFF800 1FF8FFF8001FFCFFF8001FFCFFF8001FFCFFF0001FFEFFF0001FFEFFF0001FFEFFF0001F FEFFF0001FFE7FF0001FFE7FF0001FFE7FF0001FFE7FF0001FFE7FF0001FFE3FF0001FFE 3FF0001FFC3FF0001FFC1FF8001FFC1FF8001FF80FF8003FF807FC003FF007FC007FE003 FE007FC001FF81FF8000FFFFFF00003FFFFC00000FFFF0000001FF800027387CB630>I< 0001FF8000000FFFF000003FFFFC0000FE01FF0001F8007F8003F0003FC007E0001FE007 E0000FE00FC0000FE00FC00007F01FC00007F01FC00007F01FE00007F01FE00007F01FF0 0007F01FF80007F01FFE000FE01FFF800FE01FFFE01FC00FFFF03FC00FFFFC3F800FFFFF 7F0007FFFFFC0003FFFFF80001FFFFF80000FFFFFE00007FFFFF00003FFFFFC0007FFFFF E001FFFFFFF007F8FFFFF00FF07FFFF81FE01FFFFC3FC007FFFC3F8001FFFC7F8000FFFE 7F00003FFEFF00000FFEFE000007FEFE000003FEFE000001FEFE000001FEFE000000FEFE 000000FEFE000000FCFF000000FC7F000001FC7F800001F83FC00003F03FE00007F01FF0 000FE00FFE007FC003FFFFFF0000FFFFFC00003FFFF0000003FF800027387CB630>56 D<0F803FE07FF07FF0FFF8FFF8FFF8FFF8FFF87FF07FF03FE00F80000000000000000000 000000000000000000000000000F803FE07FF07FF0FFF8FFF8FFF8FFF8FFF87FF07FF03F E00F800D2579A41B>58 D<00000003E00000000000000007F00000000000000007F00000 00000000000FF8000000000000000FF8000000000000000FF8000000000000001FFC0000 00000000001FFC000000000000003FFE000000000000003FFE000000000000003FFE0000 00000000007FFF000000000000007FFF00000000000000FFFF80000000000000FFFF8000 0000000000FFFF80000000000001FFFFC0000000000001F3FFC0000000000003F3FFE000 0000000003E1FFE0000000000003E1FFE0000000000007E1FFF0000000000007C0FFF000 000000000FC0FFF800000000000F807FF800000000000F807FF800000000001F807FFC00 000000001F003FFC00000000003F003FFE00000000003E001FFE00000000003E001FFE00 000000007E001FFF00000000007C000FFF0000000000FC000FFF8000000000F80007FF80 00000000F80007FF8000000001F80007FFC000000001F00003FFC000000003FFFFFFFFE0 00000003FFFFFFFFE000000003FFFFFFFFE000000007FFFFFFFFF000000007C00000FFF0 0000000FC00000FFF80000000F8000007FF80000000F8000007FF80000001F8000007FFC 0000001F0000003FFC0000003F0000003FFE0000003E0000001FFE0000003E0000001FFE 0000007E0000001FFF0000007C0000000FFF000000FE0000000FFF8000FFFFF80007FFFF FF80FFFFF80007FFFFFF80FFFFF80007FFFFFF80FFFFF80007FFFFFF80413A7DB948>65 DI<0000003F FC0001C0000003FFFFC003C000001FFFFFF007C00000FFFFFFFC0FC00003FFFC00FF3FC0 0007FFC0001FFFC0001FFE00000FFFC0003FFC000003FFC0007FF0000001FFC000FFE000 0000FFC001FFC0000000FFC003FFC00000007FC007FF800000003FC00FFF000000003FC0 0FFF000000001FC01FFE000000001FC01FFE000000000FC03FFE000000000FC03FFC0000 00000FC03FFC0000000007C07FFC0000000007C07FFC0000000007C07FF8000000000000 FFF8000000000000FFF8000000000000FFF8000000000000FFF8000000000000FFF80000 00000000FFF8000000000000FFF8000000000000FFF8000000000000FFF8000000000000 FFF8000000000000FFF8000000000000FFF8000000000000FFF80000000000007FF80000 000000007FFC0000000000007FFC0000000003C03FFC0000000003C03FFC0000000003C0 3FFE0000000003C01FFE0000000007C01FFE0000000007C00FFF0000000007800FFF0000 00000F8007FF800000000F0003FFC00000001F0001FFC00000003E0000FFE00000007E00 007FF8000000FC00003FFC000001F800001FFF000003F0000007FFC0000FE0000003FFFC 00FF80000000FFFFFFFE000000001FFFFFF80000000003FFFFE000000000003FFE000000 3A3B7BB945>III72 DI77 D<000000FFF800000000000FFFFF80000000007FFFFFF000000001FFC01F FC00000007FF0007FF0000001FFC0001FFC000003FF000007FE000007FE000003FF00000 FFC000001FF80001FF8000000FFC0003FF8000000FFE0007FF00000007FF0007FF000000 07FF000FFE00000003FF800FFE00000003FF801FFC00000001FFC01FFC00000001FFC03F FC00000001FFE03FFC00000001FFE03FFC00000001FFE07FF800000000FFF07FF8000000 00FFF07FF800000000FFF07FF800000000FFF0FFF800000000FFF8FFF800000000FFF8FF F800000000FFF8FFF800000000FFF8FFF800000000FFF8FFF800000000FFF8FFF8000000 00FFF8FFF800000000FFF8FFF800000000FFF8FFF800000000FFF8FFF800000000FFF8FF F800000000FFF87FF800000000FFF07FFC00000001FFF07FFC00000001FFF07FFC000000 01FFF03FFC00000001FFE03FFC00000001FFE03FFE00000003FFE01FFE00000003FFC01F FE00000003FFC00FFF00000007FF8007FF00000007FF0007FF8000000FFF0003FFC00000 1FFE0001FFC000001FFC0000FFE000003FF800007FF000007FF000003FFC0001FFE00000 1FFF0007FFC0000007FFC01FFF00000001FFFFFFFC000000007FFFFFF0000000000FFFFF 800000000000FFF80000003D3B7BB948>79 DI82 D<0007FF000E00003FFFE01E0000FFFFF83E 0003FFFFFE7E0007FC01FFFE000FF0001FFE001FE0000FFE003FC00003FE003F800001FE 007F800000FE007F000000FE007F0000007E00FF0000007E00FF0000003E00FF0000003E 00FF8000003E00FF8000001E00FFC000001E00FFE000001E00FFF000000000FFFC000000 007FFFE00000007FFFFE0000007FFFFFF000003FFFFFFE00003FFFFFFF80001FFFFFFFC0 000FFFFFFFF00007FFFFFFF80003FFFFFFFC0000FFFFFFFE00003FFFFFFE00000FFFFFFF 000001FFFFFF0000000FFFFF800000007FFF800000000FFFC000000003FFC000000001FF C000000000FFC0F00000007FC0F00000007FC0F00000007FC0F00000003FC0F00000003F C0F80000003FC0F80000003F80FC0000003F80FC0000007F80FE0000007F00FF0000007F 00FF800000FE00FFE00001FC00FFF80003FC00FFFF801FF800FCFFFFFFE000F83FFFFFC0 00F007FFFE0000E0007FF000002A3B7BB935>I<003FFE00000003FFFFE000000FFFFFF8 00001FF00FFE00003FF003FF00003FF801FF80003FF800FFC0003FF800FFC0003FF8007F E0003FF8007FE0001FF0007FE0000FE0007FE0000380007FE0000000007FE0000000007F E00000003FFFE000000FFFFFE000007FFFFFE00001FFF87FE00007FF807FE0000FFE007F E0003FF8007FE0003FF0007FE0007FE0007FE000FFE0007FE000FFC0007FE000FFC0007F E000FFC0007FE000FFC0007FE000FFC000FFE000FFE001FFE0007FE001FFE0003FF007FF F8001FFC1FBFFFC00FFFFE1FFFC003FFF80FFFC0003FE003FFC02A257DA42E>97 D<00FF00000000FFFF00000000FFFF00000000FFFF00000000FFFF0000000007FF000000 0003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF000000 0003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF000000 0003FF0000000003FF0000000003FF0000000003FF01FF800003FF0FFFF00003FF3FFFFC 0003FFFE03FF0003FFF000FF8003FFE0007FC003FF80003FE003FF00003FF003FF00001F F803FF00001FF803FF00001FFC03FF00000FFC03FF00000FFC03FF00000FFE03FF00000F FE03FF00000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00000F FE03FF00000FFE03FF00000FFE03FF00000FFC03FF00000FFC03FF00000FFC03FF00001F F803FF00001FF803FF00001FF003FF80003FF003FFC0007FE003FFE0007FC003FDF001FF 8003F8FC07FE0003F03FFFF80003E00FFFE00003C003FF00002F3A7EB935>I<0001FFC0 00000FFFFC00007FFFFF0000FF80FF8003FE00FFC007FC01FFC00FF801FFC01FF801FFC0 1FF001FFC03FF001FFC03FF000FF807FE0007F007FE0001C007FE0000000FFE0000000FF E0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0 0000007FE00000007FE00000007FF00000003FF00000003FF00001E01FF80001E01FF800 03E00FFC0007C007FE00078003FF001F8000FFC07E00007FFFFC00000FFFF0000001FF80 0023257DA42A>I<000000007F800000007FFF800000007FFF800000007FFF800000007F FF8000000003FF8000000001FF8000000001FF8000000001FF8000000001FF8000000001 FF8000000001FF8000000001FF8000000001FF8000000001FF8000000001FF8000000001 FF8000000001FF8000000001FF8000000001FF8000000001FF800001FF81FF80000FFFF1 FF80003FFFFDFF8000FFC07FFF8003FF001FFF8007FC0007FF800FFC0003FF801FF80001 FF801FF00001FF803FF00001FF803FF00001FF807FE00001FF807FE00001FF807FE00001 FF80FFE00001FF80FFE00001FF80FFE00001FF80FFE00001FF80FFE00001FF80FFE00001 FF80FFE00001FF80FFE00001FF80FFE00001FF80FFE00001FF807FE00001FF807FE00001 FF807FF00001FF803FF00001FF803FF00001FF801FF80003FF800FF80007FF8007FC000F FF8003FE001FFFC001FF80FDFFFE007FFFF9FFFE001FFFE1FFFE0003FF01FFFE2F3A7DB9 35>I<0003FF8000001FFFF000007FFFFC0001FF83FE0003FE007F8007FC003F800FF800 3FC01FF8001FE01FF0001FE03FF0000FF03FF0000FF07FE0000FF07FE0000FF87FE00007 F8FFE00007F8FFE00007F8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8FFE0000000FFE0000000 FFE0000000FFE00000007FE00000007FE00000007FE00000003FF00000003FF00000781F F00000780FF80000F80FFC0000F007FC0003F001FF000FE000FFC07FC0007FFFFF00000F FFFC000001FFE00025257DA42C>I<00001FF0000001FFFC000007FFFF00001FF87F8000 3FE0FF8000FFC1FFC000FFC1FFC001FF81FFC001FF81FFC003FF01FFC003FF00FF8003FF 00FF8003FF003E0003FF00000003FF00000003FF00000003FF00000003FF00000003FF00 000003FF00000003FF000000FFFFFF0000FFFFFF0000FFFFFF0000FFFFFF000003FF0000 0003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF000000 03FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003 FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF 00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF000000FFFFFE 0000FFFFFE0000FFFFFE0000FFFFFE0000223A7DB91D>I<000000001F000007FE00FFC0 007FFFE3FFC001FFFFFFEFE007FE07FF8FE00FF801FF1FE01FF000FF8FE03FF000FFCFE0 3FE0007FC7C03FE0007FC0007FE0007FE0007FE0007FE0007FE0007FE0007FE0007FE000 7FE0007FE0007FE0007FE0003FE0007FC0003FE0007FC0003FF000FFC0001FF000FF8000 0FF801FF000007FE07FE00000FFFFFF800000F7FFFE000001E07FE0000001E0000000000 1E00000000003E00000000003F00000000003F80000000001FC0000000001FFFFFF80000 1FFFFFFF80001FFFFFFFE0000FFFFFFFF80007FFFFFFFC0003FFFFFFFE0007FFFFFFFE00 1FFFFFFFFF003FC0000FFF007F000000FF80FF0000007F80FE0000007F80FE0000003F80 FE0000003F80FE0000003F80FF0000007F807F0000007F007F800000FF003FC00001FE00 1FF00007FC0007FE003FF00001FFFFFFC000007FFFFF00000007FFF000002B377DA530> I<00FF00000000FFFF00000000FFFF00000000FFFF00000000FFFF0000000007FF000000 0003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF000000 0003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF000000 0003FF0000000003FF0000000003FF0000000003FF007FC00003FF03FFF80003FF0FFFFE 0003FF1F03FF0003FF3C01FF8003FF7801FF8003FFF000FF8003FFE000FFC003FFC000FF C003FFC000FFC003FF8000FFC003FF8000FFC003FF0000FFC003FF0000FFC003FF0000FF C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF C0FFFFFC3FFFFFFFFFFC3FFFFFFFFFFC3FFFFFFFFFFC3FFFFF303A7DB935>I<01F00007 FC000FFE000FFE001FFF001FFF001FFF001FFF001FFF000FFE000FFE0007FC0001F00000 000000000000000000000000000000000000000000000000000000FF007FFF007FFF007F FF007FFF0007FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003 FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003 FF0003FF0003FF0003FF0003FF0003FF00FFFFF8FFFFF8FFFFF8FFFFF8153B7DBA1B>I< 00FF00000000FFFF00000000FFFF00000000FFFF00000000FFFF0000000007FF00000000 03FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF00000000 03FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF00000000 03FF0000000003FF0000000003FF0000000003FF000FFFE003FF000FFFE003FF000FFFE0 03FF000FFFE003FF0003FC0003FF0003F00003FF000FE00003FF001F800003FF003F0000 03FF007E000003FF00FC000003FF03F8000003FF07E0000003FF0FC0000003FF1FC00000 03FF7FE0000003FFFFF0000003FFFFF8000003FFFFFC000003FFFFFC000003FFCFFE0000 03FF0FFF000003FE07FF800003FE03FF800003FE01FFC00003FE00FFE00003FE00FFF000 03FE007FF00003FE003FF80003FE001FFC0003FE001FFE0003FE000FFE0003FE000FFF00 FFFFF83FFFF8FFFFF83FFFF8FFFFF83FFFF8FFFFF83FFFF82D3A7EB932>107 D<00FF00FFFF00FFFF00FFFF00FFFF0007FF0003FF0003FF0003FF0003FF0003FF0003FF 0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF 0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF 0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF 0003FF0003FF0003FF0003FF0003FF0003FF00FFFFFCFFFFFCFFFFFCFFFFFC163A7DB91B >I<00FE007FE0000FFC0000FFFE01FFFC003FFF8000FFFE07FFFF00FFFFE000FFFE1F81 FF83F03FF000FFFE3C00FF87801FF00007FE7800FFCF001FF80003FEF000FFDE001FF800 03FFE0007FFC000FFC0003FFC0007FF8000FFC0003FFC0007FF8000FFC0003FF80007FF0 000FFC0003FF80007FF0000FFC0003FF00007FE0000FFC0003FF00007FE0000FFC0003FF 00007FE0000FFC0003FF00007FE0000FFC0003FF00007FE0000FFC0003FF00007FE0000F FC0003FF00007FE0000FFC0003FF00007FE0000FFC0003FF00007FE0000FFC0003FF0000 7FE0000FFC0003FF00007FE0000FFC0003FF00007FE0000FFC0003FF00007FE0000FFC00 03FF00007FE0000FFC0003FF00007FE0000FFC0003FF00007FE0000FFC0003FF00007FE0 000FFC0003FF00007FE0000FFC0003FF00007FE0000FFC0003FF00007FE0000FFC0003FF 00007FE0000FFC00FFFFFC1FFFFF83FFFFF0FFFFFC1FFFFF83FFFFF0FFFFFC1FFFFF83FF FFF0FFFFFC1FFFFF83FFFFF04C257DA451>I<00FE007FC000FFFE03FFF800FFFE0FFFFE 00FFFE1F03FF00FFFE3C01FF8007FE7801FF8003FEF000FF8003FFE000FFC003FFC000FF C003FFC000FFC003FF8000FFC003FF8000FFC003FF0000FFC003FF0000FFC003FF0000FF C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF C003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FF C0FFFFFC3FFFFFFFFFFC3FFFFFFFFFFC3FFFFFFFFFFC3FFFFF30257DA435>I<0001FFC0 0000000FFFF80000007FFFFF000000FF80FF800003FE003FE00007FC001FF0000FF8000F F8001FF00007FC001FF00007FC003FF00007FE003FE00003FE007FE00003FF007FE00003 FF007FE00003FF00FFE00003FF80FFE00003FF80FFE00003FF80FFE00003FF80FFE00003 FF80FFE00003FF80FFE00003FF80FFE00003FF80FFE00003FF807FE00003FF007FE00003 FF007FE00003FF003FE00003FE003FF00007FE001FF00007FC001FF00007FC000FF8000F F80007FC001FF00003FE003FE00001FF80FFC000007FFFFF0000001FFFFC00000001FFC0 000029257DA430>I<00FF01FF8000FFFF0FFFF000FFFF3FFFFC00FFFFFE07FF00FFFFF0 01FF8003FFE000FFC003FF80007FE003FF00007FF003FF00003FF803FF00003FF803FF00 001FFC03FF00001FFC03FF00001FFC03FF00000FFE03FF00000FFE03FF00000FFE03FF00 000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00 000FFE03FF00000FFC03FF00001FFC03FF00001FFC03FF00001FF803FF00003FF803FF00 003FF003FF80007FF003FFC0007FE003FFE000FFC003FFF003FF8003FFFC07FE0003FF3F FFF80003FF0FFFE00003FF03FF000003FF0000000003FF0000000003FF0000000003FF00 00000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF00 00000003FF0000000003FF00000000FFFFFC000000FFFFFC000000FFFFFC000000FFFFFC 0000002F357EA435>I<00FE03F000FFFE0FFE00FFFE3FFF00FFFE7C7F80FFFEF8FFC007 FEF0FFC003FFE0FFC003FFC0FFC003FFC0FFC003FF807F8003FF803F0003FF800C0003FF 80000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00 000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF0000 0003FF00000003FF00000003FF00000003FF00000003FF00000003FF000000FFFFFE0000 FFFFFE0000FFFFFE0000FFFFFE000022257EA427>114 D<003FF03803FFFEF80FFFFFF8 1FC00FF83F0003F87E0001F87C0000F8FC0000F8FC000078FE000078FF000078FF800000 FFFC0000FFFFE0007FFFFC007FFFFF803FFFFFC01FFFFFF00FFFFFF803FFFFF800FFFFFC 001FFFFC00007FFE000007FEF00001FEF00000FEF80000FEF800007EFC00007EFC00007C FE0000FCFF0000F8FF8001F8FFF007F0FFFFFFC0F8FFFF00E01FF8001F257DA426>I<00 0F0000000F0000000F0000000F0000000F0000001F0000001F0000001F0000001F000000 3F0000003F0000007F000000FF000000FF000001FF000007FF00001FFFFFE0FFFFFFE0FF FFFFE0FFFFFFE003FF000003FF000003FF000003FF000003FF000003FF000003FF000003 FF000003FF000003FF000003FF000003FF000003FF000003FF000003FF000003FF000003 FF000003FF000003FF007803FF007803FF007803FF007803FF007803FF007803FF007803 FF007803FF00F801FF80F001FF81F000FFC3E0003FFFC0001FFF800003FE001D357EB425 >I<00FF00003FC0FFFF003FFFC0FFFF003FFFC0FFFF003FFFC0FFFF003FFFC007FF0001 FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000 FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000 FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0000 FFC003FF0000FFC003FF0000FFC003FF0000FFC003FF0001FFC003FF0001FFC003FF0003 FFC003FF0003FFC001FF0007FFC001FF800FFFE000FFC03EFFFF007FFFFCFFFF001FFFF0 FFFF0003FF80FFFF30257DA435>I119 DI123 D E /Fl 27 122 df<0000000C0000001C00000038000000F0000001E0000003 C00000078000000F0000001E0000003C0000007C000000F8000000F0000001E0000003E0 000007C00000078000000F8000001F0000001F0000003E0000003E0000007C0000007C00 0000F8000000F8000001F0000001F0000003F0000003E0000007E0000007C0000007C000 000FC000000F8000000F8000001F8000001F8000001F0000001F0000003F0000003F0000 003E0000003E0000007E0000007E0000007C0000007C0000007C0000007C000000FC0000 00F8000000F8000000F8000000F8000000F8000000F8000000F8000000F8000000F80000 00F8000000F8000000F8000000F800000078000000780000007800000078000000780000 003C0000003C0000003C0000001C0000001E0000001E0000000E00000007000000070000 000380000001C0000001C0000000C000001E5274BD22>40 D<00000C0000000E00000007 000000038000000380000001C0000001E0000001E0000000E0000000F0000000F0000000 780000007800000078000000780000007C0000003C0000003C0000003C0000003C000000 3C0000003C0000003C0000003C0000003C0000003C0000003C0000007C0000007C000000 7C0000007C0000007C0000007C0000007C000000FC000000FC000000F8000000F8000001 F8000001F8000001F0000001F0000003F0000003F0000003E0000003E0000007E0000007 E0000007C000000FC000000F8000000F8000001F8000001F0000001F0000003E0000003E 0000007C0000007C000000F8000000F8000001F0000001F0000003E0000003C0000007C0 00000F8000000F0000001F0000003E0000003C00000078000000F0000001E0000003E000 0003C00000070000000E0000001C00000078000000F0000000C00000001E527FBD22>I< 03C007F00FF01FF01FF81FF81FF81FF007B0003000700060006000E000C001C003800300 07000E001C0038007000E000C0000D197A8819>44 D<7FFFF87FFFF8FFFFF8FFFFF8FFFF F0150579941E>I<003C007E00FF01FF01FF01FF01FE01FC007000000000000000000000 00000000000000000000000000000000000000000000000000000E003F807F80FF80FF80 FF80FF007E003C00102477A319>58 D<0000F800000007FE0000001F871C00003E03FE00 007C03FE0000F801FE0001F801FE0003F000FC0007E000FC000FE000FC000FC001FC001F C001F8001FC001F8003F8001F8003F8003F8007F8003F0007F0003F0007F0003F0007F00 07F000FF0007E000FE0007E000FE0007E000FE000FE000FE000FC000FC000FC1C0FC000F C1C0FC001FC1C0FC001F83C0FC001F8380FC003F8380FC003F87807C007F87007C00FF07 003E01FF0F003E038F8E001F0F079E0007FE03FC0001F000F000222677A42A>97 D<003F00001FFF00001FFF00001FFF0000007F0000007E0000007E0000007E000000FE00 0000FC000000FC000000FC000001FC000001F8000001F8000001F8000003F8000003F000 0003F0000003F0000007F0000007E0F80007E7FE0007EF0F800FFC07C00FF807C00FF003 E00FE003E01FC003F01FC003F01F8003F01F8003F03F8003F03F0003F03F0003F03F0007 F07F0007F07E0007F07E0007F07E000FF0FE000FF0FC000FE0FC000FE0FC001FE0FC001F C0F8001FC0F8003F80F8003F80F8003F00F8007F00F8007E00F800FC007801F8007C01F0 003C03E0003E07C0001E1F80000FFE000001F000001C3B77B926>I<00007F000003FFC0 000FC1E0001F0070007E007800FC003801F801F803F003F807F003F807E003F80FE003F8 1FC003F01FC000003F8000003F8000007F8000007F0000007F0000007F000000FF000000 FE000000FE000000FE000000FE000000FC000000FC000000FC000000FC000030FC000038 FC0000787C0000F07E0001E03E0003C03E000F801F003E000F81F80003FFE00000FF0000 1D2677A426>I<00000001F8000000FFF8000000FFF8000000FFF800000003F800000003 F000000003F000000007F000000007F000000007E000000007E00000000FE00000000FE0 0000000FC00000000FC00000001FC00000001FC00000001F800000001F800000003F8000 00003F800000F83F000007FE3F00001F877F00003E03FF00007C03FE0000F801FE0001F8 01FE0003F000FE0007E000FC000FE000FC000FC001FC001FC001FC001FC001F8003F8001 F8003F8003F8007F8003F8007F0003F0007F0003F0007F0007F000FF0007F000FE0007E0 00FE0007E000FE000FE000FE000FE000FC000FC1C0FC000FC1C0FC001FC1C0FC001FC3C0 FC001F8380FC003F8380FC003F87807C007F87007C00FF07003E01FF0F003E038F8E001F 0F079E0007FE03FC0001F000F000253B77B92A>I<00007F000003FFC0000FC1E0003F00 F0007E007800FC007801F8007803F0007807E000780FE000780FC000F81FC000F03F8001 F03F8007E03F801F807F81FF007FFFF8007FFF00007F000000FF000000FE000000FE0000 00FE000000FE000000FE000000FC000000FC000000FC0000307C0000387C0000787E0000 F03E0001E03E0003C01F000F800F003E000781F80003FFE00000FF00001D2677A426>I< 00000007C00000001FF00000003E380000007C3C000000F8FC000000F9FC000001F9FC00 0001F1FC000003F1F8000003F0F0000003F000000007F000000007E000000007E0000000 07E000000007E00000000FE00000000FC00000000FC00000000FC00000000FC00000001F C00000001F8000000FFFFFC0001FFFFFC0001FFFFF8000003F800000003F000000003F00 0000003F000000003F000000007F000000007E000000007E000000007E000000007E0000 0000FE00000000FC00000000FC00000000FC00000000FC00000001FC00000001F8000000 01F800000001F800000001F800000003F800000003F000000003F000000003F000000003 F000000007F000000007E000000007E000000007E000000007E00000000FE00000000FC0 0000000FC00000000FC00000001FC00000001F800000001F800000001F800000001F0000 00003F0000001C3F0000007E3E0000007E3E000000FE3C000000FE7C000000FE78000000 F8F000000078F00000003FC00000000F80000000264C82BA19>I<000007C00000003FF0 000000FC38E00001F01FF00003E01FF00007C00FF0000F800FF0001F8007F0003F0007E0 007F0007E0007E000FE000FE000FE000FC000FC001FC000FC001FC001FC003FC001FC003 F8001F8003F8001F8003F8003F8007F8003F8007F0003F0007F0003F0007F0007F0007F0 007F0007E0007E0007E0007E0007E000FE0007E000FE0007E000FC0003E001FC0003E003 FC0003E007FC0001F00FF80000F01FF80000787BF800003FF3F800000FC3F000000003F0 00000007F000000007F000000007E000000007E00000000FE00000000FC0001C000FC000 7E001FC0007E001F8000FE003F0000FE007E0000FE00FC00007801F800007C07E000001F FF80000003FE00000024367CA426>I<0003F0000001FFF0000001FFF0000001FFF00000 0007F000000007E000000007E000000007E00000000FE00000000FC00000000FC0000000 0FC00000001FC00000001F800000001F800000001F800000003F800000003F000000003F 000000003F000000007F000000007E07F000007E1FFC00007E783E0000FFE01F0000FFC0 1F8000FF800F8000FF000F8001FE000F8001FE000FC001FC000FC001F8001F8003F8001F 8003F0001F8003F0001F8003F0003F8007F0003F0007E0003F0007E0003F0007E0007F00 0FE0007E000FC0007E000FC000FE000FC000FC001FC000FC001F8001FC1C1F8001F81C1F 8001F83C3F8003F8383F0003F0383F0003F0383F0003F0707F0003E0707E0003E0F07E00 03E0E07E0003E1C0FE0001E380FC0000FF003800003C00263B7BB92A>I<0001C00007E0 0007F0000FF0000FE00007E0000380000000000000000000000000000000000000000000 00000000000000000000000000F00003FC00071E000E1F001C1F001C1F00381F00383F00 703F00703F00707F00F07E00E07E00E0FE0000FC0000FC0001FC0001F80003F80003F800 03F00007F00007E00007E0000FE0E00FC0E00FC1E01FC1C01F81C01F81C01F83801F0380 1F07001F07001F0E000F1C0007F80001E000143879B619>I<000FC007FFC007FFC007FF C0001FC0001F80001F80003F80003F80003F00003F00007F00007F00007E00007E0000FE 0000FE0000FC0000FC0001FC0001FC0001F80001F80003F80003F80003F00003F00007F0 0007F00007E00007E0000FE0000FE0000FC0000FC0001FC0001FC0001F80001F80003F80 003F80003F00003F00007F00007F00007E0E007E0E00FE0E00FE1E00FC1C00FC1C00FC3C 00FC3800F83800F878007870007CE0001FE0000F8000123B79B915>108 D<01E000FE0007F00007F803FF801FFC000E3C0F07C0783E001E3E3C03E1E01F001C1F78 03F3C01F80383FF001F7800F80383FE001F7000F80783FC001FE000F80703FC001FE000F C0703F8001FC000FC0703F0003F8001F80F07F0003F8001F80E07E0003F0001F80E07E00 03F0001F80007E0007F0003F8000FE0007F0003F0000FC0007E0003F0000FC0007E0003F 0000FC000FE0007F0001FC000FE0007E0001F8000FC0007E0001F8000FC000FE0001F800 1FC000FC0003F8001FC000FC0003F0001F8001FC1C03F0001F8001F81C03F0003F8001F8 3C07F0003F8003F83807E0003F0003F03807E0003F0003F03807E0007F0003F0700FE000 7F0003E0700FC0007E0003E0F00FC0007E0003E0E00FC000FE0003E1C01FC000FE0001E3 C01F8000FC0000FF000700003800003C003E2679A444>I<01E000FE000007F803FF8000 0E3C0F07C0001E3E3C03E0001C1F7803F000383FF001F000383FE001F000783FC001F000 703FC001F800703F8001F800703F0003F000F07F0003F000E07E0003F000E07E0003F000 007E0007F00000FE0007E00000FC0007E00000FC0007E00000FC000FE00001FC000FC000 01F8000FC00001F8001FC00001F8001F800003F8001F800003F0003F838003F0003F0380 03F0003F078007F0007F070007E0007E070007E0007E070007E0007E0E000FE0007C0E00 0FC0007C1E000FC0007C1C000FC0007C38001FC0003C78001F80001FE000070000078000 292679A42F>I<00007F000003FFC0000FC1F0001F00F8007E007C00FC007C01F8007E03 F0003E07F0003F07E0003F0FE0003F1FC0003F1FC0003F3F80003F3F80007F7F80007F7F 00007F7F00007F7F0000FFFF0000FFFE0000FEFE0000FEFE0001FEFE0001FCFC0001FCFC 0003F8FC0003F8FC0007F0FC0007E0FC000FE07C000FC07E001F803E003F003E007E001F 00F8000F83F00003FFC00000FE0000202677A42A>I<00078007C000001FE03FF000003C F0787C000038F8E03E0000787FC03E0000707F801F000070FF001F0000F0FE001F8000E0 FE001F8000E0FC001F8001E1FC001F8001C1FC001F8001C1F8001F8001C1F8001F800003 F8003F800003F8003F800003F0003F800003F0003F800007F0007F800007F0007F800007 E0007F000007E0007F00000FE000FF00000FE000FE00000FC000FE00000FC001FC00001F C001FC00001FC001F800001F8003F800001F8003F000003F8007E000003FC00FC000003F C00F8000003FE01F0000007FE03E0000007F70FC0000007E3FF00000007E0F80000000FE 0000000000FE0000000000FC0000000000FC0000000001FC0000000001FC0000000001F8 0000000001F80000000003F80000000003F80000000003F00000000007F000000000FFFF C0000000FFFFC0000000FFFFC0000000293580A42A>I<03C003F0000FF01FFC001E783C 0F001C7C700F003C3EE03F80383FC03F80387F803F80787F803F00707F003F00707F001C 00F07E000000E0FE000000E0FC000000E0FC00000000FC00000001FC00000001F8000000 01F800000001F800000003F800000003F000000003F000000003F000000007F000000007 E000000007E000000007E00000000FE00000000FC00000000FC00000000FC00000001FC0 0000001F800000001F800000001F800000003F800000003F000000000E00000000212679 A423>114 D<0000FE000007FF80000F83C0003E00E0007C00F00078007000F800F001F8 03F001F003F001F003F001F003E003F001C003F8000003FC000003FFC00001FFF80001FF FE0000FFFF00007FFF80003FFF80000FFFC00000FFC000003FC000001FC000000FC03E00 0FC07E000FC0FE000F80FE000F80FE000F80FC001F00E0001F00F0003E0070007C003800 F8001E03E0000FFFC00001FE00001C267AA422>I<0003800007C0000FC0000FC0000FC0 000FC0001FC0001F80001F80001F80003F80003F00003F00003F00007F00007E007FFFFF 7FFFFFFFFFFF00FC0000FC0000FC0001FC0001F80001F80001F80003F80003F00003F000 03F00007F00007E00007E00007E0000FE0000FC0000FC0000FC0001FC0001F801C1F801C 1F803C3F80383F00783F00703F00F03F00E03F01C03E03C01F07800F0F0007FC0001F000 183579B31C>I<00F800000003FE0001C0078F0003E00E0F8007E01E0F8007E01C0F8007 E0380F800FE0381F800FE0781F800FC0701F800FC0703F801FC0F03F001FC0E03F001F80 E07F001F80007E003F80007E003F8000FE003F0000FC003F0000FC007F0001FC007F0001 F8007E0001F8007E0001F800FE0003F800FE0003F000FC0E03F000FC0E03F001FC1E03F0 01FC1C03F001F81C03E001F81C03E001F83C03F003F83803F007F83801F007F07001F01E F8F000F83C78E0003FF03FC0000FC00F00272679A42D>I<00F0000E0003FC003F00071E 007F800E1F007F801C1F007F803C1F007F80381F003F80383F001F80703F000F80703F00 0F80707F000F80F07E000F00E07E000700E0FE00070000FC000F0000FC000E0001FC000E 0001F8000E0001F8001E0003F8001C0003F0001C0003F0001C0003F0003C0007F0003800 07E000380007E000700007E000700007E000700007E000E00007E000E00007E001C00007 E003C00003E003800003F007000001F00E000000F83C0000007FF80000000FC000002126 79A426>I<00F0000000070003FC0003801F80071E0007C03FC00E1F000FC03FC01C1F00 0FC03FC03C1F000FC03FC0381F001FC01FC0383F001F800FC0703F001F8007C0703F001F 8007C0707F003F8007C0F07E003F800780E07E003F000380E0FE003F00038000FC007F00 078000FC007F00070001FC007E00070001F8007E00070001F800FE000F0003F800FE000E 0003F000FC000E0003F000FC000E0003F000FC001E0007F001FC001C0007E001F8001C00 07E001F8003C0007E001F800380007E001F800380007E001F800780007E001F800700007 E003F800F00007E003F800E00003E007F801E00003F00FFC03C00001F01E7C07800000FC 3C3E0F0000003FF81FFE0000000FE003F00000322679A437>I<0007E007C0001FF81FF8 00787C383C00F03E703C01E01EE0FE03C01FE0FE03801FC0FE07001FC0FC0F001F80FC0E 001F80700E003F80001E003F00001C003F00001C003F000000007F000000007F00000000 7E000000007E00000000FE00000000FE00000000FC00000000FC00000001FC00000001FC 00000001F800700001F800700003F800F00003F800E01C03F000E07E03F001E07E07F001 C0FE07F00380FE0FF00780FE0EF00F00781CF81E0078387C3C003FF03FF00007C00FC000 27267CA427>I<00F000000003FC0001C0071E0003E00E1F0007E01C1F0007E03C1F0007 E0381F000FE0383F000FC0703F000FC0703F000FC0707F001FC0F07E001F80E07E001F80 E0FE001F8000FC003F8000FC003F0001FC003F0001F8003F0001F8007F0003F8007E0003 F0007E0003F0007E0003F000FE0007F000FC0007E000FC0007E000FC0007E001FC0007E0 01F80007E001F80007E001F80007E003F80007E003F00007E007F00003E00FF00003F01F F00001F87FE000007FF7E000001FC7E00000000FE00000000FC00000000FC00000001FC0 003F001F80007F003F80007F003F00007F007E00007F007C00007E00FC00007001F80000 7003E000003807C000003C1F8000000FFE00000003F0000000233679A428>I E /Fm 27 123 df<003FFFFFFFE000FFFFFFFFF001FFFFFFFFF007FFFFFFFFF007FFFFFF FFE00F80700600001E00600E00003C00600C00003800E00C00007000C00C0000E000C01C 0000C001C01C00000001C01C00000001801C000000038038000000038038000000078038 0000000700380000000700380000000F00380000000F00780000001E007C0000001E007C 0000001E007C0000003E007C0000003C007C0000007C007C0000007C007E000000FC007E 000000F8007E000001F8007E000001F8007F000003F8007F000003F0003F000003F0003F 000003F0003F000001C0001C00002C257EA32F>25 D<000000FE00000003FF8000000F83 E000003E01F000007C00F80000F800F80001F000FC0003F0007C0007E0007E0007C0007E 000FC0007E001F80007E001F80007E003F00007E003F0000FE007F0000FE007E0000FE00 7E0000FE007E0001FE00FE0001FE00FC0001FC00FC0001FC01FC0003FC01FC0003F801F8 0003F801F80007F003F80007F003F8000FE003F0000FC003F0001FC007F0001F8007F800 3F0007F8007E0007FC00FC000FEE01F0000FE707E0000FC3FF80000FC0FC00001FC00000 001FC00000001F800000001F800000003F800000003F800000003F000000003F00000000 7F000000007F000000007E000000007E00000000FE00000000FE00000000FC00000000FC 00000000700000000027377EA42B>I<1C007F00FF80FF80FF80FF80FF807F001C000909 798817>58 D<1C007F00FF80FF80FFC0FFC0FFC07FC01CC000C000C000C000C001C00180 018003800300070006000E001C003800700060000A19798817>I<000000000060000000 00000070000000000000F0000000000001F0000000000001F0000000000003F000000000 0003F0000000000007F000000000000FF000000000000FF000000000001FF80000000000 1FF8000000000033F8000000000073F8000000000063F80000000000C3F80000000000C3 F8000000000183F8000000000183F8000000000303F8000000000603F8000000000603FC 000000000C03FC000000000C01FC000000001801FC000000003001FC000000003001FC00 0000006001FC000000006001FC00000000C001FC00000001C001FC000000018001FC0000 00030001FE000000030001FE000000060000FE0000000E0000FE0000000C0000FE000000 180000FE0000001FFFFFFE0000003FFFFFFE0000003FFFFFFE000000600000FE000000C0 0000FE000000C00000FF000001800000FF0000018000007F0000030000007F0000060000 007F0000060000007F00000C0000007F00000C0000007F0000180000007F000038000000 7F0000700000007F0000F00000007F8001F80000007F8007F8000000FF80FFFF80003FFF FFFFFF80007FFFFFFFFF80007FFFFF383C7DBB3E>65 D<0003FFFFFFFF80000007FFFFFF FFF0000007FFFFFFFFFC00000007F80003FE00000007F00000FF00000007F000007F8000 000FF000003FC000000FF000001FC000000FE000001FE000000FE000001FE000001FE000 001FE000001FE000001FE000001FC000001FE000001FC000001FE000003FC000001FE000 003FC000001FC000003F8000003FC000003F8000003F8000007F8000007F8000007F8000 007F0000007F000000FE0000007F000001FC000000FF000003F8000000FF00000FF00000 00FE00001FC0000000FE0000FF00000001FFFFFFFC00000001FFFFFFF800000001FC0000 FF00000001FC00003FC0000003FC00000FE0000003FC000007F0000003F8000007F00000 03F8000003F8000007F8000003F8000007F8000003FC000007F0000001FC000007F00000 01FC00000FF0000001FC00000FF0000003FC00000FE0000003FC00000FE0000003FC0000 1FE0000003FC00001FE0000007F800001FC0000007F800001FC000000FF000003FC00000 0FF000003FC000001FE000003F8000003FC000003F8000007F8000007F800000FF000000 7F800001FE0000007F000007FC000000FF00003FF00000FFFFFFFFFFC00000FFFFFFFFFF 000000FFFFFFFFF80000003B397DB83F>I<00000000FF8001C00000000FFFE001C00000 007FFFF80380000001FF807E0780000007F8000F0F8000001FE000079F8000003F800003 BF000000FF000001FF000001FC000000FF000003F8000000FF000007F00000007E00000F E00000007E00001FC00000007E00003F800000003E00007F800000003C0000FF00000000 3C0000FE000000003C0001FE000000003C0003FC00000000380003F800000000380007F8 0000000038000FF00000000038000FF00000000030001FF00000000030001FE000000000 00001FE00000000000003FC00000000000003FC00000000000003FC00000000000007FC0 0000000000007F800000000000007F800000000000007F80000000000000FF8000000000 0000FF00000000000000FF00000000000000FF00000000000000FF00000000000000FF00 000000030000FF00000000030000FF00000000070000FF00000000060000FF0000000006 00007F000000000E00007F000000000C00007F000000001C00007F000000003800003F80 0000003800003F800000007000001F80000000E000001FC0000001C000000FE000000380 00000FE000000780000007F000000E00000003F800003C00000001FC00007800000000FF 0001F0000000003FE00FC0000000000FFFFF000000000003FFFC0000000000007FC00000 00003A3D7CBA3B>I<0003FFFFFFFF00000007FFFFFFFFE0000007FFFFFFFFF800000007 F80007FE00000007F00000FF00000007F000003F8000000FF000001FC000000FF000000F C000000FE000000FE000000FE0000007F000001FE0000003F000001FE0000003F000001F C0000003F800001FC0000001F800003FC0000001F800003FC0000001FC00003F80000001 FC00003F80000001FC00007F80000001FC00007F80000001FC00007F00000001FC00007F 00000001FC0000FF00000001FC0000FF00000003FC0000FE00000003FC0000FE00000003 FC0001FE00000003FC0001FE00000003F80001FC00000007F80001FC00000007F80003FC 00000007F80003FC00000007F00003F80000000FF00003F80000000FF00007F80000000F E00007F80000001FE00007F00000001FC00007F00000001FC0000FF00000003F80000FF0 0000003F80000FE00000007F00000FE00000007E00001FE0000000FE00001FE0000001FC 00001FC0000001F800001FC0000003F000003FC0000007E000003FC000000FC000003F80 00001F8000003F8000007F0000007F800000FE0000007F800003FC0000007F00000FF000 0000FF00007FC00000FFFFFFFFFF000000FFFFFFFFFC000000FFFFFFFFC00000003E397D B845>I<0003FFFFFFFFFFF00007FFFFFFFFFFF00007FFFFFFFFFFF0000007F800003FF0 000007F0000007F0000007F0000003E000000FF0000001E000000FF0000000E000000FE0 000000E000000FE0000000E000001FE0000000E000001FE0000000E000001FC0000000E0 00001FC0000000C000003FC0000000C000003FC0000000C000003F80003000C000003F80 003000C000007F80007000C000007F800070000000007F000060000000007F0000E00000 0000FF0000E000000000FF0001E000000000FE0003C000000000FE000FC000000001FFFF FFC000000001FFFFFFC000000001FFFFFF8000000001FC000F8000000003FC0007800000 0003FC00078000000003F800030000000003F800030000000007F800070000000007F800 070003000007F000060003000007F00006000700000FF00006000600000FF00000000600 000FE00000000E00000FE00000000C00001FE00000001C00001FE00000001800001FC000 00003800001FC00000003800003FC00000007000003FC0000000F000003F80000001E000 003F80000001E000007F80000007E000007F8000000FC000007F0000003FC00000FF0000 03FF8000FFFFFFFFFFFF8000FFFFFFFFFFFF8000FFFFFFFFFFFF00003C397DB83D>I<00 03FFFFF803FFFFF80007FFFFF807FFFFF80007FFFFF807FFFFF8000007F8000007F80000 0007F0000007F000000007F0000007F00000000FF000000FF00000000FF000000FE00000 000FE000000FE00000000FE000000FE00000001FE000001FE00000001FE000001FC00000 001FC000001FC00000001FC000001FC00000003FC000003FC00000003FC000003F800000 003F8000003F800000003F8000003F800000007F8000007F800000007F8000007F000000 007F0000007F000000007F0000007F00000000FF000000FF00000000FF000000FE000000 00FE000000FE00000000FE000000FE00000001FFFFFFFFFE00000001FFFFFFFFFC000000 01FFFFFFFFFC00000001FC000001FC00000003FC000003FC00000003FC000003F8000000 03F8000003F800000003F8000003F800000007F8000007F800000007F8000007F0000000 07F0000007F000000007F0000007F00000000FF000000FF00000000FF000000FE0000000 0FE000000FE00000000FE000000FE00000001FE000001FE00000001FE000001FC0000000 1FC000001FC00000001FC000001FC00000003FC000003FC00000003FC000003F80000000 3F8000003F800000003F8000003F800000007F8000007F800000007F8000007F00000000 7F0000007F00000000FF800000FF800000FFFFFF00FFFFFF0000FFFFFF00FFFFFF0000FF FFFF00FFFFFF000045397DB845>72 D<0007FFFFFC0007FFFFFC0007FFFFF8000007F800 000007F000000007F00000000FF00000000FF00000000FE00000000FE00000001FE00000 001FE00000001FC00000001FC00000003FC00000003FC00000003F800000003F80000000 7F800000007F800000007F000000007F00000000FF00000000FF00000000FE00000000FE 00000001FE00000001FE00000001FC00000001FC00000003FC00000003FC00000003F800 000003F800000007F800000007F800000007F000000007F00000000FF00000000FF00000 000FE00000000FE00000001FE00000001FE00000001FC00000001FC00000003FC0000000 3FC00000003F800000003F800000007F800000007F800000007F00000000FF800000FFFF FF0000FFFFFF0000FFFFFF000026397DB824>I<0003FFFFF80007FFFC0007FFFFF80007 FFFC0007FFFFF80007FFFC000007F8000000FF80000007F0000000FC00000007F0000000 F00000000FF0000001E00000000FF0000003800000000FE0000007000000000FE000000E 000000001FE0000038000000001FE0000070000000001FC00000E0000000001FC0000380 000000003FC0000700000000003FC0000E00000000003F80003C00000000003F80007000 000000007F8000E000000000007F8001C000000000007F00070000000000007F000E0000 00000000FF001C000000000000FF007E000000000000FE00FE000000000000FE01FF0000 00000001FE03FF000000000001FE0E7F800000000001FC1C7F800000000001FC383F8000 00000003FCE03FC00000000003FDC03FC00000000003FB801FE00000000003FF001FE000 00000007FC000FF00000000007F8000FF00000000007F00007F00000000007F00007F800 0000000FF00007F8000000000FF00003FC000000000FE00003FC000000000FE00001FC00 0000001FE00001FE000000001FE00001FE000000001FC00000FF000000001FC00000FF00 0000003FC000007F800000003FC000007F800000003F8000003F800000003F8000003FC0 0000007F8000003FC00000007F8000001FE00000007F0000003FE0000000FF8000003FF0 0000FFFFFF0007FFFFC000FFFFFF0007FFFFC000FFFFFF0007FFFF800046397DB847>75 D<03FFFFFFFFFFFE03FFFFFFFFFFFE07FFFFFFFFFFFE07F8003FC001FE07C0003F80007E 0F80003F80003C0F00007F80001C1E00007F80001C1C00007F00001C1C00007F00001C38 0000FF00001C380000FF00001C300000FE00001C700000FE000018600001FE000018E000 01FE000018C00001FC000018C00001FC000018C00003FC000018000003FC000000000003 F8000000000003F8000000000007F8000000000007F8000000000007F0000000000007F0 00000000000FF000000000000FF000000000000FE000000000000FE000000000001FE000 000000001FE000000000001FC000000000001FC000000000003FC000000000003FC00000 0000003F8000000000003F8000000000007F8000000000007F8000000000007F00000000 00007F000000000000FF000000000000FF000000000000FE000000000000FE0000000000 01FE000000000001FE000000000001FC000000000001FC000000000003FC000000000003 FC000000000003F800000000000FFC000000003FFFFFFF0000007FFFFFFF0000007FFFFF FF00000037397EB831>84 D<7FFFFC00003FFFC0FFFFFC00007FFFC0FFFFFC00007FFFC0 03FF00000007FC0001FE00000003E00001FE00000003C00001FE00000003800000FE0000 0003000000FE00000007000000FE00000006000000FE0000000C000000FE0000000C0000 00FE00000018000000FF00000030000000FF000000300000007F000000600000007F0000 00E00000007F000000C00000007F000001800000007F000001800000007F000003000000 007F800006000000007F800006000000003F80000C000000003F80001C000000003F8000 18000000003F800030000000003F800030000000003F800060000000003FC000C0000000 003FC000C0000000001FC00180000000001FC00380000000001FC00300000000001FC006 00000000001FC00600000000001FC00C00000000001FE01800000000001FE01800000000 000FE03000000000000FE07000000000000FE06000000000000FE0C000000000000FE0C0 00000000000FE18000000000000FE30000000000000FF300000000000007F60000000000 0007FE00000000000007FC00000000000007F800000000000007F800000000000007F000 000000000007E000000000000007E000000000000003C000000000000003C00000000000 000380000000000000030000000000003A3B7CB830>86 D<0001FFFFF8007FFFF00001FF FFF800FFFFF00001FFFFF800FFFFE0000003FF80000FFC00000003FE00000FE000000001 FE0000078000000001FE00000F0000000000FF00000E0000000000FF00001C0000000000 7F00003800000000007F80007000000000007F8000E000000000003FC001C00000000000 3FC0038000000000001FC0030000000000001FE0060000000000001FE00C000000000000 0FF0180000000000000FF03000000000000007F06000000000000007F8C0000000000000 07F9C000000000000003FF8000000000000003FF0000000000000001FE00000000000000 01FE0000000000000001FE0000000000000000FF0000000000000000FF00000000000000 00FF0000000000000001FF80000000000000037F80000000000000063FC0000000000000 0E3FC00000000000001C1FE0000000000000381FE0000000000000700FE0000000000000 E00FF0000000000000C00FF00000000000018007F80000000000030007F8000000000006 0003F800000000000C0003FC0000000000180003FC0000000000300001FE000000000070 0001FE0000000000E00000FE0000000001C00000FF0000000003800000FF000000000700 00007F800000000E0000007F800000001E0000003F800000007E0000007FC0000003FF00 0000FFE000007FFFE0001FFFFFC000FFFFE0001FFFFFC000FFFFE0001FFFFF800044397E B845>88 D<000000003F0000001FFF0000001FFF0000001FFF000000007F000000007E00 0000007E00000000FE00000000FE00000000FC00000000FC00000001FC00000001FC0000 0001F800000001F800000003F800000003F800000003F000000003F000000007F0000000 07F000007E07E00003FF87E0000FC1CFE0001F00EFE0007E007FC000FC003FC001F8003F C003F0001FC007F0001F8007E0001F800FE0003F801FC0003F801FC0003F003F80003F00 3F80007F007F80007F007F00007E007F00007E007F0000FE00FF0000FE00FE0000FC00FE 0000FC00FE0001FC00FE0001FC00FC0001F80CFC0001F80CFC0003F80CFC0003F81CFC00 03F018FC0007F0187C0007F0387E000FF0303E001FF0303E007BF0701F00E1F0E00F83C0 F9C003FF007F8000FC001F00283B7DB92B>100 D<00000000F80000000003FE00000000 0F87000000001F0F800000003E3F800000003E7F800000007C7F800000007C7F80000000 FC7F80000000FC7F00000000FC1C00000001F80000000001F80000000001F80000000001 F80000000003F80000000003F00000000003F00000000003F00000000003F00000000007 F00000000007E00000000007E000000007FFFFF0000007FFFFF0000007FFFFF00000000F E0000000000FC0000000000FC0000000000FC0000000000FC0000000001FC0000000001F 80000000001F80000000001F80000000001F80000000003F80000000003F00000000003F 00000000003F00000000003F00000000007F00000000007E00000000007E00000000007E 00000000007E00000000007E0000000000FE0000000000FC0000000000FC0000000000FC 0000000000FC0000000001FC0000000001F80000000001F80000000001F80000000001F8 0000000003F00000000003F00000000003F00000000003F00000000003E00000000007E0 0000000007E00000000007C00000001E07C00000003F07C00000007F8F800000007F8F80 000000FF8F00000000FF1E00000000FE1E000000007C3C000000007878000000001FF000 00000007C000000000294C7CBA29>102 D<0003F000000001FFF000000001FFF0000000 01FFF00000000007F00000000007E00000000007E00000000007E0000000000FE0000000 000FC0000000000FC0000000000FC0000000001FC0000000001F80000000001F80000000 001F80000000003F80000000003F00000000003F00000000003F00000000007F00000000 007E03F80000007E0FFF0000007E3C0F800000FEF007C00000FDC007E00000FF8007E000 00FF0003E00001FE0003E00001FC0003E00001FC0003E00001F80007E00003F80007E000 03F00007E00003F00007E00003F0000FE00007F0000FC00007E0000FC00007E0000FC000 07E0001FC0000FE0001F80000FC0001F80000FC0003F80000FC0003F00001FC0003F0000 1F80007F01801F80007E01801F8000FE03803F8000FC03003F0000FC03003F0000FC0700 3F0000F806007F0000F80E007E0000F80C007E0000F81C007E0000F83800FE0000787000 FC00003FE0003800000F8000293B7CB930>104 D<0000E00003F80003F80007F80007F8 0007F80007F00001C0000000000000000000000000000000000000000000000000000000 00000000000000F80003FE00070F000E0F801C0F80180F80380F80300F80701F80601F80 603F80E03F00C03F00C07F00007E00007E0000FE0000FC0001FC0001FC0001F80003F800 03F00003F00007F01807E01807E0380FE0300FC0300FC0700F80600F80E00F80C00F81C0 0F838007870003FE0000F80015397EB71D>I<0000000F000000003F800000003F800000 007F800000007F800000007F800000007F000000001C0000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000F800000003FE0000000F0F0000001C0F800000380FC00000300FC00 000700FC00000E00FC00000C00FC00001C00FC00001801FC00003801FC00003001F80000 3001F800000003F800000003F800000003F000000003F000000007F000000007F0000000 07E000000007E00000000FE00000000FE00000000FC00000000FC00000001FC00000001F C00000001F800000001F800000003F800000003F800000003F000000003F000000007F00 0000007F000000007E000000007E00000000FE00000000FE00000000FC00000000FC0000 0001FC00001E01F800003F01F800007F83F000007F83F00000FF87E00000FF0FC00000FE 0F8000007C1F000000707E0000003FF80000000FC0000000214981B722>I<03E0007F00 00FE000007F801FFE003FFC0000E3C0781F00F03E0001C3E1E00F83C01F000383F3800FC 7001F800303F7000FCE001F800303FE0007DC000F800703FC0007F8000F800603F80007F 0000F800603F80007F0000F800E03F0000FE0001F800C07F0000FE0001F800C07E0000FC 0001F800C07E0000FC0001F800007E0001FC0003F80000FE0001FC0003F00000FC0001F8 0003F00000FC0001F80003F00000FC0003F80007F00001FC0003F80007E00001F80003F0 0007E00001F80003F0000FE00001F80007F0000FC00003F80007F0000FC00003F00007E0 001FC06003F00007E0001F806003F0000FE0003F80E007F0000FE0003F00C007E0000FC0 003F00C007E0000FC0003F01C007E0001FC0003E01800FE0001FC0003E03800FC0001F80 003E03000FC0001F80003E07000FC0003F80003E0E001FC0003F80001E1C001F80003F00 000FF8000700000E000003E00043267EA449>109 D<03E001F80007F807FE000E3C1E07 001C3E381F00183F703F80383FE07F80303FC0FF80703F80FF80603F80FF00603F007E00 603F003C00E07F000000C07E000000C07E000000007E00000000FE00000000FC00000000 FC00000000FC00000001FC00000001F800000001F800000001F800000003F800000003F0 00000003F000000003F000000007F000000007E000000007E000000007E00000000FE000 00000FC00000000FC00000000FC00000001FC00000001F80000000070000000021267EA4 25>114 D<0000FF000003FFC0000F80F0003E00380078001C0078003C00F000FC01F001 FC01E001FC01E001FC01E001FC03F000F003F8000003FC000001FFE00001FFFC0001FFFF 0000FFFF80007FFFC0001FFFE00003FFE000003FF0000007F0000003F01E0001F07F0001 F07F0001F0FF0001E0FF0001E0FF0001E0FE0003C0F80003C0E000078070000F0038003E 001E00F80007FFE00001FF00001E267CA427>I<0001C0000003E0000007E0000007E000 0007E0000007E000000FE000000FC000000FC000000FC000001FC000001F8000001F8000 001F8000003F8000003F00007FFFFF807FFFFF80FFFFFF80007E0000007E0000007E0000 00FE000000FC000000FC000000FC000001FC000001F8000001F8000001F8000003F80000 03F0000003F0000003F0000007F0000007E0000007E0000007E000000FE000000FC00600 0FC006000FC00E001FC00C001F801C001F8018001F8038001F8070001F8060001F80E000 0F81C0000787800003FE000000F8000019357EB31E>I<0007E001F000001FF807FC0000 783E0E0F0000E01F1C1F0001C01F383F8003800FF07F8003000FE0FF8007000FE0FF800E 000FC0FF000C000FC07E000C001FC03C001C001F80000018001F80000018001F80000000 003F80000000003F80000000003F00000000003F00000000007F00000000007F00000000 007E00000000007E0000000000FE0000000000FE0000000000FC000C000000FC000C0000 01FC001C001E01FC0018003F01F80018007F81F80038007F83F8007000FF83F8006000FF 07F800E000FE0E7C01C0007C1C7C03800078383E0F00001FF00FFC000007C003F0000029 267EA42F>120 D<00F800000003FE000070070F0000F80E0F8001F81C0F8001F8180F80 01F8380F8003F8300F8003F0701F8003F0601F8003F0603F8007F0E03F0007E0C03F0007 E0C07F0007E0007E000FE0007E000FC000FE000FC000FC000FC000FC001FC001FC001F80 01F8001F8001F8001F8001F8003F8003F8003F0003F0003F0003F0003F0003F0007F0003 F0007E0003F0007E0003F0007E0003F000FE0003F000FC0003F001FC0001F003FC0000F8 07FC00007C1FF800003FF9F800000FE1F800000003F800000003F000000003F0000E0007 F0003F8007E0007F800FC0007F800FC0007F801F80007F801F00007F003E00007C007C00 007000F800003801F000001E07C000000FFF00000001FC00000025367EA429>I<0001E0 0060000FF800E0001FFC00C0003FFE01C0007FFF038000FFFF070000F81FFF0001E003FE 0001C0001C0001800038000180007000000000E000000001C00000000380000000070000 00000E000000001C000000003800000000F000000001E000000003800000000700000000 0E000000001C0000000038000300007000030000E000070001C00006000380000E000700 001C000FFC007C001FFF81F8001E0FFFF8003807FFF0007003FFE0006003FFC000E001FF 0000C0007C000023267DA427>I E /Fn 40 120 df45 D<00003FF800000001FFFF0000000FFFFFE000003FFFFFF800007FF01FFC0000FFC007FE 0001FF0001FF0003FE0000FF8007FE0000FFC007FC00007FC00FFC00007FE00FF800003F E01FF800003FF01FF800003FF03FF800003FF83FF800003FF83FF000001FF87FF000001F FC7FF000001FFC7FF000001FFC7FF000001FFC7FF000001FFC7FF000001FFCFFF000001F FEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001F FEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001F FEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001F FEFFF000001FFEFFF000001FFE7FF000001FFC7FF000001FFC7FF000001FFC7FF000001F FC7FF000001FFC3FF800003FF83FF800003FF83FF800003FF81FF800003FF01FF800003F F00FF800003FE00FFC00007FE007FC00007FC007FE0000FFC003FF0001FF8001FF8003FF 0000FFC007FE00007FF01FFC00003FFFFFF800000FFFFFE0000003FFFF800000003FF800 002F427CC038>48 D<000003C000000007C00000001FC00000007FC0000003FFC000003F FFC000FFFFFFC000FFFFFFC000FFFFFFC000FFFFFFC000FFC3FFC0000003FFC0000003FF C0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0 000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC000 0003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC00000 03FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003 FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FF C0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0 000003FFC0000003FFC0000003FFC0000003FFC000FFFFFFFFFCFFFFFFFFFCFFFFFFFFFC FFFFFFFFFCFFFFFFFFFC264177C038>I<0000FFE00000000FFFFE0000003FFFFF800000 FFFFFFE00003FFFFFFF80007FC03FFFE000FE0007FFF001F80003FFF803F00000FFFC07F 000007FFC07FC00007FFE07FF00003FFE0FFF00001FFF0FFF80001FFF0FFF80001FFF8FF F80000FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF87FF00000FFF83FE00000FFF81F C00000FFF800000000FFF800000000FFF000000001FFF000000001FFF000000001FFE000 000003FFE000000003FFC000000007FF800000000FFF000000000FFF000000001FFC0000 00003FF8000000003FF0000000007FE000000000FFC000000001FF0000000003FE000000 0007FC000000000FF0000000001FE0000000003F80000000007F0000780000FE00007800 01FC0000780003F80000F80007E00000F0000FC00000F0001F800000F0003F000000F000 7C000001F000F8000003F001FFFFFFFFF003FFFFFFFFE007FFFFFFFFE00FFFFFFFFFE01F FFFFFFFFE03FFFFFFFFFE07FFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFC0FFFFFFFFFFC0FF FFFFFFFFC0FFFFFFFFFFC02D417BC038>I<0000FFF000000007FFFF0000001FFFFFC000 007FFFFFF00000FF007FF80003F8003FFE0007E0001FFF0007E0000FFF000FF80007FF80 0FFE0007FF801FFE0007FFC01FFF0007FFC01FFF0007FFC01FFF0007FFC01FFF0007FFC0 1FFF0007FFC01FFF0007FFC00FFE0007FFC007FC0007FF8003F8000FFF800000000FFF00 0000001FFF000000001FFE000000003FFC000000007FF800000000FFF000000001FFE000 00000FFF80000007FFFE00000007FFF800000007FFFF00000007FFFFC000000000FFF000 0000003FFC000000000FFE000000000FFF8000000007FF8000000003FFC000000003FFE0 00000003FFE000000001FFF000000001FFF000000001FFF800000001FFF800000001FFF8 0FC00001FFF83FF00001FFF87FF80001FFF87FF80001FFF8FFFC0001FFF8FFFC0001FFF8 FFFC0001FFF0FFFC0001FFF0FFFC0003FFF0FFFC0003FFE07FF80003FFE07FF00007FFC0 7FE00007FFC03F80000FFF801FF0001FFF000FFE00FFFE0007FFFFFFF80001FFFFFFF000 007FFFFFC000001FFFFE00000001FFE000002D427BC038>I<000000003F000000000000 3F0000000000007F000000000000FF000000000001FF000000000003FF000000000003FF 000000000007FF00000000000FFF00000000001FFF00000000003FFF00000000003FFF00 000000007FFF0000000000FFFF0000000001F7FF0000000003E7FF0000000007E7FF0000 000007C7FF000000000F87FF000000001F07FF000000003E07FF000000007E07FF000000 007C07FF00000000F807FF00000001F007FF00000003E007FF00000007E007FF00000007 C007FF0000000F8007FF0000001F0007FF0000003E0007FF0000007C0007FF0000007C00 07FF000000F80007FF000001F00007FF000003E00007FF000007C00007FF00000FC00007 FF00000F800007FF00001F000007FF00003E000007FF00007C000007FF0000FC000007FF 0000FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF 800000000FFF00000000000FFF00000000000FFF00000000000FFF00000000000FFF0000 0000000FFF00000000000FFF00000000000FFF00000000000FFF00000000000FFF000000 00000FFF00000000000FFF000000007FFFFFFF8000007FFFFFFF8000007FFFFFFF800000 7FFFFFFF8000007FFFFFFF8031417DC038>I<07000000030007E000003F0007FF0007FF 0007FFFFFFFF0007FFFFFFFE0007FFFFFFFC0007FFFFFFF80007FFFFFFF00007FFFFFFE0 0007FFFFFF800007FFFFFE000007FFFFFC000007FFFFE0000007FFFF00000007C0000000 0007C00000000007C00000000007C00000000007C00000000007C00000000007C0000000 0007C00000000007C00000000007C00000000007C03FF0000007C1FFFF000007C7FFFFC0 0007DFFFFFF00007FFE03FFC0007FF000FFE0007FC0007FF0007F00003FF8007E00003FF C007C00001FFC003800001FFE000000001FFE000000000FFF000000000FFF000000000FF F000000000FFF800000000FFF800000000FFF800000000FFF80F800000FFF83FE00000FF F87FF00000FFF8FFF00000FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF8FFF80000FF F0FFF00000FFF0FFF00001FFF07FE00001FFE07FC00001FFE07E000003FFC03E000003FF C03F000007FF801FC0000FFF000FF0001FFE0007FE00FFFC0003FFFFFFF00000FFFFFFE0 00003FFFFF8000000FFFFC00000001FFC000002D427BC038>I<000001FF800000001FFF F00000007FFFFC000001FFFFFF000007FF807F80000FFC001F80003FF0001FC0007FE000 7FC000FFC000FFE001FF8001FFE003FF8001FFE003FF0001FFE007FE0001FFE00FFE0001 FFE00FFE0001FFE01FFC0000FFC01FFC00007F801FFC00001E003FFC000000003FFC0000 00003FF8000000007FF8000000007FF8000000007FF807FC00007FF81FFF8000FFF87FFF E000FFF8FFFFF800FFF9F01FFC00FFFBC007FE00FFFF8003FF00FFFF8003FF80FFFF0001 FFC0FFFE0001FFC0FFFE0000FFE0FFFE0000FFE0FFFC0000FFF0FFFC0000FFF0FFFC0000 FFF0FFFC0000FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF87FF80000 FFF87FF80000FFF87FF80000FFF87FF80000FFF87FF80000FFF83FF80000FFF83FF80000 FFF83FF80000FFF03FFC0000FFF01FFC0000FFF01FFC0000FFF00FFC0001FFE00FFC0001 FFE007FE0001FFC007FF0003FF8003FF8003FF0001FFC007FE0000FFE01FFC00007FFFFF F800001FFFFFF0000007FFFFC0000001FFFF000000003FF000002D427BC038>I<000000 001F8000000000000000001F8000000000000000003FC000000000000000003FC0000000 00000000007FE000000000000000007FE000000000000000007FE00000000000000000FF F00000000000000000FFF00000000000000001FFF80000000000000001FFF80000000000 000001FFF80000000000000003FFFC0000000000000003FFFC0000000000000007FFFE00 00000000000007FFFE0000000000000007FFFE000000000000000FFFFF00000000000000 0F9FFF000000000000001F9FFF800000000000001F1FFF800000000000001F0FFF800000 000000003F0FFFC00000000000003E07FFC00000000000007E07FFE00000000000007C07 FFE00000000000007C03FFE0000000000000FC03FFF0000000000000F801FFF000000000 0001F801FFF8000000000001F001FFF8000000000001F000FFF8000000000003F000FFFC 000000000003E0007FFC000000000007E0007FFE000000000007C0007FFE000000000007 C0003FFE00000000000FC0003FFF00000000000F80001FFF00000000001F80001FFF8000 0000001F00000FFF80000000001F00000FFF80000000003F00000FFFC0000000003E0000 07FFC0000000007E000007FFE0000000007FFFFFFFFFE0000000007FFFFFFFFFE0000000 00FFFFFFFFFFF000000000FFFFFFFFFFF000000001FFFFFFFFFFF800000001F0000000FF F800000001F0000000FFF800000003F0000000FFFC00000003E00000007FFC00000007E0 0000007FFE00000007C00000003FFE00000007C00000003FFE0000000F800000003FFF00 00000F800000001FFF0000001F800000001FFF8000001F000000000FFF8000003F000000 000FFFC000003E000000000FFFC000007E0000000007FFC000FFFFFF00000FFFFFFFF0FF FFFF00000FFFFFFFF0FFFFFF00000FFFFFFFF0FFFFFF00000FFFFFFFF0FFFFFF00000FFF FFFFF04C457CC455>65 DI<00000000FFF00000700000001FFFFF0000F0 000001FFFFFFE001F0000007FFFFFFF803F000003FFFFFFFFE07F00000FFFFE001FF0FF0 0001FFFE00003F9FF00007FFF000000FFFF0000FFFC0000007FFF0001FFF00000003FFF0 003FFE00000001FFF0007FFC00000000FFF000FFF8000000007FF001FFF0000000003FF0 03FFE0000000001FF007FFE0000000001FF007FFC0000000000FF00FFF80000000000FF0 0FFF800000000007F01FFF000000000007F01FFF000000000003F03FFF000000000003F0 3FFE000000000003F03FFE000000000003F07FFE000000000001F07FFE000000000001F0 7FFE000000000001F07FFC00000000000000FFFC00000000000000FFFC00000000000000 FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC00000000000000 FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC00000000000000 FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC00000000000000 7FFC000000000000007FFE000000000000007FFE000000000000F07FFE000000000000F0 3FFE000000000000F03FFE000000000000F03FFF000000000000F01FFF000000000001F0 1FFF000000000001E00FFF800000000001E00FFF800000000003E007FFC00000000003C0 07FFE00000000007C003FFE00000000007C001FFF0000000000F8000FFF8000000001F00 007FFC000000003F00003FFE000000007E00001FFF80000000FC00000FFFC0000001F800 0007FFF0000007F0000001FFFE00001FE0000000FFFFF001FF800000003FFFFFFFFF0000 000007FFFFFFFC0000000001FFFFFFF000000000001FFFFF80000000000000FFF8000000 44467AC451>III73 D77 DI80 D82 D<3FFFFFFFFFFFFFFFE03F FFFFFFFFFFFFFFE03FFFFFFFFFFFFFFFE03FFFFFFFFFFFFFFFE03FFFFFFFFFFFFFFFE03F FE000FFF8003FFE07FE0000FFF80003FF07FC0000FFF80001FF07F00000FFF800007F07F 00000FFF800007F07E00000FFF800003F07C00000FFF800001F07C00000FFF800001F07C 00000FFF800001F07800000FFF800000F07800000FFF800000F07800000FFF800000F078 00000FFF800000F0F800000FFF800000F8F000000FFF80000078F000000FFF80000078F0 00000FFF80000078F000000FFF80000078F000000FFF800000780000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000000000FFF800000000000000FFF800000000000000FFF8000000000 00000FFF800000000007FFFFFFFFFF00000007FFFFFFFFFF00000007FFFFFFFFFF000000 07FFFFFFFFFF00000007FFFFFFFFFF000045437CC24E>84 D86 D<0001FFE0000000001FFFFE000000007FFFFF80000001FFFFFFE0000003FE007FF8 000007FC001FFC000007FE000FFE00000FFF0007FF00000FFF0007FF00000FFF0003FF80 000FFF0003FF80000FFF0003FF80000FFF0001FFC00007FE0001FFC00003FC0001FFC000 00F00001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000 0003FFFFC0000000FFFFFFC0000007FFFFFFC000003FFFF1FFC00000FFFC01FFC00003FF E001FFC0000FFF8001FFC0001FFE0001FFC0003FFC0001FFC0003FF80001FFC0007FF800 01FFC0007FF00001FFC000FFF00001FFC000FFE00001FFC000FFE00001FFC000FFE00001 FFC000FFE00003FFC000FFE00003FFC000FFF00007FFC0007FF8000FFFC0007FF8001FFF F0003FFE003EFFFFC01FFF80FC7FFFC007FFFFF87FFFC003FFFFE01FFFC0007FFF8007FF C0000FFC00000000322F7DAD36>97 D<00003FFC00000001FFFFC000000FFFFFF000003F FFFFFC00007FF003FE0000FFC001FF0003FF8003FF0007FF0007FF8007FE0007FF800FFE 0007FF801FFC0007FF801FFC0007FF803FF80007FF803FF80003FF007FF80001FE007FF8 000078007FF0000000007FF000000000FFF000000000FFF000000000FFF000000000FFF0 00000000FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF0 00000000FFF000000000FFF0000000007FF8000000007FF8000000007FF8000000003FF8 000000003FFC000003C03FFC000003C01FFE000007C00FFE000007800FFF00000F8007FF 80001F0003FFC0003E0001FFF0007C00007FFC03F800003FFFFFF000000FFFFFC0000003 FFFF000000003FF800002A2F7CAD32>99 D<0000000003FE0000000007FFFE0000000007 FFFE0000000007FFFE0000000007FFFE0000000007FFFE00000000001FFE00000000000F FE00000000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE 00000000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE00 000000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE0000 0000000FFE0000003FE00FFE000003FFFC0FFE00000FFFFF8FFE00003FFFFFCFFE0000FF F807FFFE0001FFC001FFFE0003FF80007FFE0007FF00003FFE000FFE00001FFE000FFC00 000FFE001FFC00000FFE003FF800000FFE003FF800000FFE003FF800000FFE007FF80000 0FFE007FF000000FFE007FF000000FFE00FFF000000FFE00FFF000000FFE00FFF000000F FE00FFF000000FFE00FFF000000FFE00FFF000000FFE00FFF000000FFE00FFF000000FFE 00FFF000000FFE00FFF000000FFE00FFF000000FFE00FFF000000FFE007FF000000FFE00 7FF000000FFE007FF000000FFE007FF800000FFE003FF800000FFE003FF800000FFE001F FC00001FFE001FFC00001FFE000FFE00003FFE0007FE00007FFE0003FF0000FFFF0001FF C003FFFFFC00FFF01FEFFFFC007FFFFF8FFFFC001FFFFE0FFFFC0007FFF80FFFFC00007F C00FF80036467CC43E>I<00003FF800000003FFFF8000000FFFFFE000003FFFFFF00000 7FF83FF80000FFC007FC0001FF8003FE0003FF0001FF0007FE0000FF800FFC0000FF801F FC00007FC01FF800007FC03FF800003FE03FF800003FE07FF800003FE07FF000003FE07F F000003FF07FF000001FF0FFF000001FF0FFF000001FF0FFFFFFFFFFF0FFFFFFFFFFF0FF FFFFFFFFF0FFFFFFFFFFF0FFF000000000FFF000000000FFF000000000FFF000000000FF F0000000007FF0000000007FF0000000007FF8000000007FF8000000003FF8000000003F F8000000F01FFC000000F01FFC000001F00FFE000001E007FF000003E003FF800007C001 FFC0000F8000FFF0003F00007FFE01FE00001FFFFFFC000007FFFFF0000001FFFFC00000 001FFE00002C2F7DAD33>I<000000FF8000000FFFE000007FFFF00001FFFFF80003FF8F FC000FFE0FFE001FFC1FFE001FF81FFE003FF81FFE007FF01FFE007FF01FFE007FF00FFC 00FFE00FFC00FFE003F000FFE000C000FFE0000000FFE0000000FFE0000000FFE0000000 FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00000FFFF FFF800FFFFFFF800FFFFFFF800FFFFFFF800FFFFFFF80000FFE0000000FFE0000000FFE0 000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE000 0000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00000 00FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000 FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FF E0000000FFE0000000FFE000007FFFFFE0007FFFFFE0007FFFFFE0007FFFFFE0007FFFFF E00027467DC522>I<0000FFE0007E00000FFFFE03FF80003FFFFF8FFF8000FFFFFFFFFF C001FFC07FFF3FC003FF001FF83FC007FE000FFC3FC00FFC0007FE1F801FFC0007FF0F00 1FF80003FF00001FF80003FF00003FF80003FF80003FF80003FF80003FF80003FF80003F F80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80001FF8 0003FF00001FF80003FF00001FFC0007FF00000FFC0007FE000007FE000FFC000003FF00 1FF8000001FFC07FF0000003FFFFFFE0000003FFFFFF800000078FFFFE0000000780FFE0 0000000F8000000000000F8000000000000F8000000000000F8000000000000FC0000000 00000FE000000000000FF000000000000FFFFFFFC000000FFFFFFFFC000007FFFFFFFF80 0007FFFFFFFFE00003FFFFFFFFF00001FFFFFFFFFC0000FFFFFFFFFC0003FFFFFFFFFE00 0FFFFFFFFFFF001FF000007FFF003FC0000007FF007F80000001FF807F80000000FF80FF 00000000FF80FF000000007F80FF000000007F80FF000000007F80FF000000007F80FF80 000000FF807F80000000FF007FC0000001FF003FE0000003FE001FF0000007FC000FFE00 003FF80007FFC001FFF00001FFFFFFFFC000007FFFFFFF0000000FFFFFF8000000007FFF 00000032427DAC38>I<007FC000000000FFFFC000000000FFFFC000000000FFFFC00000 0000FFFFC000000000FFFFC00000000003FFC00000000001FFC00000000001FFC0000000 0001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC000000000 01FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001 FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FF C007FE000001FFC03FFF800001FFC0FFFFE00001FFC1FFFFF80001FFC7F03FFC0001FFCF 801FFC0001FFDF000FFE0001FFDE000FFE0001FFFC000FFE0001FFF80007FF0001FFF000 07FF0001FFF00007FF0001FFE00007FF0001FFE00007FF0001FFE00007FF0001FFC00007 FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF 0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF00 01FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001 FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FF C00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF00FFFFFF83FFFFFEFFFFFF 83FFFFFEFFFFFF83FFFFFEFFFFFF83FFFFFEFFFFFF83FFFFFE37457CC43E>I<007C0001 FF0003FF8007FFC007FFC00FFFE00FFFE00FFFE00FFFE00FFFE007FFC007FFC003FF8001 FF00007C0000000000000000000000000000000000000000000000000000000000000000 7FC07FFFC07FFFC07FFFC07FFFC07FFFC003FFC001FFC001FFC001FFC001FFC001FFC001 FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001 FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001 FFC001FFC001FFC001FFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18467CC520>I<007FC0 00000000FFFFC000000000FFFFC000000000FFFFC000000000FFFFC000000000FFFFC000 00000003FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000 000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0000000 0001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC000000000 01FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0007FFFE001 FFC0007FFFE001FFC0007FFFE001FFC0007FFFE001FFC0007FFFE001FFC0000FE00001FF C0001FC00001FFC0003F000001FFC0007E000001FFC000FC000001FFC003F8000001FFC0 07E0000001FFC00FC0000001FFC01F80000001FFC07F00000001FFC0FE00000001FFC1FC 00000001FFC3FE00000001FFC7FE00000001FFDFFF00000001FFFFFF80000001FFFFFFC0 000001FFFFFFC0000001FFF9FFE0000001FFE1FFF0000001FFC0FFF8000001FF807FF800 0001FF803FFC000001FF803FFE000001FF801FFF000001FF800FFF000001FF8007FF8000 01FF8007FFC00001FF8003FFE00001FF8001FFE00001FF8000FFF00001FF8000FFF80001 FF80007FFC0001FF80003FFC00FFFFFF03FFFFF8FFFFFF03FFFFF8FFFFFF03FFFFF8FFFF FF03FFFFF8FFFFFF03FFFFF835457DC43B>107 D<007FC000FFFFC000FFFFC000FFFFC0 00FFFFC000FFFFC00003FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0 0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0 0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0 0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0 0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0 0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0 0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000FFFFFF80FFFFFF80FFFFFF 80FFFFFF80FFFFFF8019457CC420>I<007F8007FE00000FFC0000FFFF803FFFC0007FFF 8000FFFF80FFFFF001FFFFE000FFFF81FFFFF803FFFFF000FFFF87F01FFC0FE03FF800FF FF8FC00FFE1F801FFC0003FF9F000FFF3E001FFE0001FF9E0007FF3C000FFE0001FFBC00 07FF78000FFE0001FFF80003FFF00007FF0001FFF80003FFF00007FF0001FFF00003FFE0 0007FF0001FFE00003FFC00007FF0001FFE00003FFC00007FF0001FFE00003FFC00007FF 0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FF C00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003 FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF8000 07FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF00 01FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC0 0003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF 800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007 FF0001FFC00003FF800007FF0001FFC00003FF800007FF00FFFFFF81FFFFFF03FFFFFEFF FFFF81FFFFFF03FFFFFEFFFFFF81FFFFFF03FFFFFEFFFFFF81FFFFFF03FFFFFEFFFFFF81 FFFFFF03FFFFFE572D7CAC5E>I<007F8007FE0000FFFF803FFF8000FFFF80FFFFE000FF FF81FFFFF800FFFF87F03FFC00FFFF8F801FFC0003FF9F000FFE0001FF9E000FFE0001FF BC000FFE0001FFF80007FF0001FFF00007FF0001FFF00007FF0001FFE00007FF0001FFE0 0007FF0001FFE00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC000 07FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007 FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF 0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF00 01FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001 FFC00007FF00FFFFFF83FFFFFEFFFFFF83FFFFFEFFFFFF83FFFFFEFFFFFF83FFFFFEFFFF FF83FFFFFE372D7CAC3E>I<00001FFC0000000001FFFFC000000007FFFFF00000001FFF FFFC0000007FF80FFF000000FFC001FF800001FF8000FFC00003FE00003FE00007FE0000 3FF0000FFC00001FF8000FF800000FF8001FF800000FFC001FF800000FFC003FF800000F FE003FF0000007FE007FF0000007FF007FF0000007FF007FF0000007FF007FF0000007FF 00FFF0000007FF80FFF0000007FF80FFF0000007FF80FFF0000007FF80FFF0000007FF80 FFF0000007FF80FFF0000007FF80FFF0000007FF80FFF0000007FF80FFF0000007FF807F F0000007FF007FF0000007FF007FF0000007FF007FF0000007FF003FF800000FFE003FF8 00000FFE001FF800000FFC001FFC00001FFC000FFC00001FF80007FE00003FF00007FE00 003FF00003FF8000FFE00001FFC001FFC000007FF80FFF0000003FFFFFFE0000000FFFFF F800000001FFFFC0000000001FFC000000312F7DAD38>I<007FC00FF80000FFFFC0FFFF 8000FFFFC3FFFFE000FFFFCFFFFFF800FFFFDFC03FFC00FFFFFF001FFE0003FFFC0007FF 0001FFF80003FF8001FFF00003FFC001FFE00001FFE001FFC00001FFE001FFC00000FFF0 01FFC00000FFF001FFC000007FF801FFC000007FF801FFC000007FF801FFC000007FF801 FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FF C000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC0 00003FFC01FFC000003FFC01FFC000007FF801FFC000007FF801FFC000007FF801FFC000 007FF001FFC00000FFF001FFC00000FFF001FFC00001FFE001FFE00001FFC001FFF00003 FFC001FFF80007FF8001FFFC000FFF0001FFFE001FFE0001FFDFC07FFC0001FFCFFFFFF0 0001FFC3FFFFC00001FFC0FFFF000001FFC01FF0000001FFC00000000001FFC000000000 01FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001 FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FF C000000000FFFFFF80000000FFFFFF80000000FFFFFF80000000FFFFFF80000000FFFFFF 8000000036407DAC3E>I<007F807F00FFFF81FFE0FFFF83FFF0FFFF8FFFF8FFFF8F8FFC FFFF9F1FFE03FFBE1FFE01FFBC1FFE01FFF81FFE01FFF81FFE01FFF01FFE01FFF00FFC01 FFE007F801FFE001E001FFE0000001FFE0000001FFE0000001FFC0000001FFC0000001FF C0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC0 000001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC000 0001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC00000FFFFFFE000 FFFFFFE000FFFFFFE000FFFFFFE000FFFFFFE000272D7DAC2E>114 D<001FFC038000FFFF878003FFFFFF800FFFFFFF801FF003FF803FC000FF803F80003F80 7F00001F807E00001F80FE00000F80FE00000F80FE00000780FF00000780FF00000780FF 80000780FFE0000000FFFE0000007FFFF000007FFFFF00003FFFFFC0003FFFFFF0001FFF FFFC000FFFFFFE0003FFFFFF0001FFFFFF80007FFFFF80000FFFFFC000003FFFC0000003 FFE0000000FFE0F000003FE0F000003FE0F800001FE0F800000FE0F800000FE0FC00000F E0FC00000FE0FE00000FC0FF00001FC0FF00001FC0FF80003F80FFE0007F00FFF803FE00 FFFFFFFC00FCFFFFF800F03FFFE000E007FE0000232F7CAD2C>I<0001E000000001E000 000001E000000001E000000001E000000003E000000003E000000003E000000003E00000 0007E000000007E00000000FE00000000FE00000001FE00000001FE00000003FE0000000 7FE0000000FFE0000003FFE000000FFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFF FFFF8000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0 000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE000 0000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00000 00FFE001E000FFE001E000FFE001E000FFE001E000FFE001E000FFE001E000FFE001E000 FFE001E000FFE001E000FFE003E000FFF003C0007FF003C0007FF007C0003FF80F80001F FC1F00000FFFFF000007FFFC000001FFF80000003FE00023407EBE2C>I<007FC00001FF 00FFFFC003FFFF00FFFFC003FFFF00FFFFC003FFFF00FFFFC003FFFF00FFFFC003FFFF00 03FFC0000FFF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001 FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FF C00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC0 0007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC000 07FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007 FF0001FFC00007FF0001FFC0000FFF0001FFC0000FFF0001FFC0001FFF0001FFC0001FFF 0001FFC0003FFF0000FFC0003FFF0000FFE0007FFF80007FE001F7FFFE007FF807E7FFFE 003FFFFFC7FFFE000FFFFF07FFFE0003FFFE07FFFE00007FF007FC00372E7CAC3E>III E /Fo 15 117 df<0F003FC07FE0FFF0FFF0FFF0FFF0FFF0FFF07FE03FC00F 000C0C7A8B19>46 D<000078000000F8000003F800001FF80003FFF800FFFFF800FFFFF8 00FFFFF800FC1FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF8 00001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF8 00001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF8 00001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF800001FF8 00001FF800001FF8007FFFFFFE7FFFFFFE7FFFFFFE7FFFFFFE1F317AB02C>49 D<0000001F800000000000001F800000000000003FC00000000000003FC0000000000000 7FE00000000000007FE00000000000007FE0000000000000FFF0000000000000FFF00000 00000001FFF8000000000001FFF8000000000001FFF8000000000003FFFC000000000003 FFFC000000000007FFFE000000000007CFFE000000000007CFFE00000000000FCFFF0000 0000000F87FF00000000001F87FF80000000001F03FF80000000003F03FFC0000000003E 01FFC0000000003E01FFC0000000007E01FFE0000000007C00FFE000000000FC00FFF000 000000F8007FF000000000F8007FF000000001F8007FF800000001F0003FF800000003F0 003FFC00000003E0001FFC00000003E0001FFC00000007FFFFFFFE00000007FFFFFFFE00 00000FFFFFFFFF0000000FFFFFFFFF0000001F800007FF8000001F000003FF8000001F00 0003FF8000003F000003FFC000003E000001FFC000007E000001FFE000007C000000FFE0 00007C000000FFE00000FC000000FFF00000F80000007FF000FFFFF0003FFFFFF0FFFFF0 003FFFFFF0FFFFF0003FFFFFF0FFFFF0003FFFFFF03C347DB343>65 D70 D<3FFFFFFFFFFFF83FFF FFFFFFFFF83FFFFFFFFFFFF83FFFFFFFFFFFF83FF003FF801FF87F8003FF8003FC7F0003 FF8001FC7E0003FF8000FC7C0003FF80007C7C0003FF80007C780003FF80003C780003FF 80003C780003FF80003C780003FF80003CF80003FF80003EF00003FF80001EF00003FF80 001EF00003FF80001EF00003FF80001E000003FF800000000003FF800000000003FF8000 00000003FF800000000003FF800000000003FF800000000003FF800000000003FF800000 000003FF800000000003FF800000000003FF800000000003FF800000000003FF80000000 0003FF800000000003FF800000000003FF800000000003FF800000000003FF8000000000 03FF800000000003FF800000000003FF800000000003FF800000000003FF800000000003 FF800000000003FF800000000003FF800000000003FF800000001FFFFFFFF000001FFFFF FFF000001FFFFFFFF000001FFFFFFFF00037327DB13E>84 D<007FFE000003FFFFE00007 FFFFF8000FF00FFC001FF803FF001FF801FF001FF800FF801FF800FFC01FF8007FC00FF0 007FC007E0007FC00180007FC00000007FC000007FFFC0000FFFFFC000FFFFFFC003FFF0 7FC00FFF007FC01FF8007FC03FF0007FC07FE0007FC0FFC0007FC0FF80007FC0FF80007F C0FF80007FC0FF8000FFC0FFC000FFC07FC001FFC07FE003FFE03FF80FBFFF0FFFFF1FFF 03FFFC0FFF007FE007FF28217EA02B>97 D<01FC00000000FFFC00000000FFFC00000000 FFFC00000000FFFC000000000FFC0000000007FC0000000007FC0000000007FC00000000 07FC0000000007FC0000000007FC0000000007FC0000000007FC0000000007FC00000000 07FC0000000007FC0000000007FC0000000007FC0000000007FC07FC000007FC7FFF8000 07FDFFFFE00007FFF00FF80007FFC007FC0007FF0003FE0007FE0001FF0007FC0000FF80 07FC0000FF8007FC0000FFC007FC00007FC007FC00007FC007FC00007FE007FC00007FE0 07FC00007FE007FC00007FE007FC00007FE007FC00007FE007FC00007FE007FC00007FE0 07FC00007FE007FC00007FC007FC00007FC007FC0000FFC007FC0000FF8007FC0000FF80 07FE0001FF0007FF0003FE0007FFC007FC0007F3F01FF80007E1FFFFE00007C07FFF8000 07800FF800002B347EB331>I<0007FF8000003FFFF00000FFFFFC0003FE01FE0007FC03 FF000FF803FF001FF003FF003FE003FF003FE003FF007FE001FE007FC000FC007FC00030 00FFC0000000FFC0000000FFC0000000FFC0000000FFC0000000FFC0000000FFC0000000 FFC0000000FFC00000007FC00000007FE00000007FE00000003FE00007803FF00007801F F8000F800FF8001F0007FE003E0003FF80FC0000FFFFF800003FFFE0000007FF00002121 7DA027>I<0003FF8000003FFFF00000FFFFFC0001FF03FE0007FC007F000FF8003F801F F0001FC01FE0001FC03FE0000FE07FE0000FE07FC0000FE07FC0000FF0FFC0000FF0FFC0 0007F0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFC0000000FFC0000000FFC0000000FFC000 00007FC00000007FE00000003FE00000003FE00000F01FF00000F00FF00001F007F80003 E003FE000FC001FF807F80007FFFFF00001FFFFC000003FFE00024217EA029>101 D<00000000F8000FFC07FE007FFF9FFE01FFFFFF7F07FC0FFC7F0FF003FC7F1FF003FE7F 1FE001FE3E3FE001FF1C3FE001FF003FE001FF003FE001FF003FE001FF003FE001FF003F E001FF001FE001FE001FF003FE000FF003FC0007FC0FF80007FFFFE0000F7FFF80000F0F FC00001F000000001F000000001F000000001F800000001FC00000001FFFFFF0001FFFFF FE000FFFFFFF800FFFFFFFE007FFFFFFF003FFFFFFF807FFFFFFFC1FFFFFFFFC3F80001F FC7F000003FEFF000001FEFE000000FEFE000000FEFE000000FEFE000000FEFF000001FE 7F800003FC3FC00007F81FE0000FF00FFC007FE003FFFFFF8000FFFFFE00000FFFE00028 327EA12C>103 D<03F00007F8000FFC001FFE001FFE001FFE001FFE001FFE001FFE000F FC0007F80003F00000000000000000000000000000000000000000000000000001FC00FF FC00FFFC00FFFC00FFFC000FFC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007 FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007 FC0007FC0007FC0007FC00FFFFC0FFFFC0FFFFC0FFFFC012357DB418>105 D<01FC00FFFC00FFFC00FFFC00FFFC000FFC0007FC0007FC0007FC0007FC0007FC0007FC 0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC 0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC 0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC0007FC 00FFFFE0FFFFE0FFFFE0FFFFE013347DB318>108 D<01F81F80FFF87FF0FFF8FFF8FFF9 E3FCFFFBC7FE0FFF87FE07FF07FE07FF07FE07FE07FE07FE03FC07FE01F807FE006007FC 000007FC000007FC000007FC000007FC000007FC000007FC000007FC000007FC000007FC 000007FC000007FC000007FC000007FC000007FC000007FC000007FC0000FFFFF000FFFF F000FFFFF000FFFFF0001F217EA024>114 D<00FFE1C007FFFFC00FFFFFC03F803FC07E 000FC07E0007C0FC0007C0FC0003C0FE0003C0FE0003C0FF800000FFFC0000FFFFE0007F FFFC007FFFFE003FFFFF800FFFFFC007FFFFE000FFFFE0000FFFF000007FF000000FF0F0 0007F0F00003F0F80003F0F80003F0FC0003E0FE0007E0FF000FC0FFC01F80FFFFFF00F9 FFFC00E03FE0001C217DA023>I<003C0000003C0000003C0000003C0000003C0000007C 0000007C0000007C000000FC000000FC000001FC000001FC000003FC000007FC00001FFF FF80FFFFFF80FFFFFF80FFFFFF8007FC000007FC000007FC000007FC000007FC000007FC 000007FC000007FC000007FC000007FC000007FC000007FC000007FC000007FC000007FC 000007FC000007FC03C007FC03C007FC03C007FC03C007FC03C007FC03C007FC03C007FE 078003FE078001FF0F0000FFFE00003FFC00000FF0001A2F7EAE22>I E /Fp 2 104 df<000007E000003FE00000FE000003F8000007F000000FE000000FC000 001FC000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000003F8000003F0000007E0000 00FC000003F800007FE00000FF0000007FE0000003F8000000FC0000007E0000003F0000 003F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001FC000000FC000000FE000 0007F0000003F8000000FE0000003FE0000007E01B4B7BB726>102 DI E /Fq 66 123 df<1000207C00F8FE01 FCFE01FCFE01FCFE01FCFE01FCFE01FCFE01FCFE01FCFE01FCFE01FCFC00FC7C00F87C00 F87C00F87C00F87C00F87C00F87C00F87C00F87C00F8380070161778AE27>34 D<0F003FC03FE07FF07FF07FF87FF83FF83FF80FF801F801F003F007E01FE07FC0FF80FF 00FE0070000D14738927>44 D<1E007F807F80FFC0FFC0FFC0FFC07F807F801E000A0A72 8927>46 D<0007E000003FFC00007FFE0000FFFF0001FFFF8003FC3FC007F00FE00FE007 F00FC003F01F8001F81F8001F83F0000FC3F0000FC3E00007C7E00007E7E00007E7E0000 7E7C00003EFC00003FFC00003FFC00003FFC00003FFC00003FFC00003FFC00003FFC0000 3FFC00003FFC00003FFC00003FFC00003F7E00007E7E00007E7E00007E7E00007E3F0000 FC3F0000FC3F8001FC1F8001F81FC003F80FC003F00FE007F007F00FE003FC3FC001FFFF 8000FFFF00007FFE00003FFC000007E00020307DAE27>48 D<000E0000001F0000001F00 00003F0000007F0000007F000000FF000001FF000003FF00007FFF0000FFFF0000FFFF00 00FFBF00007E3F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00 00003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00 00003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00 00003F0000003F0000003F00003FFFFF807FFFFF807FFFFFC07FFFFF807FFFFF801A2F79 AE27>I<003FE00001FFF80003FFFE000FFFFF801FFFFFC03FE07FE03F800FE07F0007F0 7E0003F8FE0001F8FC0001F8FE0001FCFE0000FCFE0000FCFE0000FC7C0000FC000000FC 000000FC000001FC000001F8000001F8000003F8000003F0000007F000000FE000001FC0 00003FC000007F800000FF000001FE000003FC000007F800000FF000001FE000003FC000 007F800000FE000001FC000007F800780FF000FC1FE000FC3FC000FC7FFFFFFCFFFFFFFC FFFFFFFCFFFFFFFC7FFFFFF81E2F7CAE27>I<001FF80000FFFE0003FFFF800FFFFFC00F FFFFE01FF01FF03FC007F83F8001F83F8001FC3F8000FC3F8000FC1F0000FC040000FC00 0000FC000001FC000001F8000003F8000007F000000FF000003FE0001FFFC0003FFF8000 3FFF80003FFFE0001FFFF000001FF8000003FC000001FC000000FE0000007E0000007F00 00003F0000003F3800003F7C00003FFE00003FFE00003FFE00007FFC00007EFE0000FE7F 0001FC7F8003FC3FF01FF81FFFFFF00FFFFFE003FFFF8000FFFE00001FF80020307DAE27 >I<00003F800000007FC00000007FC0000000FFC0000001FFC0000001FFC0000003F7C0 000007E7C0000007E7C000000FC7C000000F87C000001F87C000003F07C000003F07C000 007E07C00000FC07C00000FC07C00001F807C00001F007C00003F007C00007E007C00007 E007C0000FC007C0001F8007C0001F8007C0003F0007C0003E0007C0007E0007C000FC00 07C000FFFFFFFF80FFFFFFFFC0FFFFFFFFC0FFFFFFFFC07FFFFFFF80000007C000000007 C000000007C000000007C000000007C000000007C000000007C000000007C0000001FFFF 000003FFFF800003FFFF800003FFFF800001FFFF00222F7EAE27>I<1FFFFFE03FFFFFF0 3FFFFFF03FFFFFF03FFFFFE03F0000003F0000003F0000003F0000003F0000003F000000 3F0000003F0000003F0000003F0000003F0000003F0000003F1FF0003FFFFC003FFFFF00 3FFFFF803FFFFFC03FF03FE03FC00FF03F0007F03E0003F81C0001F8000001F8000001FC 000000FC000000FC000000FC7C0000FCFE0000FCFE0000FCFE0001FCFE0001F8FC0003F8 FE0003F07F000FF07F801FE03FE07FC01FFFFF800FFFFF0007FFFE0001FFF800007FC000 1E2F7CAD27>I<0000FF000007FFC0001FFFF0003FFFF800FFFFF801FF81FC03FE01FC03 F801FC07F001FC0FE001FC0FC000F81FC000003F8000003F0000003F0000007F0000007E 0000007E0FF800FE3FFE00FCFFFF80FFFFFFC0FFFFFFE0FFF80FF0FFE007F8FF8001FCFF 0000FCFF0000FEFE00007EFE00007FFE00003FFE00003FFE00003F7E00003F7E00003F7E 00003F7F00003F3F00007F3F00007E1F8000FE1FC001FC0FC001FC0FF007F807F81FF003 FFFFE001FFFFC000FFFF80003FFE00000FF80020307DAE27>I<78000000FFFFFFFEFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFEFC0001FCFC0003F8FC0007F0780007E000000FE00000 1FC000001F8000003F8000007F0000007E000000FE000000FC000001FC000001F8000003 F8000003F0000007F0000007E0000007E000000FC000000FC000000FC000001F8000001F 8000001F8000003F8000003F0000003F0000003F0000003F0000003F0000007F0000007E 0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000003C 000020307DAE27>I<000FF000007FFE0001FFFF8003FFFFC00FFFFFF00FF81FF01FE007 F83F8001FC3F0000FC7F0000FE7E00007E7E00007E7E00007E7E00007E7E00007E3F0000 FC3F8001FC1FC003F80FE007F007FC3FE001FFFF80007FFE00003FFC0000FFFF0003FFFF C00FF00FF01FC003F83F8001FC3F0000FC7E00007E7E00007EFC00003FFC00003FFC0000 3FFC00003FFC00003FFC00003F7E00007E7E00007E7F0000FE3F8001FC1FE007F81FF81F F80FFFFFF007FFFFE001FFFF80007FFE00000FF00020307DAE27>I<000FF000007FFC00 01FFFF0003FFFF8007FFFFC00FF81FE01FE007F03FC003F83F8001F87F0001FC7E0000FC FE0000FCFC00007EFC00007EFC00007EFC00007EFC00007FFC00007FFC00007FFE00007F 7E00007F7F0000FF3F0000FF3F8001FF1FE007FF0FF01FFF07FFFFFF03FFFFFF01FFFF3F 007FFC7F001FF07E0000007E0000007E000000FC000000FC000001FC000001F81F0003F8 3F8007F03F800FE03F801FE03F803FC03FC0FF801FFFFF001FFFFE000FFFF80003FFE000 00FF800020307DAE27>I<0001FE000007FF80001FFFC0007FFFE000FFFFF001FF03F803 FC01F807F000FC0FE01F7C0FC07FFE1F80FFFE1F01FFFE3F03FFFE3E07F1FF7E07E0FF7C 0FC07F7C0F803F7C0F803FFC1F803FF81F001FF81F001FF81F001FF81F001FF81F001FF8 1F001FF81F001FF81F001FFC1F803F7C0F803E7C0F803E7C0FC07E7E07E0FC3E07F1FC3F 03FFF81F01FFF01F80FFE00FC07FC00FE01F1E07F0003F03FC007F01FF03FF00FFFFFE00 7FFFFC001FFFF00007FFC00001FF00202E7DAD27>64 D<0003F000000007F800000007F8 0000000FFC0000000FFC0000000FFC0000000FFC0000000F3C0000001F3E0000001F3E00 00001F3E0000001F3E0000001F3E0000003F3F0000003F3F0000003F3F0000003E1F0000 003E1F0000007E1F8000007E1F8000007E1F8000007E1F800000FC0FC00000FC0FC00000 FC0FC00000FC0FC00000FC0FC00001F807E00001F807E00001F807E00001FFFFE00001FF FFE00003FFFFF00003FFFFF00003FFFFF00003F003F00003F003F00007E001F80007E001 F80007E001F80007E001F8000FE001FC007FFC0FFF80FFFC0FFFC0FFFE1FFFC0FFFC0FFF C07FFC0FFF80222F7EAE27>I<7FFFFF0000FFFFFFC000FFFFFFE000FFFFFFF8007FFFFF F80007E003FC0007E000FE0007E0007E0007E0007F0007E0003F0007E0003F0007E0003F 0007E0003F0007E0003F0007E0003F0007E0007E0007E0007E0007E000FC0007E003FC00 07E00FF80007FFFFF00007FFFFC00007FFFFF00007FFFFF80007FFFFFC0007E000FE0007 E0007F0007E0003F8007E0001F8007E0001F8007E0000FC007E0000FC007E0000FC007E0 000FC007E0000FC007E0000FC007E0001FC007E0001F8007E0003F8007E0007F0007E001 FF007FFFFFFE00FFFFFFFC00FFFFFFF800FFFFFFE0007FFFFF8000222E7FAD27>I<0003 F80E001FFE1F003FFFBF00FFFFFF01FFFFFF03FE0FFF07F803FF07F001FF0FE000FF1FC0 00FF1F80007F1F80007F3F00003F3F00003F7F00003F7E00003F7E00001E7E000000FE00 0000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00 0000FC000000FE0000007E0000007E0000007E00001E7F00003F3F00003F3F00003F1F80 003F1F80007F1FC0007E0FE000FE07F001FC07F803FC03FE0FF801FFFFF000FFFFE0003F FFC0001FFF000003F80020307DAE27>I<7FFFFC00007FFFFF0000FFFFFFC0007FFFFFE0 007FFFFFF00007E00FF80007E007F80007E001FC0007E000FE0007E000FE0007E0007E00 07E0007F0007E0003F0007E0003F8007E0001F8007E0001F8007E0001F8007E0001FC007 E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0 000FC007E0000FC007E0000FC007E0000FC007E0001F8007E0001F8007E0001F8007E000 3F8007E0003F0007E0003F0007E0007F0007E000FE0007E000FE0007E001FC0007E003F8 0007E00FF8007FFFFFF0007FFFFFE000FFFFFFC0007FFFFF00007FFFFC0000222E7FAD27 >I<7FFFFFFF80FFFFFFFFC0FFFFFFFFC0FFFFFFFFC07FFFFFFFC007E0000FC007E0000F C007E0000FC007E0000FC007E0000FC007E0000FC007E000078007E000000007E0000000 07E000000007E000000007E007800007E00FC00007E00FC00007E00FC00007FFFFC00007 FFFFC00007FFFFC00007FFFFC00007FFFFC00007E00FC00007E00FC00007E00FC00007E0 07800007E000000007E000000007E000000007E000000007E00003C007E00007E007E000 07E007E00007E007E00007E007E00007E007E00007E007E00007E07FFFFFFFE0FFFFFFFF E0FFFFFFFFE0FFFFFFFFE07FFFFFFFC0232E7FAD27>I<7FFFFFFF80FFFFFFFFC0FFFFFF FFC0FFFFFFFFC07FFFFFFFC007E0000FC007E0000FC007E0000FC007E0000FC007E0000F C007E0000FC007E000078007E000000007E000000007E000000007E000000007E0078000 07E00FC00007E00FC00007E00FC00007FFFFC00007FFFFC00007FFFFC00007FFFFC00007 FFFFC00007E00FC00007E00FC00007E00FC00007E007800007E000000007E000000007E0 00000007E000000007E000000007E000000007E000000007E000000007E000000007E000 000007E000000007E00000007FFF800000FFFFC00000FFFFC00000FFFFC000007FFF8000 00222E7EAD27>I<0007F03800001FFC7C00007FFFFC0000FFFFFC0001FFFFFC0003FC1F FC0007F00FFC000FE007FC000FC003FC001FC001FC001F8001FC003F8001FC003F0000FC 003F0000FC007E0000FC007E0000FC007E000078007E00000000FC00000000FC00000000 FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC001FFF00FC 003FFF80FC003FFF80FC003FFF807E001FFF007E0000FC007E0000FC007E0000FC003F00 01FC003F0001FC003F8001FC001F8001FC001FC003FC000FC003FC000FE007FC0007F00F FC0003FC1FFC0001FFFFFC0000FFFFFC00007FFEFC00001FFC78000007F0000021307DAE 27>I<7FFE07FFE0FFFF0FFFF0FFFF0FFFF0FFFF0FFFF07FFE07FFE007E0007E0007E000 7E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E 0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007FFFFFE00 07FFFFFE0007FFFFFE0007FFFFFE0007FFFFFE0007E0007E0007E0007E0007E0007E0007 E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0 007E0007E0007E0007E0007E0007E0007E0007E0007E0007E0007E007FFE07FFE0FFFF0F FFF0FFFF0FFFF0FFFF0FFFF07FFE07FFE0242E7FAD27>I<7FFFFFE0FFFFFFF0FFFFFFF0 FFFFFFF07FFFFFE0001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F80007FFFFFE0FFFFFFF0FFFFFFF0FFFFFFF07FFFFFE01C2E7BAD27>I<00 1FFFF8003FFFFC003FFFFC003FFFFC001FFFF800001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000 001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F807C001F807C 001F80FE001F80FE001F80FE003F00FE007F007F81FE007FFFFE003FFFFC001FFFF80007 FFE00000FF00001E2F7BAD27>I<7FFC07FF807FFC07FFC0FFFE0FFFC07FFC07FFC07FFC 07FF8007C001F80007C003F80007C003F00007C007E00007C00FC00007C01FC00007C01F 800007C03F000007C07E000007C0FE000007C0FC000007C1F8000007C3F0000007C7F000 0007C7E0000007CFF0000007DFF8000007FFF8000007FFFC000007FEFC000007FC7E0000 07FC3E000007F83F000007F01F000007E01F800007E00F800007C00FC00007C007C00007 C007E00007C003E00007C003F00007C001F80007C001F80007C000FC0007C0007C0007C0 007E007FFC01FFC07FFC01FFE0FFFE03FFE07FFC01FFE07FFC01FFC0232E7FAD27>I<7F FFC000007FFFE00000FFFFE000007FFFE000007FFFC0000003F000000003F000000003F0 00000003F000000003F000000003F000000003F000000003F000000003F000000003F000 000003F000000003F000000003F000000003F000000003F000000003F000000003F00000 0003F000000003F000000003F000000003F000000003F000000003F000000003F0000000 03F000000003F000000003F000000003F000000003F000078003F0000FC003F0000FC003 F0000FC003F0000FC003F0000FC003F0000FC003F0000FC07FFFFFFFC07FFFFFFFC0FFFF FFFFC07FFFFFFFC07FFFFFFF80222E7FAD27>I<7FE0007FE0FFF000FFF0FFF000FFF0FF F801FFF07FF801FFE00FF801FF000FB801DF000FBC03DF000FBC03DF000FBC03DF000FBE 07DF000F9E079F000F9E079F000F9E079F000F9F0F9F000F9F0F9F000F8F0F1F000F8F0F 1F000F8F9F1F000F8F9F1F000F879E1F000F879E1F000F879E1F000F879E1F000F839C1F 000F83FC1F000F83FC1F000F83FC1F000F81F81F000F81F81F000F80F01F000F80001F00 0F80001F000F80001F000F80001F000F80001F000F80001F000F80001F000F80001F000F 80001F000F80001F007FF000FFE0FFF801FFF0FFF801FFF0FFF801FFF07FF000FFE0242E 7FAD27>I<7FF003FFE0FFF807FFF0FFF807FFF0FFFC07FFF07FFC03FFE007FC003E0007 DE003E0007DE003E0007DE003E0007CF003E0007CF003E0007CF003E0007CF803E0007C7 803E0007C7C03E0007C7C03E0007C3C03E0007C3E03E0007C3E03E0007C1E03E0007C1F0 3E0007C1F03E0007C1F03E0007C0F83E0007C0F83E0007C0F83E0007C0783E0007C07C3E 0007C07C3E0007C03C3E0007C03E3E0007C03E3E0007C01E3E0007C01F3E0007C00F3E00 07C00F3E0007C00F3E0007C007BE0007C007BE0007C007BE0007C003FE007FFC03FE00FF FE03FE00FFFE01FE00FFFE01FE007FFC00FC00242E7FAD27>I<00FFFC0007FFFF801FFF FFE01FFFFFE03FFFFFF03FC00FF07F8007F87F0003F87E0001F87E0001F87E0001F8FC00 00FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC00 00FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC00 00FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFE0001FC7E0001F87E00 01F87E0001F87F0003F87F8007F83FE01FF03FFFFFF01FFFFFE01FFFFFE007FFFF8000FF FC001E307CAE27>I<7FFFFF0000FFFFFFE000FFFFFFF000FFFFFFF8007FFFFFFC0007E0 03FE0007E000FF0007E0007F0007E0003F8007E0001F8007E0001FC007E0000FC007E000 0FC007E0000FC007E0000FC007E0000FC007E0000FC007E0001FC007E0001F8007E0003F 8007E0007F0007E000FF0007E003FE0007FFFFFC0007FFFFF80007FFFFF00007FFFFE000 07FFFF000007E000000007E000000007E000000007E000000007E000000007E000000007 E000000007E000000007E000000007E000000007E000000007E000000007E00000007FFE 000000FFFF000000FFFF000000FFFF0000007FFE000000222E7FAD27>I<00FFFC0007FF FF801FFFFFE01FFFFFE03FFFFFF03FE01FF07F8007F87F0003F87E0001F87E0001F87E00 01F8FE0001FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC00 00FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC00 00FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC07E0FCFC07E0FCFE07F1FC7E07 F1F87E03F9F87E03F9F87F01FFF87F81FFF83FE0FFF03FFFFFF01FFFFFE01FFFFFE007FF FF8000FFFF8000001FC000001FC000000FE000000FE0000007F0000007F0000003F80000 03F8000001F01E397CAE27>I<7FFFF00000FFFFFE0000FFFFFF8000FFFFFFC0007FFFFF E00007E01FF00007E007F00007E003F80007E001F80007E001FC0007E000FC0007E000FC 0007E000FC0007E000FC0007E000FC0007E001FC0007E001F80007E003F80007E007F000 07E01FF00007FFFFE00007FFFFC00007FFFF800007FFFF800007FFFFC00007E01FC00007 E00FE00007E007E00007E003F00007E003F00007E003F00007E003F00007E003F00007E0 03F00007E003F00007E003F00007E003F0F007E003F1F807E003F1F807E003F1F807E003 F1F87FFE01FBF8FFFF01FFF0FFFF00FFF0FFFF00FFE07FFE007FC00000001F00252F7FAD 27>I<007FC0E001FFF1F007FFFFF00FFFFFF01FFFFFF03FE0FFF03F801FF07F000FF07E 0007F0FE0007F0FC0007F0FC0003F0FC0003F0FC0003F0FC0001E0FE0000007E0000007F 0000003FC000003FF800001FFF80000FFFF80007FFFE0003FFFF8000FFFFC0000FFFE000 00FFF000000FF0000007F8000003F8000001F8000001FC000000FC780000FCFC0000FCFC 0000FCFC0000FCFC0000FCFE0001F8FE0001F8FF0003F8FF8007F0FFF01FE0FFFFFFE0FF FFFFC0FFFFFF00F8FFFE00701FF8001E307CAE27>I<7FFFFFFF80FFFFFFFFC0FFFFFFFF C0FFFFFFFFC0FFFFFFFFC0FC03F00FC0FC03F00FC0FC03F00FC0FC03F00FC0FC03F00FC0 FC03F00FC07803F007800003F000000003F000000003F000000003F000000003F0000000 03F000000003F000000003F000000003F000000003F000000003F000000003F000000003 F000000003F000000003F000000003F000000003F000000003F000000003F000000003F0 00000003F000000003F000000003F000000003F000000003F000000003F000000003F000 000003F000000003F0000000FFFFC00001FFFFE00001FFFFE00001FFFFE00000FFFFC000 222E7EAD27>I<7FFE01FFF8FFFF03FFFCFFFF03FFFCFFFF03FFFC7FFE01FFF807E0001F 8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F80 07E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007 E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0 001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007E0001F8007F000 3F8003F0003F0003F0003F0003F8007F0001F8007E0001FC00FE0000FE01FC00007F87F8 00007FFFF800003FFFF000000FFFC0000007FF80000001FE0000262F80AD27>I<7FFC03 FFE07FFE07FFE0FFFE07FFF07FFE07FFE07FFC03FFE007E0007E0007E0007E0007E0007E 0007E0007E0003F000FC0003F000FC0003F000FC0003F000FC0003F801FC0001F801F800 01F801F80001F801F80001F801F80000FC03F00000FC03F00000FC03F00000FC03F00000 7E07E000007E07E000007E07E000007E07E000007E07E000003F0FC000003F0FC000003F 0FC000003F0FC000001F0F8000001F9F8000001F9F8000001F9F8000000F9F0000000F9F 0000000F9F0000000F9F0000000F9F00000007FE00000007FE00000007FE00000007FE00 000003FC00000003FC00000001F80000242F7FAD27>I<7FE0007FE0FFF000FFF0FFF000 FFF0FFF000FFF07FE0007FE01F00000F801F00000F801F00000F801F00000F801F00000F 801F00000F801F00000F800F80001F000F80001F000F80001F000F80001F000F80001F00 0F80001F000F80F01F000F81F81F0007C3FC3E0007C3FC3E0007C3FC3E0007C3FC3E0007 C39C3E0007C79E3E0007C79E3E0007C79E3E0003C79E3C0003C79E3C0003C79E3C0003E7 9E7C0003EF9F7C0003EF9F7C0003EF0F7C0003EF0F7C0001EF0F780001EF0F780001EF0F 780001EF0F780001FE07F80001FE07F80001FE07F80000FE07F00000FE07F00000FC03F0 00007801E000242F7FAD27>I<3FFC1FFE007FFE3FFE007FFE3FFF007FFE3FFE003FFC1F FE0003F00FE00003F80FC00001F80FC00001FC1FC00000FC1F800000FE3F8000007E3F00 00007F7F0000003F7E0000003FFE0000001FFC0000001FFC0000000FF80000000FF80000 0007F000000007F000000003F000000007F000000007F80000000FF80000000FFC000000 1FFC0000001FFE0000003F7E0000003F7F0000007F3F0000007E3F8000007E1F800000FC 1FC00000FC0FC00001F80FE00001F807E00003F807E00003F003F00007F003F00007E003 F8007FFC0FFF80FFFC0FFFC0FFFE1FFFC0FFFC0FFFC07FFC0FFF80222E7EAD27>I<7FFC 03FFE07FFE07FFE0FFFE07FFF07FFE07FFE07FFC03FFE007F000FE0003F000FC0003F801 FC0001F801F80001F801F80001FC03F80000FC03F00000FE07F000007E07E000007E07E0 00003F0FC000003F0FC000001F9F8000001F9F8000001F9F8000000F9F0000000F9F0000 0007FE00000007FE00000003FC00000003FC00000001F800000001F800000001F8000000 01F800000001F800000001F800000001F800000001F800000001F800000001F800000001 F800000001F800000001F800000001F800000001F80000001FFF8000003FFFC000003FFF C000003FFFC000001FFF8000242E7FAD27>I<3FFFFFFE7FFFFFFF7FFFFFFF7FFFFFFF7F FFFFFF7E0000FE7E0001FC7E0001FC7E0003F87E0007F07E0007F03C000FE000001FC000 001FC000003F8000007F0000007F000000FE000000FC000001FC000003F8000003F00000 07F000000FE000000FC000001FC000003F8000003F0000007F000000FE000000FE000001 FC000003F8001E03F8003F07F0003F0FE0003F0FE0003F1FC0003F3F80003F3F80003F7F 00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFE202E7DAD27>I<03FFC000000F FFF000001FFFFC00003FFFFF00003FFFFF80003F80FF80003F801FC0001F000FC0000400 0FE000000007E000000007E000000FFFE000007FFFE00003FFFFE0000FFFFFE0001FFFFF E0003FFC07E0007FC007E0007F0007E000FE0007E000FC0007E000FC0007E000FC0007E0 00FC0007E000FE000FE0007F001FE0007FC0FFE0003FFFFFFF801FFFFFFFC00FFFFFFFC0 03FFF1FFC000FF807F8022207C9F27>97 D<7FE0000000FFF0000000FFF0000000FFF000 00007FF000000003F000000003F000000003F000000003F000000003F000000003F00000 0003F000000003F000000003F000000003F0FF000003F3FFC00003FFFFF00003FFFFF800 03FFFFFC0003FF81FE0003FE00FF0003FC003F8003F8001F8003F8001FC003F0000FC003 F0000FC003F0000FE003F00007E003F00007E003F00007E003F00007E003F00007E003F0 0007E003F0000FE003F0000FC003F8000FC003F8001FC003FC003F8003FC007F8003FE00 FF0003FF83FE0003FFFFFC0003FFFFF80003FFFFF00003F3FFC00001E0FE0000232E7FAD 27>I<000FFF00007FFFC001FFFFE003FFFFF007FFFFF00FF807F01FE007F03FC003E03F 8000807F0000007E0000007E000000FE000000FC000000FC000000FC000000FC000000FC 000000FC000000FE0000007E0000007E0000007F0000F03F8001F83FC001F81FE003F80F F80FF007FFFFF003FFFFE001FFFFC0007FFF00000FF8001D207B9F27>I<00003FF00000 007FF80000007FF80000007FF80000003FF800000001F800000001F800000001F8000000 01F800000001F800000001F800000001F800000001F800000001F800000FE1F800007FFD F80001FFFFF80003FFFFF80007FFFFF8000FF83FF8001FE00FF8003FC007F8003F8003F8 007F0003F8007E0001F8007E0001F800FE0001F800FC0001F800FC0001F800FC0001F800 FC0001F800FC0001F800FC0001F800FE0001F8007E0003F8007E0003F8007F0003F8003F 0007F8003F800FF8001FE01FF8000FF03FF80007FFFFFFC003FFFFFFE001FFFDFFE0007F F9FFE0001FE0FFC0232E7EAD27>I<000FF800003FFE0000FFFF8003FFFFC007FFFFE00F FC0FF01FE003F81FC001F83F8001FC7F0000FC7E0000FC7E00007EFE00007EFFFFFFFEFF FFFFFEFFFFFFFEFFFFFFFEFFFFFFFCFC000000FE0000007E0000007F0000003F00003C3F 80007E1FC0007E1FF000FE0FFC07FC07FFFFFC01FFFFF800FFFFF0003FFFC00007FE001F 207D9F27>I<00001FF00000FFF80001FFFC0003FFFE0007FFFE000FF0FE000FC0FE001F C07C001F8000001F8000001F8000001F8000001F8000001F80007FFFFFF0FFFFFFF8FFFF FFF8FFFFFFF87FFFFFF0001F8000001F8000001F8000001F8000001F8000001F8000001F 8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F 8000001F8000001F8000001F8000001F8000001F8000001F80003FFFFFC07FFFFFE07FFF FFE07FFFFFE03FFFFFC01F2E7EAD27>I<0000003F00001FC0FF80007FF3FFC001FFFFFF E003FFFFFFE007FFFFEFE00FF07F87E01FC01FC3C01FC01FC0001F800FC0003F0007E000 3F0007E0003F0007E0003F0007E0003F0007E0003F0007E0001F800FC0001FC01FC0001F C01FC0000FF07F80000FFFFF00000FFFFE00001FFFFC00001F7FF000001F1FC000001F00 0000001F000000001F800000000FFFFF00000FFFFFE0000FFFFFF8001FFFFFFE003FFFFF FF003F8001FF007E00003F807C00000F80FC00000FC0F8000007C0F8000007C0F8000007 C0F8000007C0FC00000FC07C00000F807F00003F803F80007F003FF807FF001FFFFFFE00 07FFFFF80003FFFFF00000FFFFC000000FFC000023337EA027>I<7FE0000000FFF00000 00FFF0000000FFF00000007FF000000003F000000003F000000003F000000003F0000000 03F000000003F000000003F000000003F000000003F000000003F07F000003F1FFC00003 F7FFF00003FFFFF00003FFFFF80003FFC1F80003FF01FC0003FE00FC0003FC00FC0003F8 00FC0003F800FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000 FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC 0003F000FC0003F000FC0003F000FC007FFF83FFE0FFFFC7FFF0FFFFC7FFF0FFFFC7FFF0 7FFF83FFE0242E7FAD27>I<000F0000001F8000003FC000003FC000003FC000003FC000 001F8000000F000000000000000000000000000000000000000000000000000000000000 3FFF80007FFFC0007FFFC0007FFFC0003FFFC000000FC000000FC000000FC000000FC000 000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000 7FFFFFF0FFFFFFF0FFFFFFF8FFFFFFF07FFFFFF01D2F7BAE27>I<00003C00007E0000FF 0000FF0000FF0000FF00007E00003C000000000000000000000000000000000000000000 01FFFE03FFFF03FFFF03FFFF01FFFF00003F00003F00003F00003F00003F00003F00003F 00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F 00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F 00003F00003F00003F00007E38007E7C00FEFE01FCFE03FCFFFFF8FFFFF07FFFE03FFF80 07FE0018407CAE27>I<7FE00000007FF0000000FFF00000007FF00000007FF000000001 F000000001F000000001F000000001F000000001F000000001F000000001F000000001F0 00000001F000000001F03FFFC001F07FFFE001F07FFFE001F07FFFE001F03FFFC001F003 F80001F007F00001F00FE00001F01FC00001F03F800001F0FF000001F1FE000001F3FC00 0001F7F8000001FFFC000001FFFE000001FFFF000001FF3F000001FE1F800001FC0FC000 01F80FE00001F007E00001F003F00001F001F80001F001FC0001F000FE0001F0007E007F FFC1FFF07FFFC3FFF8FFFFE3FFF87FFFC3FFF87FFFC3FFF0252E80AD27>I<7FFF8000FF FFC000FFFFC000FFFFC0007FFFC000000FC000000FC000000FC000000FC000000FC00000 0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000 0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000 0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000 0FC000000FC000000FC000000FC0007FFFFFF8FFFFFFFCFFFFFFFCFFFFFFFC7FFFFFF81E 2E7CAD27>I<7F07C01F0000FF9FF07FC000FFFFF9FFE000FFFFFFFFF0007FFFFFFFF000 0FFC7FF1F8000FF03FC0F8000FE03F80F8000FC03F00F8000FC03F00F8000FC03F00F800 0F803E00F8000F803E00F8000F803E00F8000F803E00F8000F803E00F8000F803E00F800 0F803E00F8000F803E00F8000F803E00F8000F803E00F8000F803E00F8000F803E00F800 0F803E00F8000F803E00F8000F803E00F8000F803E00F8007FF0FFC3FF00FFF8FFE3FF80 FFF9FFE7FF80FFF8FFE3FF807FF0FFC3FF002920819F27>I<7FE07F0000FFF1FFC000FF F7FFF000FFFFFFF0007FFFFFF80003FFC1F80003FF01FC0003FE00FC0003FC00FC0003F8 00FC0003F800FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000 FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC 0003F000FC0003F000FC0003F000FC007FFF83FFE0FFFFC7FFF0FFFFC7FFF0FFFFC7FFF0 7FFF83FFE024207F9F27>I<001FE000007FF80001FFFE0003FFFF0007FFFF800FF03FC0 1FC00FE03F8007F03F0003F07F0003F87E0001F87E0001F8FC0000FCFC0000FCFC0000FC FC0000FCFC0000FCFC0000FCFC0000FCFE0001FC7E0001F87E0001F87F0003F83F8007F0 3F8007F01FE01FE00FF03FC007FFFF8003FFFF0001FFFE00007FF800001FE0001E207C9F 27>I<7FE0FF0000FFF3FFC000FFFFFFF000FFFFFFF8007FFFFFFC0003FF81FE0003FE00 FF0003FC003F8003F8001F8003F8001FC003F0000FC003F0000FC003F0000FE003F00007 E003F00007E003F00007E003F00007E003F00007E003F00007E003F0000FE003F0000FC0 03F8000FC003F8001FC003FC003F8003FC007F8003FE00FF0003FF83FE0003FFFFFC0003 FFFFF80003FFFFF00003F3FFC00003F0FE000003F000000003F000000003F000000003F0 00000003F000000003F000000003F000000003F000000003F000000003F000000003F000 000003F00000007FFF800000FFFFC00000FFFFC00000FFFFC000007FFF80000023317F9F 27>I<000FF03C00003FFE7E0000FFFF7E0003FFFFFE0007FFFFFE000FFC1FFE001FE007 FE001FC003FE003F8001FE007F0000FE007E0000FE007E0000FE00FE00007E00FC00007E 00FC00007E00FC00007E00FC00007E00FC00007E00FC00007E00FE00007E007E0000FE00 7E0000FE007F0001FE003F8001FE003FC003FE001FE007FE000FF81FFE0007FFFFFE0003 FFFFFE0001FFFF7E00007FFC7E00000FF07E000000007E000000007E000000007E000000 007E000000007E000000007E000000007E000000007E000000007E000000007E00000000 7E000000007E0000001FFFF800001FFFF800003FFFFC00001FFFF800001FFFF826317E9F 27>I<7FFC03FC00FFFE0FFF00FFFE3FFF80FFFE7FFFC07FFEFFFFC0007FFE1FC0007FF8 1FC0007FF00F80007FE00200007FC00000007F800000007F800000007F000000007F0000 00007E000000007E000000007E000000007E000000007E000000007E000000007E000000 007E000000007E000000007E000000007E000000007E000000007E0000007FFFFF8000FF FFFFC000FFFFFFC000FFFFFFC0007FFFFF800022207E9F27>I<00FFF38007FFFFC01FFF FFC03FFFFFC07FFFFFC07F803FC0FC000FC0F8000FC0F8000FC0F8000780FC0000007F80 00007FFC00003FFFF0001FFFFC0007FFFF0001FFFF80000FFFC000003FE0000007E07800 03F0FC0001F0FC0001F0FE0001F0FE0003F0FF0007E0FFE01FE0FFFFFFC0FFFFFF80FFFF FF00FBFFFC00707FF0001C207B9F27>I<003C0000007E0000007E0000007E0000007E00 00007E0000007E0000007E0000007E00007FFFFFF0FFFFFFF8FFFFFFF8FFFFFFF87FFFFF F0007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00 00007E0000007E0000007E0000007E0000007E0000007E0018007E007E007E007E007E00 7E007E007E007E00FE003F00FC003F83FC003FFFF8001FFFF0000FFFE00003FFC00000FF 001F297EA827>I<7FE01FF800FFF03FFC00FFF03FFC00FFF03FFC007FF01FFC0003F000 FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC 0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC00 03F000FC0003F000FC0003F000FC0003F001FC0003F001FC0003F003FC0003FC0FFC0001 FFFFFFE001FFFFFFF000FFFFFFF0003FFEFFF0000FF87FE024207F9F27>I<7FFC0FFF80 FFFE1FFFC0FFFE1FFFC0FFFE1FFFC07FFC0FFF8007C000F80007E001F80003E001F00003 E001F00003F003F00001F003E00001F003E00001F807E00000F807C00000F807C00000F8 07C000007C0F8000007C0F8000007C0F8000003E1F0000003E1F0000003E1F0000003F3F 0000001F3E0000001F3E0000001FFE0000000FFC0000000FFC0000000FFC00000007F800 000007F800000003F0000022207E9F27>I<7FFE07FFE0FFFE07FFF0FFFF0FFFF0FFFE07 FFF07FFE07FFE00F80001F000F80001F000F80001F000FC0003F0007C0003E0007C0003E 0007C0003E0007C0003E0007C0F03E0007C1F83E0003E3FC7C0003E3FC7C0003E3FC7C00 03E3FC7C0003E79E7C0003E79E7C0001E79E780001E79E780001E79E780001F79EF80001 F79EF80001FF0FF80000FF0FF00000FF0FF00000FF0FF00000FE07F000007C03E0002420 7F9F27>I<3FFC1FFF007FFE3FFF007FFE3FFF807FFE3FFF003FFC1FFF0001F807E00000 FC0FC00000FC1F8000007E1F0000003F3F0000001F7E0000001FFC0000000FF800000007 F800000003F000000003E000000003F000000007F80000000FF80000001FFC0000001F3E 0000003E3F0000007E1F0000007C0F800000F80FC00001F807E00003F003E0007FFE1FFF 807FFE1FFF80FFFF3FFFC07FFE1FFF807FFE1FFF8022207E9F27>I<7FFC0FFF80FFFE1F FFC0FFFE1FFFC0FFFE1FFFC07FFC0FFF8007E000F80003E001F80003E001F00003F001F0 0001F003F00001F803E00000F803E00000F803E00000FC07C000007C07C000007C07C000 007E0F8000003E0F8000003E0F8000001F0F0000001F1F0000001F1F0000000F1F000000 0F9E0000000FBE00000007BE00000007FC00000003FC00000003FC00000003F800000001 F800000001F800000001F000000001F000000003F000000003E000000003E000000007E0 00000007C000000807C000003E0FC000007F0F8000007F1F8000007E7F0000007FFE0000 003FFC0000003FF80000001FF000000007C000000022317E9F27>I<1FFFFFFE3FFFFFFF 3FFFFFFF3FFFFFFF3FFFFFFF3F0001FE3F0003FC3F0007F83F000FF01E001FE000003FC0 00007F800000FF000001FE000003FC000007F800001FE000003FC000007F800000FF0000 01FE000003FC001E07F8003F0FF0003F1FE0003F3FC0003F7F80003FFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF7FFFFFFE20207E9F27>I E /Fr 72 124 df<00001FE0000000FFFC 000003F01E00000FC00780001F800780003F000FC0007E001FC000FC001FC000FC001FC0 01F8001FC001F8000F8001F800000001F800000001F800000001F800000001F800000001 F800000001F800000001F800000001F800000001F8000FC0FFFFFFFFC0FFFFFFFFC0FFFF FFFFC001F8001FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F800 0FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000F C001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC0 01F8000FC001F8000FC001F8000FC001F8000FC003FC001FE07FFFC1FFFF7FFFC1FFFF7F FFC1FFFF28357FB42B>12 D<07C01FF03018600CC006C006C006C006C006600C30181FF0 07C00F0D6BB53A>23 D<3C00F07E01F8FF03FCFF03FCFF83FEFF83FE7F81FE3D80F60180 0601800601800601800603800E03000C03000C07001C0600180E00380C00301C00703800 E07001C060018017177EB326>34 D<3C007E00FF00FF00FF80FF807F803D800180018001 800180038003000300070006000E000C001C0038007000600009177AB315>39 D<0000C00001C0000380000F00000E00001C00003C0000780000F00000F00001E00003C0 0003C00007C0000780000F80000F00001F00001F00001E00003E00003E00003E00003C00 007C00007C00007C00007C00007C0000F80000F80000F80000F80000F80000F80000F800 00F80000F80000F80000F80000F80000F80000F80000F80000F800007C00007C00007C00 007C00007C00003C00003E00003E00003E00001E00001F00001F00000F00000F80000780 0007C00003C00003C00001E00000F00000F000007800003C00001C00000E00000F000003 800001C00000C0124A79B71E>II<3C007E00FF00FF00FF 80FF807F803D800180018001800180038003000300070006000E000C001C003800700060 0009177A8715>44 DI<3C7EFFFFFF FF7E3C08087A8715>I<0000003000000078000000F8000000F8000000F0000001F00000 01F0000001E0000003E0000003E0000003C0000007C0000007C00000078000000F800000 0F8000000F0000001F0000001F0000003E0000003E0000003C0000007C0000007C000000 78000000F8000000F8000000F0000001F0000001F0000001E0000003E0000003E0000003 C0000007C0000007C000000F8000000F8000000F0000001F0000001F0000001E0000003E 0000003E0000003C0000007C0000007C00000078000000F8000000F8000000F0000001F0 000001F0000001E0000003E0000003E0000007C0000007C00000078000000F8000000F80 00000F0000001F0000001F0000001E0000003E0000003E0000003C0000007C0000007C00 000078000000F8000000F8000000F0000000600000001D4B7CB726>I<000FE000007FFC 0000F83E0003E00F8007C007C0078003C00F8003E01F0001F01F0001F03F0001F83F0001 F83E0000F87E0000FC7E0000FC7E0000FC7E0000FC7E0000FCFE0000FEFE0000FEFE0000 FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000 FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FEFE0000FE7E0000FC7E0000FC7E0000 FC7E0000FC7E0000FC3F0001F83F0001F83F0001F81F0001F01F0001F00F8003E007C007 C007C007C003E00F8000F83E00007FFC00000FE0001F347DB126>I<00070000000F0000 001F0000007F000007FF0000FFFF0000FFBF0000F83F0000003F0000003F0000003F0000 003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000 003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000 003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000 003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000007F8000 7FFFFF807FFFFF807FFFFF8019327AB126>I<003FC00000FFF00003FFFC000F80FF001E 007F801C003FC038001FE070000FE070000FF0600007F0FC0007F0FE0007F8FF0007F8FF 0003F8FF0003F8FF0003F87E0007F83C0007F8000007F8000007F0000007F000000FF000 000FE000001FC000001FC000003F8000003F0000007E000000FC000001F8000001F00000 03E0000007C000000F8000001F0000003E0000003C00000078001800F0001801E0001803 C00030078000300F0000301C0000701FFFFFF03FFFFFF07FFFFFF0FFFFFFE0FFFFFFE0FF FFFFE01D327CB126>I<001FE00000FFFC0001FFFF0007E03F800F001FC01E000FE01C00 07F03F0007F03F8007F83F8003F83FC003F83F8003F83F8003F81F0007F8000007F80000 07F0000007F000000FE000000FC000001FC000003F8000007E000001F800007FE000007F FC0000003F0000001FC000000FE0000007F0000007F8000003F8000003FC000001FC0000 01FE000001FE000001FE7E0001FEFF0001FEFF0001FEFF0001FEFF0001FEFF0001FCFE00 03FC780003FC700007F8380007F03C000FF01F001FE00FE03F8003FFFF0000FFFC00001F E0001F347DB126>I<000001C000000001C000000003C000000007C000000007C0000000 0FC00000001FC00000001FC00000003FC00000007FC00000006FC0000000CFC0000001CF C00000038FC00000030FC00000070FC000000E0FC000000C0FC000001C0FC00000380FC0 0000300FC00000700FC00000E00FC00000C00FC00001800FC00003800FC00003000FC000 06000FC0000E000FC0000C000FC00018000FC00038000FC00030000FC00060000FC000E0 000FC000FFFFFFFF80FFFFFFFF80FFFFFFFF8000000FC00000000FC00000000FC0000000 0FC00000000FC00000000FC00000000FC00000000FC00000000FC00000001FE0000007FF FF800007FFFF800007FFFF8021337EB226>I<0C0000C00FC00FC00FFFFF800FFFFF000F FFFE000FFFFC000FFFF0000FFFC0000C1800000C0000000C0000000C0000000C0000000C 0000000C0000000C0000000C0000000C0000000C0FC0000C7FF8000CF07C000FC03F000F 001F800F000FC00E000FC00C0007E00C0007E0000007F0000003F0000003F0000003F800 0003F8000003F8000003F8180003F87E0003F8FE0003F8FE0003F8FE0003F8FE0003F0FE 0007F0F80007F0600007E0700007E070000FC038001FC03C001F801E007F000F80FE0007 FFF80001FFE000003F80001D347CB126>I<0000FE000007FF80001FFFE0003F00F0007C 007001F801F801F003F803E003F807E003F80FC003F80FC001F01F8000001F8000003F00 00003F0000003F0000007F0000007E0000007E07F0007E1FFC00FE381F00FE700F80FEE0 07C0FFC003E0FF8003F0FF8001F8FF0001F8FF0001FCFF0000FCFF0000FCFE0000FEFE00 00FEFE0000FEFE0000FEFE0000FE7E0000FE7E0000FE7E0000FE7E0000FE7F0000FE3F00 00FC3F0000FC1F0001FC1F8001F80F8001F00FC003F007C007E003E00FC001F81F8000FF FF00003FFC00000FE0001F347DB126>I<300000003C0000003FFFFFFF3FFFFFFF3FFFFF FF7FFFFFFE7FFFFFFE7FFFFFFC700000386000003060000070600000E0C00000C0C00001 C0C0000380000007000000060000000E0000001C00000018000000380000007000000070 000000E0000000E0000001C0000003C0000003C0000003C0000007800000078000000F80 00000F8000000F8000001F8000001F0000001F0000003F0000003F0000003F0000003F00 00003F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F00 00007F0000001C000020347CB126>I<000FE000007FFC0000FFFF0003F01F8007C007C0 0F0003E00E0001F01E0000F01C0000F83C0000783C0000783C0000783E0000783E000078 3F0000F83F8000F03FC001F01FF001E01FF803C00FFE078007FF0F0003FFDE0001FFF800 00FFF800003FFE00003FFF0000F7FFC003E3FFE00780FFF00F007FF81E001FF83E0007FC 3C0003FC780001FC7800007EF800007EF000003EF000003EF000001EF000001EF000001E F800001EF800003C7800003C7C0000783E0000781F0000F00F8003E007F01FC001FFFF00 007FFC00001FE0001F347DB126>I<000FE000007FF80000FFFE0003F83F0007E00F800F C007C01F8007E01F8003F03F0003F07F0001F87E0001F87E0001F8FE0001FCFE0000FCFE 0000FCFE0000FCFE0000FCFE0000FEFE0000FEFE0000FEFE0000FEFE0000FE7E0001FE7E 0001FE7F0001FE3F0001FE3F0003FE1F8003FE0F8007FE07C00EFE03E01CFE01F038FE00 7FF0FE001FC0FC000000FC000001FC000001FC000001F8000001F8000001F0000003F01F 0003E03F8007E03F8007C03F800FC03F801F803F003F001C007E001F01FC000FFFF00003 FFC00000FF00001F347DB126>I<3C7EFFFFFFFF7E3C0000000000000000000000000000 00003C7EFFFFFFFF7E3C08207A9F15>I<3C7EFFFFFFFF7E3C0000000000000000000000 00000000003C7EFEFFFFFF7F3F03030303070606060E0C1C38307060082F7A9F15>I<00 0000E0000000000000E0000000000000E0000000000001F0000000000001F00000000000 03F8000000000003F8000000000003F8000000000007FC000000000007FC000000000007 FC00000000000DFE00000000000CFE00000000000CFE0000000000187F0000000000187F 0000000000187F0000000000303F8000000000303F8000000000703FC000000000601FC0 00000000601FC000000000E01FE000000000C00FE000000000C00FE000000001800FF000 0000018007F0000000018007F0000000030003F8000000030003F8000000030003F80000 00060001FC000000060001FC0000000E0001FE0000000FFFFFFE0000000FFFFFFE000000 1FFFFFFF0000001800007F0000001800007F0000003000007F8000003000003F80000030 00003F8000006000001FC000006000001FC000006000001FC00000C000000FE00000C000 000FE00001C000000FF00001C0000007F00003E0000007F0001FF000000FF800FFFE0001 FFFFE0FFFE0001FFFFE0FFFE0001FFFFE033367DB53A>65 DI<000003FE000C00003FFF801C0000FFFFE01C0003FE01 F83C000FF0003C7C001FC0000EFC007F800007FC00FE000003FC01FC000001FC03FC0000 00FC03F8000000FC07F00000007C0FE00000007C0FE00000003C1FC00000003C1FC00000 001C3FC00000001C3F800000001C7F800000000C7F800000000C7F800000000C7F000000 000CFF0000000000FF0000000000FF0000000000FF0000000000FF0000000000FF000000 0000FF0000000000FF0000000000FF0000000000FF0000000000FF00000000007F000000 00007F800000000C7F800000000C7F800000000C3F800000000C3FC00000000C1FC00000 001C1FC0000000180FE0000000180FE00000003807F00000003003F80000007003FC0000 00E001FC000000E000FE000001C0007F80000380001FC0000F00000FF0001E000003FE00 FC000000FFFFF00000003FFFC000000003FE00002E377CB437>IIII<000003FE000C0000003FFF801C000000FFFFE01C000003FE01F83C 00000FF0003C7C00001FC0000EFC00007F800007FC0000FE000003FC0001FC000001FC00 03FC000000FC0003F8000000FC0007F00000007C000FE00000007C000FE00000003C001F C00000003C001FC00000001C003FC00000001C003F800000001C007F800000000C007F80 0000000C007F800000000C007F000000000C00FF000000000000FF000000000000FF0000 00000000FF000000000000FF000000000000FF000000000000FF000000000000FF000000 000000FF000000000000FF000000000000FF000003FFFFE07F000003FFFFE07F800003FF FFE07F80000003FE007F80000001FC003F80000001FC003FC0000001FC001FC0000001FC 001FC0000001FC000FE0000001FC000FF0000001FC0007F0000001FC0003F8000001FC00 03FC000001FC0001FE000003FC0000FF000003FC00007F800007FC00001FC0000E7C0000 0FF0001C3C000003FE00F81C000000FFFFF00C0000003FFFC00000000003FE0000003337 7CB43C>III<007FFFFF007FFFFF007FFF FF00003FE000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001F C000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001F C000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001F C000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001F C07E001FC0FF001FC0FF001FC0FF001FC0FF001FC0FF003F80FE003F8060003F0070007F 003800FE001C01FC000F03F00003FFC00000FF000020357DB227>IIIII<000007FC00000000007FFFC000000001FC07F000000007E000FC0000 000F80003E0000003F00001F8000007E00000FC00000FC000007E00001F8000003F00003 F0000001F80003F0000001F80007E0000000FC000FE0000000FE000FC00000007E001FC0 0000007F001FC00000007F003F800000003F803F800000003F807F800000003FC07F8000 00003FC07F000000001FC07F000000001FC0FF000000001FE0FF000000001FE0FF000000 001FE0FF000000001FE0FF000000001FE0FF000000001FE0FF000000001FE0FF00000000 1FE0FF000000001FE0FF000000001FE0FF000000001FE07F000000001FC07F800000003F C07F800000003FC07F800000003FC03F800000003F803FC00000007F803FC00000007F80 1FC00000007F001FE0000000FF000FE0000000FE0007F0000001FC0007F0000001FC0003 F8000003F80001F8000003F00000FC000007E000007E00000FC000003F00001F8000001F C0007F00000007E000FC00000001FC07F0000000007FFFC00000000007FC00000033377C B43C>II82 D<001FE00300007FFC070001FFFF070007F01FCF000F8003FF 001F0000FF003E00007F003E00003F007C00001F007C00001F007800000F00F800000700 F800000700F800000700F800000700FC00000300FC00000300FE00000300FE000000007F 000000007FC00000003FF00000003FFF0000001FFFF000000FFFFF000007FFFFC00003FF FFF00000FFFFF800003FFFFC000003FFFE0000003FFF00000003FF00000000FF80000000 7F800000003F800000001FC00000000FC0C000000FC0C000000FC0C0000007C0C0000007 C0C0000007C0E0000007C0E0000007C0F000000F80F000000F80F800000F00FC00001F00 FE00003E00FF00007E00FFC000FC00F1FC03F800E0FFFFE000E01FFF8000C003FE000022 377CB42B>I<7FFFFFFFFFFE7FFFFFFFFFFE7FFFFFFFFFFE7F8007F001FE7C0007F0003E 780007F0001E700007F0000E700007F0000E600007F00006E00007F00007E00007F00007 E00007F00007C00007F00003C00007F00003C00007F00003C00007F00003C00007F00003 C00007F00003000007F00000000007F00000000007F00000000007F00000000007F00000 000007F00000000007F00000000007F00000000007F00000000007F00000000007F00000 000007F00000000007F00000000007F00000000007F00000000007F00000000007F00000 000007F00000000007F00000000007F00000000007F00000000007F00000000007F00000 000007F00000000007F00000000007F00000000007F00000000007F00000000007F00000 00000FF80000001FFFFFFC00001FFFFFFC00001FFFFFFC0030337DB237>IIII89 D<03000C07001C0E00381C00701800603800E03000C07001C0600180600180E00380C003 00C00300C00300C00300DE0378FF03FCFF83FEFF83FE7F81FE7F81FE3F00FC1E00781717 74B326>92 D<007F80000003FFF000000F80FC00001C003E00003F003F00003F801F8000 3F800FC0003F800FC0003F8007E0001F0007E000000007E000000007E000000007E00000 0007E0000001FFE000001FFFE00000FF87E00003FC07E0000FF007E0001FC007E0003F80 07E0007F8007E0007F0007E000FF0007E0C0FE0007E0C0FE0007E0C0FE0007E0C0FE000F E0C0FE000FE0C0FF001FE0C07F003BE0C03F8071F1801FC1E1FF8007FFC0FF0000FE003C 0022237DA126>97 D<03F0000000FFF0000000FFF0000000FFF000000007F000000003F0 00000003F000000003F000000003F000000003F000000003F000000003F000000003F000 000003F000000003F000000003F000000003F000000003F000000003F000000003F03F80 0003F0FFE00003F3C0F80003F7007E0003FE003F0003FC001F8003F8000FC003F0000FC0 03F00007E003F00007F003F00007F003F00003F003F00003F803F00003F803F00003F803 F00003F803F00003F803F00003F803F00003F803F00003F803F00003F803F00003F803F0 0003F003F00007F003F00007E003F00007E003F0000FC003F8000FC003FC001F8003EC00 3F0003CF007C00038381F8000301FFE00000007F000025357EB32B>I<0007F800003FFF 0000FC07C001F000E003E003F007C007F00FC007F01F8007F03F8007F03F0003E07F0000 007F0000007E000000FE000000FE000000FE000000FE000000FE000000FE000000FE0000 00FE000000FE000000FE0000007F0000007F0000003F0000183F8000181F8000381FC000 300FC0007007E000E003F001C000FC0F80003FFE000007F0001D237EA122>I<0000003F 0000000FFF0000000FFF0000000FFF000000007F000000003F000000003F000000003F00 0000003F000000003F000000003F000000003F000000003F000000003F000000003F0000 00003F000000003F000000003F000000003F000007F03F00003FFC3F0000FC0F3F0001F0 03BF0007E001FF000FC000FF001F80007F001F80003F003F00003F003F00003F007F0000 3F007E00003F00FE00003F00FE00003F00FE00003F00FE00003F00FE00003F00FE00003F 00FE00003F00FE00003F00FE00003F00FE00003F007E00003F007F00003F007F00003F00 3F00003F001F80007F001F80007F000FC000FF0007E001FF8003F007BFFC00F81E3FFC00 3FFC3FFC000FE03F0026357DB32B>I<000FE000007FFC0000F83F0003F00F8007E00FC0 0FC007E01F8003E01F8003F03F0003F03F0001F07F0001F87E0001F87E0001F8FE0001F8 FE0001F8FFFFFFF8FFFFFFF8FE000000FE000000FE000000FE000000FE0000007E000000 7F0000007F0000003F0000183F0000181F8000380F8000300FC0007007E000E001F003C0 00FC0F00003FFE000007F0001D237EA122>I<0001FC000007FF00001F0780003E0FC000 7C1FC000FC1FC001F81FC001F81FC003F8070003F0000003F0000003F0000003F0000003 F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00000FFFFF000FF FFF000FFFFF00003F0000003F0000003F0000003F0000003F0000003F0000003F0000003 F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003 F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000007 F800007FFFE0007FFFE0007FFFE0001A357FB417>I<0000001F00001FC07F8000FFF8E3 C001F07FC7C007E03F03C00FC01F83800F800F80001F800FC0001F0007C0003F0007E000 3F0007E0003F0007E0003F0007E0003F0007E0003F0007E0001F0007C0001F800FC0000F 800F80000FC01F800007E03F000007F07C00000EFFF800000C1FC000001C000000001C00 0000001C000000001E000000001E000000001F000000000FFFFE00000FFFFFC00007FFFF F00003FFFFFC0007FFFFFE001F0001FE003E00007F007C00003F007C00001F80F800000F 80F800000F80F800000F80F800000F80F800000F80FC00001F807C00001F003E00003E00 1F00007C000FC001F80003F007E00000FFFF8000001FFC000022337EA126>I<03F00000 00FFF0000000FFF0000000FFF000000007F000000003F000000003F000000003F0000000 03F000000003F000000003F000000003F000000003F000000003F000000003F000000003 F000000003F000000003F000000003F000000003F01FC00003F07FF00003F1E0FC0003F3 807C0003F7007E0003FE007E0003FC003F0003FC003F0003F8003F0003F8003F0003F000 3F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F 0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F00 03F0003F0003F0003F0003F0003F0003F0003F0007F8007F80FFFFC7FFFCFFFFC7FFFCFF FFC7FFFC26347EB32B>I<07800FC01FE01FE01FE01FE00FC00780000000000000000000 000000000000000000000007E0FFE0FFE0FFE00FE007E007E007E007E007E007E007E007 E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E00FF0FF FFFFFFFFFF10337EB215>I<0003C00007E0000FF0000FF0000FF0000FF00007E00003C0 0000000000000000000000000000000000000000000000000000000000000003F000FFF0 00FFF000FFF00007F00003F00003F00003F00003F00003F00003F00003F00003F00003F0 0003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F0 0003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F0 0003F03803F07C03F0FE03E0FE07E0FE07C0FE0FC07C0F80381F001FFC0007F000144384 B217>I<03F0000000FFF0000000FFF0000000FFF000000007F000000003F000000003F0 00000003F000000003F000000003F000000003F000000003F000000003F000000003F000 000003F000000003F000000003F000000003F000000003F000000003F000000003F003FF E003F003FFE003F003FFE003F001FF0003F000F80003F001E00003F001C00003F0038000 03F00F000003F01C000003F038000003F070000003F0F0000003F3F8000003F7FC000003 FEFC000003FC7E000003F87F000003F03F800003F01F800003F00FC00003F00FE00003F0 07E00003F003F00003F003F80003F001F80003F000FC0003F000FE0007F800FF80FFFFC3 FFF0FFFFC3FFF0FFFFC3FFF024347EB329>I<07E0FFE0FFE0FFE00FE007E007E007E007 E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007 E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007 E007E007E007E00FF0FFFFFFFFFFFF10347EB315>I<03F01FE000FF0000FFF07FF803FF C000FFF1E07C0F03E000FFF3803E1C01F00007F7003F3801F80003FE003F7001F80003FC 001FE000FC0003FC001FE000FC0003F8001FC000FC0003F8001FC000FC0003F0001F8000 FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0 001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000 FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0 001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000 FC0007F8003FC001FE00FFFFC7FFFE3FFFF0FFFFC7FFFE3FFFF0FFFFC7FFFE3FFFF03C21 7EA041>I<03F01FC000FFF07FF000FFF1E0FC00FFF3807C0007F7007E0003FE007E0003 FC003F0003FC003F0003F8003F0003F8003F0003F0003F0003F0003F0003F0003F0003F0 003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F000 3F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F 0003F0003F0007F8007F80FFFFC7FFFCFFFFC7FFFCFFFFC7FFFC26217EA02B>I<0007F0 0000003FFE000000FC1F800001F007C00003C001E00007C001F0000F8000F8001F00007C 001F00007C003F00007E003E00003E007E00003F007E00003F007E00003F00FE00003F80 FE00003F80FE00003F80FE00003F80FE00003F80FE00003F80FE00003F80FE00003F807E 00003F007E00003F007E00003F003F00007E003F00007E001F00007C001F8000FC000FC0 01F80007C001F00003F007E00000FC1F8000003FFE00000007F0000021237EA126>I<03 F03F8000FFF0FFE000FFF3C0F800FFF7007E0007FE003F0003FC001F8003F8001FC003F0 000FC003F0000FE003F00007F003F00007F003F00007F003F00003F803F00003F803F000 03F803F00003F803F00003F803F00003F803F00003F803F00003F803F00003F803F00007 F803F00007F003F00007F003F00007E003F0000FE003F0000FC003F8001FC003FC003F80 03FC003F0003FF00FC0003F381F80003F1FFE00003F07F000003F000000003F000000003 F000000003F000000003F000000003F000000003F000000003F000000003F000000003F0 00000007F8000000FFFFC00000FFFFC00000FFFFC0000025307EA02B>I<03E07C00FFE1 FF00FFE38F80FFE71FC007EE1FC003EC1FC003EC1FC003FC0F8003F8000003F8000003F8 000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0 000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0 000007F80000FFFFE000FFFFE000FFFFE0001A217FA01E>114 D<00FF060007FFCE001F 00FE003C003E0078001E0078000E00F0000E00F0000600F0000600F8000600F8000600FE 000000FF8000007FFC00003FFFC0003FFFF0000FFFF80007FFFC0000FFFE00000FFF0000 00FF0000003F80C0001F80C0000F80E0000780E0000780E0000780F0000780F0000700F8 000F00FC000E00FE001C00F7807800E1FFE000C07F800019237EA11E>I<003000003000 00300000300000300000700000700000700000F00000F00001F00001F00003F00007F000 1FFFFEFFFFFEFFFFFE03F00003F00003F00003F00003F00003F00003F00003F00003F000 03F00003F00003F00003F00003F00003F00003F00303F00303F00303F00303F00303F003 03F00303F00303F00701F80601F80600FC0E007E1C001FF80007E0182F7FAD1E>I<03F0 003F00FFF00FFF00FFF00FFF00FFF00FFF0007F0007F0003F0003F0003F0003F0003F000 3F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F 0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F00 03F0003F0003F0003F0003F0007F0003F0007F0003F0007F0003F000FF0001F000FF0001 F801FF8000F803BFFC007E073FFC001FFE3FFC0007F83F0026227EA02B>IIII<7FFF807F F87FFF807FF87FFF807FF807F8001FC003F8000F8001F800070001F800060000FC000C00 00FC000C0000FE001C00007E001800007E001800003F003000003F003000003F80700000 1F806000001FC0E000000FC0C000000FC0C0000007E180000007E180000007F380000003 F300000003FB00000001FE00000001FE00000000FC00000000FC00000000FC0000000078 0000000078000000003000000000300000000060000000006000000000E000000000C000 000000C0000000018000007801800000FC03000000FC03000000FC06000000FC0E000000 701C00000078380000001FF00000000FC000000025307F9F29>I<3FFFFFF03FFFFFF03F 000FF03C000FE038001FC030003F8070007F8070007F006000FE006001FC006003FC0060 03F8000007F000000FE000000FE000001FC000003F8000007F0000007F003000FE003001 FC003003FC003003F8003007F000700FE000701FE000601FC000E03F8000E07F0003E0FF 000FE0FFFFFFE0FFFFFFE01C207E9F22>II E /Fs 8 54 df<000C0038007000E001C00380030007000E000E001C001C003800380038 007800700070007000F000F000F000F000F000F000F000F000F000F000F0007000700070 0078003800380038001C001C000E000E0007000300038001C000E000700038000C0E317A A418>40 DI<00FF0003FFC00781E00F00F01E00783C003C3C003C78001E78001E78001E78001EF8 001FF8001FF8001FF8001FF8001FF8001FF8001FF8001FF8001FF8001FF8001FF8001FF8 001F78001E78001E7C003E3C003C3C003C1E00780F00F00781E003FFC000FF0018227DA0 1E>48 D<00E00001E00007E000FFE000F9E00001E00001E00001E00001E00001E00001E0 0001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E0 0001E00001E00001E00001E00001E00001E00001E00003F000FFFFC0FFFFC012217AA01E >I<01FC0007FF801C0FC03003E06001F06000F8F800F8FC00FCFC00FCFC007C78007C30 00FC0000FC0000F80000F80001F00003E00003C0000780000F00001E0000380000700000 E00001C00C03800C0600180C00181800183FFFF87FFFF8FFFFF0FFFFF016217CA01E>I< 00FF0003FFC00F03E01C00F01C00F83E00FC3E007C3E007C1E00FC0C00FC0000F80000F8 0001F00003E0000FC001FF0001FF000003E00000F000007800007C00003E00003F30003F 78003FFC003FFC003FFC003EF8007E60007C3800F81E03F00FFFC001FF0018227DA01E> I<0000E00001E00001E00003E00007E00007E0000DE0001DE00039E00031E00061E000E1 E000C1E00181E00381E00701E00601E00C01E01C01E01801E03001E07001E0E001E0FFFF FFFFFFFF0001E00001E00001E00001E00001E00001E00003F0003FFF003FFF18227DA11E >I<1000301E01F01FFFE01FFFC01FFF801FFE001BF00018000018000018000018000018 000018FE001BFF801F03C01C01E01800F01800F800007800007800007C00007C30007C78 007CF8007CF8007CF80078F000F86000F07001E03801E01E078007FF0001F80016227CA0 1E>I E /Ft 7 117 df<000001800000038000000780000007000000070000000F000000 0E0000001E0000001C0000001C0000003C00000038000000780000007000000070000000 F0000000E0000000E0000001E0000001C0000003C0000003800000038000000780000007 0000000F0000000E0000000E0000001E0000001C0000003C000000380000003800000078 00000070000000F0000000E0000000E0000001E0000001C0000003C00000038000000380 00000780000007000000070000000F0000000E0000001E0000001C0000001C0000003C00 000038000000780000007000000070000000F0000000E0000000E0000000193B7CAB22> 61 D<000300000003000000030000000300000003000000078000000780000007800000 07800000078000C007800CFC0780FC7FE79FF80FFFFFC003FFFF0000FFFC00003FF00000 1FE000003FF000003FF000007CF8000078780000F87C0000F03C0001E01E0003C00F0003 80070007000380060001801E1D7E9C22>63 D<000E00001F00003F00003F00003E00001C 0000000000000000000000000000000000000000000003E00007F0000C7800187C00307C 00307C00607C0060F800C0F800C0F80001F00001F00001F00003E00003E00007C00007C0 0007C1800F81800F81801F03001F03001F06000F0C000F1C0007F00003E00011287DA617 >105 D<0000070000000F8000001F8000001F8000001F0000000E000000000000000000 00000000000000000000000000000000000000000003E0000007F800000C3C0000183C00 00303E0000603E0000C03E0000C03E0001807C0001807C0000007C0000007C000000F800 0000F8000000F8000000F8000001F0000001F0000001F0000001F0000003E0000003E000 0003E0000003E0000007C0000007C0000007C0000007C000000F8000000F8000380F8000 7C1F0000FC1F0000FC3E0000F87C000070F800007FE000001F800000193380A61B>I<07 801FC007E0000FE07FF01FF80018F0E0F8783C0030F1807CE03E0030FB007D801E0060FE 003F001E0060FC003F001E0060F8003E001E00C1F8007C003E00C1F0007C003E0001F000 7C003E0001F0007C003E0003E000F8007C0003E000F8007C0003E000F8007C0003E000F8 00F80007C001F000F80007C001F000F83007C001F001F03007C001F001F0300F8003E003 E0600F8003E003E0600F8003E003E0C00F8003E001E1801F0007C001E3801F0007C000FF 000E000380007C00341B7D993B>109 D<000FE0007FF800F03C01C00E03C01E07803E07 803E07803C0F80180FE00007FF0007FFC003FFE001FFF000FFF80007F80001F83C00F87E 00787E0078FC00F0F800F07001E07003C03C0F801FFE0007F800171B7C991F>115 D<001C00003E00003E00007C00007C00007C00007C0000F80000F80000F80000F80001F0 00FFFFE0FFFFE001F00003E00003E00003E00003E00007C00007C00007C00007C0000F80 000F80000F80000F80001F00001F00601F00601F00C03E00C03E01803E03001E06001F1C 000FF80003E00013267EA419>I E /Fu 12 58 df<0006000C00180030006000E001C003 80038007000F000E001E001E001C003C003C003C0078007800780078007800F800F000F0 00F000F000F000F000F000F000F000F000F000F800780078007800780078003C003C003C 001C001E001E000E000F0007000380038001C000E0006000300018000C00060F3B7AAB1A >40 DI<003F800001FFF00003E0F80007803C00 0F001E001E000F003E000F803E000F803C0007807C0007C07C0007C07C0007C07C0007C0 FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0 FC0007E0FC0007E0FC0007E0FC0007E0FC0007E07C0007C07C0007C07C0007C03E000F80 3E000F803E000F801F001F000F001E0007803C0003E0F80001FFF000003F80001B277EA5 21>48 D<00380000780001F8001FF800FEF800E0F80000F80000F80000F80000F80000F8 0000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F8 0000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F8 0001FC00FFFFF8FFFFF815267BA521>I<00FF000003FFE0000E03F0001800F80030007C 0060007E0078003F00FC003F00FE001F80FE001F80FE001F80FE001F807C001F8000001F 8000001F0000003F0000003E0000007E0000007C000000F8000001F0000003E0000003C0 0000078000000E0000001C0000003800000070018000E001800180018003000300060003 000C0003001FFFFF003FFFFF007FFFFE00FFFFFE00FFFFFE0019267DA521>I<00FF0000 03FFE0000F01F8001C007C0030007E003C003E007E003F007E003F007E003F007E003F00 3C003F0000003E0000007E0000007C000000F8000001F0000007E00001FF800001FF0000 0001E0000000F00000007C0000003E0000003F0000001F0000001F8000001F8038001F80 7C001F80FE001F80FE001F80FE001F00FC003F0078003E0070007C003800F8001F01F000 07FFC00000FF000019277DA521>I<0000380000003800000078000000F8000001F80000 01F8000003F8000007F8000006F800000CF800001CF8000018F8000030F8000070F80000 60F80000C0F80001C0F8000180F8000300F8000700F8000E00F8000C00F8001C00F80038 00F8003000F8006000F800E000F800FFFFFFE0FFFFFFE00000F8000000F8000000F80000 00F8000000F8000000F8000000F8000001FC00003FFFE0003FFFE01B277EA621>I<1800 0C001F007C001FFFF8001FFFF0001FFFE0001FFF800019FC000018000000180000001800 000018000000180000001800000018000000187F000019FFE0001F81F0001E0078001C00 3C0018003E0000003E0000001F0000001F0000001F8000001F8030001F807C001F80FC00 1F80FC001F80FC001F80FC001F00F0001F0060003E0070003E0030007C001C00F8000F03 E00003FFC00000FE000019277DA521>I<000FE000003FF80000F81C0001E0060003C01F 0007803F000F003F001F003F001E003F003E001E003E0000007C0000007C0000007C0400 007C3FC000FCFFF000FDC07800FF003C00FF003E00FE001E00FE001F00FE001F00FC001F 80FC001F80FC001F80FC001F807C001F807C001F807C001F807C001F803C001F003E001F 001E001E001E003E000F003C000780780003C1F00001FFC000007F000019277DA521>I< 300000003C0000003FFFFFE03FFFFFE03FFFFFC07FFFFF807FFFFF807000070060000E00 60000C00C0001C00C0003800C00070000000E0000000C0000001C0000003800000038000 00070000000F0000000E0000001E0000001E0000001E0000003E0000003C0000003C0000 007C0000007C0000007C0000007C000000FC000000FC000000FC000000FC000000FC0000 00FC000000FC000000FC0000007800001B287DA621>I<007F000003FFE0000781F8000E 007C001C001E0038001E0038000F0078000F0078000F0078000F007C000F007E001E003F 801E003FE03C001FF078000FFCF00007FFC00003FF800000FFE00001FFF000079FFC000F 07FE001E03FE003C00FF0078003F0078001F80F0000F80F0000F80F0000780F0000780F0 000780F00007007800070078000E003C001C001E0038000F80F00003FFE000007F000019 277DA521>I<007F000001FFC00007C1E0000F0070001E0078003E003C003C003E007C00 1E007C001E00FC001F00FC001F00FC001F00FC001F00FC001F80FC001F80FC001F80FC00 1F807C003F807C003F803C003F803E007F801E007F800F01DF8007FF9F8001FE1F800010 1F0000001F0000001F0000003E003C003E007E003C007E003C007E0078007E00F0007C00 E0003003C0001C0780000FFF000003F8000019277DA521>I E /Fv 79 123 df<00000FF800FC0000007FFF07FF000001F807DF83C00007E001FF0FC0001F80 07FE1FE0003F000FFC1FE0007E000FFC1FE0007E000FF81FE000FC000FF81FE000FC000F F0078001F80007F0000001F80003F0000001F80003F0000001F80003F0000001F80003F0 000001F80003F0000001F80003F0000001F80003F0000001F80003F0000001F80003F000 0001F80003F0000001F80003F0000001F80003F00000FFFFFFFFFFF800FFFFFFFFFFF800 FFFFFFFFFFF80001F80003F0000001F80003F0000001F80003F0000001F80003F0000001 F80003F0000001F80003F0000001F80003F0000001F80003F0000001F80003F0000001F8 0003F0000001F80003F0000001F80003F0000001F80003F0000001F80003F0000001F800 03F0000001F80003F0000001F80003F0000001F80003F0000001F80003F0000001F80003 F0000001F80003F0000001F80003F0000001F80003F0000001F80003F0000001F80003F0 000001F80003F0000001F80003F0000001F80003F0000001F80003F0000003FC0007F800 007FFFE0FFFFF0007FFFE0FFFFF0007FFFE0FFFFF000333B7FBA30>11 D<00000FF8000000007FFE00000001F80780000007E001C000001F8000E000003F0007E0 00007E000FF000007E000FF00000FC000FF00000FC000FF00001F8000FF00001F80007E0 0001F80001800001F80000000001F80000000001F80000000001F80000000001F8000000 0001F80000000001F80000000001F80000000001F80000000001F80003F000FFFFFFFFF0 00FFFFFFFFF000FFFFFFFFF00001F8000FF00001F80003F00001F80003F00001F80003F0 0001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F0 0001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F0 0001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F0 0001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F0 0001F80003F00003FC0007F8007FFFE0FFFFC07FFFE0FFFFC07FFFE0FFFFC02A3B7FBA2E >I<00000FFC000000007FFF70000001F803F0000007E007F000001F800FF000003F000F F000007E000FF000007E000FF00000FC000FF00000FC0007F00001F80003F00001F80003 F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003 F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F000FFFFFFFF F000FFFFFFFFF000FFFFFFFFF00001F80003F00001F80003F00001F80003F00001F80003 F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003 F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003 F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003 F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003 F00001F80003F00003FC0007F8007FFFE0FFFFC07FFFE0FFFFC07FFFE0FFFFC02A3B7FBA 2E>I<00000FF0001FF0000000007FFE00FFFC00000001F80F83F00F00000007E001CFC0 038000001F8000FF0001C000003F0007FE000FC000007E000FFC001FE000007E000FFC00 1FE00000FC000FF8001FE00000FC000FF8001FE00001F8000FF0001FE00001F80007F000 0FC00001F80003F00003000001F80003F00000000001F80003F00000000001F80003F000 00000001F80003F00000000001F80003F00000000001F80003F00000000001F80003F000 00000001F80003F00000000001F80003F00000000001F80003F00007E000FFFFFFFFFFFF FFE000FFFFFFFFFFFFFFE000FFFFFFFFFFFFFFE00001F80003F0001FE00001F80003F000 07E00001F80003F00007E00001F80003F00007E00001F80003F00007E00001F80003F000 07E00001F80003F00007E00001F80003F00007E00001F80003F00007E00001F80003F000 07E00001F80003F00007E00001F80003F00007E00001F80003F00007E00001F80003F000 07E00001F80003F00007E00001F80003F00007E00001F80003F00007E00001F80003F000 07E00001F80003F00007E00001F80003F00007E00001F80003F00007E00001F80003F000 07E00001F80003F00007E00001F80003F00007E00001F80003F00007E00001F80003F000 07E00001F80003F00007E00001F80003F00007E00001F80003F00007E00003FC0007F800 0FF0007FFFE0FFFFC1FFFF807FFFE0FFFFC1FFFF807FFFE0FFFFC1FFFF80413B7FBA45> I<000380000003800000038000000FF000007FFE0001FFFF8003F38FC007C381E00F8380 F01F0380383E0380383C03801C7C03800C7C03800E7803803EF80380FEF80381FEF80381 FEF80381FEF80381FEFC0380FCFC038078FE038000FF0380007F0380007FC380007FE380 003FFF80001FFFC0001FFFF8000FFFFE0007FFFF8001FFFFC000FFFFE0003FFFF00003FF F00003BFF800038FF8000383FC000381FC000381FC000380FE0003807E3C03807EFF0380 7EFF03803EFF03803EFF03803EFF03803EFE03803EF803803CE003807C6003807C700380 78700380F8380380F03C0381F01E0383E00F0387C007E39F8001FFFE0000FFFC00001FE0 00000380000003800000038000000380001F437BBD2A>36 D<007C00000000600001FF00 000000F00007C380000001F0000F81C0000003F0000F00E0000007E0001E007800000FC0 003E003C00001FC0003C003F00007F80007C001BE003FF00007C0018FFFFBF0000780018 1FFC3E0000F8001C00007C0000F8000C0000FC0000F8000C0000F80000F8000C0001F000 00F8000C0003F00000F8000C0003E00000F8000C0007C00000F8000C000FC00000F8000C 000F800000F8000C001F000000F8001C003F000000780018003E0000007C0018007C0000 007C001800FC0000003C003800F80000003E003001F00000001E007003F00000000F00E0 03E00000000F81C007C000000007C3800FC000000001FF000F80000000007C001F000000 000000003F0007C0000000003E001FF0000000007C003C3800000000FC00F81C00000000 F800F00E00000001F001E00600000003F003E00700000003E003C00300000007C007C003 8000000FC007C0018000000F8007C0018000001F00078001C000003F000F8000C000003E 000F8000C000007C000F8000C00000FC000F8000C00000F8000F8000C00001F0000F8000 C00003F0000F8000C00003E0000F8000C00007C0000F8000C0000FC0000F8000C0000F80 00078001C0001F000007C00180003F000007C00180003E000007C00380007C000003C003 0000FC000003E0070000F8000001E0060001F0000000F00E0003F0000000F81C0003E000 00003C380003C00000001FF000018000000007C0003A437BBD45>I<1C007F00FF80FF80 FFC0FFC0FFC07FC01CC000C000C000C000C001C00180018003800300070006000E001C00 3800700060000A1979B917>39 D<0000600000E00001C0000380000700000E00001E0000 3C0000780000780000F00001E00001E00003C00003C00007C0000780000F80000F00000F 00001F00001E00001E00003E00003E00003E00007C00007C00007C00007C00007C00007C 0000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F8 0000F80000F80000F80000F80000F80000F800007C00007C00007C00007C00007C00007C 00003E00003E00003E00001E00001E00001F00000F00000F00000F800007800007C00003 C00003C00001E00001E00000F000007800007800003C00001E00000E0000070000038000 01C00000E0000060135278BD20>II<0000003000000000000078000000000000780000 000000007800000000000078000000000000780000000000007800000000000078000000 000000780000000000007800000000000078000000000000780000000000007800000000 000078000000000000780000000000007800000000000078000000000000780000000000 007800000000000078000000000000780000000000007800000000000078000000000000 78000000000000780000007FFFFFFFFFFFF8FFFFFFFFFFFFFCFFFFFFFFFFFFFC7FFFFFFF FFFFF8000000780000000000007800000000000078000000000000780000000000007800 000000000078000000000000780000000000007800000000000078000000000000780000 000000007800000000000078000000000000780000000000007800000000000078000000 000000780000000000007800000000000078000000000000780000000000007800000000 000078000000000000780000000000007800000000000078000000000000300000003636 7BAF41>43 D<1C007F00FF80FF80FFC0FFC0FFC07FC01CC000C000C000C000C001C00180 018003800300070006000E001C003800700060000A19798817>II<1C007F00FF80FF80FF80FF80FF807F001C000909798817> I<0000000C0000001E0000003E0000003E0000003C0000007C0000007C00000078000000 F8000000F8000000F0000001F0000001F0000001E0000003E0000003E0000003C0000007 C0000007C00000078000000F8000000F8000000F0000001F0000001F0000001E0000003E 0000003E0000003C0000007C0000007C00000078000000F8000000F8000000F0000001F0 000001F0000001E0000003E0000003E0000007C0000007C00000078000000F8000000F80 00000F0000001F0000001F0000001E0000003E0000003E0000003C0000007C0000007C00 000078000000F8000000F8000000F0000001F0000001F0000001E0000003E0000003E000 0003C0000007C0000007C00000078000000F8000000F8000000F0000001F0000001F0000 001E0000003E0000003E0000003C0000007C0000007C00000078000000F8000000F80000 00F0000000600000001F537BBD2A>I<0003F80000001FFF0000007E0FC00000F803E000 01E000F00003C000780007C0007C000F80003E000F80003E001F00001F001F00001F003F 00001F803F00001F803F00001F807E00000FC07E00000FC07E00000FC07E00000FC07E00 000FC07E00000FC0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE0000 0FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000F E0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE07E00000FC0 7E00000FC07E00000FC07E00000FC07F00001FC03F00001F803F00001F803F00001F801F 00001F001F80003F000F80003E000F80003E0007C0007C0003E000F80001F001F00000F8 03E000007E0FC000001FFF00000003F80000233A7DB72A>I<0001C0000003C0000007C0 00001FC00000FFC000FFFFC000FFFFC000FF1FC000001FC000001FC000001FC000001FC0 00001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0 00001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0 00001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0 00001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0 00001FC000001FC000001FC000001FC000003FE0007FFFFFF07FFFFFF07FFFFFF01C3879 B72A>I<000FF00000007FFE000001FFFF800003E03FE0000F000FF0000E0007F8001C00 03FC00380001FE00300001FE00700000FF00600000FF00FC0000FF00FF00007F80FF8000 7F80FF80007F80FF80007F80FF80007F80FF80007F807F00007F801C00007F800000007F 80000000FF00000000FF00000000FF00000001FE00000001FC00000003FC00000003F800 000007F000000007E00000000FE00000001FC00000003F800000003F000000007C000000 00F800000001F000000003E000000007C00000000F800000000F000000001E000180003C 000180007800018000F000038001E000030003C000030007800003000E000007000FFFFF FF001FFFFFFF003FFFFFFF007FFFFFFE00FFFFFFFE00FFFFFFFE00FFFFFFFE0021387CB7 2A>I<0007F80000003FFF0000007FFFC00001F80FF00003C007F800078003FC000E0001 FC000F0001FE001FE000FE001FF000FF001FF000FF001FF000FF001FF000FF001FF000FF 000FE000FF0007C000FF00000000FE00000001FE00000001FE00000001FC00000003F800 000003F800000007F000000007E00000000F800000007E0000001FFC0000001FFF800000 000FE000000007F000000001FC00000001FE00000000FF000000007F800000007F800000 007FC00000007FC00000003FC00000003FE00000003FE01E00003FE07F80003FE0FFC000 3FE0FFC0003FE0FFC0003FE0FFC0003FE0FFC0003FC0FF80007FC07F80007F807E00007F 80700000FF00380001FE001E0001FE000F8003F80007F00FF00001FFFFC000007FFF0000 000FF80000233A7DB72A>I<000000380000000038000000007800000000F800000000F8 00000001F800000003F800000007F800000007F80000000FF80000001FF80000001BF800 000033F800000073F800000063F8000000C3F8000001C3F800000183F800000303F80000 0703F800000603F800000C03F800001C03F800001803F800003003F800007003F8000060 03F80000C003F80001C003F800038003F800030003F800070003F8000E0003F8000C0003 F800180003F800380003F800300003F800600003F800E00003F800FFFFFFFFF8FFFFFFFF F8FFFFFFFFF8000003F800000003F800000003F800000003F800000003F800000003F800 000003F800000003F800000003F800000003F800000003F800000007FC000003FFFFF800 03FFFFF80003FFFFF825397EB82A>I<0600000C000780003C0007F003F80007FFFFF800 07FFFFF00007FFFFE00007FFFF800007FFFF000007FFFC0000067FE00000060000000006 000000000600000000060000000006000000000600000000060000000006000000000600 000000060000000006000000000607F80000063FFE000006780F800007E007E000078003 F000070001F800060001F800060000FC00000000FE00000000FE00000000FF000000007F 000000007F000000007F800000007F800000007F800000007F803E00007F807F00007F80 FF80007F80FF80007F80FF80007F80FF80007F80FF00007F00FE0000FF00E00000FF0060 0000FE00700000FE00300001FC00380001F8001C0003F8001E0007F0000F800FE00007E0 3F800001FFFF0000007FFC0000001FE00000213A7CB72A>I<00003FC0000001FFF00000 07FFFC00000FE03E00003F800700007E001F0000FC003F8001F8007F8003F0007F8003F0 007F8007E0007F800FE0003F000FC0001E001FC00000001FC00000003F800000003F8000 00003F800000007F800000007F000000007F01FC00007F07FF8000FF1E07E000FF3801F0 00FF7000F800FF6000FC00FFE0007E00FFC0003F00FFC0003F00FF80003F80FF80003FC0 FF80001FC0FF80001FC0FF00001FE0FF00001FE0FF00001FE0FF00001FE0FF00001FE07F 00001FE07F00001FE07F00001FE07F00001FE07F00001FE03F80001FE03F80001FC03F80 001FC01F80001FC01F80003F801FC0003F800FC0003F0007E0007F0007E000FE0003F000 FC0001F801F80000FE07F000003FFFC000001FFF00000003FC0000233A7DB72A>I<3000 00000038000000003E000000003FFFFFFFE03FFFFFFFE03FFFFFFFE03FFFFFFFC07FFFFF FFC07FFFFFFF807FFFFFFF0070000006006000000E006000001C006000001800E0000038 00C000007000C00000E000C00000C000000001C000000003800000000300000000070000 00000E000000000C000000001C0000000038000000003800000000700000000070000000 00F000000001E000000001E000000003E000000003E000000003C000000007C000000007 C00000000FC00000000FC00000000FC00000001F800000001F800000001F800000003F80 0000003F800000003F800000003F800000003F800000007F800000007F800000007F8000 00007F800000007F800000007F800000007F800000007F800000007F800000003F000000 001E000000233B7BB82A>I<0003F80000001FFF0000007FFFC00000FC07F00001E001F8 0003C000FC000780007C000700003E000F00001E000E00001F001E00000F001E00000F00 1E00000F001F00000F001F00000F001F80000F001F80001F001FE0001E000FF0003E000F FC003C000FFE00780007FF80F00007FFC1E00003FFF3C00001FFFF000000FFFE0000003F FF0000001FFFC000001FFFE000007FFFF80000F0FFFC0003E07FFE0007801FFF000F000F FF801F0003FF803E0001FFC03C00007FC07C00003FC07800000FE0F8000007E0F0000007 E0F0000003E0F0000003E0F0000001E0F0000001E0F0000001E0F8000001C078000001C0 78000003C07C000003803E000007001F00000F000F80001E0007E0007C0003F803F00000 FFFFE000003FFF80000007FC0000233A7DB72A>I<0003F80000001FFF0000007FFFC000 00FC07E00003F803F00007F001F8000FE000FC000FC0007E001FC0007E003F80003F003F 80003F007F80003F807F00003F807F00003F80FF00001FC0FF00001FC0FF00001FC0FF00 001FC0FF00001FC0FF00001FC0FF00001FE0FF00001FE0FF00001FE0FF00001FE0FF0000 1FE07F00003FE07F00003FE07F80003FE03F80003FE01F80007FE01F80007FE00FC000FF E007E000DFE003E001DFE001F0039FE000FC0F1FE0003FFC1FC00007F01FC00000001FC0 0000003FC00000003F800000003F800000003F800000003F000000007F000F00007E001F 80007E003FC000FC003FC000FC003FC001F8003FC003F0003F8007E0001F000FC0001C00 1F80000F807F000007FFFC000001FFF00000003FC00000233A7DB72A>I<1C007F00FF80 FF80FF80FF80FF807F001C00000000000000000000000000000000000000000000000000 0000000000000000000000001C007F00FF80FF80FF80FF80FF807F001C00092479A317> I<1C007F00FF80FF80FF80FF80FF807F001C000000000000000000000000000000000000 000000000000000000000000000000000000001C007F00FF00FF80FF80FF80FF807F801D 8001800180018001800380030003000700060006000E001C001800380070006000093479 A317>I<7FFFFFFFFFFFF8FFFFFFFFFFFFFCFFFFFFFFFFFFFCFFFFFFFFFFFFFC00000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000FFFFFFFFFFFFFCFFFFFFFFFFFFFC FFFFFFFFFFFFFC7FFFFFFFFFFFF836167B9F41>61 D<0000003800000000000038000000 000000380000000000007C0000000000007C0000000000007C000000000000FE00000000 0000FE000000000000FE000000000001FF000000000001FF000000000001FF0000000000 037F8000000000037F8000000000077FC000000000063FC000000000063FC0000000000E 3FE0000000000C1FE0000000000C1FE0000000001C1FF000000000180FF000000000180F F000000000380FF8000000003007F8000000003007F8000000007007FC000000006003FC 000000006003FC00000000C003FE00000000C001FE00000000C001FE000000018001FF00 0000018000FF000000018000FF000000030000FF8000000300007F8000000300007F8000 000600007FC0000007FFFFFFC0000007FFFFFFC000000FFFFFFFE000000C00001FE00000 0C00001FE000001800000FF000001800000FF000001800000FF0000030000007F8000030 000007F8000030000007F8000060000003FC000060000003FC0000E0000003FC0000E000 0001FE0001E0000001FE0003F0000001FF000FFC000007FF80FFFF8000FFFFFEFFFF8000 FFFFFEFFFF8000FFFFFE373C7DBB3E>65 DI<000001FF80018000 000FFFE0038000007FFFF803800001FF807E07800003FC000F0F80000FF000039F80001F E00001DF80003F800000FF80007F0000007F8000FE0000003F8001FE0000003F8003FC00 00001F8007F80000000F8007F80000000F800FF000000007800FF000000007801FE00000 0007801FE000000003803FE000000003803FC000000003807FC000000001807FC0000000 01807FC000000001807F800000000180FF800000000000FF800000000000FF8000000000 00FF800000000000FF800000000000FF800000000000FF800000000000FF800000000000 FF800000000000FF800000000000FF800000000000FF800000000000FF8000000000007F 8000000000007FC000000001807FC000000001807FC000000001803FC000000001803FE0 00000001801FE000000003801FE000000003000FF000000003000FF0000000070007F800 0000070007F8000000060003FC0000000E0001FE0000001C0000FE0000001800007F0000 003800003F8000007000001FE00000E000000FF00003C0000003FC000F80000001FF803F 000000007FFFFC000000000FFFF00000000001FF800000313D7BBA3C>IIII<000000FF8000C000000FFFF001C000003FFFFC01C00000FF803F03C00003FC0007 87C0000FF00003CFC0001FE00000EFC0003FC000007FC0007F8000003FC000FF0000001F C001FE0000001FC003FC0000000FC007F800000007C007F800000007C00FF000000003C0 0FF000000003C01FE000000003C01FE000000001C03FE000000001C03FC000000001C07F C000000000C07FC000000000C07FC000000000C07FC000000000C0FF800000000000FF80 0000000000FF800000000000FF800000000000FF800000000000FF800000000000FF8000 00000000FF800000000000FF800000000000FF800000000000FF800000000000FF800000 FFFFFFFF800000FFFFFF7FC00000FFFFFF7FC00000007FE07FC00000003FC07FC0000000 3FC03FC00000003FC03FE00000003FC01FE00000003FC01FE00000003FC00FF00000003F C00FF00000003FC007F80000003FC007F80000003FC003FC0000003FC001FE0000003FC0 00FF0000007FC0007F8000007FC0003FC00000FFC0001FE00000EFC0000FF80003C7C000 03FE000783C00000FFC03F01C000003FFFFC00C000000FFFF00000000000FF800000383D 7CBA41>III<003F FFFFE0003FFFFFE0003FFFFFE000001FFC00000007F800000007F800000007F800000007 F800000007F800000007F800000007F800000007F800000007F800000007F800000007F8 00000007F800000007F800000007F800000007F800000007F800000007F800000007F800 000007F800000007F800000007F800000007F800000007F800000007F800000007F80000 0007F800000007F800000007F800000007F800000007F800000007F800000007F8000000 07F800000007F800000007F800000007F800000007F800000007F800000007F8003F0007 F8007F8007F800FFC007F800FFC007F800FFC007F800FFC007F800FFC00FF000FF800FF0 007F000FE00070001FE00038001FC0001C003F80000E007F00000781FC000001FFF00000 007F800000233B7DB82B>IIIII<000003FF00000000001FFFE00000 0000FE01FC00000001F8007E00000007E0001F8000000FC0000FC000003F800007F00000 7F000003F80000FE000001FC0001FC000000FE0001F80000007E0003F80000007F0007F0 0000003F8007F00000003F800FE00000001FC00FE00000001FC01FE00000001FE01FC000 00000FE03FC00000000FF03FC00000000FF03FC00000000FF07FC00000000FF87F800000 0007F87F8000000007F87F8000000007F8FF8000000007FCFF8000000007FCFF80000000 07FCFF8000000007FCFF8000000007FCFF8000000007FCFF8000000007FCFF8000000007 FCFF8000000007FCFF8000000007FCFF8000000007FCFF8000000007FC7F8000000007F8 7FC00000000FF87FC00000000FF87FC00000000FF83FC00000000FF03FC00000000FF01F E00000001FE01FE00000001FE01FE00000001FE00FF00000003FC007F00000003F8007F8 0000007F8003F80000007F0001FC000000FE0001FC000000FE0000FE000001FC00007F00 0003F800003F800007F000001FC0000FE0000007E0001F80000003F8007F00000000FE01 FC000000001FFFE00000000003FF000000363D7BBA41>II82 D<000FF800C0003FFE01C000 FFFF81C003F807E3C007E000F7C00FC0007FC01F80003FC03F00001FC03E00000FC07E00 0007C07E000007C07C000003C0FC000003C0FC000001C0FC000001C0FC000001C0FE0000 00C0FE000000C0FE000000C0FF000000C0FF800000007FC00000007FE00000007FF80000 003FFF8000001FFFF800001FFFFF80000FFFFFE00007FFFFF80003FFFFFE0000FFFFFF00 003FFFFF800007FFFFC000007FFFC0000007FFE00000007FE00000003FF00000001FF000 00000FF000000007F800000007F8C0000003F8C0000003F8C0000001F8C0000001F8C000 0001F8E0000001F8E0000001F8E0000001F0F0000001F0F0000003F0F8000003E0FC0000 07E0FE000007C0FF00000FC0FF80001F80FBF0003F00F0FE00FE00E03FFFF800E00FFFE0 00C001FF0000253D7CBA2E>I<3FFFFFFFFFFFE03FFFFFFFFFFFE03FFFFFFFFFFFE03FC0 03FF001FE03E0001FE0003E07C0001FE0001F0780001FE0000F0700001FE000070700001 FE000070700001FE000070600001FE000030600001FE000030600001FE000030600001FE 000030E00001FE000038C00001FE000018C00001FE000018C00001FE000018C00001FE00 0018000001FE000000000001FE000000000001FE000000000001FE000000000001FE0000 00000001FE000000000001FE000000000001FE000000000001FE000000000001FE000000 000001FE000000000001FE000000000001FE000000000001FE000000000001FE00000000 0001FE000000000001FE000000000001FE000000000001FE000000000001FE0000000000 01FE000000000001FE000000000001FE000000000001FE000000000001FE000000000001 FE000000000001FE000000000001FE000000000001FE000000000001FE000000000001FE 000000000001FE000000000001FE000000000001FE000000000007FF800000001FFFFFFF E000001FFFFFFFE000001FFFFFFFE00035397DB83C>IIII<7FFFFF003FFFFC007FFFFF003FFFFC007FFFFF003FFFFC0000FFF80007 FF8000007FE00003FC0000003FE00001F00000001FF00001E00000001FF00001C0000000 0FF800018000000007FC00038000000007FC00070000000003FE00060000000003FE000E 0000000001FF001C0000000000FF80180000000000FF803800000000007FC03000000000 003FE06000000000003FE0E000000000001FF0C000000000000FF18000000000000FFB80 000000000007FF00000000000007FE00000000000003FE00000000000001FF0000000000 0001FF00000000000000FF800000000000007FC00000000000007FC0000000000000FFE0 000000000000DFE00000000000019FF00000000000038FF80000000000030FF800000000 000607FC00000000000E03FE00000000000C03FE00000000001801FF00000000003800FF 00000000003000FF800000000060007FC000000000E0007FC000000000C0003FE0000000 0180001FF00000000380001FF00000000300000FF800000006000007FC0000000E000007 FC0000000C000003FE0000001C000001FE0000003C000001FF000000FE000001FF800007 FF800007FFE000FFFFE0003FFFFF80FFFFE0003FFFFF80FFFFE0003FFFFF8039397EB83E >I91 D93 D<0180038007000E001C00180038003000700060006000E000C000C000C000C000CE00FF 80FFC0FFC0FFC07FC07FC03F800E000A197AB917>96 D<001FE0000000FFFC000003E03F 000007000F80000F8007E0001FC003F0001FE003F0001FE001F8001FE001F8001FE000FC 000FC000FC00078000FC00000000FC00000000FC00000000FC00000000FC0000007FFC00 0007FFFC00003FE0FC0000FE00FC0003F800FC000FF000FC001FC000FC003FC000FC007F 8000FC007F0000FC007F0000FC0CFE0000FC0CFE0000FC0CFE0000FC0CFE0001FC0CFE00 01FC0CFF0003FC0C7F00077C0C7F80063E183FC01E3E180FE0781FF003FFF00FE0007F80 07C026277DA52A>I<03F0000000FFF0000000FFF0000000FFF00000000FF000000003F0 00000003F000000003F000000003F000000003F000000003F000000003F000000003F000 000003F000000003F000000003F000000003F000000003F000000003F000000003F00000 0003F000000003F01FE00003F07FF80003F1E03E0003F3801F8003F7000FC003FE0007E0 03FC0003F003F80001F803F00001F803F00000FC03F00000FC03F00000FE03F00000FE03 F000007E03F000007F03F000007F03F000007F03F000007F03F000007F03F000007F03F0 00007F03F000007F03F000007F03F000007F03F000007E03F00000FE03F00000FE03F000 00FC03F00001FC03F80001F803F80003F003FC0003F003EE0007E003C6000FC003C7801F 000381E07E000300FFF80000001FC000283B7EB92E>I<0003FC00001FFF80007E03E001 F8007003F000F807E001FC0FC003FC0FC003FC1F8003FC3F8003FC3F0001F87F0000F07F 0000007F0000007E000000FE000000FE000000FE000000FE000000FE000000FE000000FE 000000FE000000FE000000FE0000007E0000007F0000007F0000003F0000063F8000061F 80000E1FC0000C0FC0001C07E0003803F0007001F800E0007C07C0001FFF000007F8001F 277DA525>I<0000000FC0000003FFC0000003FFC0000003FFC00000003FC00000000FC0 0000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC000 00000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000 000FC00003F80FC0001FFF0FC0007E078FC000F801EFC003F0007FC007E0003FC00FC000 1FC00FC0001FC01F80000FC03F80000FC03F00000FC07F00000FC07F00000FC07E00000F C0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0 FE00000FC0FE00000FC0FE00000FC07E00000FC07F00000FC07F00000FC03F00000FC03F 00000FC01F80001FC01F80001FC00FC0003FC007E0007FC003F000EFF001F801CFFF007C 078FFF001FFE0FFF0007F80FC0283B7DB92E>I<0007F800001FFF00007C0FC001F803E0 03F001F007E001F80FC000F81F80007C1F80007C3F00007E3F00003E7F00003E7F00003F 7E00003FFE00003FFE00003FFE00003FFFFFFFFFFFFFFFFFFE000000FE000000FE000000 FE000000FE0000007E0000007E0000007F0000007F0000003F0000033F8000031F800007 0FC0000607C0000E07E0001C01F0003800F80070007E03E0001FFF800003FC0020277EA5 25>I<00007E000003FF80000FC1E0001F87E0003F0FF0007E0FF0007E0FF000FC0FF000 FC0FF001F803C001F8000001F8000001F8000001F8000001F8000001F8000001F8000001 F8000001F8000001F8000001F8000001F8000001F80000FFFFFC00FFFFFC00FFFFFC0001 F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001 F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001 F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001 F8000001F8000003FC00007FFFF8007FFFF8007FFFF8001C3B7FBA19>I<00000003F000 0FF00FF8003FFC3C3C00F81F707C01F00FE07C03E007C07C07C003E0100FC003F0000FC0 03F0001F8001F8001F8001F8001F8001F8001F8001F8001F8001F8001F8001F8001F8001 F8001F8001F8000FC003F0000FC003F00007C003E00003E007C00003F00F800003F81F00 00073FFC0000060FF000000E000000000E000000000E000000000E000000000F00000000 0F000000000FC000000007FFFFC00007FFFFF80003FFFFFE0001FFFFFF8003FFFFFFC00F 80007FE01F00000FF03E000003F07C000001F07C000001F8F8000000F8F8000000F8F800 0000F8F8000000F8F8000000F8FC000001F87C000001F03E000003E03F000007E00F8000 0F8007E0003F0001FC01FC00007FFFF0000007FF000026387EA52A>I<03F000000000FF F000000000FFF000000000FFF0000000000FF00000000003F00000000003F00000000003 F00000000003F00000000003F00000000003F00000000003F00000000003F00000000003 F00000000003F00000000003F00000000003F00000000003F00000000003F00000000003 F00000000003F00000000003F00FF0000003F03FFC000003F0F03F000003F1C01F800003 F3800FC00003F7000FC00003FE000FC00003FC0007E00003FC0007E00003F80007E00003 F80007E00003F80007E00003F00007E00003F00007E00003F00007E00003F00007E00003 F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003 F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003 F00007E00003F00007E00003F00007E00003F00007E00003F00007E00007F8000FF000FF FFC1FFFF80FFFFC1FFFF80FFFFC1FFFF80293A7EB92E>I<0380000FE0001FF0001FF000 1FF0001FF0001FF0000FE000038000000000000000000000000000000000000000000000 00000000000000000003F000FFF000FFF000FFF00007F00003F00003F00003F00003F000 03F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F000 03F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F000 07F800FFFFC0FFFFC0FFFFC012387EB717>I<0001C00007F0000FF8000FF8000FF8000F F8000FF80007F00001C00000000000000000000000000000000000000000000000000000 000000000001F800FFF800FFF800FFF80007F80001F80001F80001F80001F80001F80001 F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001 F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001 F80001F80001F80001F80001F80001F80001F80001F80001F83C01F87E01F8FF01F0FF03 F0FF03F0FF03E0FE07C07C07C03C0F000FFE0003F800154984B719>I<03F0000000FFF0 000000FFF0000000FFF00000000FF000000003F000000003F000000003F000000003F000 000003F000000003F000000003F000000003F000000003F000000003F000000003F00000 0003F000000003F000000003F000000003F000000003F000000003F000000003F001FFFC 03F001FFFC03F001FFFC03F0007FC003F0007F0003F0007C0003F000700003F000E00003 F001C00003F003800003F007000003F01E000003F038000003F078000003F0FC000003F1 FC000003F3FE000003F73F000003FE3F800003F81F800003F00FC00003F00FE00003F007 E00003F003F00003F001F80003F001FC0003F000FC0003F0007E0003F0007F0003F0003F 0003F0003F8003F0001FC007F8003FF0FFFFC0FFFFFFFFC0FFFFFFFFC0FFFF283A7EB92C >I<03F000FFF000FFF000FFF0000FF00003F00003F00003F00003F00003F00003F00003 F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003 F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003 F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003 F00003F00003F00003F00003F00003F00003F00007F800FFFFC0FFFFC0FFFFC0123A7EB9 17>I<03F00FF0001FE000FFF03FFC007FF800FFF0F03F01E07E00FFF1C01F83803F000F F3800FC7001F8003F7000FCE001F8003FE000FDC001F8003FC0007F8000FC003FC0007F8 000FC003F80007F0000FC003F80007F0000FC003F80007F0000FC003F00007E0000FC003 F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0 000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003 F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0 000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003 F00007E0000FC003F00007E0000FC007F8000FF0001FE0FFFFC1FFFF83FFFFFFFFC1FFFF 83FFFFFFFFC1FFFF83FFFF40257EA445>I<03F00FF00000FFF03FFC0000FFF0F03F0000 FFF1C01F80000FF3800FC00003F7000FC00003FE000FC00003FC0007E00003FC0007E000 03F80007E00003F80007E00003F80007E00003F00007E00003F00007E00003F00007E000 03F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E000 03F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E000 03F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E000 07F8000FF000FFFFC1FFFF80FFFFC1FFFF80FFFFC1FFFF8029257EA42E>I<0003FE0000 000FFF8000003E03E00000F800F80001F0007C0003E0003E0007C0001F000F80000F801F 80000FC01F000007C03F000007E03F000007E07E000003F07E000003F07E000003F07E00 0003F0FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE0000 03F8FE000003F8FE000003F87E000003F07E000003F07F000007F03F000007E03F000007 E01F80000FC00F80000F800FC0001F8007E0003F0003F0007E0000F800F800007E03F000 001FFFC0000003FE000025277EA52A>I<03F01FE000FFF07FF800FFF1E07E00FFF3801F 8007F7000FC003FE0007E003FC0003F003F80003F803F00001F803F00001FC03F00000FC 03F00000FE03F00000FE03F00000FE03F000007F03F000007F03F000007F03F000007F03 F000007F03F000007F03F000007F03F000007F03F000007F03F000007F03F00000FE03F0 0000FE03F00000FE03F00001FC03F00001FC03F80003F803F80003F003FC0007F003FE00 0FE003F6000FC003F7803F0003F1E07E0003F0FFF80003F01FC00003F000000003F00000 0003F000000003F000000003F000000003F000000003F000000003F000000003F0000000 03F000000003F000000007F8000000FFFFC00000FFFFC00000FFFFC0000028357EA42E> I<0003F800C0001FFE01C0007E0781C000FC01C3C003F000E3C007F00077C00FE00037C0 0FC0003FC01FC0001FC03F80001FC03F80000FC07F00000FC07F00000FC07F00000FC0FE 00000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE00 000FC0FE00000FC0FE00000FC07F00000FC07F00000FC07F00000FC03F00000FC03F8000 1FC01F80001FC01FC0003FC00FC0003FC007E0007FC003F000EFC001F801CFC0007E078F C0001FFE0FC00007F80FC00000000FC00000000FC00000000FC00000000FC00000000FC0 0000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000001FE000 0003FFFF000003FFFF000003FFFF28357DA42C>I<07E01F00FFE07FC0FFE1E3E0FFE387 F00FE707F003E607F003EE07F003EC03E003FC008003F8000003F8000003F8000003F800 0003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F000 0003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F000 0003F0000003F0000007F80000FFFFF000FFFFF000FFFFF0001C257EA421>I<00FF0300 03FFE7000F80FF001E003F003C001F0078000F0070000700F0000700F0000700F0000300 F8000300F8000300FC000300FF0000007FE000007FFF00003FFFE0001FFFF8000FFFFC00 03FFFE0000FFFF000007FF8000007F8000001F80C0000FC0C00007C0C00007C0E00003C0 E00003C0E00003C0F00003C0F0000380F8000780FC000780FC000F00FF001E00F3C07C00 E1FFF000C03F80001A277DA521>I<001800000018000000180000001800000018000000 380000003800000038000000780000007800000078000000F8000001F8000003F8000007 F800001FFFFF00FFFFFF00FFFFFF0001F8000001F8000001F8000001F8000001F8000001 F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001 F8000001F8000001F8000001F8000001F800C001F800C001F800C001F800C001F800C001 F800C001F800C001F800C001F800C000FC01C000FC0180007C0380007E0300003F070000 0FFE000001F8001A347FB220>I<03F00007E000FFF001FFE000FFF001FFE000FFF001FF E0000FF0001FE00003F00007E00003F00007E00003F00007E00003F00007E00003F00007 E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007 E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007 E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F0000F E00003F0000FE00003F0000FE00003F0001FE00001F0001FE00001F8003FE00000F80077 F80000FC00E7FF80003F03C7FF80001FFF87FF800003FC07E00029267EA42E>IIIII<3FFFFFFC3FFFFFFC3F8003FC3E0003F83C0007F03800 0FE030000FE070001FC070003F8060007F8060007F006000FE006001FC006001FC000003 F8000007F0000007F000000FE000001FC000003F8000003F8000007F000600FE000600FE 000601FC000603F8000607F8000E07F0000E0FE0000C1FC0001C1FC0001C3F80003C7F00 007CFF0003FCFFFFFFFCFFFFFFFC1F247EA325>I E /Fw 1 64 df<0000030000000000 0700000000000700000000000700000000000F80000000000F80000000000F8000000000 0F80000000000F80000000001FC0000000001FC0000000001FC0000000001FC000000000 1FC0000000001FC0000070003FE00070FFF03FE07FF8FFFFFFFFFFF83FFFFFFFFFE01FFF FFFFFFC007FFFFFFFF0001FFFFFFFC00007FFFFFF000001FFFFFC0000007FFFF00000001 FFFC00000001FFFC00000003FFFE00000003FFFE00000003FFFE00000007FFFF00000007 FDFF0000000FF8FF8000000FF07F8000001FE03FC000001FC01FC000003F800FE000003F 0007E000007E0003F000007C0001F00000F00000780000E0000038000040000010002D2B 7FA930>63 D E /Fx 25 117 df45 D<000003FFC0000000003FFFFC00000000FFFFFF00000003FFFFFFC000000FFF 81FFF000001FFC003FF800003FF8001FFC00007FF0000FFE0000FFE00007FF0001FFC000 03FF8003FF800001FFC003FF800001FFC007FF800001FFE00FFF000000FFF00FFF000000 FFF00FFF000000FFF01FFF000000FFF81FFF000000FFF83FFF000000FFFC3FFE0000007F FC3FFE0000007FFC3FFE0000007FFC7FFE0000007FFE7FFE0000007FFE7FFE0000007FFE 7FFE0000007FFE7FFE0000007FFE7FFE0000007FFEFFFE0000007FFFFFFE0000007FFFFF FE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE 0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE00 00007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000 007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE0000007FFFFFFE000000 7FFF7FFE0000007FFE7FFE0000007FFE7FFE0000007FFE7FFE0000007FFE7FFE0000007F FE7FFE0000007FFE3FFE0000007FFC3FFE0000007FFC3FFF000000FFFC3FFF000000FFFC 1FFF000000FFF81FFF000000FFF81FFF000000FFF80FFF000000FFF00FFF000000FFF007 FF800001FFE007FF800001FFE003FFC00003FFC001FFC00003FF8001FFE00007FF8000FF F0000FFF00007FF8001FFE00001FFC003FF800000FFF81FFF0000007FFFFFFE0000001FF FFFF800000003FFFFC0000000003FFC00000384F7BCD43>48 D<000000780000000000FC 0000000003FC0000000007FC000000001FFC00000000FFFC0000000FFFFC000007FFFFFC 0000FFFFFFFC0000FFFFFFFC0000FFFF7FFC0000FFF07FFC0000F8007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC 000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC00007FFFFFFF FFFE7FFFFFFFFFFE7FFFFFFFFFFE7FFFFFFFFFFE7FFFFFFFFFFE2F4E76CD43>I<000000 0FFF0000000000FFFFE000000007FFFFF00000001FFFFFFC0000007FFE03FE000001FFF0 007F000003FFC0003F800007FF00001F80000FFE00007FC0001FFC0000FFC0003FF80001 FFE0007FF00003FFE000FFF00007FFE001FFE00007FFE001FFE00007FFE003FFC00007FF E007FFC00007FFE007FFC00007FFE00FFFC00003FFC00FFF800001FF801FFF800000FF00 1FFF8000007E001FFF80000000003FFF80000000003FFF80000000003FFF00000000007F FF00000000007FFF00000000007FFF00080000007FFF01FFF800007FFF07FFFF0000FFFF 0FFFFFC000FFFF1FFFFFF000FFFF3F007FF800FFFF3C003FFC00FFFF78001FFE00FFFFF0 000FFF00FFFFF00007FF80FFFFE00007FFC0FFFFE00007FFC0FFFFC00007FFE0FFFFC000 03FFF0FFFF800003FFF0FFFF800003FFF8FFFF800003FFF8FFFF800003FFF8FFFF800003 FFF8FFFF000003FFFCFFFF000003FFFCFFFF000003FFFC7FFF000003FFFC7FFF000003FF FC7FFF000003FFFC7FFF000003FFFC7FFF000003FFFC7FFF000003FFFC3FFF000003FFFC 3FFF000003FFFC3FFF000003FFFC3FFF000003FFFC1FFF000003FFF81FFF800003FFF81F FF800003FFF80FFF800003FFF80FFF800003FFF007FF800007FFF007FF800007FFE003FF C00007FFC001FFC00007FFC001FFE0000FFF8000FFF0000FFF00007FF8001FFE00003FFC 007FFC00001FFF01FFF800000FFFFFFFF0000003FFFFFFC0000000FFFFFF000000003FFF FC0000000007FFC00000364F7ACD43>54 D<07F0000FF8001FFC003FFE007FFF00FFFF80 FFFF80FFFF80FFFF80FFFF80FFFF80FFFF807FFF003FFE001FFC000FF80007F000000000 000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000007F0000FF8001FFC003FFE007FFF00FFFF80 FFFF80FFFF80FFFF80FFFF80FFFF80FFFF807FFF003FFE001FFC000FF80007F000113576 B425>58 D<00000000001F00000000000000000000003F80000000000000000000007FC0 000000000000000000007FC000000000000000000000FFE000000000000000000000FFE0 00000000000000000000FFE000000000000000000001FFF000000000000000000001FFF0 00000000000000000003FFF800000000000000000003FFF800000000000000000003FFF8 00000000000000000007FFFC00000000000000000007FFFC00000000000000000007FFFC 0000000000000000000FFFFE0000000000000000000FFFFE0000000000000000001FFFFF 0000000000000000001FFFFF0000000000000000001FFFFF0000000000000000003FFFFF 8000000000000000003F7FFF8000000000000000007F7FFFC000000000000000007E7FFF C000000000000000007E3FFFC00000000000000000FE3FFFE00000000000000000FC1FFF E00000000000000001FC1FFFF00000000000000001F81FFFF00000000000000001F80FFF F00000000000000003F80FFFF80000000000000003F007FFF80000000000000007F007FF FC0000000000000007E007FFFC0000000000000007E003FFFC000000000000000FE003FF FE000000000000000FC001FFFE000000000000001FC001FFFF000000000000001F8001FF FF000000000000001F8000FFFF000000000000003F8000FFFF800000000000003F00007F FF800000000000007F00007FFFC00000000000007E00007FFFC00000000000007E00003F FFC0000000000000FE00003FFFE0000000000000FC00001FFFE0000000000001FC00001F FFF0000000000001F800001FFFF0000000000001F800000FFFF0000000000003F800000F FFF8000000000003F0000007FFF8000000000007F0000007FFFC000000000007E0000007 FFFC000000000007E0000003FFFC00000000000FFFFFFFFFFFFE00000000000FFFFFFFFF FFFE00000000001FFFFFFFFFFFFF00000000001FFFFFFFFFFFFF00000000001FFFFFFFFF FFFF00000000003F80000000FFFF80000000003F000000007FFF80000000007F00000000 7FFFC0000000007F000000007FFFC0000000007E000000003FFFC000000000FE00000000 3FFFE000000000FC000000001FFFE000000001FC000000001FFFF000000001FC00000000 1FFFF000000001F8000000000FFFF000000003F8000000000FFFF800000003F000000000 07FFF800000007F00000000007FFFC00000007F00000000007FFFC00000007E000000000 03FFFC0000000FE00000000003FFFE0000000FC00000000003FFFE0000001FC000000000 01FFFF000000FFFC0000000001FFFF0000FFFFFFF800000FFFFFFFFFE0FFFFFFF800000F FFFFFFFFE0FFFFFFF800000FFFFFFFFFE0FFFFFFF800000FFFFFFFFFE0FFFFFFF800000F FFFFFFFFE05B547BD366>65 D68 DI73 D77 D80 D82 D<00000FFF800007000000FFFFF8000F000007FFFFFF001F00001FFFFFFFC03F00003FFF FFFFF07F0000FFFC00FFF8FF0001FFE0000FFDFF0003FF800001FFFF0007FE0000007FFF 000FFC0000003FFF000FF80000000FFF001FF800000007FF001FF000000003FF003FF000 000003FF003FE000000001FF007FE000000000FF007FE000000000FF007FE0000000007F 00FFE0000000007F00FFE0000000003F00FFE0000000003F00FFF0000000003F00FFF000 0000003F00FFF8000000001F00FFF8000000001F00FFFC000000001F00FFFE000000001F 00FFFF000000000000FFFFC000000000007FFFF000000000007FFFFF00000000007FFFFF F8000000003FFFFFFF800000003FFFFFFFFC0000001FFFFFFFFFC000001FFFFFFFFFF000 000FFFFFFFFFFC000007FFFFFFFFFF000003FFFFFFFFFFC00001FFFFFFFFFFE00000FFFF FFFFFFF000007FFFFFFFFFF800003FFFFFFFFFFC00000FFFFFFFFFFE000003FFFFFFFFFE 000000FFFFFFFFFF0000001FFFFFFFFF80000000FFFFFFFF800000000FFFFFFFC0000000 007FFFFFC00000000007FFFFE00000000000FFFFE000000000003FFFE000000000000FFF F0000000000007FFF0000000000003FFF0000000000003FFF0780000000001FFF0F80000 000000FFF0F80000000000FFF0F80000000000FFF0F800000000007FF0F800000000007F F0FC00000000007FF0FC00000000007FF0FC00000000007FE0FE00000000007FE0FE0000 0000007FE0FF0000000000FFC0FF0000000000FFC0FF8000000000FFC0FFC000000001FF 80FFE000000001FF00FFF000000003FF00FFFC00000007FE00FFFF0000000FFC00FFFFC0 00001FF800FFFFF800007FF000FF1FFFC003FFE000FE0FFFFFFFFFC000FC03FFFFFFFF00 00F8007FFFFFFC0000F0000FFFFFF00000E000007FFF0000003C5479D24B>I86 D<000000000001FF80000000000007FFFF80000000000007FFFF80000000000007FFFF80 000000000007FFFF80000000000007FFFF800000000000001FFF8000000000000007FF80 00000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF80 00000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF80 00000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF80 00000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF80 00000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF80 00000000000007FF8000000001FFE007FF800000001FFFFC07FF80000000FFFFFF07FF80 000003FFFFFFC7FF8000000FFFE03FE7FF8000001FFF0007F7FF8000007FFC0001FFFF80 0000FFF80000FFFF800001FFF000003FFF800003FFE000001FFF800007FFC000001FFF80 0007FFC000000FFF80000FFF8000000FFF80001FFF8000000FFF80001FFF0000000FFF80 003FFF0000000FFF80003FFF0000000FFF80003FFF0000000FFF80007FFE0000000FFF80 007FFE0000000FFF80007FFE0000000FFF80007FFE0000000FFF8000FFFE0000000FFF80 00FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF80 00FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF80 00FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF80007FFE0000000FFF80 007FFE0000000FFF80007FFE0000000FFF80003FFF0000000FFF80003FFF0000000FFF80 003FFF0000000FFF80001FFF0000000FFF80001FFF0000000FFF80000FFF8000000FFF80 000FFF8000001FFF800007FFC000003FFF800003FFC000003FFF800001FFE000007FFF80 0000FFF00001FFFF8000007FF80003FFFFE000003FFE000FEFFFFF80000FFFC07FCFFFFF 800007FFFFFF8FFFFF800001FFFFFE0FFFFF8000003FFFF80FFFFF80000003FFC00FFE00 0041547CD24B>100 D<000003FFC0000000003FFFFC00000001FFFFFF00000007FFFFFF C000000FFF81FFE000003FFC007FF800007FF8003FFC0000FFF0001FFE0001FFE0000FFE 0003FFC00007FF0007FFC00007FF800FFF800003FF800FFF800003FFC01FFF800001FFC0 1FFF000001FFC03FFF000001FFE03FFF000001FFE07FFF000000FFE07FFE000000FFE07F FE000000FFF07FFE000000FFF0FFFE000000FFF0FFFE000000FFF0FFFE000000FFF0FFFE 000000FFF0FFFFFFFFFFFFF0FFFFFFFFFFFFF0FFFFFFFFFFFFF0FFFFFFFFFFFFE0FFFE00 00000000FFFE0000000000FFFE0000000000FFFE0000000000FFFE0000000000FFFE0000 0000007FFE00000000007FFE00000000007FFF00000000003FFF00000000003FFF000000 00003FFF00000000E01FFF00000001F01FFF80000003F00FFF80000003F007FFC0000007 E007FFC0000007E003FFE000000FC001FFF000001FC000FFF800003F80007FFC0000FF00 001FFE0003FE00000FFFC03FF8000003FFFFFFF0000000FFFFFFC00000001FFFFE000000 0001FFF0000034387CB63D>I<0000003FFC00000003FFFF0000000FFFFFC000003FFFFF E00000FFF81FF00001FFC03FF80003FF807FF80007FF00FFFC000FFE00FFFC001FFC00FF FC001FFC00FFFC003FF800FFFC003FF800FFFC003FF8007FF8007FF0007FF8007FF0003F F0007FF0000FC0007FF0000000007FF0000000007FF0000000007FF0000000007FF00000 00007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF00000 00007FF0000000007FF0000000007FF0000000FFFFFFFFE000FFFFFFFFE000FFFFFFFFE0 00FFFFFFFFE000FFFFFFFFE000007FF8000000007FF8000000007FF8000000007FF80000 00007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF80000 00007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF80000 00007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF80000 00007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF80000 00007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF80000 00007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF80000 00007FF8000000007FF8000000007FF80000007FFFFFFE00007FFFFFFE00007FFFFFFE00 007FFFFFFE00007FFFFFFE00002E547CD329>I<00003FFF0000FF000003FFFFF007FFC0 000FFFFFFC1FFFE0003FFFFFFF7FFFE0007FFC0FFFFF9FF000FFE001FFF83FF001FFC000 FFE03FF003FF80007FF01FF007FF00003FF81FE00FFF00003FFC0FC00FFF00003FFC0780 1FFE00001FFE00001FFE00001FFE00003FFE00001FFF00003FFE00001FFF00003FFE0000 1FFF00003FFE00001FFF00003FFE00001FFF00003FFE00001FFF00003FFE00001FFF0000 3FFE00001FFF00003FFE00001FFF00001FFE00001FFE00001FFE00001FFE00000FFF0000 3FFC00000FFF00003FFC000007FF00003FF8000003FF80007FF0000001FFC000FFE00000 00FFE001FFC0000000FFFC0FFF80000001FFFFFFFF00000003EFFFFFFC00000003C3FFFF F000000007C03FFF0000000007C000000000000007C00000000000000FC0000000000000 0FC00000000000000FC00000000000000FE00000000000000FE00000000000000FF80000 000000000FFE0000000000000FFFFFFFFF00000007FFFFFFFFF8000007FFFFFFFFFF0000 07FFFFFFFFFFC00003FFFFFFFFFFE00001FFFFFFFFFFF00000FFFFFFFFFFF800007FFFFF FFFFFC00007FFFFFFFFFFE0001FFFFFFFFFFFF0007FFFFFFFFFFFF000FFE000003FFFF80 1FF80000003FFF803FF000000007FF807FE000000003FFC07FE000000001FFC0FFC00000 0001FFC0FFC000000000FFC0FFC000000000FFC0FFC000000000FFC0FFC000000000FFC0 FFC000000000FFC0FFE000000001FFC07FE000000001FF807FF000000003FF803FF00000 0003FF001FF800000007FE000FFE0000001FFC0007FF8000007FF80003FFE00001FFF000 01FFFE001FFFE000007FFFFFFFFF8000000FFFFFFFFC00000001FFFFFFE0000000000FFF FC0000003C4F7CB543>I<003FF0000000000000FFFFF0000000000000FFFFF000000000 0000FFFFF0000000000000FFFFF0000000000000FFFFF000000000000003FFF000000000 000000FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000 000000FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000 000000FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000 000000FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000 000000FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000 000000FFF000000000000000FFF000000000000000FFF0001FFC00000000FFF000FFFFC0 000000FFF003FFFFF0000000FFF00FFFFFF8000000FFF01FE07FFC000000FFF03F001FFE 000000FFF07C001FFF000000FFF0F0000FFF000000FFF1E0000FFF800000FFF3C0000FFF 800000FFF7800007FF800000FFF7800007FFC00000FFFF000007FFC00000FFFE000007FF C00000FFFE000007FFC00000FFFC000007FFC00000FFFC000007FFC00000FFFC000007FF C00000FFFC000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FF C00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FF C00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FF C00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FF C00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FF C00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FF C00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FF C00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC000FFFFFFF807FFFF FFC0FFFFFFF807FFFFFFC0FFFFFFF807FFFFFFC0FFFFFFF807FFFFFFC0FFFFFFF807FFFF FFC042537BD24B>I<007F000000FF800003FFE00007FFF00007FFF0000FFFF8000FFFF8 000FFFF8000FFFF8000FFFF8000FFFF8000FFFF80007FFF00007FFF00003FFE00000FF80 00007F000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000003FF000FFFFF000FFFFF000FFFFF0 00FFFFF000FFFFF00001FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF0 0000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF0 0000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF0 0000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF0 0000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF0 00FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE01B547BD325>I<003FF0001FFC0000 00FFFFF000FFFFC00000FFFFF003FFFFF00000FFFFF00FFFFFF80000FFFFF01FE07FFC00 00FFFFF03F001FFE000003FFF07C001FFF000000FFF0F0000FFF000000FFF1E0000FFF80 0000FFF3C0000FFF800000FFF7800007FF800000FFF7800007FFC00000FFFF000007FFC0 0000FFFE000007FFC00000FFFE000007FFC00000FFFC000007FFC00000FFFC000007FFC0 0000FFFC000007FFC00000FFFC000007FFC00000FFF8000007FFC00000FFF8000007FFC0 0000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC0 0000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC0 0000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC0 0000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC0 0000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC0 0000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC0 0000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC0 00FFFFFFF807FFFFFFC0FFFFFFF807FFFFFFC0FFFFFFF807FFFFFFC0FFFFFFF807FFFFFF C0FFFFFFF807FFFFFFC042367BB54B>110 D<000001FFE000000000001FFFFE00000000 00FFFFFFC000000003FFFFFFF00000000FFF807FFC0000001FFC000FFE0000007FF80007 FF800000FFF00003FFC00001FFE00001FFE00003FFC00000FFF00003FF8000007FF00007 FF8000007FF8000FFF0000003FFC000FFF0000003FFC001FFF0000003FFE001FFF000000 3FFE003FFE0000001FFF003FFE0000001FFF003FFE0000001FFF007FFE0000001FFF807F FE0000001FFF807FFE0000001FFF807FFE0000001FFF80FFFE0000001FFFC0FFFE000000 1FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FF FE0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE000000 1FFFC0FFFE0000001FFFC07FFE0000001FFF807FFE0000001FFF807FFE0000001FFF803F FE0000001FFF003FFF0000003FFF003FFF0000003FFF001FFF0000003FFE001FFF000000 3FFE000FFF0000003FFC000FFF8000007FFC0007FF8000007FF80003FFC00000FFF00001 FFE00001FFE00000FFF00003FFC000007FF80007FF8000003FFE001FFF0000000FFF807F FC00000007FFFFFFF800000000FFFFFFC0000000003FFFFF000000000001FFE00000003A 387CB643>I<007FE003FE00FFFFE00FFF80FFFFE03FFFE0FFFFE07FFFF0FFFFE0FE1FF8 FFFFE1F83FFC03FFE3E03FFE00FFE3C07FFE00FFE7807FFE00FFEF807FFE00FFEF007FFE 00FFEE007FFE00FFFE003FFC00FFFC003FFC00FFFC001FF800FFFC000FF000FFF8000000 00FFF800000000FFF800000000FFF800000000FFF800000000FFF000000000FFF0000000 00FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF0000000 00FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF0000000 00FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF0000000 00FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF0000000 00FFF000000000FFF0000000FFFFFFFC0000FFFFFFFC0000FFFFFFFC0000FFFFFFFC0000 FFFFFFFC00002F367CB537>114 D<0003FFF00F00003FFFFE1F0000FFFFFFFF0003FFFF FFFF0007FF003FFF000FF80007FF001FE00001FF003FC00000FF003F8000007F007F8000 007F007F0000003F007F0000003F00FF0000001F00FF0000001F00FF8000001F00FF8000 001F00FFC000001F00FFF000000000FFFC00000000FFFFC00000007FFFFF0000007FFFFF F800003FFFFFFF00003FFFFFFFC0001FFFFFFFF0000FFFFFFFF80007FFFFFFFC0003FFFF FFFE0000FFFFFFFF00003FFFFFFF80000FFFFFFFC00000FFFFFFC0000007FFFFE0000000 3FFFE000000007FFF000000001FFF0780000007FF0F80000003FF0F80000001FF0FC0000 001FF0FC0000000FF0FC0000000FF0FE0000000FF0FE0000000FE0FF0000000FE0FF8000 001FE0FF8000001FC0FFC000001FC0FFE000003F80FFF800007F00FFFE0001FE00FFFFC0 0FFC00FF7FFFFFF800FC1FFFFFE000F807FFFF8000F000FFF800002C387CB635>I<0000 3E00000000003E00000000003E00000000003E00000000003E00000000003E0000000000 7E00000000007E00000000007E00000000007E0000000000FE0000000000FE0000000001 FE0000000001FE0000000001FE0000000003FE0000000007FE0000000007FE000000000F FE000000001FFE000000003FFE00000000FFFE00000001FFFE0000000FFFFFFFFF00FFFF FFFFFF00FFFFFFFFFF00FFFFFFFFFF00FFFFFFFFFF00003FFE000000003FFE000000003F FE000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE000000003F FE000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE000000003F FE000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE000000003F FE000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE000000003F FE000000003FFE0007C0003FFE0007C0003FFE0007C0003FFE0007C0003FFE0007C0003F FE0007C0003FFE0007C0003FFE0007C0003FFE0007C0003FFE0007C0003FFE0007C0001F FE000F80001FFF000F80001FFF000F80000FFF001F00000FFF801F000007FFC03E000003 FFF0FC000001FFFFF80000007FFFF00000001FFFE000000003FF80002A4D7ECB34>I E end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: a4 %%EndSetup %%Page: 1 1 1 0 bop 1384 387 a Fx(RIPEMD-160:)693 527 y(A)45 b(Strengthened)g(V)-11 b(ersion)45 b(of)g(RIPEMD)2867 483 y Fw(?)832 816 y Fv(Hans)27 b(Dobb)r(ertin)1412 786 y Fu(1)1478 816 y Fv(An)n(to)r(on)g(Bosselaers) 2147 786 y Fu(2)2209 816 y Fv(Bart)g(Preneel)2672 786 y Fu(2)s Ft(??)1138 959 y Fs(1)1211 990 y Fr(German)e(Information)g (Securit)n(y)g(Agency)1059 1082 y(P)-6 b(.O.)26 b(Bo)n(x)g(20)g(03)h (63,)f(D-53133)h(Bonn,)f(German)n(y)1355 1197 y Fq (dobbertin@skom.rhein.de)992 1304 y Fs(2)1065 1335 y Fr(Katholiek)n(e)g(Univ)n(ersiteit)f(Leuv)n(en,)g(ESA)-6 b(T-COSIC)1048 1427 y(K.)25 b(Mercierlaan)j(94,)f(B-3001)g(Hev)n (erlee,)f(Belgium)787 1542 y Fp(f)p Fq(antoon.bosselaers,bart.pren)q (eel)p Fp(g)q Fq(@esa)q(t.ku)q(leuv)q(en.ac)q(.be)1561 1744 y Fv(18)g(April)i(1996)602 1927 y Fo(Abstract.)42 b Fr(Cryptographic)22 b(hash)g(functions)g(are)g(an)g(imp)r(ortan)n(t)f (to)r(ol)h(in)g(cryp-)602 2018 y(tograph)n(y)f(for)i(applications)g (suc)n(h)e(as)i(digital)g(\014ngerprin)n(ting)e(of)i(messages,)g(mes-) 602 2109 y(sage)28 b(authen)n(tication,)f(and)g(k)n(ey)f(deriv)l (ation.)i(During)f(the)f(last)i(\014v)n(e)f(y)n(ears,)g(sev-)602 2201 y(eral)h(fast)g(soft)n(w)n(are)h(hash)f(functions)f(ha)n(v)n(e)g (b)r(een)g(prop)r(osed;)h(most)f(of)h(them)e(are)602 2292 y(based)g(on)f(the)h(design)g(principles)h(of)g(Ron)e(Riv)n(est's) h(MD4.)h(One)e(suc)n(h)h(prop)r(osal)602 2383 y(w)n(as)e(RIPEMD,)g (whic)n(h)h(w)n(as)f(dev)n(elop)r(ed)g(in)g(the)g(framew)n(ork)g(of)h (the)e(EU)h(pro)t(ject)602 2475 y(RIPE)d(\(Race)h(In)n(tegrit)n(y)f (Primitiv)n(es)h(Ev)l(aluation\).)g(Because)h(of)g(recen)n(t)f (progress)602 2566 y(in)30 b(the)g(cryptanalysis)g(of)h(these)g(hash)f (functions,)h(w)n(e)g(prop)r(ose)g(a)f(new)h(v)n(ersion)602 2657 y(of)36 b(RIPEMD)g(with)g(a)h(160-bit)f(result,)h(as)g(w)n(ell)g (as)f(a)h(plug-in)e(substitute)h(for)602 2749 y(RIPEMD)d(with)g(a)h (128-bit)g(result.)g(W)-6 b(e)33 b(also)i(compare)e(the)g(soft)n(w)n (are)i(p)r(erfor-)602 2840 y(mance)27 b(of)i(sev)n(eral)f(MD4-based)g (algorithms,)h(whic)n(h)f(is)h(of)g(indep)r(enden)n(t)d(in)n(ter-)602 2931 y(est.)365 3220 y Fn(1)112 b(In)m(tro)s(duction)37 b(and)h(Bac)m(kground)365 3425 y Fv(Hash)30 b(functions)h(are)e (functions)h(that)h(map)f(bitstrings)f(of)h(arbitrary)f(\014nite)h (length)h(in)n(to)365 3524 y(strings)f(of)g(\014xed)h(length.)g(Giv)n (en)f Fm(h)g Fv(and)h(an)f(input)h Fm(x)p Fv(,)h(computing)e Fm(h)p Fv(\()p Fm(x)p Fv(\))h(m)n(ust)g(b)r(e)g(easy)-7 b(.)365 3624 y(A)28 b Fl(one-way)j(hash)g(function)j Fv(m)n(ust)28 b(satisfy)f(the)h(follo)n(wing)e(prop)r(erties:)417 3733 y Fk({)41 b(preimage)j(resistance)p Fv(:)39 b(it)h(is)f (computationally)g(infeasible)g(to)g(\014nd)h(an)n(y)e(input)506 3832 y(whic)n(h)28 b(hashes)f(to)g(an)n(y)g(pre-sp)r(eci\014ed)g (output.)417 3933 y Fk({)41 b(second)34 b(preimage)f(resistance)p Fv(:)c(it)h(is)g(computationally)f(infeasible)g(to)h(\014nd)g(an)n(y) 506 4032 y(second)d(input)i(whic)n(h)e(has)g(the)h(same)f(output)i(as)d (an)n(y)h(sp)r(eci\014ed)h(input.)365 4140 y(F)-7 b(or)37 b(an)h Fl(ide)l(al)h Fv(one-w)n(a)n(y)d(hash)h(function)i(with)f(an)g Fm(m)p Fv(-bit)g(result,)f(\014nding)h(a)f(preimage)365 4240 y(or)c(a)g(second)g(preimage)f(requires)g(ab)r(out)i(2)1787 4210 y Ft(m)1883 4240 y Fv(op)r(erations.)e(A)i Fl(c)l(ol)t(lision)j(r) l(esistant)e(hash)365 4339 y(function)f Fv(is)28 b(a)f(one-w)n(a)n(y)f (hash)h(function)h(that)g(satis\014es)f(an)g(additional)g(condition:)p 365 4413 473 4 v 381 4466 a Fj(?)442 4498 y Fr(An)37 b(earlier)j(v)n(ersion)e(app)r(eared)g(in)g Fi(F)-6 b(ast)40 b(Softwar)l(e)g(Encryption,)g(LNCS)f(1039)p Fr(,)g(Springer-)442 4589 y(V)-6 b(erlag,)24 b(1996,)g(pp.)h(71{82.)g(The)d(order)h(of)h Fh(\031)h Fr(and)d Fh(\032)1957 4558 y Fj(i)2006 4589 y Fr(in)g(Section)k(3)d(has)g(b)r(een)f(exc)n(hanged,)g(and)442 4681 y(four)k(errors)h(in)e(App)r(endix)f(A)h(ha)n(v)n(e)g(b)r(een)g (corrected.)348 4740 y Fj(??)442 4772 y Fr(N.F.W.O.)37 b(p)r(ostdo)r(ctoral)h(researc)n(her,)f(sp)r(onsored)g(b)n(y)e(the)h (National)h(F)-6 b(und)35 b(for)i(Scien)n(ti\014c)442 4863 y(Researc)n(h)26 b(\(Belgium\).)1785 5112 y Fv(1)p eop %%Page: 2 2 2 1 bop 733 387 a Fk({)41 b(collision)28 b(resistance)p Fv(:)e(it)h(is)f(computationally)f(infeasible)h(to)h(\014nd)f(a)g (collision,)g(i.e.)822 487 y(t)n(w)n(o)h(distinct)h(inputs)g(that)g (hash)f(to)h(the)g(same)f(result.)681 670 y(F)-7 b(or)20 b(an)h Fl(ide)l(al)i Fv(collision)d(resistan)n(t)h(hash)f(function)i (with)g(an)f Fm(m)p Fv(-bit)g(result,)g(the)h(fastest)f(w)n(a)n(y)681 770 y(to)j(\014nd)h(a)f(collision)g(is)g(a)g(birthda)n(y)g(or)f(square) h(ro)r(ot)f(attac)n(k)h(whic)n(h)g(needs)h(appro)n(ximately)681 869 y(2)723 839 y Ft(m=)p Fu(2)880 869 y Fv(op)r(erations)h([19)o(].) 805 974 y(Almost)k(all)g(hash)f(functions)h(are)f(iterativ)n(e)g(pro)r (cesses)f(whic)n(h)i(hash)g(inputs)g(of)g(arbi-)681 1074 y(trary)i(length)h(b)n(y)g(pro)r(cessing)f(successiv)n(e)g (\014xed-size)g(blo)r(c)n(ks)h(of)g(the)h(input.)g(The)f(input)681 1174 y Fm(X)38 b Fv(is)31 b(padded)g(to)h(a)f(m)n(ultiple)h(of)f(the)h (blo)r(c)n(k)f(length)g(and)h(subsequen)n(tly)f(divided)g(in)n(to)h Fm(t)681 1273 y Fv(blo)r(c)n(ks)27 b Fm(X)1002 1285 y Fu(1)1066 1273 y Fv(through)g Fm(X)1449 1285 y Ft(t)1478 1273 y Fv(.)h(The)g(hash)f(function)h Fm(h)f Fv(can)h(then)g(b)r(e)g (describ)r(ed)f(as)g(follo)n(ws:)989 1478 y Fm(H)1058 1490 y Fu(0)1119 1478 y Fv(=)22 b Fm(I)7 b(V)19 b Fv(;)250 b Fm(H)1658 1490 y Ft(i)1709 1478 y Fv(=)23 b Fm(f)9 b Fv(\()p Fm(H)1948 1490 y Ft(i)p Fg(\000)p Fu(1)2060 1478 y Fm(;)14 b(X)2166 1490 y Ft(i)2194 1478 y Fv(\))p Fm(;)g Fv(1)22 b Ff(\024)h Fm(i)g Ff(\024)f Fm(t)236 b(h)p Fv(\()p Fm(X)7 b Fv(\))23 b(=)g Fm(H)3188 1490 y Ft(t)3231 1478 y Fm(:)681 1682 y Fv(Here)35 b Fm(f)43 b Fv(is)35 b(the)h Fl(c)l(ompr)l(ession)h(function)42 b Fv(of)35 b Fm(h)p Fv(,)g Fm(H)2301 1694 y Ft(i)2364 1682 y Fv(is)g(the)g Fl(chaining)j(variable)44 b Fv(b)r(et)n(w)n(een) 681 1782 y(stage)26 b Fm(i)18 b Ff(\000)g Fv(1)28 b(and)f(stage)g Fm(i)p Fv(,)g(and)g Fm(I)7 b(V)47 b Fv(denotes)27 b(the)h(initial)g(v) -5 b(alue.)805 1887 y(Collision)30 b(resistan)n(t)f(hash)i(functions)f (w)n(ere)g(\014rst)g(used)h(in)f(the)h(con)n(text)f(of)h(practical)681 1986 y(digital)g(signature)f(sc)n(hemes:)g(in)i(order)e(to)h(impro)n(v) n(e)f(the)h(e\016ciency)g(\(and)h(the)f(securit)n(y\))681 2086 y(of)f(these)h(sc)n(hemes,)f(messages)f(are)g(hashed,)h(and)h(the) g(\(slo)n(w\))f(digital)g(signature)g(is)g(only)681 2186 y(applied)36 b(to)h(the)g(short)f(hash-result.)g(Other)g(applications)g (include)h(the)g(protection)f(of)681 2285 y(passw)n(ords,)25 b(the)k(construction)d(of)i(message)f(authen)n(tication)g(co)r(des)g (or)g(MA)n(Cs,)h(and)f(the)681 2385 y(deriv)-5 b(ation)27 b(of)g(k)n(ey)g(v)-5 b(arian)n(ts.)805 2490 y(The)28 b(\014rst)f(constructions)f(for)h(hash)g(functions)g(w)n(ere)g(based)f (on)h(blo)r(c)n(k)g(ciphers)g(\(suc)n(h)681 2590 y(as)22 b(DES\))h([8)o(,)g(9,)f(10)o(].)h(Although)g(some)f(trust)g(has)g(b)r (een)h(built)h(up)f(in)f(the)h(securit)n(y)f(of)h(these)681 2689 y(prop)r(osals,)k(their)h(soft)n(w)n(are)f(p)r(erformance)h(is)g (not)h(v)n(ery)e(go)r(o)r(d,)h(since)h(they)g(are)e(t)n(ypically)681 2789 y(2.)13 b(.)h(.)g(4)33 b(times)g(slo)n(w)n(er)e(than)j(the)f (corresp)r(onding)e(blo)r(c)n(k)i(cipher.)g(Hash)g(functions)g(based) 681 2889 y(on)23 b(mo)r(dular)h(arithmetic)f(are)g(slo)n(w)g(as)g(w)n (ell,)h(and)g(serious)e(doubt)i(has)g(b)r(een)g(raised)f(ab)r(out)681 2988 y(their)k(securit)n(y)-7 b(.)805 3094 y(The)26 b(most)f(p)r (opular)g(hash)g(functions,)g(whic)n(h)h(are)e(curren)n(tly)g(used)i (in)f(a)g(wide)h(v)-5 b(ariet)n(y)681 3193 y(of)33 b(applications,)f (are)g(the)i(custom)f(designed)f(hash)h(functions)h(from)e(the)i (MD4-family)-7 b(.)681 3293 y(MD4)28 b(w)n(as)f(prop)r(osed)g(in)h (1990)e(b)n(y)i(R.)d(Riv)n(est)j([13)o(,)g(14)o(];)h(it)f(is)g(a)g(v)n (ery)f(fast)h(hash)f(function)681 3392 y(tuned)22 b(to)n(w)n(ards)f (32-bit)g(pro)r(cessors.)e(Because)i(of)h(unexp)r(ected)h (vulnerabilities)e(iden)n(ti\014ed)681 3492 y(in)k([3])g(\(namely)g (collisions)f(for)g(t)n(w)n(o)g(rounds)h(our)f(of)h(three\),)g(R.)g (Riv)n(est)g(designed)f(in)i(1991)681 3592 y(a)32 b(strengthened)g(v)n (ersion)f(of)i(MD4,)f(called)h(MD5)f([15)o(].)h(An)g(additional)f (argumen)n(t)g(w)n(as)681 3691 y(that)20 b(although)g(MD4)g(w)n(as)g (not)g(a)g(v)n(ery)f(conserv)-5 b(ativ)n(e)19 b(design,)h(it)g(w)n(as)g (b)r(eing)g(implemen)n(ted)681 3791 y(fast)j(in)n(to)f(pro)r(ducts.)h (MD5)g(is)g(probably)f(the)h(most)g(widely)f(used)h(hash)g(function,)g (in)h(spite)681 3891 y(of)i(the)g(fact)g(that)g(it)g(w)n(as)f(sho)n(wn) g(in)h([4])g(that)g(the)g(compression)f(function)h(of)g(MD5)g(is)g(not) 681 3990 y(collision)e(resistan)n(t:)f(the)i(collision)f(found)h(c)n (hanges)e(the)i(c)n(haining)f(v)-5 b(ariables)23 b(rather)h(than)681 4090 y(the)d(message)f(blo)r(c)n(k.)g(This)h(do)r(es)g(not)g(p)r(ose)f (a)h(threat)f(for)h(standard)f(applications)g(of)h(MD5,)681 4189 y(but)28 b(still)g(implies)g(a)f(violation)f(of)i(one)f(of)h(the)g (design)f(principles.)805 4295 y(The)32 b(RIPE)e(consortium)1618 4265 y Fu(3)1686 4295 y Fv(had)h(as)g(goal)f(to)h(prop)r(ose)f(a)h(p)r (ortfolio)g(of)g(recommended)681 4394 y(in)n(tegrit)n(y)25 b(primitiv)n(es)i([12)o(].)f(Based)g(on)h(its)f(indep)r(enden)n(t)i(ev) -5 b(aluation)26 b(of)g(MD4)h(and)g(MD5)681 4494 y([3)o(,)f(4)o(])g (the)f(consortium)g(prop)r(osed)f(a)h(strengthened)f(v)n(ersion)g(of)h (MD4,)h(whic)n(h)f(w)n(as)f(called)681 4594 y(RIPEMD.)33 b(RIPEMD)h(consists)f(of)h(essen)n(tially)f(t)n(w)n(o)g(parallel)g(v)n (ersions)f(of)i(MD4,)g(with)p 681 4685 473 4 v 697 4740 a Fs(3)758 4772 y Fr(C.W.I.)23 b(\(NL\))e(prime)g(con)n(tractor,)1794 4759 y(\027)1794 4772 y(Arh)n(us)g(Univ)n(ersit)n(y)h(\(DK\),)f(KPN)h (\(NL\),)f(K.U.Leuv)n(en)g(\(B\),)758 4863 y(Philips)26 b(Crypto)g(B.V.)g(\(NL\),)f(and)g(Siemens)g(A)n(G)h(\(D\).)2101 5112 y Fv(2)p eop %%Page: 3 3 3 2 bop 365 387 a Fv(some)20 b(impro)n(v)n(emen)n(ts)e(to)i(the)g (shifts)g(and)g(the)g(order)e(of)i(the)g(message)f(w)n(ords;)f(the)i(t) n(w)n(o)f(par-)365 487 y(allel)27 b(instances)f(di\013er)g(only)g(in)h (the)g(round)f(constan)n(ts.)g(A)n(t)h(the)g(end)f(of)h(the)g (compression)365 587 y(function,)i(the)f(w)n(ords)e(of)h(left)i(and)e (righ)n(t)g(halv)n(es)f(are)h(added.)490 688 y(A)f(second)g(alternativ) n(e)f(for)g(MD5)i(is)f(the)g(Secure)g(Hash)g(Algorithm)g(\(SHA-1\),)g (whic)n(h)365 788 y(w)n(as)j(designed)g(b)n(y)h(NSA)h(and)e(published)h (b)n(y)g(NIST)g(\(National)g(Institute)g(of)g(Standards)365 887 y(and)g(T)-7 b(ec)n(hnology)g(,)29 b(US\))h([7].)g(The)g(t)n(w)n(o) g(main)g(impro)n(v)n(emen)n(ts)e(are)h(the)i(increased)e(size)g(of)365 987 y(the)k(result)f(\(160)g(bits)g(compared)g(to)g(128)f(bits)i(for)e (the)i(other)f(sc)n(hemes\),)g(and)g(the)h(fact)365 1086 y(that)28 b(the)f(message)f(w)n(ords)g(in)h(the)g(di\013eren)n(t)h (rounds)e(are)g(not)h(p)r(erm)n(uted)g(but)h(computed)365 1186 y(as)h(the)g(sum)h(of)f(previous)f(message)f(w)n(ords.)h(This)h (has)g(as)f(main)h(consequence)f(that)i(it)f(is)365 1286 y(m)n(uc)n(h)k(harder)e(to)i(mak)n(e)f(lo)r(cal)g(c)n(hanges)f (con\014ned)i(to)f(a)h(few)g(bits:)g(individual)g(message)365 1385 y(bits)f(in\015uence)g(the)f(calculations)g(at)g(a)g(large)f(n)n (um)n(b)r(er)h(of)g(places.)g(The)g(\014rst)g(v)n(ersion)f(of)365 1485 y(SHA,)d(whic)n(h)e(w)n(as)g(published)h(in)g(Ma)n(y)e(1993,)g (had)h(a)h(w)n(eak)n(er)d(form)i(of)h(this)g(prop)r(ert)n(y)e(\(no)365 1585 y(mixing)29 b(w)n(as)e(done)i(b)r(et)n(w)n(een)f(bits)h(at)g (di\013eren)n(t)g(p)r(ositions)f(in)h(a)f(w)n(ord\),)g(and)h(apparen)n (tly)365 1684 y(this)g(can)f(b)r(e)h(exploited)f(to)g(pro)r(duce)g (collisions)f(faster)h(than)h(2)2391 1654 y Fu(80)2489 1684 y Fv(op)r(erations.)e(Ho)n(w)n(ev)n(er,)365 1784 y(no)21 b(details)g(ha)n(v)n(e)e(b)r(een)j(made)f(a)n(v)-5 b(ailable.)19 b(This)i(w)n(eakness)f(w)n(as)g(remo)n(v)n(ed)f(in)i(the) h(impro)n(v)n(ed)365 1883 y(v)n(ersion,)k(published)i(in)g(April)g ('95.)490 1985 y(The)d(remainder)f(of)h(this)g(pap)r(er)f(is)h (organized)e(as)h(follo)n(ws.)g(In)h Ff(x)p Fv(2)g(w)n(e)f(discuss)h (in)g(more)365 2084 y(detail)h(wh)n(y)e(a)h(new)h(v)n(ersion)d(of)i (RIPEMD)g(is)g(prop)r(osed.)g(In)g Ff(x)p Fv(3)g(w)n(e)g(giv)n(e)f(a)h (description)f(of)365 2184 y(the)31 b(new)f(sc)n(hemes,)f(and)h(in)g Ff(x)p Fv(4)g(w)n(e)f(motiv)-5 b(ate)30 b(the)g(design)g(decisions.)f (In)h Ff(x)p Fv(5)g(the)g(p)r(erfor-)365 2284 y(mance)d(of)g(the)g(new) g(v)n(ersions)f(of)h(RIPEMD)f(are)g(compared)g(to)h(other)f(MD4-based)h (hash)365 2383 y(functions.)h Ff(x)p Fv(6)f(presen)n(ts)g(the)h (conclusions.)365 2660 y Fn(2)112 b(Motiv)-6 b(ation)36 b(for)i(a)g(New)f(V)-9 b(ersion)36 b(of)i(RIPEMD)365 2868 y Fv(The)25 b(main)g(con)n(tribution)f(of)h(MD4)g(is)f(that)h(it)g (is)g(the)g(\014rst)g(cryptographic)d(hash)j(function)365 2967 y(whic)n(h)g(made)f(optimal)g(use)g(of)h(the)f(structure)g(of)g (curren)n(t)g(32-bit)g(pro)r(cessors.)e(The)i(use)g(of)365 3067 y(serial)h(op)r(erations)g(and)g(the)i(fa)n(v)n(orable)c(treatmen) n(t)j(of)g(little-endian)g(arc)n(hitectures)e(sho)n(w)365 3167 y(that)k(MD4)g(is)f(tuned)i(to)n(w)n(ards)c(soft)n(w)n(are)h (implemen)n(tations.)490 3268 y(Ho)n(w)n(ev)n(er,)32 b(in)n(tro)r(ducing)i(a)g(new)g(structure)g(in)h(cryptographic)d (algorithms)h(also)g(in-)365 3367 y(v)n(olv)n(es)i(the)j(risk)e(of)h (unexp)r(ected)g(w)n(eaknesses.)e(It)i(b)r(ecame)g(clear)f(that)h (existing)g(tec)n(h-)365 3467 y(niques)29 b(suc)n(h)g(as)f(di\013eren)n (tial)h(or)f(linear)h(cryptanalysis)e(w)n(ere)h(not)h(applicable,)g (and)g(that)365 3567 y(an)n(y)h(successful)h(cryptanalysis)e(w)n(ould)i (require)f(the)h(dev)n(elopmen)n(t)g(of)f(new)h(tec)n(hniques.)365 3666 y(The)h(attac)n(ks)e(b)n(y)g(B.)25 b(den)32 b(Bo)r(er)e(and)h(A.) 25 b(Bosselaers)k(on)i(t)n(w)n(o)f(\(out)i(of)f(three\))g(rounds)f(of) 365 3766 y(MD4)g([3])g(and)f(on)h(the)g(compression)e(function)j(of)f (MD5)f([4])h(w)n(ere)f(the)h(\014rst)g(indications)365 3866 y(that)f(some)f(structural)f(prop)r(erties)h(of)g(the)h (algorithms)e(can)h(b)r(e)h(exploited,)f(but)h(did)g(not)365 3965 y(seem)23 b(a)f(serious)g(threat)g(to)h(the)g(o)n(v)n(erall)e (algorithm.)g(More)h(recen)n(tly)-7 b(,)23 b(the)g(attac)n(k)f(on)g (MD4)365 4065 y(w)n(as)30 b(impro)n(v)n(ed)g(b)n(y)h(S.)25 b(V)-7 b(audena)n(y)30 b([18])h(yielding)g(t)n(w)n(o)f(hash-results)g (that)h(di\013er)g(only)g(in)365 4164 y(a)f(few)g(bits.)g(This)f(w)n (as)g(a)h(clear)e(illustration)h(that)h(MD4)g(did)g(not)g(b)r(eha)n(v)n (e)f(as)g(one)g(could)365 4264 y(exp)r(ect)f(from)f(a)f(random)g (function)i(\(e.g.,)f(it)h(is)f(not)g(correlation)e(resistan)n(t)h(as)h (de\014ned)g(in)365 4364 y([1]\).)490 4465 y(Early)34 b('95)i(H.)25 b(Dobb)r(ertin)36 b(found)h(collisions)d(for)i(the)g (last)g(t)n(w)n(o)f(out)h(of)g(three)g(\(and)365 4565 y(later)31 b(for)g(the)g(\014rst)g(t)n(w)n(o\))g(rounds)g(of)g(RIPEMD)g ([5].)g(While)h(this)f(is)h(not)f(an)g(immediate)365 4664 y(threat)21 b(to)g(RIPEMD)g(with)h(three)f(rounds,)f(the)h(attac)n (k)g(w)n(as)f(quite)h(surprising.)f(Moreo)n(v)n(er,)365 4764 y(it)26 b(in)n(tro)r(duced)g(a)f(new)g(tec)n(hnique)h(to)f (cryptanalyze)f(this)i(t)n(yp)r(e)g(of)g(functions.)g(In)f(the)h(F)-7 b(all)365 4863 y(of)33 b('95,)f(H.)25 b(Dobb)r(ertin)33 b(w)n(as)f(able)g(to)h(extend)g(these)f(tec)n(hniques)h(to)f(pro)r (duce)g(collisions)1785 5112 y(3)p eop %%Page: 4 4 4 3 bop 681 387 a Fv(for)30 b(MD4)g([6],)g(and)g(for)g(the)h (compression)e(function)i(of)f(the)h(extended)f(v)n(ersion)f(of)i(MD4) 681 487 y([13)o(])g(\(see)g(also)g Ff(x)24 b Fv(3.3\).)31 b(The)g(attac)n(k)g(on)g(MD4)g(requires)f(only)h(a)f(few)i(seconds)e (on)h(a)g(PC,)681 587 y(and)24 b(still)h(lea)n(v)n(es)e(some)g(freedom) h(to)h(the)g(message;)e(it)i(clearly)e(rules)h(out)g(the)h(use)f(of)h (MD4)681 686 y(as)i(a)g(collision)g(resistan)n(t)f(function.)805 786 y(It)31 b(is)f(an)n(ticipated)g(that)g(these)g(tec)n(hniques)g(can) g(b)r(e)g(used)h(to)f(pro)r(duce)f(collisions)g(for)681 886 y(MD5)k(and)f(p)r(erhaps)h(also)e(for)i(RIPEMD.)f(This)h(will)g (probably)f(require)g(an)g(additional)681 985 y(e\013ort,)27 b(but)h(it)g(no)g(longer)e(seems)h(as)g(far)g(a)n(w)n(a)n(y)f(as)h(it)h (w)n(as)e(a)h(y)n(ear)g(ago.)805 1085 y(An)d(indep)r(enden)n(t)g (reason)d(to)i(upgrade)f(RIPEMD)h(is)g(the)g(limited)h(resistance)e (against)681 1184 y(a)27 b(brute)h(force)g(collision)f(searc)n(h)f (attac)n(k.)i(P)-7 b(.)24 b(v)-5 b(an)28 b(Oorsc)n(hot)e(and)i(M.)d (Wiener)j(presen)n(t)f(in)681 1284 y([17)o(])h(a)g(design)f(for)g(a)h ($10)f(million)h(collision)f(searc)n(h)f(mac)n(hine)i(for)f(MD5)h(that) h(could)e(\014nd)681 1384 y(a)i(collision)g(in)h(24)e(da)n(ys.)h(If)h (only)f(a)g($1)g(million)h(budget)f(is)h(a)n(v)-5 b(ailable,)28 b(and)i(the)g(memory)681 1483 y(of)24 b(an)f(existing)h(computer)f(net) n(w)n(ork)g(is)g(used,)h(the)h(computation)e(w)n(ould)h(require)e(ab)r (out)i(6)681 1583 y(mon)n(ths.)h(T)-7 b(aking)26 b(in)n(to)f(accoun)n (t)g(the)h(fact)h(that)f(the)g(cost)f(of)h(computation)g(and)g(memory) 681 1683 y(is)h(divided)h(b)n(y)f(four)g(ev)n(ery)f(three)h(y)n(ears)f (\(this)h(observ)-5 b(ation)26 b(is)i(kno)n(wn)e(as)h(Mo)r(ore's)f(la)n (w\),)681 1782 y(one)31 b(can)g(conclude)g(that)g(a)g(128-bit)f (hash-result)g(do)r(es)h(not)g(o\013er)g(su\016cien)n(t)g(protection) 681 1882 y(for)e(the)i(next)f(ten)g(y)n(ears.)e(Note)i(that)g (collisions)f(obtained)h(in)g(this)g(w)n(a)n(y)f(need)h(less)g(than)681 1981 y(10)c(random)h(lo)r(oking)g(b)n(ytes;)g(the)h(rest)f(of)h(the)g (inputs)g(can)f(b)r(e)h(c)n(hosen)f(arbitrarily)-7 b(.)805 2081 y(RIPEMD)39 b(is)g(in)g(use)g(in)g(sev)n(eral)f(banking)g (applications,)g(and)h(is)g(\(together)f(with)681 2181 y(SHA-1\))26 b(curren)n(tly)f(under)h(consideration)e(as)h(a)h (candidate)f(for)h(standardization)e(within)681 2280 y(ISO/IEC)f(JTC1/SC27.)18 b(Ho)n(w)n(ev)n(er,)g(the)j(curren)n(t)e (situation)h(brings)f(us)h(to)g(the)h(conclusion)681 2380 y(that)31 b(it)g(w)n(ould)g(b)r(e)g(pruden)n(t)g(to)g(upgrade)e (curren)n(t)h(implemen)n(tations,)h(and)g(to)g(consider)681 2480 y(a)40 b(more)g(secure)g(sc)n(heme)g(for)g(standardization.)g (Therefore)f(the)i(authors)f(designed)g(a)681 2579 y(strengthened)33 b(v)n(ersion)f(of)i(RIPEMD-160)d(whic)n(h)j(should)g(b)r(e)g(secure)e (for)i(ten)g(y)n(ears)e(or)681 2679 y(more.)25 b(Also,)h(an)g(impro)n (v)n(ed)e(128-bit)h(v)n(ersion)g(is)h(prop)r(osed,)f(whic)n(h)h(should) g(only)f(b)r(e)i(used)681 2778 y(to)g(replace)g(RIPEMD)g(in)h(curren)n (t)f(applications.)805 2878 y(SHA-1)i(has)f(already)g(a)g(160-bit)g (result,)g(and)h(b)r(ecause)g(of)f(some)h(of)f(its)h(prop)r(erties)f (it)681 2978 y(is)h(quite)h(lik)n(ely)f(that)h(SHA-1)f(is)g(not)h (vulnerable)f(to)g(the)h(kno)n(wn)f(attac)n(ks.)f(Ho)n(w)n(ev)n(er,)g (its)681 3077 y(design)f(criteria)f(and)i(the)g(attac)n(k)e(on)i(the)g (\014rst)f(v)n(ersion)f(are)h(secret.)681 3334 y Fn(3)112 b(Description)36 b(of)h(the)h(New)f(RIPEMD)681 3521 y Fv(In)22 b(this)g(section)f(w)n(e)g(brie\015y)h(describ)r(e)f (RIPEMD-160,)f(RIPEMD-128,)g(and)h(t)n(w)n(o)g(v)-5 b(arian)n(ts)681 3621 y(whic)n(h)28 b(giv)n(e)f(a)g(longer)g(hash-result.)g(W)-7 b(e)28 b(assume)g(that)g(the)g(reader)f(is)h(familiar)f(with)h(the)681 3721 y(structure)f(and)g(notation)g(of)h(MD4)g(\(see)f(for)g(example)g ([13)o(]\).)681 3958 y Fk(3.1)94 b(RIPEMD-160)681 4112 y Fv(The)37 b(bitsize)f(of)h(the)g(hash-result)f(and)h(c)n(haining)e(v) -5 b(ariable)36 b(for)g(RIPEMD-160)f(are)h(in-)681 4211 y(creased)29 b(to)g(160)g(bits)h(\(\014v)n(e)g(32-bit)g(w)n(ords\),)f (the)h(n)n(um)n(b)r(er)g(of)g(rounds)f(is)h(increased)f(from)681 4311 y(three)e(to)h(\014v)n(e,)f(and)h(the)g(t)n(w)n(o)f(lines)g(are)g (made)h(more)f(di\013eren)n(t)g(\(not)h(only)g(the)g(constan)n(ts)681 4411 y(are)19 b(mo)r(di\014ed,)h(but)g(also)f(the)h(Bo)r(olean)e (functions)j(and)e(the)h(order)f(of)g(the)h(message)f(w)n(ords\).)805 4510 y(This)36 b(results)g(in)g(the)h(follo)n(wing)e(parameters)f (\(pseudo-co)r(de)h(for)h(RIPEMD-160)e(is)681 4610 y(giv)n(en)27 b(in)g(App)r(endix)f(A\):)716 4764 y(1.)41 b Fk(Op)s(erations)h(in)h (one)g(step.)36 b Fm(A)k Fv(:=)f(\()p Fm(A)26 b Fv(+)f Fm(f)9 b Fv(\()p Fm(B)t(;)14 b(C)q(;)g(D)r Fv(\))26 b(+)e Fm(X)32 b Fv(+)24 b Fm(K)6 b Fv(\))3109 4734 y Fg(\034)p Ft(s)3236 4764 y Fv(+)24 b Fm(E)43 b Fv(and)822 4863 y Fm(C)29 b Fv(:=)23 b Fm(C)1086 4833 y Fg(\034)p Fu(10)1223 4863 y Fv(.)k(Here)1470 4833 y Fg(\034)p Ft(s)1599 4863 y Fv(denotes)g(cyclic)h(shift)g(\(rotation\))f(o)n(v)n(er)f Fm(s)h Fv(p)r(ositions.)2101 5112 y(4)p eop %%Page: 5 5 5 4 bop 400 387 a Fv(2.)41 b Fk(Ordering)32 b(of)f(the)h(message)e(w)m (ords.)d Fv(T)-7 b(ak)n(e)26 b(the)i(follo)n(wing)f(p)r(erm)n(utation)g Fm(\032)p Fv(:)p 511 500 2731 4 v 509 600 4 100 v 709 600 V 726 600 V 884 600 V 1042 600 V 1199 600 V 1357 600 V 1515 600 V 1673 600 V 1831 600 V 1989 600 V 2147 600 V 2305 600 V 2463 600 V 2621 600 V 2778 600 V 2936 600 V 3094 600 V 3241 600 V 509 610 V 597 580 a Fm(i)p 709 610 V 726 610 V 160 w Fv(0)p 884 610 V 116 w(1)p 1042 610 V 115 w(2)p 1199 610 V 116 w(3)p 1357 610 V 116 w(4)p 1515 610 V 116 w(5)p 1673 610 V 116 w(6)p 1831 610 V 116 w(7)p 1989 610 V 116 w(8)p 2147 610 V 116 w(9)p 2305 610 V 95 w(10)p 2463 610 V 74 w(11)p 2621 610 V 74 w(12)p 2778 610 V 73 w(13)p 2936 610 V 74 w(14)p 3094 610 V 69 w(15)p 3241 610 V 511 613 2731 4 v 509 713 4 100 v 543 683 a Fm(\032)p Fv(\()p Fm(i)p Fv(\))p 709 713 V 726 713 V 107 w(7)p 884 713 V 116 w(4)p 1042 713 V 95 w(13)p 1199 713 V 94 w(1)p 1357 713 V 95 w(10)p 1515 713 V 95 w(6)p 1673 713 V 95 w(15)p 1831 713 V 95 w(3)p 1989 713 V 95 w(12)p 2147 713 V 95 w(0)p 2305 713 V 116 w(9)p 2463 713 V 115 w(5)p 2621 713 V 116 w(2)p 2778 713 V 95 w(14)p 2936 713 V 74 w(11)p 3094 713 V 89 w(8)p 3241 713 V 511 716 2731 4 v 506 966 a(F)-7 b(urther)31 b(de\014ne)g(the)f(p)r(erm)n(utation)h Fm(\031)j Fv(b)n(y)c(setting)g Fm(\031)s Fv(\()p Fm(i)p Fv(\))f(=)e(9)p Fm(i)20 b Fv(+)g(5)82 b(\(mo)r(d)28 b(16\).)i(The)506 1065 y(order)d(of)g(the)h(message)e(w)n (ords)h(is)g(then)h(giv)n(en)f(b)n(y)g(the)h(follo)n(wing)f(table:)p 639 1178 2448 4 v 637 1278 4 100 v 706 1248 a(Line)p 929 1278 V 946 1278 V 142 w(Round)g(1)p 1373 1278 V 118 w(Round)g(2)p 1801 1278 V 118 w(Round)g(3)p 2229 1278 V 118 w(Round)g(4)p 2657 1278 V 117 w(Round)h(5)p 3085 1278 V 639 1281 2448 4 v 639 1298 V 637 1397 4 100 v 726 1367 a(left)p 929 1397 V 946 1397 V 282 w Fm(id)p 1373 1397 V 370 w(\032)p 1801 1397 V 367 w(\032)2020 1337 y Fu(2)p 2229 1397 V 2405 1367 a Fm(\032)2448 1337 y Fu(3)p 2657 1397 V 2832 1367 a Fm(\032)2875 1337 y Fu(4)p 3085 1397 V 639 1401 2448 4 v 637 1500 4 100 v 698 1470 a Fv(righ)n(t)p 929 1500 V 946 1500 V 264 w Fm(\031)p 1373 1500 V 359 w(\032\031)p 1801 1500 V 320 w(\032)1995 1440 y Fu(2)2032 1470 y Fm(\031)p 2229 1500 V 300 w(\032)2422 1440 y Fu(3)2460 1470 y Fm(\031)p 2657 1500 V 300 w(\032)2850 1440 y Fu(4)2887 1470 y Fm(\031)p 3085 1500 V 639 1503 2448 4 v 400 1709 a Fv(3.)41 b Fk(Bo)s(olean)31 b(functions.)c Fv(De\014ne)h(the)g(follo)n(wing)f(Bo)r(olean)f (functions:)1307 1907 y Fm(f)1348 1919 y Fu(1)1385 1907 y Fv(\()p Fm(x;)14 b(y)s(;)g(z)t Fv(\))23 b(=)g Fm(x)c Ff(\010)f Fm(y)j Ff(\010)d Fm(z)t(;)1307 2031 y(f)1348 2043 y Fu(2)1385 2031 y Fv(\()p Fm(x;)c(y)s(;)g(z)t Fv(\))23 b(=)g(\()p Fm(x)c Ff(^)g Fm(y)s Fv(\))f Ff(_)h Fv(\()p Ff(:)p Fm(x)g Ff(^)g Fm(z)t Fv(\))p Fm(;)1307 2156 y(f)1348 2168 y Fu(3)1385 2156 y Fv(\()p Fm(x;)14 b(y)s(;)g(z)t Fv(\))23 b(=)g(\()p Fm(x)c Ff(_)g(:)p Fm(y)s Fv(\))f Ff(\010)g Fm(z)t(;)1307 2281 y(f)1348 2293 y Fu(4)1385 2281 y Fv(\()p Fm(x;)c(y)s(;)g(z)t Fv(\))23 b(=)g(\()p Fm(x)c Ff(^)g Fm(z)t Fv(\))f Ff(_)g Fv(\()p Fm(y)k Ff(^)d(:)p Fm(z)t Fv(\))p Fm(;)1307 2405 y(f)1348 2417 y Fu(5)1385 2405 y Fv(\()p Fm(x;)14 b(y)s(;)g(z)t Fv(\))23 b(=)g Fm(x)c Ff(\010)f Fv(\()p Fm(y)j Ff(_)e(:)p Fm(z)t Fv(\))p Fm(:)506 2603 y Fv(These)28 b(Bo)r(olean)e(functions)i(are)f(applied)g (as)g(follo)n(ws:)p 639 2716 V 637 2816 4 100 v 706 2786 a(Line)p 929 2816 V 946 2816 V 142 w(Round)g(1)p 1373 2816 V 118 w(Round)g(2)p 1801 2816 V 118 w(Round)g(3)p 2229 2816 V 118 w(Round)g(4)p 2657 2816 V 117 w(Round)h(5)p 3085 2816 V 639 2819 2448 4 v 639 2835 V 637 2935 4 100 v 726 2905 a(left)p 929 2935 V 946 2935 V 279 w Fm(f)1163 2917 y Fu(1)p 1373 2935 V 1550 2905 a Fm(f)1591 2917 y Fu(2)p 1801 2935 V 1978 2905 a Fm(f)2019 2917 y Fu(3)p 2229 2935 V 2406 2905 a Fm(f)2447 2917 y Fu(4)p 2657 2935 V 2834 2905 a Fm(f)2875 2917 y Fu(5)p 3085 2935 V 639 2938 2448 4 v 637 3038 4 100 v 698 3008 a Fv(righ)n(t)p 929 3038 V 946 3038 V 250 w Fm(f)1163 3020 y Fu(5)p 1373 3038 V 1550 3008 a Fm(f)1591 3020 y Fu(4)p 1801 3038 V 1978 3008 a Fm(f)2019 3020 y Fu(3)p 2229 3038 V 2406 3008 a Fm(f)2447 3020 y Fu(2)p 2657 3038 V 2834 3008 a Fm(f)2875 3020 y Fu(1)p 3085 3038 V 639 3041 2448 4 v 400 3247 a Fv(4.)41 b Fk(Shifts.)27 b Fv(F)-7 b(or)27 b(b)r(oth)h(lines)g(w)n(e)f(tak)n(e)g(the)h(follo)n(wing)e(shifts:)p 506 3443 2787 4 v 504 3542 4 100 v 518 3513 a(Round)p 769 3542 V 786 3542 V 52 w Fm(X)880 3525 y Fu(0)p 939 3542 V 964 3513 a Fm(X)1033 3525 y Fu(1)p 1092 3542 V 1117 3513 a Fm(X)1186 3525 y Fu(2)p 1245 3542 V 1270 3513 a Fm(X)1339 3525 y Fu(3)p 1398 3542 V 1424 3513 a Fm(X)1493 3525 y Fu(4)p 1551 3542 V 1577 3513 a Fm(X)1646 3525 y Fu(5)p 1705 3542 V 1730 3513 a Fm(X)1799 3525 y Fu(6)p 1858 3542 V 1883 3513 a Fm(X)1952 3525 y Fu(7)p 2011 3542 V 2036 3513 a Fm(X)2105 3525 y Fu(8)p 2164 3542 V 2189 3513 a Fm(X)2258 3525 y Fu(9)p 2317 3542 V 2331 3513 a Fm(X)2400 3525 y Fu(10)p 2480 3542 V 2493 3513 a Fm(X)2562 3525 y Fu(11)p 2642 3542 V 2655 3513 a Fm(X)2724 3525 y Fu(12)p 2804 3542 V 2818 3513 a Fm(X)2887 3525 y Fu(13)p 2967 3542 V 2980 3513 a Fm(X)3049 3525 y Fu(14)p 3129 3542 V 3142 3513 a Fm(X)3211 3525 y Fu(15)p 3291 3542 V 506 3546 2787 4 v 506 3562 V 504 3662 4 100 v 769 3662 V 786 3662 V 939 3662 V 1092 3662 V 1245 3662 V 1398 3662 V 1551 3662 V 1705 3662 V 1858 3662 V 2011 3662 V 2164 3662 V 2317 3662 V 2480 3662 V 2642 3662 V 2804 3662 V 2967 3662 V 3129 3662 V 3291 3662 V 504 3672 V 618 3642 a Fv(1)p 769 3672 V 786 3672 V 162 w(11)p 939 3672 V 70 w(14)p 1092 3672 V 69 w(15)p 1245 3672 V 69 w(12)p 1398 3672 V 90 w(5)p 1551 3672 V 111 w(8)p 1705 3672 V 111 w(7)p 1858 3672 V 111 w(9)p 2011 3672 V 91 w(11)p 2164 3672 V 69 w(13)p 2317 3672 V 74 w(14)p 2480 3672 V 78 w(15)p 2642 3672 V 99 w(6)p 2804 3672 V 120 w(7)p 2967 3672 V 121 w(9)p 3129 3672 V 120 w(8)p 3291 3672 V 506 3676 2787 4 v 504 3775 4 100 v 618 3745 a(2)p 769 3775 V 786 3775 V 162 w(12)p 939 3775 V 70 w(13)p 1092 3775 V 69 w(11)p 1245 3775 V 69 w(15)p 1398 3775 V 90 w(6)p 1551 3775 V 111 w(9)p 1705 3775 V 111 w(9)p 1858 3775 V 111 w(7)p 2011 3775 V 91 w(12)p 2164 3775 V 69 w(15)p 2317 3775 V 74 w(11)p 2480 3775 V 78 w(13)p 2642 3775 V 99 w(7)p 2804 3775 V 120 w(8)p 2967 3775 V 121 w(7)p 3129 3775 V 120 w(7)p 3291 3775 V 506 3778 2787 4 v 504 3878 4 100 v 618 3848 a(3)p 769 3878 V 786 3878 V 162 w(13)p 939 3878 V 70 w(15)p 1092 3878 V 69 w(14)p 1245 3878 V 69 w(11)p 1398 3878 V 90 w(7)p 1551 3878 V 111 w(7)p 1705 3878 V 111 w(6)p 1858 3878 V 111 w(8)p 2011 3878 V 91 w(13)p 2164 3878 V 69 w(14)p 2317 3878 V 74 w(13)p 2480 3878 V 78 w(12)p 2642 3878 V 99 w(5)p 2804 3878 V 120 w(5)p 2967 3878 V 121 w(6)p 3129 3878 V 120 w(9)p 3291 3878 V 506 3881 2787 4 v 504 3981 4 100 v 618 3951 a(4)p 769 3981 V 786 3981 V 162 w(14)p 939 3981 V 70 w(11)p 1092 3981 V 69 w(12)p 1245 3981 V 69 w(14)p 1398 3981 V 90 w(8)p 1551 3981 V 111 w(6)p 1705 3981 V 111 w(5)p 1858 3981 V 111 w(5)p 2011 3981 V 91 w(15)p 2164 3981 V 69 w(12)p 2317 3981 V 74 w(15)p 2480 3981 V 78 w(14)p 2642 3981 V 99 w(9)p 2804 3981 V 120 w(9)p 2967 3981 V 121 w(8)p 3129 3981 V 120 w(6)p 3291 3981 V 506 3984 2787 4 v 504 4084 4 100 v 618 4054 a(5)p 769 4084 V 786 4084 V 162 w(15)p 939 4084 V 70 w(12)p 1092 4084 V 69 w(13)p 1245 4084 V 69 w(13)p 1398 4084 V 90 w(9)p 1551 4084 V 111 w(5)p 1705 4084 V 111 w(8)p 1858 4084 V 111 w(6)p 2011 4084 V 91 w(14)p 2164 4084 V 69 w(11)p 2317 4084 V 74 w(12)p 2480 4084 V 78 w(11)p 2642 4084 V 99 w(8)p 2804 4084 V 120 w(6)p 2967 4084 V 121 w(5)p 3129 4084 V 120 w(5)p 3291 4084 V 506 4087 2787 4 v 400 4335 a(5.)41 b Fk(Constan)m(ts.)28 b Fv(T)-7 b(ak)n(e)26 b(the)i(in)n(teger)f(parts)g(of)g(the)h(follo)n (wing)f(n)n(um)n(b)r(ers:)p 639 4447 2448 4 v 637 4547 4 100 v 706 4517 a(Line)p 929 4547 V 946 4547 V 142 w(Round)g(1)p 1373 4547 V 118 w(Round)g(2)p 1801 4547 V 118 w(Round)g(3)p 2229 4547 V 118 w(Round)g(4)p 2657 4547 V 117 w(Round)h(5)p 3085 4547 V 639 4550 2448 4 v 639 4567 V 637 4666 4 100 v 929 4666 V 946 4666 V 1373 4666 V 1801 4666 V 2229 4666 V 2657 4666 V 3085 4666 V 637 4682 4 106 v 726 4652 a(left)p 929 4682 V 946 4682 V 297 w(0)p 1373 4682 V 266 w(2)1490 4622 y Fu(30)1578 4652 y Ff(\001)1619 4584 y(p)p 1689 4584 42 4 v 1689 4652 a Fv(2)p 1801 4682 4 106 v 144 w(2)1917 4622 y Fu(30)2006 4652 y Ff(\001)2047 4584 y(p)p 2116 4584 42 4 v 68 x Fv(3)p 2229 4682 4 106 v 145 w(2)2345 4622 y Fu(30)2434 4652 y Ff(\001)2475 4584 y(p)p 2544 4584 42 4 v 68 x Fv(5)p 2657 4682 4 106 v 145 w(2)2773 4622 y Fu(30)2862 4652 y Ff(\001)2903 4584 y(p)p 2972 4584 42 4 v 68 x Fv(7)p 3085 4682 4 106 v 639 4686 2448 4 v 637 4785 4 100 v 929 4785 V 946 4785 V 1373 4785 V 1801 4785 V 2229 4785 V 2657 4785 V 3085 4785 V 637 4801 4 106 v 698 4771 a(righ)n(t)p 929 4801 V 946 4801 V 145 w(2)1059 4741 y Fu(30)1147 4771 y Ff(\001)1212 4733 y Fe(3)1194 4702 y Ff(p)p 1263 4702 42 4 v 69 x Fv(2)p 1373 4801 4 106 v 140 w(2)1487 4741 y Fu(30)1575 4771 y Ff(\001)1640 4733 y Fe(3)1622 4702 y Ff(p)p 1691 4702 42 4 v 69 x Fv(3)p 1801 4801 4 106 v 140 w(2)1915 4741 y Fu(30)2003 4771 y Ff(\001)2068 4733 y Fe(3)2050 4702 y Ff(p)p 2119 4702 42 4 v 69 x Fv(5)p 2229 4801 4 106 v 140 w(2)2343 4741 y Fu(30)2431 4771 y Ff(\001)2496 4733 y Fe(3)2478 4702 y Ff(p)p 2547 4702 42 4 v 69 x Fv(7)p 2657 4801 4 106 v 263 w(0)p 3085 4801 V 639 4804 2448 4 v 1785 5112 a(5)p eop %%Page: 6 6 6 5 bop 681 387 a Fk(3.2)94 b(RIPEMD-128)681 553 y Fv(The)25 b(main)g(di\013erence)g(with)h(RIPEMD-160)c(is)j(that)h(w)n(e)e(k)n (eep)h(a)g(hash-result)f(and)h(c)n(hain-)681 653 y(ing)i(v)-5 b(ariable)27 b(of)g(128)f(bits)i(\(four)g(32-bit)f(w)n(ords\);)f(only)h (four)h(rounds)e(are)h(used.)716 819 y(1.)41 b Fk(Op)s(eration)31 b(in)g(one)h(step.)27 b Fm(A)c Fv(:=)g(\()p Fm(A)c Fv(+)f Fm(f)9 b Fv(\()p Fm(B)t(;)14 b(C)q(;)g(D)r Fv(\))19 b(+)f Fm(X)25 b Fv(+)18 b Fm(K)6 b Fv(\))2955 789 y Fg(\034)p Ft(s)3056 819 y Fv(.)716 919 y(2.)41 b Fk(Bo)s(olean)31 b(functions.)26 b Fv(The)i(Bo)r(olean)f(functions)g(are)g(applied)h(as) f(follo)n(ws:)p 1169 1013 2020 4 v 1167 1112 4 100 v 1235 1083 a(Line)p 1458 1112 V 1475 1112 V 142 w(Round)h(1)p 1903 1112 V 117 w(Round)g(2)p 2331 1112 V 117 w(Round)g(3)p 2758 1112 V 117 w(Round)g(4)p 3186 1112 V 1169 1116 2020 4 v 1169 1132 V 1167 1232 4 100 v 1256 1202 a(left)p 1458 1232 V 1475 1232 V 278 w Fm(f)1692 1214 y Fu(1)p 1903 1232 V 2079 1202 a Fm(f)2120 1214 y Fu(2)p 2331 1232 V 2507 1202 a Fm(f)2548 1214 y Fu(3)p 2758 1232 V 2935 1202 a Fm(f)2976 1214 y Fu(4)p 3186 1232 V 1169 1235 2020 4 v 1167 1335 4 100 v 1228 1305 a Fv(righ)n(t)p 1458 1335 V 1475 1335 V 249 w Fm(f)1692 1317 y Fu(4)p 1903 1335 V 2079 1305 a Fm(f)2120 1317 y Fu(3)p 2331 1335 V 2507 1305 a Fm(f)2548 1317 y Fu(2)p 2758 1335 V 2935 1305 a Fm(f)2976 1317 y Fu(1)p 3186 1335 V 1169 1338 2020 4 v 716 1520 a Fv(3.)41 b Fk(Constan)m(ts.)27 b Fv(T)-7 b(ak)n(e)27 b(the)h(in)n(teger)f(parts)f(of)i(the)g(follo)n (wing)e(n)n(um)n(b)r(ers:)p 1169 1614 V 1167 1714 4 100 v 1235 1684 a(Line)p 1458 1714 V 1475 1714 V 142 w(Round)i(1)p 1903 1714 V 117 w(Round)g(2)p 2331 1714 V 117 w(Round)g(3)p 2758 1714 V 117 w(Round)g(4)p 3186 1714 V 1169 1717 2020 4 v 1169 1734 V 1167 1834 4 100 v 1458 1834 V 1475 1834 V 1903 1834 V 2331 1834 V 2758 1834 V 3186 1834 V 1167 1849 4 106 v 1256 1820 a(left)p 1458 1849 V 1475 1849 V 297 w(0)p 1903 1849 V 265 w(2)2019 1789 y Fu(30)2107 1820 y Ff(\001)2149 1751 y(p)p 2218 1751 42 4 v 69 x Fv(2)p 2331 1849 4 106 v 145 w(2)2447 1789 y Fu(30)2535 1820 y Ff(\001)2577 1751 y(p)p 2646 1751 42 4 v 69 x Fv(3)p 2758 1849 4 106 v 145 w(2)2875 1789 y Fu(30)2963 1820 y Ff(\001)3005 1751 y(p)p 3074 1751 42 4 v 69 x Fv(5)p 3186 1849 4 106 v 1169 1853 2020 4 v 1167 1952 4 100 v 1458 1952 V 1475 1952 V 1903 1952 V 2331 1952 V 2758 1952 V 3186 1952 V 1167 1968 4 106 v 1228 1938 a(righ)n(t)p 1458 1968 V 1475 1968 V 145 w(2)1589 1908 y Fu(30)1677 1938 y Ff(\001)1741 1900 y Fe(3)1724 1870 y Ff(p)p 1793 1870 42 4 v 68 x Fv(2)p 1903 1968 4 106 v 139 w(2)2016 1908 y Fu(30)2105 1938 y Ff(\001)2169 1900 y Fe(3)2151 1870 y Ff(p)p 2221 1870 42 4 v 2221 1938 a Fv(3)p 2331 1968 4 106 v 139 w(2)2444 1908 y Fu(30)2533 1938 y Ff(\001)2597 1900 y Fe(3)2579 1870 y Ff(p)p 2649 1870 42 4 v 2649 1938 a Fv(5)p 2758 1968 4 106 v 262 w(0)p 3186 1968 V 1169 1972 2020 4 v 681 2237 a Fk(3.3)94 b(Optional)31 b(Extensions)g(to)g(256)g(and)i(320)e(bit)g(Hash-Results) 681 2403 y Fv(Some)19 b(applications)g(of)g(hash)h(functions)f(require) g(a)g(longer)f(hash-result,)h(without)h(needing)681 2502 y(a)34 b(larger)e(securit)n(y)i(lev)n(el.)g(A)g(straigh)n(tforw)n(ard)e (w)n(a)n(y)h(to)h(ac)n(hiev)n(e)f(this)i(w)n(ould)f(b)r(e)h(to)f(use) 681 2602 y(t)n(w)n(o)j(parallel)f(instances)h(of)g(the)h(same)f(hash)g (function)i(with)f(di\013eren)n(t)f(initial)h(v)-5 b(alues;)681 2702 y(ho)n(w)n(ev)n(er,)34 b(this)k(migh)n(t)e(result)h(in)g(un)n(w)n (an)n(ted)f(dep)r(endencies)h(b)r(et)n(w)n(een)f(the)i(t)n(w)n(o)e(c)n (hains)681 2801 y(\(suc)n(h)31 b(dep)r(endencies)g(ha)n(v)n(e)e(b)r (een)j(exploited)e(in)h(the)h(attac)n(k)e(on)g(RIPEMD\).)h(Therefore) 681 2901 y(it)d(is)f(advisable)g(to)g(ha)n(v)n(e)g(a)g(stronger)f(in)n (teraction)g(b)r(et)n(w)n(een)i(the)g(t)n(w)n(o)f(instances.)805 3000 y(In)f([13)o(])g(an)g(extension)f(of)h(MD4)g(w)n(as)f(prop)r(osed) g(whic)n(h)g(yields)h(a)f(256-bit)g(hash-result)681 3100 y(b)n(y)j(running)g(t)n(w)n(o)g(parallel)f(instances)h(of)h(MD4)f(whic) n(h)h(di\013er)g(only)f(in)g(the)h(initial)g(v)-5 b(alues)681 3200 y(and)30 b(in)h(the)g(constan)n(ts)f(in)h(the)g(second)f(and)h (third)g(round.)f(After)h(ev)n(ery)f(application)g(of)681 3299 y(the)35 b(compression)e(function,)i(the)g(v)-5 b(alue)35 b(of)f(the)h(register)e Fm(A)i Fv(is)g(in)n(terc)n(hanged)e (b)r(et)n(w)n(een)681 3399 y(the)26 b(t)n(w)n(o)g(c)n(hains.)g(H.)f (Dobb)r(ertin)i(w)n(as)e(able)h(to)g(pro)r(duce)g(collisions)f(for)h (the)g(compression)681 3499 y(function)c(of)f(this)g(extension;)g (moreo)n(v)n(er,)e(w)n(e)i(an)n(ticipate)g(that)g(it)h(is)f(p)r (ossible)g(to)g(construct)681 3598 y(collisions)26 b(for)h(the)h (complete)g(extension)f(as)g(w)n(ell.)805 3698 y(RIPEMD-128)20 b(and)h(RIPEMD-160)e(ha)n(v)n(e)h(already)g(t)n(w)n(o)h(parallel)f (lines,)i(hence)f(a)g(dou-)681 3798 y(ble)32 b(length)g(extension)f (\(to)h(256)f(resp)r(ectiv)n(ely)g(320)g(bits\))h(can)g(b)r(e)g (constructed)f(without)681 3897 y(the)k(need)g(for)f(t)n(w)n(o)g (parallel)g(instances:)g(it)h(is)g(su\016cien)n(t)g(to)g(omit)g(the)g (com)n(bination)f(of)681 3997 y(the)g(t)n(w)n(o)f(lines)h(at)f(the)i (end)f(of)f(ev)n(ery)g(application)g(of)h(the)g(compression)e (function.)i(W)-7 b(e)681 4096 y(prop)r(ose)34 b(to)i(in)n(tro)r(duce)f (in)n(teraction)g(b)r(et)n(w)n(een)g(the)h(lines)g(b)n(y)f(sw)n(apping) g(after)g(round)24 b(1)681 4196 y(the)j(con)n(ten)n(ts)e(of)i (registers)d(A)j(and)f(A',)h(after)f(round)e(2)i(the)h(con)n(ten)n(ts)f (of)g(registers)f(B)h(and)681 4296 y(B',)h(etc.)681 4565 y Fn(4)112 b(Motiv)-6 b(ation)36 b(of)h(the)h(Design)f(Decisions)681 4764 y Fv(The)30 b(main)h(design)f(principle)g(of)g(RIPEMD-160)f(is)h (to)g(o)n(v)n(ercome)e(the)j(problems)f(raised)681 4863 y(in)d Ff(x)p Fv(2,)g(but)h(with)g(as)f(few)g(c)n(hanges)f(as)h(p)r (ossible)g(to)g(the)g(original)f(structure)h(to)g(maximize)2101 5112 y(6)p eop %%Page: 7 7 7 6 bop 365 387 a Fv(on)33 b(con\014dence)f(previously)g(gained)g(with) i(RIPEMD)e(and)h(its)g(predecessors)d(MD4)j(and)365 487 y(MD5.)490 597 y(Also,)g(it)h(w)n(as)e(decided)h(to)h(aim)f(for)f(a)h (rather)g(conserv)-5 b(ativ)n(e)31 b(design)i(whic)n(h)g(o\013ers)g(a) 365 697 y(high)d(securit)n(y)e(lev)n(el,)h(rather)f(than)i(to)f(push)h (the)g(limits)g(of)f(p)r(erformance)f(with)i(the)g(risk)365 796 y(of)e(a)f(redesign)g(a)g(few)h(y)n(ears)e(from)h(no)n(w.)490 906 y(The)e(basic)g(design)f(philosoph)n(y)h(of)g(RIPEMD)g(w)n(as)f(to) h(ha)n(v)n(e)f(t)n(w)n(o)g(parallel)g(iterations;)365 1006 y(the)c(t)n(w)n(o)e(main)h(impro)n(v)n(emen)n(ts)e(are)h(that)h (the)h(n)n(um)n(b)r(er)e(of)h(rounds)f(is)h(increased)f(from)g(three) 365 1106 y(to)27 b(\014v)n(e)g(\(four)f(for)h(RIPEMD-128\))e(and)h (that)h(the)h(t)n(w)n(o)e(parallel)f(rounds)i(are)e(made)i(more)365 1205 y(di\013eren)n(t.)k(F)-7 b(rom)31 b(the)g(attac)n(k)f(on)h(RIPEMD) f(w)n(e)h(conclude)g(that)g(ha)n(ving)f(only)g(di\013eren)n(t)365 1305 y(additiv)n(e)22 b(constan)n(ts)f(in)i(the)f(t)n(w)n(o)g(lines)g (is)g(not)g(su\016cien)n(t.)g(In)h(RIPEMD-160,)d(the)i(order)f(of)365 1405 y(the)27 b(message)e(blo)r(c)n(ks)h(in)h(the)g(t)n(w)n(o)f (iterations)f(is)i(completely)f(di\013eren)n(t;)h(in)f(addition,)h(the) 365 1504 y(order)e(of)g(the)h(Bo)r(olean)f(functions)h(is)g(rev)n (ersed.)e(W)-7 b(e)26 b(en)n(visage)e(that)i(in)g(the)g(next)g(y)n (ears)e(it)365 1604 y(will)h(b)r(ecome)f(p)r(ossible)g(to)g(attac)n(k)f (one)h(of)g(the)h(t)n(w)n(o)e(lines)h(and)h(up)f(to)g(three)g(rounds)g (of)g(the)365 1703 y(t)n(w)n(o)30 b(parallel)g(lines,)h(but)h(that)f (the)g(com)n(bination)f(of)h(the)g(t)n(w)n(o)f(parallel)g(lines)h(will) g(resist)365 1803 y(attac)n(ks.)490 1913 y(The)d(op)r(eration)e(for)i (RIPEMD-160)d(on)j(the)g Fm(A)g Fv(register)f(is)g(related)h(to)f(that) h(of)g(MD5)365 2013 y(\(but)37 b(\014v)n(e)e(w)n(ords)f(are)h(in)n(v)n (olv)n(ed\);)f(the)i(rotate)f(of)g(the)h Fm(C)42 b Fv(register)34 b(has)h(b)r(een)h(added)f(to)365 2112 y(a)n(v)n(oid)28 b(the)i(MD5)g(attac)n(k)f(whic)n(h)g(fo)r(cuses)g(on)h(the)g(most)f (signi\014can)n(t)g(bit)h([4].)f(SHA-1)h(has)365 2212 y(t)n(w)n(o)c(rotates)f(as)h(w)n(ell,)h(but)g(in)g(di\013eren)n(t)f(lo) r(cations.)g(The)g(v)-5 b(alue)27 b(of)f(10)g(for)g(the)h Fm(C)33 b Fv(register)365 2312 y(w)n(as)f(c)n(hosen)g(since)g(it)h(is)g (not)f(used)h(for)f(the)h(other)f(rotations.)g(The)g(step)h(op)r (eration)f(for)365 2411 y(RIPEMD-128)26 b(is)h(iden)n(tical)h(to)f (that)h(of)g(MD4)f(\(and)h(RIPEMD\).)490 2521 y(The)h(p)r(erm)n (utation)f(of)h(the)h(message)d(w)n(ords)h(of)g(RIPEMD)h(w)n(as)f (designed)g(suc)n(h)h(that)365 2621 y(t)n(w)n(o)37 b(w)n(ords)f(that)i (are)f(`close')g(in)h(round)f(1-2)g(are)f(far)h(apart)g(in)h(round)f (2-3)g(\(and)h(vice)365 2721 y(v)n(ersa\).)25 b(If)h(this)g(p)r(erm)n (utation)f(w)n(ould)g(ha)n(v)n(e)g(b)r(een)h(applied)f(in)h (RIPEMD-160,)e(this)i(crite-)365 2820 y(rion)d(w)n(ould)g(not)h(ha)n(v) n(e)e(b)r(een)i(satis\014ed)f(\(message)g(blo)r(c)n(ks)f(2)i(and)f(13)g (form)g(an)g(undesirable)365 2920 y(pattern)i(due)f(to)g(a)g(cycle)g (of)h(length)f(2)g([5]\).)h(Therefore,)e(it)i(w)n(as)e(decided)i(to)f (exc)n(hange)f(the)365 3020 y(v)-5 b(alues)33 b(for)f(12)g(and)g(13,)g (resulting)h(in)g(the)g(p)r(erm)n(utation)f Fm(\032)h Fv(of)g Ff(x)p Fv(3.1.)f(The)h(p)r(erm)n(utation)365 3119 y Fm(\031)h Fv(w)n(as)c(c)n(hosen)f(suc)n(h)i(that)f(t)n(w)n(o)g (message)f(w)n(ords)h(whic)n(h)g(are)g(close)f(in)i(the)g(left)g(half)g (will)365 3219 y(alw)n(a)n(ys)26 b(b)r(e)h(at)g(least)g(sev)n(en)f(p)r (ositions)h(apart)f(in)i(the)f(righ)n(t)g(half.)g(F)-7 b(or)26 b(the)i(Bo)r(olean)e(func-)365 3318 y(tions,)f(it)g(w)n(as)f (decided)h(to)g(eliminate)g(the)g(ma)5 b(jorit)n(y)23 b(function)j(b)r(ecause)e(of)h(its)g(symmetry)365 3418 y(prop)r(erties)h(and)h(a)g(p)r(erformance)e(disadv)-5 b(an)n(tage.)26 b(The)h(Bo)r(olean)e(functions)j(are)e(no)n(w)g(the)365 3518 y(same)j(as)f(those)h(used)g(in)g(MD5.)h(As)f(men)n(tioned)g(ab)r (o)n(v)n(e,)f(the)h(Bo)r(olean)f(functions)i(in)f(the)365 3617 y(left)g(and)e(righ)n(t)g(half)h(are)e(used)i(in)g(a)f(di\013eren) n(t)h(order.)490 3727 y(The)33 b(shifts)h(in)f(RIPEMD)g(w)n(ere)f(c)n (hosen)g(according)f(to)i(a)g(sp)r(eci\014c)g(strategy)-7 b(,)32 b(whic)n(h)365 3827 y(w)n(as)19 b(only)h(do)r(cumen)n(ted)h(in)f (an)g(in)n(ternal)g(rep)r(ort.)f(The)h(same)g(strategy)f(has)g(b)r(een) i(extended)365 3927 y(to)k(the)h(strengthened)f(algorithms)f(in)i(a)e (straigh)n(tforw)n(ard)f(w)n(a)n(y)-7 b(.)24 b(The)h(design)g(criteria) f(are)365 4026 y(the)k(follo)n(wing:)417 4234 y Fk({)41 b Fv(the)25 b(shifts)g(are)f(c)n(hosen)f(b)r(et)n(w)n(een)i(5)f(and)g (15)f(\(to)r(o)i(small/large)d(shifts)j(are)e(considered)506 4334 y(not)28 b(v)n(ery)e(go)r(o)r(d,)h(and)h(a)f(c)n(hoice)g(larger)f (than)h(16)g(do)r(es)g(not)h(help)g(m)n(uc)n(h\);)417 4444 y Fk({)41 b Fv(ev)n(ery)19 b(message)g(blo)r(c)n(k)h(should)g(b)r (e)g(rotated)f(o)n(v)n(er)g(di\013eren)n(t)h(amoun)n(ts,)g(not)g(all)g (of)g(them)506 4544 y(ha)n(ving)27 b(the)h(same)f(parit)n(y;)417 4654 y Fk({)41 b Fv(the)f(shifts)f(applied)f(to)h(eac)n(h)f(register)f (should)i(not)g(ha)n(v)n(e)e(a)h(sp)r(ecial)h(pattern)g(\(for)506 4753 y(example,)28 b(the)g(total)f(should)g(not)h(b)r(e)g(divisible)g (b)n(y)f(32\);)417 4863 y Fk({)41 b Fv(not)28 b(to)r(o)f(man)n(y)g (shift)i(constan)n(ts)d(should)i(b)r(e)g(divisible)f(b)n(y)g(four.)1785 5112 y(7)p eop %%Page: 8 8 8 7 bop 805 387 a Fv(Note)37 b(that)f(the)h(design)f(decisions)f (require)g(a)h(compromise:)f(it)i(is)f(not)g(p)r(ossible)g(to)681 487 y(mak)n(e)25 b(a)h(go)r(o)r(d)g(c)n(hoice)g(of)g(message)f (ordering)f(and)j(shift)g(constan)n(ts)e(for)h(\014v)n(e)g(rounds)f (that)681 587 y(is)i(also)g(`optimal')g(for)g(three)h(rounds)f(out)g (of)h(\014v)n(e.)681 834 y Fn(5)112 b(P)m(erformance)37 b(Ev)-6 b(aluation)681 1012 y Fv(In)39 b(this)h(section)f(w)n(e)g (compare)f(the)i(p)r(erformance)e(of)h(RIPEMD-160,)f(RIPEMD-128,)681 1111 y(RIPEMD,)29 b(SHA-1,)g(MD5,)h(and)f(MD4.)g(Implemen)n(tations)h (w)n(ere)e(written)i(in)f(Assem)n(bly)681 1211 y(language)21 b(optimized)j(for)f(the)g(P)n(en)n(tium)g(pro)r(cessor)e(\(90)k(MHz\).) f(Note)f(that)h(the)f(n)n(um)n(b)r(ers)681 1310 y(are)f(for)h (realistic)f(inputs,)i(i.e.,)f(256)f(Megab)n(yte)g(of)i(data)e(are)h (hashed)f(using)h(an)g(8)i(K)e(bu\013er)681 1410 y(\(this)29 b(is)g(slo)n(w)n(er)e(than)h(hashing)h(short)f(blo)r(c)n(ks)f(from)i (the)g(cac)n(he)f(memory\).)g(The)h(relativ)n(e)681 1510 y(sp)r(eeds)36 b(coincide)g(more)f(or)h(less)g(with)g(predictions)g (based)g(on)g(a)g(simple)g(coun)n(t)g(of)g(the)681 1609 y(n)n(um)n(b)r(er)29 b(of)g(op)r(erations.)g(RIPEMD-160)e(is)i(ab)r (out)h(15\045)e(slo)n(w)n(er)g(than)h(SHA-1,)h(half)f(the)681 1709 y(sp)r(eed)38 b(of)f(RIPEMD,)h(and)g(four)f(times)h(slo)n(w)n(er)e (than)i(MD4.)g(On)f(a)g(big-endian)g(RISC)681 1809 y(mac)n(hine,)22 b(the)i(di\013erence)f(b)r(et)n(w)n(een)g(SHA-1)g(and)g(RIPEMD-160)d (will)k(b)r(e)f(sligh)n(tly)g(larger.)681 1908 y(RIPEMD-128)28 b(is)j(30\045)f(slo)n(w)n(er)f(than)h(RIPEMD.)h(Optimized)g(C)f (implemen)n(tations)h(are)681 2008 y(a)25 b(factor)g(of)h(1.8.)13 b(.)g(.)h(2.2)25 b(slo)n(w)n(er;)f(for)h(MD5)h(the)g(sp)r(eed)g(of)g (our)f(C)g(co)r(de)h(is)g(36\045)f(faster)g(than)681 2107 y(that)j(of)f([16)o(].)732 2441 y Fo(T)-7 b(able)28 b(1.)e Fr(P)n(erformance)g(of)g(sev)n(eral)h(MD4-based)f(hash)f (functions)h(on)g(a)g(90)g(MHz)f(P)n(en)n(tium)p 1408 2536 1427 4 v 1406 2627 4 92 v 1467 2600 a(algorithm)p 1983 2627 V 1983 2627 V 253 w(p)r(erformance)g(\(Mbit/s\))p 2833 2627 V 1406 2719 V 1983 2719 V 1983 2719 V 2044 2691 a(Assem)n(bly)236 b(C)p 2833 2719 V 1408 2722 1427 4 v 1406 2813 4 92 v 1467 2786 a(MD4)p 1983 2813 V 482 w(165.7)271 b(81.4)p 2833 2813 V 1406 2905 V 1467 2877 a(MD5)p 1983 2905 V 482 w(113.5)g(59.7)p 2833 2905 V 1406 2996 V 1467 2969 a(SHA-1)p 1983 2996 V 464 w(46.5)g(21.2)p 2833 2996 V 1406 3087 V 1467 3060 a(RIPEMD)p 1983 3087 V 369 w(82.1)g(44.0)p 2833 3087 V 1406 3179 V 1467 3151 a(RIPEMD-128)p 1983 3179 V 229 w(63.8)g(35.6)p 2833 3179 V 1406 3270 V 1467 3242 a(RIPEMD-160)p 1983 3270 V 229 w(39.8)g(19.3)p 2833 3270 V 1408 3273 1427 4 v 681 3761 a Fn(6)112 b(Concluding)36 b(Remarks)681 3939 y Fv(W)-7 b(e)22 b(ha)n(v)n(e)e(prop)r(osed)g(RIPEMD-160,)g(whic)n(h)h(is)h(an)f (enhanced)g(v)n(ersion)f(of)h(RIPEMD.)h(The)681 4038 y(design)31 b(is)h(made)g(suc)n(h)g(that)g(the)h(con\014dence)f(built)g (up)h(with)f(RIPEMD)g(is)g(transferred)681 4138 y(to)26 b(the)h(new)f(algorithm.)f(The)i(signi\014can)n(t)e(increase)g(in)i (securit)n(y)e(comes)h(at)g(the)h(cost)f(of)g(a)681 4237 y(reduced)c(p)r(erformance)f(\(a)i(factor)e(of)i(t)n(w)n(o\),)f(but)h (the)g(resulting)f(sp)r(eed)g(is)h(still)f(acceptable.)681 4337 y(W)-7 b(e)28 b(encourage)d(commen)n(ts)j(and)f(results)g(on)g (the)h(securit)n(y)f(of)h(RIPEMD-160.)681 4565 y Fk(Ac)m(kno)m (wledgmen)m(ts)54 b Fv(W)-7 b(e)38 b(w)n(ould)f(lik)n(e)g(to)g(thank)h (Bert)f(den)h(Bo)r(er,)f(Markus)f(Dic)n(h)n(tl,)681 4664 y(W)-7 b(alter)39 b(F)-7 b(um)n(y)g(,)40 b(and)f(P)n(eter)f(Landro)r(c) n(k)g(for)h(encouragemen)n(t)f(and)h(advice,)g(and)g(Chris)681 4764 y(Mitc)n(hell,)34 b(Xuejia)h(Lai,)f(and)g(W)-7 b(ei)35 b(Dai)f(for)g(helpful)h(commen)n(ts)f(on)g(earlier)e(v)n(ersions)h(of) 681 4863 y(this)28 b(pap)r(er.)2101 5112 y(8)p eop %%Page: 9 9 9 8 bop 365 387 a Fn(References)404 578 y Fr(1.)42 b(R.)25 b(Anderson,)37 b(\\The)h(classi\014cation)h(of)f(hash)g(functions,")g Fi(Pr)l(o)l(c.)h(of)f(the)h(IMA)e(Confer-)505 670 y(enc)l(e)26 b(on)f(Crypto)l(gr)l(aphy)j(and)e(Co)l(ding,)f(Cir)l(enc)l(ester,)i(De) l(c)l(emb)l(er)f(1993)p Fr(,)e(Oxford)f(Univ)n(ersit)n(y)505 761 y(Press,)k(1995,)g(pp.)e(83{95.)404 852 y(2.)42 b(I.B.)26 b(Damg)-10 b(\027)-48 b(ard,)29 b(\\A)h(design)g(principle)g(for)h (hash)e(functions,")61 b Fi(A)l(dvanc)l(es)33 b(in)e(Cryptolo)l(gy,)505 944 y(Pr)l(o)l(c.)23 b(Crypto'89,)h(LNCS)h(435)p Fr(,)c(G.)26 b(Brassard,)c(Ed.,)f(Springer-V)-6 b(erlag,)21 b(1990,)i(pp.)h (416{427.)404 1035 y(3.)42 b(B.)26 b(den)20 b(Bo)r(er,)j(A.)i (Bosselaers,)f(\\An)d(attac)n(k)g(on)h(the)f(last)h(t)n(w)n(o)f(rounds) g(of)i(MD4,")43 b Fi(A)l(dvanc)l(es)505 1126 y(in)31 b(Cryptolo)l(gy,)h(Pr)l(o)l(c.)g(Crypto'91,)g(LNCS)25 b(576)p Fr(,)31 b(J.)25 b(F)-6 b(eigen)n(baum,)30 b(Ed.,)g(Springer-V) -6 b(erlag,)505 1218 y(1992,)27 b(pp.)e(194{203.)404 1309 y(4.)42 b(B.)26 b(den)20 b(Bo)r(er,)i(A.)j(Bosselaers,)e (\\Collisions)h(for)e(the)e(compression)h(function)g(of)g(MD5,")42 b Fi(A)l(d-)505 1400 y(vanc)l(es)29 b(in)e(Cryptolo)l(gy,)i(Pr)l(o)l (c.)f(Eur)l(o)l(crypt'93,)h(LNCS)c(765)p Fr(,)h(T.)g(Helleseth,)h(Ed.,) f(Springer-)505 1492 y(V)-6 b(erlag,)26 b(1994,)i(pp.)c(293{304.)404 1583 y(5.)42 b(H.)25 b(Dobb)r(ertin,)k(\\RIPEMD)h(with)f(t)n(w)n (o-round)g(compress)h(function)f(is)h(not)f(collisionfree,")505 1674 y Fi(Journal)f(of)f(Cryptolo)l(gy)p Fr(,)h(to)e(app)r(ear.)404 1766 y(6.)42 b(H.)25 b(Dobb)r(ertin,)g(\\Cryptanalysis)i(of)g(MD4,")f Fi(F)-6 b(ast)29 b(Softwar)l(e)g(Encryption)p Fr(,)e(this)f(v)n(olume.) 404 1857 y(7.)42 b(FIPS)25 b(180-1,)g Fi(Se)l(cur)l(e)i(hash)f(standar) l(d,)f Fr(NIST,)e(US)g(Departmen)n(t)f(of)i(Commerce,)f(W)-6 b(ashing-)505 1948 y(ton)25 b(D.C.,)i(April)f(1995.)404 2040 y(8.)42 b(R.)25 b(Merkle,)33 b(\\One)f(w)n(a)n(y)g(hash)g (functions)h(and)f(DES,")64 b Fi(A)l(dvanc)l(es)36 b(in)d(Cryptolo)l (gy,)i(Pr)l(o)l(c.)505 2131 y(Crypto'89,)28 b(LNCS)d(435)p Fr(,)i(G.)e(Brassard,)j(Ed.,)e(Springer-V)-6 b(erlag,)26 b(1990,)h(pp.)e(428{446.)404 2222 y(9.)42 b(C.H.)26 b(Mey)n(er,)44 b(M.)26 b(Sc)n(hilling,)45 b(\\Secure)g(program)f(load)h(with)g (Manipulation)g(Detection)505 2313 y(Co)r(de,")27 b Fi(Pr)l(o)l(c.)h (Se)l(curic)l(om)h(1988)p Fr(,)d(pp.)f(111{130.)365 2405 y(10.)43 b(B.)26 b(Preneel,)32 b(R.)25 b(Go)n(v)l(aerts,)32 b(J.)26 b(V)-6 b(andew)n(alle,)32 b(\\Hash)g(functions)g(based)g(on)f (blo)r(c)n(k)h(ciphers:)505 2496 y(a)43 b(syn)n(thetic)f(approac)n(h,") 86 b Fi(A)l(dvanc)l(es)45 b(in)e(Cryptolo)l(gy,)i(Pr)l(o)l(c.)e (Crypto'93,)h(LNCS)25 b(773)p Fr(,)505 2587 y(D.)g(Stinson,)h(Ed.,)g (Springer-V)-6 b(erlag,)26 b(1994,)h(pp.)e(368{378.)365 2679 y(11.)43 b(B.)26 b(Preneel,)36 b Fi(Crypto)l(gr)l(aphic)j(Hash)d (F)-6 b(unctions)p Fr(,)37 b(Klu)n(w)n(er)f(Academic)e(Publishers,)i (to)g(ap-)505 2770 y(p)r(ear.)365 2861 y(12.)43 b(RIPE,)59 b Fi(\\Inte)l(grity)i(Primitives)d(for)h(Se)l(cur)l(e)h(Information)e (Systems.)i(Final)e(R)l(ep)l(ort)505 2953 y(of)c(RA)n(CE)g(Inte)l (grity)i(Primitives)f(Evaluation)g(\(RIPE-RA)n(CE)25 b(1040\),")56 b(LNCS)25 b(1007)p Fr(,)505 3044 y(Springer-V)-6 b(erlag,)26 b(1995.)365 3135 y(13.)43 b(R.L.)25 b(Riv)n(est,)c(\\The)i (MD4)e(message)i(digest)f(algorithm,")44 b Fi(A)l(dvanc)l(es)25 b(in)f(Cryptolo)l(gy,)h(Pr)l(o)l(c.)505 3227 y(Crypto'90,)j(LNCS)d(537) p Fr(,)i(S.)e(V)-6 b(anstone,)25 b(Ed.,)h(Springer-V)-6 b(erlag,)26 b(1991,)i(pp.)d(303{311.)365 3318 y(14.)43 b(R.L.)25 b(Riv)n(est,)f(\\The)h(MD4)g(message-digest)g(algorithm,")h Fi(R)l(e)l(quest)i(for)e(Comments)i(\(RF)n(C\))505 3409 y(1320)p Fr(,)f(In)n(ternet)d(Activities)i(Board,)h(In)n(ternet)e(Priv) l(acy)g(T)-6 b(ask)26 b(F)-6 b(orce,)27 b(April)e(1992.)365 3501 y(15.)43 b(R.L.)25 b(Riv)n(est,)f(\\The)h(MD5)g(message-digest)g (algorithm,")h Fi(R)l(e)l(quest)i(for)e(Comments)i(\(RF)n(C\))505 3592 y(1321)p Fr(,)f(In)n(ternet)d(Activities)i(Board,)h(In)n(ternet)e (Priv)l(acy)g(T)-6 b(ask)26 b(F)-6 b(orce,)27 b(April)e(1992.)365 3683 y(16.)43 b(J.)26 b(T)-6 b(ouc)n(h,)36 b(\\Rep)r(ort)h(on)g(MD5)g (p)r(erformance,")h Fi(R)l(e)l(quest)i(for)d(Comments)i(\(RF)n(C\))f (1810)p Fr(,)505 3775 y(In)n(ternet)25 b(Activities)h(Board,)g(In)n (ternet)f(Priv)l(acy)h(T)-6 b(ask)25 b(F)-6 b(orce,)27 b(June)e(1995.)365 3866 y(17.)43 b(P)-6 b(.C.)26 b(v)l(an)19 b(Oorsc)n(hot,)i(M.J.)26 b(Wiener,)21 b(\\P)n(arallel)i(collision)f (searc)n(h)e(with)h(application)g(to)f(hash)505 3957 y(functions)26 b(and)f(discrete)g(logarithms,")i Fi(Pr)l(o)l(c.)h(2nd)f (A)n(CM)g(Confer)l(enc)l(e)i(on)e(Computer)i(and)505 4049 y(Communic)l(ations)f(Se)l(curity)p Fr(,)f(A)n(CM,)g(1994,)g(pp.)e (210{218.)365 4140 y(18.)43 b(S.)25 b(V)-6 b(audena)n(y)g(,)41 b(\\On)h(the)g(need)g(for)h(m)n(ultip)r(erm)n(utations:)e (cryptanalysis)i(of)g(MD4)f(and)505 4231 y(SAFER,")35 b Fi(F)-6 b(ast)21 b(Softwar)l(e)g(Encryption,)g(LNCS)k(1008)p Fr(,)19 b(B.)25 b(Preneel,)19 b(Ed.,)f(Springer-V)-6 b(erlag,)505 4323 y(1995,)27 b(pp.)e(286{297.)365 4414 y(19.)43 b(G.)25 b(Y)-6 b(uv)l(al,)25 b(\\Ho)n(w)i(to)e(swindle)i (Rabin,")f Fi(Cryptolo)l(gia)p Fr(,)h(V)-6 b(ol.)25 b(3,)h(No.)g(3,)g (1979,)i(pp.)c(187{189.)1785 5112 y Fv(9)p eop %%Page: 10 10 10 9 bop 681 387 a Fn(A)111 b(Pseudo-co)s(de)39 b(for)e(RIPEMD-160)681 617 y Fv(RIPEMD-160)29 b(is)j(an)f(iterativ)n(e)f(hash)h(function)h (that)g(op)r(erates)f(on)g(32-bit)g(w)n(ords.)f(The)681 717 y(round)23 b(function)i(tak)n(es)e(as)g(input)i(a)f(5-w)n(ord)e(c)n (haining)h(v)-5 b(ariable)23 b(and)h(a)g(16-w)n(ord)d(message)681 816 y(blo)r(c)n(k)32 b(and)g(maps)g(this)h(to)g(a)f(new)g(c)n(haining)g (v)-5 b(ariable.)31 b(All)i(op)r(erations)f(are)f(de\014ned)i(on)681 916 y(32-bit)25 b(w)n(ords.)f(P)n(adding)h(is)h(iden)n(tical)f(to)h (that)g(of)g(MD4)g([13)o(,)g(14)o(].)g(T)-7 b(est)26 b(v)-5 b(alues)26 b(are)e(listed)681 1016 y(in)k(App)r(endix)d(B.)j (First)f(w)n(e)h(de\014ne)f(all)h(the)g(constan)n(ts)e(and)i (functions.)847 1277 y Fk(RIPEMD-160:)i(de\014nitions)847 1476 y Fl(nonline)l(ar)g(functions)g(at)f(bit)h(level:)i(exor,)e(mux,)f (-,)h(mux,)f(-)847 1592 y Fm(f)9 b Fv(\()p Fm(j;)14 b(x;)g(y)s(;)g(z)t Fv(\))22 b(=)h Fm(x)c Ff(\010)f Fm(y)j Ff(\010)d Fm(z)868 b Fv(\(0)23 b Ff(\024)g Fm(j)28 b Ff(\024)22 b Fv(15\))847 1709 y Fm(f)9 b Fv(\()p Fm(j;)14 b(x;)g(y)s(;)g(z)t Fv(\))22 b(=)h(\()p Fm(x)c Ff(^)g Fm(y)s Fv(\))f Ff(_)h Fv(\()p Ff(:)p Fm(x)h Ff(^)f Fm(z)t Fv(\))517 b(\(16)22 b Ff(\024)h Fm(j)28 b Ff(\024)22 b Fv(31\))847 1825 y Fm(f)9 b Fv(\()p Fm(j;)14 b(x;)g(y)s(;)g(z)t Fv(\))22 b(=)h(\()p Fm(x)c Ff(_)g(:)p Fm(y)s Fv(\))g Ff(\010)f Fm(z)716 b Fv(\(32)22 b Ff(\024)h Fm(j)28 b Ff(\024)22 b Fv(47\))847 1941 y Fm(f)9 b Fv(\()p Fm(j;)14 b(x;)g(y)s(;)g(z)t Fv(\))22 b(=)h(\()p Fm(x)c Ff(^)g Fm(z)t Fv(\))f Ff(_)h Fv(\()p Fm(y)i Ff(^)e(:)p Fm(z)t Fv(\))523 b(\(48)22 b Ff(\024)h Fm(j)28 b Ff(\024)22 b Fv(63\))847 2057 y Fm(f)9 b Fv(\()p Fm(j;)14 b(x;)g(y)s(;)g(z)t Fv(\))22 b(=)h Fm(x)c Ff(\010)f Fv(\()p Fm(y)j Ff(_)e(:)p Fm(z)t Fv(\))713 b(\(64)22 b Ff(\024)h Fm(j)28 b Ff(\024)22 b Fv(79\))847 2257 y Fl(adde)l(d)31 b(c)l(onstants)e(\(hexade)l(cimal\))847 2373 y Fm(K)6 b Fv(\()p Fm(j)f Fv(\))23 b(=)k Fq(00000000)1454 2387 y(x)1842 2373 y Fv(\(0)c Ff(\024)g Fm(j)28 b Ff(\024)23 b Fv(15\))847 2489 y Fm(K)6 b Fv(\()p Fm(j)f Fv(\))23 b(=)k Fq(5A827999)1454 2503 y(x)1801 2489 y Fv(\(16)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(31\))172 b Ff(b)p Fv(2)2544 2459 y Fu(30)2632 2489 y Ff(\001)2674 2420 y(p)p 2743 2420 42 4 v 69 x Fv(2)14 b Ff(c)847 2605 y Fm(K)6 b Fv(\()p Fm(j)f Fv(\))23 b(=)k Fq(6ED9EBA1)1454 2619 y(x)1801 2605 y Fv(\(32)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(47\))172 b Ff(b)p Fv(2)2544 2575 y Fu(30)2632 2605 y Ff(\001)2674 2537 y(p)p 2743 2537 V 68 x Fv(3)14 b Ff(c)847 2721 y Fm(K)6 b Fv(\()p Fm(j)f Fv(\))23 b(=)k Fq(8F1BBCDC)1454 2735 y(x)1801 2721 y Fv(\(48)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(63\))172 b Ff(b)p Fv(2)2544 2691 y Fu(30)2632 2721 y Ff(\001)2674 2653 y(p)p 2743 2653 V 68 x Fv(5)14 b Ff(c)847 2838 y Fm(K)6 b Fv(\()p Fm(j)f Fv(\))23 b(=)k Fq(A953FD4E)1454 2852 y(x)1801 2838 y Fv(\(64)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(79\))172 b Ff(b)p Fv(2)2544 2808 y Fu(30)2632 2838 y Ff(\001)2674 2769 y(p)p 2743 2769 V 69 x Fv(7)14 b Ff(c)847 2954 y Fm(K)924 2924 y Fg(0)947 2954 y Fv(\()p Fm(j)5 b Fv(\))23 b(=)k Fq(50A28BE6)1477 2968 y(x)1842 2954 y Fv(\(0)c Ff(\024)g Fm(j)28 b Ff(\024)23 b Fv(15\))172 b Ff(b)p Fv(2)2544 2924 y Fu(30)2632 2954 y Ff(\001)2697 2915 y Fe(3)2679 2885 y Ff(p)p 2748 2885 V 69 x Fv(2)14 b Ff(c)847 3070 y Fm(K)924 3040 y Fg(0)947 3070 y Fv(\()p Fm(j)5 b Fv(\))23 b(=)k Fq(5C4DD124)1477 3084 y(x)1801 3070 y Fv(\(16)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(31\))172 b Ff(b)p Fv(2)2544 3040 y Fu(30)2632 3070 y Ff(\001)2697 3032 y Fe(3)2679 3001 y Ff(p)p 2748 3001 V 69 x Fv(3)14 b Ff(c)847 3186 y Fm(K)924 3156 y Fg(0)947 3186 y Fv(\()p Fm(j)5 b Fv(\))23 b(=)k Fq(6D703EF3)1477 3200 y(x)1801 3186 y Fv(\(32)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(47\))172 b Ff(b)p Fv(2)2544 3156 y Fu(30)2632 3186 y Ff(\001)2697 3148 y Fe(3)2679 3118 y Ff(p)p 2748 3118 V 68 x Fv(5)14 b Ff(c)847 3303 y Fm(K)924 3272 y Fg(0)947 3303 y Fv(\()p Fm(j)5 b Fv(\))23 b(=)k Fq(7A6D76E9)1477 3317 y(x)1801 3303 y Fv(\(48)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(63\))172 b Ff(b)p Fv(2)2544 3272 y Fu(30)2632 3303 y Ff(\001)2697 3264 y Fe(3)2679 3234 y Ff(p)p 2748 3234 V 69 x Fv(7)14 b Ff(c)847 3419 y Fm(K)924 3389 y Fg(0)947 3419 y Fv(\()p Fm(j)5 b Fv(\))23 b(=)k Fq(00000000)1477 3433 y(x)1801 3419 y Fv(\(64)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(79\))847 3618 y Fl(sele)l(ction)30 b(of)h(message)f (wor)l(d)847 3734 y Fm(r)r Fv(\()p Fm(j)5 b Fv(\))287 b(=)23 b Fm(j)874 b Fv(\(0)22 b Ff(\024)h Fm(j)28 b Ff(\024)23 b Fv(15\))847 3851 y Fm(r)r Fv(\(16)p Fm(::)p Fv(31\))112 b(=)23 b(7)p Fm(;)14 b Fv(4)p Fm(;)g Fv(13)p Fm(;)g Fv(1)p Fm(;)g Fv(10)p Fm(;)g Fv(6)p Fm(;)g Fv(15)p Fm(;)g Fv(3)p Fm(;)g Fv(1)o(2)p Fm(;)f Fv(0)p Fm(;)h Fv(9)o Fm(;)g Fv(5)p Fm(;)g Fv(2)o Fm(;)g Fv(14)o Fm(;)g Fv(11)o Fm(;)g Fv(8)847 3967 y Fm(r)r Fv(\(32)p Fm(::)p Fv(47\))112 b(=)23 b(3)p Fm(;)14 b Fv(10)p Fm(;)g Fv(14)p Fm(;)g Fv(4)p Fm(;)g Fv(9)p Fm(;)g Fv(15)p Fm(;)g Fv(8)p Fm(;)g Fv(1)p Fm(;)g Fv(2)o Fm(;)g Fv(7)o Fm(;)g Fv(0)p Fm(;)g Fv(6)o Fm(;)g Fv(13)o Fm(;)g Fv(11)o Fm(;)g Fv(5)p Fm(;)f Fv(12)847 4083 y Fm(r)r Fv(\(48)p Fm(::)p Fv(63\))112 b(=)23 b(1)p Fm(;)14 b Fv(9)p Fm(;)g Fv(11)p Fm(;)g Fv(10)p Fm(;)g Fv(0)p Fm(;)g Fv(8)p Fm(;)g Fv(12)p Fm(;)g Fv(4)p Fm(;)g Fv(1)o(3)p Fm(;)f Fv(3)p Fm(;)h Fv(7)o Fm(;)g Fv(15)o Fm(;)g Fv(14)o Fm(;)g Fv(5)p Fm(;)g Fv(6)o Fm(;)g Fv(2)847 4199 y Fm(r)r Fv(\(64)p Fm(::)p Fv(79\))112 b(=)23 b(4)p Fm(;)14 b Fv(0)p Fm(;)g Fv(5)p Fm(;)g Fv(9)p Fm(;)g Fv(7)p Fm(;)g Fv(12)p Fm(;)g Fv(2)p Fm(;)g Fv(10)p Fm(;)g Fv(14)o Fm(;)g Fv(1)o Fm(;)g Fv(3)p Fm(;)g Fv(8)o Fm(;)g Fv(11)o Fm(;)g Fv(6)p Fm(;)f Fv(15)p Fm(;)g Fv(13)847 4315 y Fm(r)886 4285 y Fg(0)910 4315 y Fv(\(0)p Fm(::)p Fv(15\))130 b(=)23 b(5)p Fm(;)14 b Fv(14)p Fm(;)g Fv(7)p Fm(;)g Fv(0)p Fm(;)g Fv(9)p Fm(;)g Fv(2)p Fm(;)g Fv(11)p Fm(;)g Fv(4)p Fm(;)g Fv(13)o Fm(;)g Fv(6)o Fm(;)g Fv(15)o Fm(;)g Fv(8)p Fm(;)g Fv(1)o Fm(;)g Fv(10)o Fm(;)g Fv(3)p Fm(;)f Fv(12)847 4432 y Fm(r)886 4402 y Fg(0)910 4432 y Fv(\(16)p Fm(::)p Fv(31\))88 b(=)23 b(6)p Fm(;)14 b Fv(11)p Fm(;)g Fv(3)p Fm(;)g Fv(7)p Fm(;)g Fv(0)p Fm(;)g Fv(13)p Fm(;)g Fv(5)p Fm(;)g Fv(10)p Fm(;)g Fv(1)o(4)p Fm(;)f Fv(15)o Fm(;)h Fv(8)p Fm(;)g Fv(1)o(2)p Fm(;)g Fv(4)o Fm(;)g Fv(9)p Fm(;)g Fv(1)o Fm(;)g Fv(2)847 4548 y Fm(r)886 4518 y Fg(0)910 4548 y Fv(\(32)p Fm(::)p Fv(47\))88 b(=)23 b(15)p Fm(;)14 b Fv(5)p Fm(;)g Fv(1)p Fm(;)g Fv(3)p Fm(;)g Fv(7)p Fm(;)g Fv(14)p Fm(;)g Fv(6)p Fm(;)g Fv(9)p Fm(;)g Fv(11)o Fm(;)g Fv(8)o Fm(;)g Fv(12)o Fm(;)g Fv(2)p Fm(;)g Fv(1)o(0)p Fm(;)g Fv(0)o Fm(;)g Fv(4)p Fm(;)f Fv(13)847 4664 y Fm(r)886 4634 y Fg(0)910 4664 y Fv(\(48)p Fm(::)p Fv(63\))88 b(=)23 b(8)p Fm(;)14 b Fv(6)p Fm(;)g Fv(4)p Fm(;)g Fv(1)p Fm(;)g Fv(3)p Fm(;)g Fv(11)p Fm(;)g Fv(15)p Fm(;)g Fv(0)p Fm(;)g Fv(5)p Fm(;)f Fv(12)o Fm(;)h Fv(2)p Fm(;)g Fv(1)o(3)p Fm(;)g Fv(9)o Fm(;)g Fv(7)p Fm(;)f Fv(10)p Fm(;)g Fv(14)847 4780 y Fm(r)886 4750 y Fg(0)910 4780 y Fv(\(64)p Fm(::)p Fv(79\))88 b(=)23 b(12)p Fm(;)14 b Fv(15)p Fm(;)g Fv(10)p Fm(;)g Fv(4)p Fm(;)g Fv(1)p Fm(;)g Fv(5)p Fm(;)g Fv(8)p Fm(;)g Fv(7)p Fm(;)g Fv(6)o Fm(;)g Fv(2)o Fm(;)g Fv(13)o Fm(;)g Fv(14)o Fm(;)g Fv(0)p Fm(;)g Fv(3)o Fm(;)g Fv(9)p Fm(;)f Fv(11)2080 5112 y(10)p eop %%Page: 11 11 11 10 bop 531 387 a Fl(amount)30 b(for)g(r)l(otate)g(left)g(\()p Fv(rol)o Fl(\))531 504 y Fm(s)p Fv(\(0)p Fm(::)p Fv(15\))155 b(=)22 b(11)p Fm(;)14 b Fv(14)p Fm(;)g Fv(15)p Fm(;)g Fv(12)p Fm(;)g Fv(5)p Fm(;)g Fv(8)p Fm(;)g Fv(7)p Fm(;)g Fv(9)p Fm(;)g Fv(1)o(1)p Fm(;)f Fv(13)o Fm(;)h Fv(14)o Fm(;)g Fv(15)o Fm(;)g Fv(6)p Fm(;)g Fv(7)o Fm(;)g Fv(9)p Fm(;)f Fv(8)531 620 y Fm(s)p Fv(\(16)p Fm(::)p Fv(31\))113 b(=)22 b(7)p Fm(;)14 b Fv(6)p Fm(;)g Fv(8)p Fm(;)g Fv(13)p Fm(;)g Fv(11)p Fm(;)g Fv(9)p Fm(;)g Fv(7)p Fm(;)g Fv(15)p Fm(;)g Fv(7)p Fm(;)f Fv(12)o Fm(;)h Fv(15)o Fm(;)g Fv(9)p Fm(;)g Fv(1)o(1)p Fm(;)g Fv(7)o Fm(;)g Fv(13)o Fm(;)g Fv(1)o(2)531 736 y Fm(s)p Fv(\(32)p Fm(::)p Fv(47\))113 b(=)22 b(11)p Fm(;)14 b Fv(13)p Fm(;)g Fv(6)p Fm(;)g Fv(7)p Fm(;)g Fv(14)p Fm(;)g Fv(9)p Fm(;)g Fv(13)p Fm(;)g Fv(15)o Fm(;)g Fv(14)o Fm(;)g Fv(8)o Fm(;)g Fv(13)o Fm(;)g Fv(6)p Fm(;)g Fv(5)o Fm(;)g Fv(12)o Fm(;)g Fv(7)p Fm(;)f Fv(5)531 852 y Fm(s)p Fv(\(48)p Fm(::)p Fv(63\))113 b(=)22 b(11)p Fm(;)14 b Fv(12)p Fm(;)g Fv(14)p Fm(;)g Fv(15)p Fm(;)g Fv(14)p Fm(;)g Fv(15)p Fm(;)g Fv(9)o Fm(;)g Fv(8)p Fm(;)g Fv(9)o Fm(;)g Fv(1)o(4)p Fm(;)g Fv(5)o Fm(;)g Fv(6)p Fm(;)g Fv(8)o Fm(;)g Fv(6)p Fm(;)g Fv(5)o Fm(;)g Fv(1)o(2)531 969 y Fm(s)p Fv(\(64)p Fm(::)p Fv(79\))113 b(=)22 b(9)p Fm(;)14 b Fv(15)p Fm(;)g Fv(5)p Fm(;)g Fv(11)p Fm(;)g Fv(6)p Fm(;)g Fv(8)p Fm(;)g Fv(13)p Fm(;)g Fv(12)p Fm(;)g Fv(5)o Fm(;)g Fv(1)o(2)p Fm(;)g Fv(1)o(3)p Fm(;)g Fv(1)o(4)p Fm(;)g Fv(1)o(1)p Fm(;)g Fv(8)o Fm(;)g Fv(5)p Fm(;)f Fv(6)531 1085 y Fm(s)570 1055 y Fg(0)594 1085 y Fv(\(0)p Fm(::)p Fv(15\))131 b(=)22 b(8)p Fm(;)14 b Fv(9)p Fm(;)g Fv(9)p Fm(;)g Fv(11)p Fm(;)g Fv(13)p Fm(;)g Fv(15)p Fm(;)g Fv(15)p Fm(;)g Fv(5)p Fm(;)g Fv(7)o Fm(;)g Fv(7)o Fm(;)g Fv(8)p Fm(;)g Fv(1)o(1)p Fm(;)g Fv(1)o(4)p Fm(;)g Fv(1)o(4)p Fm(;)g Fv(1)o(2)p Fm(;)f Fv(6)531 1201 y Fm(s)570 1171 y Fg(0)594 1201 y Fv(\(16)p Fm(::)p Fv(31\))89 b(=)22 b(9)p Fm(;)14 b Fv(13)p Fm(;)g Fv(15)p Fm(;)g Fv(7)p Fm(;)g Fv(12)p Fm(;)g Fv(8)p Fm(;)g Fv(9)p Fm(;)g Fv(11)p Fm(;)g Fv(7)o Fm(;)g Fv(7)o Fm(;)g Fv(12)o Fm(;)g Fv(7)p Fm(;)g Fv(6)o Fm(;)g Fv(15)o Fm(;)g Fv(13)o Fm(;)g Fv(1)o(1)531 1317 y Fm(s)570 1287 y Fg(0)594 1317 y Fv(\(32)p Fm(::)p Fv(47\))89 b(=)22 b(9)p Fm(;)14 b Fv(7)p Fm(;)g Fv(15)p Fm(;)g Fv(11)p Fm(;)g Fv(8)p Fm(;)g Fv(6)p Fm(;)g Fv(6)p Fm(;)g Fv(14)p Fm(;)g Fv(12)o Fm(;)g Fv(1)o(3)p Fm(;)g Fv(5)o Fm(;)g Fv(14)o Fm(;)g Fv(13)o Fm(;)g Fv(13)o Fm(;)g Fv(7)p Fm(;)f Fv(5)531 1433 y Fm(s)570 1403 y Fg(0)594 1433 y Fv(\(48)p Fm(::)p Fv(63\))89 b(=)22 b(15)p Fm(;)14 b Fv(5)p Fm(;)g Fv(8)p Fm(;)g Fv(11)p Fm(;)g Fv(14)p Fm(;)g Fv(14)p Fm(;)g Fv(6)p Fm(;)g Fv(14)o Fm(;)g Fv(6)p Fm(;)f Fv(9)p Fm(;)h Fv(1)o(2)p Fm(;)g Fv(9)o Fm(;)g Fv(12)o Fm(;)g Fv(5)p Fm(;)g Fv(1)o(5)p Fm(;)f Fv(8)531 1550 y Fm(s)570 1520 y Fg(0)594 1550 y Fv(\(64)p Fm(::)p Fv(79\))89 b(=)22 b(8)p Fm(;)14 b Fv(5)p Fm(;)g Fv(12)p Fm(;)g Fv(9)p Fm(;)g Fv(12)p Fm(;)g Fv(5)p Fm(;)g Fv(14)p Fm(;)g Fv(6)p Fm(;)g Fv(8)p Fm(;)f Fv(13)o Fm(;)h Fv(6)p Fm(;)g Fv(5)o Fm(;)g Fv(15)o Fm(;)g Fv(13)o Fm(;)g Fv(11)o Fm(;)g Fv(1)o(1)531 1749 y Fl(initial)31 b(value)g(\(hexade)l (cimal\))531 1865 y Fm(h)579 1877 y Fu(0)644 1865 y Fv(=)c Fq(67452301)1048 1879 y(x)1089 1865 y Fv(;)h Fm(h)1188 1877 y Fu(1)1253 1865 y Fv(=)f Fq(EFCDAB89)1657 1879 y(x)1698 1865 y Fv(;)h Fm(h)1797 1877 y Fu(2)1862 1865 y Fv(=)f Fq(98BADCFE)2266 1879 y(x)2307 1865 y Fv(;)531 1981 y Fm(h)579 1993 y Fu(3)644 1981 y Fv(=)g Fq(10325476)1048 1995 y(x)1089 1981 y Fv(;)h Fm(h)1188 1993 y Fu(4)1253 1981 y Fv(=)f Fq(C3D2E1F0)1657 1995 y(x)1698 1981 y Fv(;)490 2139 y(It)36 b(is)f(assumed)g(that)h(the)g(message)e(after)i(padding)f (consists)g(of)g Fm(t)h Fv(16-w)n(ord)d(blo)r(c)n(ks)365 2239 y(that)27 b(will)g(b)r(e)f(denoted)h(with)g Fm(X)1381 2251 y Ft(i)1408 2239 y Fv([)p Fm(j)5 b Fv(],)27 b(with)g(0)e Ff(\024)e Fm(i)g Ff(\024)f Fm(t)16 b Ff(\000)g Fv(1)26 b(and)g(0)g Ff(\024)d Fm(j)28 b Ff(\024)e Fv(15.)f(The)i(sym)n(b)r(ol)p 397 2294 54 4 v 397 2341 4 48 v 448 2341 V 397 2344 54 4 v 401 2319 48 4 v 423 2340 4 48 v 508 2338 a(denotes)e(addition)f(mo) r(dulo)h(2)1467 2308 y Fu(32)1561 2338 y Fv(and)g(rol)1817 2350 y Ft(s)1877 2338 y Fv(denotes)g(cyclic)f(left)i(shift)f (\(rotate\))f(o)n(v)n(er)f Fm(s)365 2438 y Fv(p)r(ositions.)g(The)f (pseudo-co)r(de)g(for)g(RIPEMD-160)f(is)i(then)g(giv)n(en)f(b)r(elo)n (w,)g(and)h(an)f(outline)365 2538 y(of)28 b(the)g(compression)e (function)i(is)f(giv)n(en)g(in)h(Figure)c(1.)531 2787 y Fk(RIPEMD-160:)30 b(pseudo-co)s(de)531 2903 y Fl(for)f Fm(i)e Fv(:=)h(0)f Fl(to)g Fm(t)19 b Ff(\000)f Fv(1)27 b Ff(f)697 3019 y Fm(A)42 b Fv(:=)27 b Fm(h)964 3031 y Fu(0)1002 3019 y Fv(;)g Fm(B)46 b Fv(:=)27 b Fm(h)1324 3031 y Fu(1)1361 3019 y Fv(;)h Fm(C)48 b Fv(:=)27 b Fm(h)1682 3031 y Fu(2)1719 3019 y Fv(;)h Fm(D)44 b Fv(=)27 b Fm(h)2023 3031 y Fu(3)2060 3019 y Fv(;)h Fm(E)46 b Fv(=)27 b Fm(h)2358 3031 y Fu(4)2395 3019 y Fv(;)697 3135 y Fm(A)759 3105 y Fg(0)811 3135 y Fv(:=)g Fm(h)974 3147 y Fu(0)1011 3135 y Fv(;)h Fm(B)1129 3105 y Fg(0)1180 3135 y Fv(:=)f Fm(h)1343 3147 y Fu(1)1380 3135 y Fv(;)h Fm(C)1496 3105 y Fg(0)1547 3135 y Fv(:=)g Fm(h)1711 3147 y Fu(2)1748 3135 y Fv(;)f Fm(D)1869 3105 y Fg(0)1920 3135 y Fv(=)h Fm(h)2061 3147 y Fu(3)2098 3135 y Fv(;)f Fm(E)2214 3105 y Fg(0)2265 3135 y Fv(=)h Fm(h)2406 3147 y Fu(4)2443 3135 y Fv(;)697 3252 y Fl(for)h Fm(j)k Fv(:=)27 b(0)g Fl(to)h Fv(79)e Ff(f)863 3368 y Fm(T)39 b Fv(:=)27 b(rol)1164 3383 y Ft(s)p Fu(\()p Ft(j)s Fu(\))1296 3368 y Fv(\()p Fm(A)p 1422 3323 54 4 v 1422 3370 4 48 v 1473 3370 V 1422 3373 54 4 v 1426 3348 48 4 v 1448 3370 4 48 v 118 w(f)9 b Fv(\()p Fm(j;)14 b(B)t(;)g(C)q(;)g(D)r Fv(\))p 1998 3323 54 4 v 1998 3370 4 48 v 2049 3370 V 1998 3373 54 4 v 2002 3348 48 4 v 2024 3370 4 48 v 119 w Fm(X)2153 3380 y Ft(i)2181 3368 y Fv([)p Fm(r)r Fv(\()p Fm(j)5 b Fv(\)])p 2402 3323 54 4 v 2402 3370 4 48 v 2453 3370 V 2402 3373 54 4 v 2406 3348 48 4 v 2428 3370 4 48 v 119 w Fm(K)h Fv(\()p Fm(j)f Fv(\)\))p 2747 3323 54 4 v 2747 3370 4 48 v 2797 3370 V 2747 3373 54 4 v 2750 3348 48 4 v 2772 3370 4 48 v 133 w Fm(E)g Fv(;)863 3484 y Fm(A)28 b Fv(:=)g Fm(E)5 b Fv(;)27 b Fm(E)33 b Fv(:=)28 b Fm(D)r Fv(;)f Fm(D)j Fv(:=)d(rol)1827 3496 y Fu(10)1898 3484 y Fv(\()p Fm(C)6 b Fv(\);)28 b Fm(C)34 b Fv(:=)28 b Fm(B)t Fv(;)f Fm(B)32 b Fv(:=)c Fm(T)12 b Fv(;)863 3600 y Fm(T)30 b Fv(:=)18 b(rol)1145 3615 y Ft(s)1176 3599 y Fd(0)1199 3615 y Fu(\()p Ft(j)s Fu(\))1300 3600 y Fv(\()p Fm(A)1394 3570 y Fg(0)p 1450 3555 54 4 v 1450 3603 4 48 v 1500 3603 V 1450 3606 54 4 v 1453 3581 48 4 v 1475 3602 4 48 v 1536 3600 a Fm(f)9 b Fv(\(79)17 b Ff(\000)h Fm(j;)c(B)1940 3570 y Fg(0)1964 3600 y Fm(;)g(C)2066 3570 y Fg(0)2089 3600 y Fm(;)g(D)2197 3570 y Fg(0)2220 3600 y Fv(\))p 2285 3555 54 4 v 2285 3603 4 48 v 2335 3603 V 2285 3606 54 4 v 2288 3581 48 4 v 2310 3602 4 48 v 119 w Fm(X)2440 3612 y Ft(i)2467 3600 y Fv([)p Fm(r)2529 3570 y Fg(0)2553 3600 y Fv(\()p Fm(j)5 b Fv(\)])p 2712 3555 54 4 v 2712 3603 4 48 v 2762 3603 V 2712 3606 54 4 v 2715 3581 48 4 v 2737 3602 4 48 v 119 w Fm(K)2875 3570 y Fg(0)2898 3600 y Fv(\()p Fm(j)g Fv(\)\))p 3079 3555 54 4 v 3079 3603 4 48 v 3130 3603 V 3079 3606 54 4 v 3083 3581 48 4 v 3105 3602 4 48 v 132 w Fm(E)3231 3570 y Fg(0)3255 3600 y Fv(;)863 3717 y Fm(A)925 3686 y Fg(0)977 3717 y Fv(:=)27 b Fm(E)1158 3686 y Fg(0)1181 3717 y Fv(;)h Fm(E)1298 3686 y Fg(0)1349 3717 y Fv(:=)f Fm(D)1535 3686 y Fg(0)1559 3717 y Fv(;)g Fm(D)1680 3686 y Fg(0)1731 3717 y Fv(:=)h(rol)1944 3729 y Fu(10)2014 3717 y Fv(\()p Fm(C)2111 3686 y Fg(0)2135 3717 y Fv(\);)g Fm(C)2283 3686 y Fg(0)2334 3717 y Fv(:=)g Fm(B)2517 3686 y Fg(0)2540 3717 y Fv(;)g Fm(B)2658 3686 y Fg(0)2709 3717 y Fv(:=)f Fm(T)12 b Fv(;)697 3833 y Ff(g)697 3949 y Fm(T)39 b Fv(:=)27 b Fm(h)948 3961 y Fu(1)p 1018 3904 54 4 v 1018 3951 4 48 v 1068 3951 V 1018 3954 54 4 v 1021 3929 48 4 v 1043 3951 4 48 v 1104 3949 a Fm(C)p 1201 3904 54 4 v 1201 3951 4 48 v 1252 3951 V 1201 3954 54 4 v 1204 3929 48 4 v 1226 3951 4 48 v 124 w(D)1358 3919 y Fg(0)1381 3949 y Fv(;)h Fm(h)1480 3961 y Fu(1)1545 3949 y Fv(:=)f Fm(h)1708 3961 y Fu(2)p 1777 3904 54 4 v 1777 3951 4 48 v 1828 3951 V 1777 3954 54 4 v 1781 3929 48 4 v 1803 3951 4 48 v 1863 3949 a Fm(D)p 1966 3904 54 4 v 1966 3951 4 48 v 2017 3951 V 1966 3954 54 4 v 1970 3929 48 4 v 1992 3951 4 48 v 120 w(E)2118 3919 y Fg(0)2142 3949 y Fv(;)h Fm(h)2241 3961 y Fu(2)2305 3949 y Fv(:=)g Fm(h)2469 3961 y Fu(3)p 2538 3904 54 4 v 2538 3951 4 48 v 2588 3951 V 2538 3954 54 4 v 2541 3929 48 4 v 2563 3951 4 48 v 2624 3949 a Fm(E)p 2722 3904 54 4 v 2722 3951 4 48 v 2773 3951 V 2722 3954 54 4 v 2725 3929 48 4 v 2747 3951 4 48 v 123 w(A)2870 3919 y Fg(0)2894 3949 y Fv(;)697 4065 y Fm(h)745 4077 y Fu(3)810 4065 y Fv(:=)f Fm(h)973 4077 y Fu(4)p 1043 4020 54 4 v 1043 4068 4 48 v 1093 4068 V 1043 4071 54 4 v 1046 4046 48 4 v 1068 4067 4 48 v 1129 4065 a Fm(A)p 1223 4020 54 4 v 1223 4068 4 48 v 1274 4068 V 1223 4071 54 4 v 1226 4046 48 4 v 1248 4067 4 48 v 118 w(B)1376 4035 y Fg(0)1399 4065 y Fv(;)h Fm(h)1498 4077 y Fu(4)1563 4065 y Fv(:=)f Fm(h)1726 4077 y Fu(0)p 1795 4020 54 4 v 1795 4068 4 48 v 1846 4068 V 1795 4071 54 4 v 1799 4046 48 4 v 1821 4067 4 48 v 1881 4065 a Fm(B)p 1981 4020 54 4 v 1981 4068 4 48 v 2031 4068 V 1981 4071 54 4 v 1984 4046 48 4 v 2006 4067 4 48 v 123 w(C)2132 4035 y Fg(0)2155 4065 y Fv(;)h Fm(h)2254 4077 y Fu(0)2319 4065 y Fv(:=)f Fm(T)12 b Fv(;)531 4265 y Ff(g)1765 5112 y Fv(11)p eop %%Page: 12 12 12 11 bop 1834 436 a Fh(h)1878 444 y Fs(0)p 1872 662 4 166 v 1874 662 a Fc(?)p 1872 3721 4 3225 v 1874 3723 414 4 v 2285 4101 4 381 v 2287 4101 a(?)p 2251 4101 73 4 v 2251 4167 4 67 v 2320 4167 V 2251 4170 73 4 v 2285 4167 4 67 v 2254 4136 67 4 v 1874 662 a Fb(q)1917 436 y Fh(h)1961 444 y Fs(1)p 1955 745 4 249 v 1956 745 a Fc(?)p 1955 3771 4 3274 v 1956 3771 a(?)p 1920 3771 73 4 v 1920 3837 4 67 v 1989 3837 V 1920 3840 73 4 v 1955 3837 4 67 v 1923 3805 67 4 v 1956 745 a Fb(q)2000 436 y Fh(h)2044 444 y Fs(2)p 2037 827 4 331 v 2039 827 a Fc(?)p 2037 3853 4 3357 v 2039 3853 a(?)p 2003 3853 73 4 v 2003 3919 4 67 v 2072 3919 V 2003 3922 73 4 v 2037 3919 4 67 v 2006 3888 67 4 v 2039 827 a Fb(q)2082 436 y Fh(h)2126 444 y Fs(3)p 2120 910 4 414 v 2122 910 a Fc(?)p 2120 3936 4 3440 v 2122 3936 a(?)p 2085 3936 73 4 v 2085 4002 4 67 v 2155 4002 V 2085 4005 73 4 v 2120 4002 4 67 v 2089 3971 67 4 v 2122 910 a Fb(q)2165 436 y Fh(h)2209 444 y Fs(4)p 2203 993 4 497 v 2204 993 a Fc(?)p 2203 4019 4 3522 v 2204 4019 a(?)p 2168 4019 73 4 v 2168 4085 4 67 v 2237 4085 V 2168 4088 73 4 v 2203 4085 4 67 v 2171 4053 67 4 v 2204 993 a Fb(q)p 1336 664 1075 4 v 1335 1158 4 497 v 1336 1158 a Fc(?)p 2409 1158 V 992 w(?)p 1419 746 1075 4 v 1417 1158 4 414 v -1075 w(?)p 2492 1158 V 992 w(?)p 1502 829 1075 4 v 1500 1158 4 331 v -1075 w(?)p 2575 1158 V 991 w(?)p 1584 912 1075 4 v 1583 1158 4 249 v -1075 w(?)p 2657 1158 V 992 w(?)p 1667 994 1075 4 v 1665 1158 4 166 v -1075 w(?)p 2740 1158 V 992 w(?)p 1292 3142 421 4 v 1292 3473 4 331 v 1399 3326 a Fh(f)1436 3334 y Fs(5)1471 3326 y Fh(;)13 b(K)1570 3334 y Fs(5)p 1708 3473 V 1292 3476 421 4 v 943 3319 a Fh(X)1006 3335 y Fj(\032)1038 3321 y Fe(4)1070 3335 y Fs(\()p Fj(i)p Fs(\))p 1163 3309 133 4 v 1212 3307 a Fc(-)p 1335 3638 4 166 v 1336 3638 a(?)p 1417 3638 V(?)p 1500 3638 V(?)p 1583 3638 V -1 w(?)p 1665 3638 V(?)p 1292 2646 421 4 v 1292 2977 4 331 v 1399 2830 a Fh(f)1436 2838 y Fs(4)1471 2830 y Fh(;)g(K)1570 2838 y Fs(4)p 1708 2977 V 1292 2980 421 4 v 943 2823 a Fh(X)1006 2838 y Fj(\032)1038 2824 y Fe(3)1070 2838 y Fs(\()p Fj(i)p Fs(\))p 1163 2813 133 4 v 1212 2811 a Fc(-)p 1335 3142 4 166 v 1336 3142 a(?)p 1417 3142 V(?)p 1500 3142 V(?)p 1583 3142 V -1 w(?)p 1665 3142 V(?)p 1292 2150 421 4 v 1292 2481 4 331 v 1399 2334 a Fh(f)1436 2342 y Fs(3)1471 2334 y Fh(;)g(K)1570 2342 y Fs(3)p 1708 2481 V 1292 2484 421 4 v 943 2327 a Fh(X)1006 2342 y Fj(\032)1038 2328 y Fe(2)1070 2342 y Fs(\()p Fj(i)p Fs(\))p 1163 2317 133 4 v 1212 2315 a Fc(-)p 1335 2646 4 166 v 1336 2646 a(?)p 1417 2646 V(?)p 1500 2646 V(?)p 1583 2646 V -1 w(?)p 1665 2646 V(?)p 1292 1654 421 4 v 1292 1985 4 331 v 1399 1838 a Fh(f)1436 1846 y Fs(2)1471 1838 y Fh(;)g(K)1570 1846 y Fs(2)p 1708 1985 V 1292 1988 421 4 v 959 1833 a Fh(X)1022 1845 y Fj(\032)p Fs(\()p Fj(i)p Fs(\))p 1163 1821 133 4 v 1212 1819 a Fc(-)p 1335 2150 4 166 v 1336 2150 a(?)p 1417 2150 V(?)p 1500 2150 V(?)p 1583 2150 V -1 w(?)p 1665 2150 V(?)p 1292 1158 421 4 v 1292 1489 4 331 v 1399 1342 a Fh(f)1436 1350 y Fs(1)1471 1342 y Fh(;)g(K)1570 1350 y Fs(1)p 1708 1489 V 1292 1492 421 4 v 999 1345 a Fh(X)1062 1353 y Fj(i)p 1163 1325 133 4 v 1212 1323 a Fc(-)p 1335 1654 4 166 v 1336 1654 a(?)p 1417 1654 V(?)p 1500 1654 V(?)p 1583 1654 V -1 w(?)p 1665 1654 V(?)p 2366 3142 421 4 v 2366 3473 4 331 v 2474 3330 a Fh(f)2511 3338 y Fs(1)2545 3330 y Fh(;)h(K)2650 3298 y Fa(0)2645 3344 y Fs(5)p 2783 3473 V 2366 3476 421 4 v 2944 3319 a Fh(X)3007 3335 y Fj(\032)3039 3321 y Fe(4)3072 3335 y Fj(\031)r Fs(\()p Fj(i)p Fs(\))p 2783 3309 133 4 v 2783 3307 a Fc(\033)p 2409 3638 4 166 v 2411 3638 a(?)p 2492 3638 V(?)p 2575 3638 V -1 w(?)p 2657 3638 V(?)p 2740 3638 V(?)p 2366 2646 421 4 v 2366 2977 4 331 v 2474 2834 a Fh(f)2511 2842 y Fs(2)2545 2834 y Fh(;)g(K)2650 2802 y Fa(0)2645 2848 y Fs(4)p 2783 2977 V 2366 2980 421 4 v 2944 2823 a Fh(X)3007 2838 y Fj(\032)3039 2824 y Fe(3)3072 2838 y Fj(\031)r Fs(\()p Fj(i)p Fs(\))p 2783 2813 133 4 v 2783 2811 a Fc(\033)p 2409 3142 4 166 v 2411 3142 a(?)p 2492 3142 V(?)p 2575 3142 V -1 w(?)p 2657 3142 V(?)p 2740 3142 V(?)p 2366 2150 421 4 v 2366 2481 4 331 v 2474 2338 a Fh(f)2511 2346 y Fs(3)2545 2338 y Fh(;)g(K)2650 2306 y Fa(0)2645 2352 y Fs(3)p 2783 2481 V 2366 2484 421 4 v 2944 2327 a Fh(X)3007 2342 y Fj(\032)3039 2328 y Fe(2)3072 2342 y Fj(\031)r Fs(\()p Fj(i)p Fs(\))p 2783 2317 133 4 v 2783 2315 a Fc(\033)p 2409 2646 4 166 v 2411 2646 a(?)p 2492 2646 V(?)p 2575 2646 V -1 w(?)p 2657 2646 V(?)p 2740 2646 V(?)p 2366 1654 421 4 v 2366 1985 4 331 v 2474 1842 a Fh(f)2511 1850 y Fs(4)2545 1842 y Fh(;)g(K)2650 1810 y Fa(0)2645 1855 y Fs(2)p 2783 1985 V 2366 1988 421 4 v 2960 1833 a Fh(X)3023 1845 y Fj(\032\031)r Fs(\()p Fj(i)p Fs(\))p 2783 1821 133 4 v 2783 1819 a Fc(\033)p 2409 2150 4 166 v 2411 2150 a(?)p 2492 2150 V(?)p 2575 2150 V -1 w(?)p 2657 2150 V(?)p 2740 2150 V(?)p 2366 1158 421 4 v 2366 1489 4 331 v 2474 1346 a Fh(f)2511 1354 y Fs(5)2545 1346 y Fh(;)g(K)2650 1314 y Fa(0)2645 1359 y Fs(1)p 2783 1489 V 2366 1492 421 4 v 2976 1337 a Fh(X)3039 1349 y Fj(\031)r Fs(\()p Fj(i)p Fs(\))p 2783 1325 133 4 v 2783 1323 a Fc(\033)p 2409 1654 4 166 v 2411 1654 a(?)p 2492 1654 V(?)p 2575 1654 V -1 w(?)p 2657 1654 V(?)p 2740 1654 V(?)p 1500 3804 V 1502 3805 422 4 v 1840 3803 a(-)p 2657 3804 4 166 v 1989 3805 670 4 v 66 w(\033)p 1583 3886 4 249 v 1584 3888 422 4 v 1923 3886 a(-)p 2740 3886 4 249 v 2072 3888 670 4 v 66 w(\033)p 1665 3969 4 331 v 1667 3971 422 4 v 2006 3969 a(-)p 2409 3969 4 331 v 2155 3971 257 4 v 66 w(\033)p 1335 4052 4 414 v 1336 4053 836 4 v 2088 4051 a(-)p 2492 4052 4 414 v 2237 4053 257 4 v 66 w(\033)p 1417 4134 4 497 v 1419 4136 836 4 v 2171 4134 a(-)p 2575 4134 4 497 v 2320 4136 257 4 v 66 w(\033)p 1955 4300 4 463 v 1956 4300 a(?)1917 4404 y Fh(h)1961 4412 y Fs(0)p 2037 4300 4 381 v 2039 4300 a Fc(?)2000 4404 y Fh(h)2044 4412 y Fs(1)p 2120 4300 4 298 v 2122 4300 a Fc(?)2082 4404 y Fh(h)2126 4412 y Fs(2)p 2203 4300 4 215 v 2204 4300 a Fc(?)2165 4404 y Fh(h)2209 4412 y Fs(3)p 2285 4300 4 133 v 2287 4300 a Fc(?)2248 4404 y Fh(h)2292 4412 y Fs(4)681 4640 y Fo(Fig.)g(1.)35 b Fr(Outline)f(of)i(the)e (compression)i(function)e(of)i(RIPEMD-160.)g(Inputs)d(are)j(a)f(16-w)n (ord)681 4731 y(message)29 b(blo)r(c)n(k)g Fh(X)1248 4739 y Fj(i)1304 4731 y Fr(and)g(a)g(5-w)n(ord)g(c)n(haining)h(v)l (ariable)f Fh(h)2425 4739 y Fs(0)2460 4731 y Fh(h)2504 4739 y Fs(1)2539 4731 y Fh(h)2583 4739 y Fs(2)2618 4731 y Fh(h)2662 4739 y Fs(3)2697 4731 y Fh(h)2741 4739 y Fs(4)2775 4731 y Fr(,)h(output)e(is)h(a)h(new)f(v)l(alue)681 4822 y(of)d(the)g(c)n(haining)g(v)l(ariable.)2080 5112 y Fv(12)p eop %%Page: 13 13 13 12 bop 365 387 a Fn(B)112 b(T)-9 b(est)37 b(V)-9 b(alues)365 578 y Fv(RIPEMD-160:)365 736 y Fq("")365 827 y (9c1185a5c5e9fc54612808977ee8)q(f548)q(b2258)q(d31)365 919 y("a")365 1010 y(0bdc9d2d256b3ee9daae347be6f4)q(dc83)q(5a467)q(ffe) 365 1101 y("abc")365 1193 y(8eb208f7e05d987a9b044a8e98c6)q(b087)q (f15a0)q(bfc)365 1284 y("message)41 b(digest")365 1375 y(5d0689ef49d2fae572b881b123a8)q(5ffa)q(21595)q(f36)365 1467 y("abcdefghijklmnopqrstuvwxyz")365 1558 y (f71c27109c692c1b56bbdceb5b9d)q(2865)q(b3708)q(dbc)365 1649 y("abcdbcdecdefdefgefghfghighi)q(jhij)q(kijkl)q(jklm)q(klmn)q (lmnom)q(nopn)q(opq")365 1741 y(12a053384a9c0c88e405a06c27dc)q(f49a)q (da62e)q(b2b)365 1832 y("ABCDEFGHIJKLMNOPQRSTUVWXYZa)q(bcde)q(fghij)q (klmn)q(opqr)q(stuvw)q(xyz0)q(12345)q(6789)q(")365 1923 y(b0e20b6e3116640286ed3a87a571)q(3079)q(b21f5)q(189)365 2015 y(8)f(times)g("1234567890")365 2106 y (9b752e45573d4b39f4dbd3323cab)q(82bf)q(63326)q(bfb)365 2197 y(1)g(million)h(times)f("a")365 2289 y (52783243c1697bdbe16d37f97f68)q(f083)q(25dc1)q(528)365 2564 y Fv(RIPEMD-128:)365 2722 y Fq("")365 2814 y (cdf26213a150dc3ecb610f18f6b3)q(8b46)365 2905 y("a")365 2996 y(86be7afa339d0fc7cfc785e72f57)q(8d33)365 3087 y("abc")365 3179 y(c14a12199c66e4ba84636b0f6914)q(4c77)365 3270 y("message)h (digest")365 3361 y(9e327b3d6e523062afc1132d7df9)q(d1b8)365 3453 y("abcdefghijklmnopqrstuvwxyz")365 3544 y (fd2aa607f71dc8f510714922b371)q(834e)365 3635 y ("abcdbcdecdefdefgefghfghighi)q(jhij)q(kijkl)q(jklm)q(klmn)q(lmnom)q (nopn)q(opq")365 3727 y(a1aa0689d0fafa2ddc22e88b4913)q(3a06)365 3818 y("ABCDEFGHIJKLMNOPQRSTUVWXYZa)q(bcde)q(fghij)q(klmn)q(opqr)q (stuvw)q(xyz0)q(12345)q(6789)q(")365 3909 y (d1e959eb179c911faea4624c60c5)q(c702)365 4001 y(8)f(times)g ("1234567890")365 4092 y(3f45ef194732c2dbb2c4a2c76979)q(5fa3)365 4183 y(1)g(million)h(times)f("a")365 4275 y (4a7f5723f954eba1216c9d8f6320)q(431f)1765 5112 y Fv(13)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF trf2.1.4/generic/ripemd/hashtest.c0000644000175000017500000002353111216343142016436 0ustar sergeisergei/********************************************************************\ * * FILE: hashtest.c * * CONTENTS: test file for sample C-implementation of * RIPEMD-160 and RIPEMD128 * * command line arguments: * filename -- compute hash code of file read binary * -sstring -- print string & hashcode * -t -- perform time trial * -x -- execute standard test suite, ASCII input * * for linkage with rmd128.c: define RMDsize as 128 * for linkage with rmd160.c: define RMDsize as 160 (default) * TARGET: any computer with an ANSI C compiler * * AUTHOR: Antoon Bosselaers, ESAT-COSIC * DATE: 18 April 1996 * VERSION: 1.1 * HISTORY: bug in RMDonemillion() corrected * * Copyright (c) Katholieke Universiteit Leuven * 1996, All Rights Reserved * \********************************************************************/ #ifndef RMDsize #define RMDsize 160 #endif #include #include #include #include #if RMDsize == 128 #include "rmd128.h" #elif RMDsize == 160 #include "rmd160.h" #endif #define TEST_BLOCK_SIZE 8000 #define TEST_BLOCKS 1250 #define TEST_BYTES ((long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS) /********************************************************************/ byte *RMD(byte *message) /* * returns RMD(message) * message should be a string terminated by '\0' */ { dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */ static byte hashcode[RMDsize/8]; /* for final hash-value */ dword X[16]; /* current 16-word chunk */ word i; /* counter */ dword length; /* length in bytes of message */ dword nbytes; /* # of bytes not yet processed */ /* initialize */ MDinit(MDbuf); length = (dword)strlen((char *)message); /* process message in 16-word chunks */ for (nbytes=length; nbytes > 63; nbytes-=64) { for (i=0; i<16; i++) { X[i] = BYTES_TO_DWORD(message); message += 4; } compress(MDbuf, X); } /* length mod 64 bytes left */ /* finish: */ MDfinish(MDbuf, message, length, 0); for (i=0; i>2]; /* implicit cast to byte */ hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */ hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */ hashcode[i+3] = (MDbuf[i>>2] >> 24); } return (byte *)hashcode; } /********************************************************************/ byte *RMDbinary(char *fname) /* * returns RMD(message in file fname) * fname is read as binary data. */ { FILE *mf; /* pointer to file */ byte data[1024]; /* contains current mess. block */ dword nbytes; /* length of this block */ dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */ static byte hashcode[RMDsize/8]; /* for final hash-value */ dword X[16]; /* current 16-word chunk */ word i, j; /* counters */ dword length[2]; /* length in bytes of message */ dword offset; /* # of unprocessed bytes at */ /* call of MDfinish */ /* initialize */ if ((mf = fopen(fname, "rb")) == NULL) { fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n", fname); exit(1); } MDinit(MDbuf); length[0] = 0; length[1] = 0; while ((nbytes = fread(data, 1, 1024, mf)) != 0) { /* process all complete blocks */ for (i=0; i<(nbytes>>6); i++) { for (j=0; j<16; j++) X[j] = BYTES_TO_DWORD(data+64*i+4*j); compress(MDbuf, X); } /* update length[] */ if (length[0] + nbytes < length[0]) length[1]++; /* overflow to msb of length */ length[0] += nbytes; } /* finish: */ offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */ MDfinish(MDbuf, data+offset, length[0], length[1]); for (i=0; i>2]; hashcode[i+1] = (MDbuf[i>>2] >> 8); hashcode[i+2] = (MDbuf[i>>2] >> 16); hashcode[i+3] = (MDbuf[i>>2] >> 24); } fclose(mf); return (byte *)hashcode; } /********************************************************************/ void speedtest(void) /* * A time trial routine, to measure the speed of ripemd. * Measures processor time required to process TEST_BLOCKS times * a message of TEST_BLOCK_SIZE characters. */ { clock_t t0, t1; byte *data; byte hashcode[RMDsize/8]; dword X[16]; dword MDbuf[RMDsize/32]; word i, j, k; srand(time(NULL)); /* allocate and initialize test data */ if ((data = (byte*)malloc(TEST_BLOCK_SIZE)) == NULL) { fprintf(stderr, "speedtest: allocation error\n"); exit(1); } for (i=0; i> 7); /* start timer */ printf("RIPEMD time trial. Processing %ld characters...\n", TEST_BYTES); t0 = clock(); /* process data */ MDinit(MDbuf); for (i=0; i>2]; hashcode[i+1] = (MDbuf[i>>2] >> 8); hashcode[i+2] = (MDbuf[i>>2] >> 16); hashcode[i+3] = (MDbuf[i>>2] >> 24); } printf("\nhashcode: "); for (i=0; i0; i--) compress(MDbuf, X); MDfinish(MDbuf, NULL, 1000000UL, 0); for (i=0; i>2]; hashcode[i+1] = (MDbuf[i>>2] >> 8); hashcode[i+2] = (MDbuf[i>>2] >> 16); hashcode[i+3] = (MDbuf[i>>2] >> 24); } printf("\n* message: 1 million times \"a\"\n hashcode: "); for (i=0; i added __alpha, * <> unique prefix for function names * <> using tcl.h, _ANSI_ARGS_ */ #ifndef RMD160H /* make sure this file is read only once */ #define RMD160H /********************************************************************/ #include /* typedef 8, 16 and 32 bit types, resp. */ /* adapt these, if necessary, for your operating system and compiler */ typedef unsigned char byte; /* unsigned 8-bit integer */ typedef unsigned short word; /* unsigned 16-bit integer */ #if defined(__alpha) || defined(__LP64__) typedef unsigned int dword; /* unsigned 32-bit integer (AXP) */ #else typedef unsigned long dword; /* unsigned 32-bit integer */ #endif /********************************************************************/ /* macro definitions */ /* collect four bytes into one word: */ #define BYTES_TO_DWORD(strptr) \ (((dword) *((strptr)+3) << 24) | \ ((dword) *((strptr)+2) << 16) | \ ((dword) *((strptr)+1) << 8) | \ ((dword) *(strptr))) /* ROL(x, n) cyclically rotates x over n bits to the left */ /* x must be of an unsigned 32 bits type and 0 <= n < 32. */ #define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* the three basic functions F(), G() and H() */ #define F(x, y, z) ((x) ^ (y) ^ (z)) #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) #define H(x, y, z) (((x) | ~(y)) ^ (z)) #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define J(x, y, z) ((x) ^ ((y) | ~(z))) /* the eight basic operations FF() through III() */ #define FF(a, b, c, d, e, x, s) {\ (a) += F((b), (c), (d)) + (x);\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define GG(a, b, c, d, e, x, s) {\ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define HH(a, b, c, d, e, x, s) {\ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define II(a, b, c, d, e, x, s) {\ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define JJ(a, b, c, d, e, x, s) {\ (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define FFF(a, b, c, d, e, x, s) {\ (a) += F((b), (c), (d)) + (x);\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define GGG(a, b, c, d, e, x, s) {\ (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define HHH(a, b, c, d, e, x, s) {\ (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define III(a, b, c, d, e, x, s) {\ (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } #define JJJ(a, b, c, d, e, x, s) {\ (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ } /********************************************************************/ /* function prototypes */ void ripemd160_MDinit _ANSI_ARGS_ ((dword *MDbuf)); /* * initializes MDbuffer to "magic constants" */ void ripemd160_compress _ANSI_ARGS_ ((dword *MDbuf, dword *X)); /* * the compression function. * transforms MDbuf using message bytes X[0] through X[15] */ void ripemd160_MDfinish _ANSI_ARGS_ ((dword *MDbuf, byte *strptr, dword lswlen, dword mswlen)); /* * puts bytes from strptr into X and pad out; appends length * and finally, compresses the last block(s) * note: length in bits == 8 * (lswlen + 2^32 mswlen). * note: there are (lswlen mod 64) bytes left in strptr. */ #endif /* RMD160H */ /*********************** end of file rmd160.h ***********************/ trf2.1.4/generic/sha.c0000644000175000017500000001545311216344224014114 0ustar sergeisergei/* * sha.c -- * * Implements and registers message digest generator SHA. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: sha.c,v 1.4 2007/10/05 23:12:21 andreas_kupries Exp $ */ #include "transformInt.h" #include "sha/sha.h" #ifdef WORDS_BIGENDIAN #undef LITTLE_ENDIAN #else #undef LITTLE_ENDIAN #define LITTLE_ENDIAN #endif /* * Generator description * --------------------- * * The SHA alogrithm is used to compute a cryptographically strong * message digest. */ #define DIGEST_SIZE (SHA_DIGESTSIZE) #define CTX_TYPE sha_trf_info #define CHUNK_SIZE 256 /* We cannot use SHA_INFO directly as context cause 'sha_update' handles * a chunk smaller then CHUNK_SIZE bytes correct if and only if it is * the last chunk. This forces us to buffer the incoming bytes till a chunk * is complete before doing an update. */ typedef struct _sha_trf_info { SHA_INFO s; unsigned short count; unsigned char buf [CHUNK_SIZE]; /* SHA block */ } sha_trf_info; /* * Declarations of internal procedures. */ static void MDsha_Start _ANSI_ARGS_ ((VOID* context)); static void MDsha_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDsha_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDsha_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ "sha", sizeof (CTX_TYPE), DIGEST_SIZE, MDsha_Start, MDsha_Update, MDsha_UpdateBuf, MDsha_Final, NULL }; /* *------------------------------------------------------* * * TrfInit_SHA -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_SHA (interp) Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDsha_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDsha_Start (context) VOID* context; { sha_trf_info* s = (sha_trf_info*) context; memset (s, '\0', sizeof (sha_trf_info)); sha_init (&s->s); } /* *------------------------------------------------------* * * MDsha_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDsha_Update (context, character) VOID* context; unsigned int character; { sha_trf_info* s = (sha_trf_info*) context; s->buf [s->count] = character; s->count ++; if (s->count == CHUNK_SIZE) { sha_update (&s->s, s->buf, s->count); s->count = 0; } } /* *------------------------------------------------------* * * MDsha_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDsha_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { sha_trf_info* s = (sha_trf_info*) context; if ((s->count + bufLen) < CHUNK_SIZE) { /* * Not enough for full chunk. Remember incoming * data and wait for another call containing more data. */ memcpy ((VOID*) (s->buf + s->count), (VOID*) buffer, bufLen); s->count += bufLen; } else { /* * Complete chunk with incoming data, update digest, * then use all chunks contained in the buffer. Remember * an incomplete chunk and wait for further calls. */ int k = CHUNK_SIZE - s->count; if (k < CHUNK_SIZE) { memcpy ((VOID*) (s->buf + s->count), (VOID*) buffer, k); sha_update (&s->s, s->buf, CHUNK_SIZE); buffer += k; bufLen -= k; } /* k == CHUNK_SIZE => internal buffer was empty, so skip it entirely */ while (bufLen > CHUNK_SIZE) { sha_update (&s->s, buffer, CHUNK_SIZE); buffer += CHUNK_SIZE; bufLen -= CHUNK_SIZE; } s->count = bufLen; if (bufLen > 0) memcpy ((VOID*) s->buf, (VOID*) buffer, bufLen); } } /* *------------------------------------------------------* * * MDsha_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDsha_Final (context, digest) VOID* context; VOID* digest; { sha_trf_info* s = (sha_trf_info*) context; if (s->count > 0) { sha_update (&s->s, s->buf, s->count); } sha_final (&s->s); #ifndef WORDS_BIGENDIAN Trf_FlipRegisterLong (s->s.digest, SHA_DIGESTSIZE); #endif memcpy (digest, s->s.digest, SHA_DIGESTSIZE); } /* * External code from here on. * * To make smaller object code, but run a little slower, don't use UNROLL_LOOPS. * To use NIST's modified SHA of 7/11/94, define USE_MODIFIED_SHA */ #define UNROLL_LOOPS #include "sha/sha.c" trf2.1.4/generic/patchlevel.h0000644000175000017500000000167311216344305015474 0ustar sergeisergei/* -*- c -*- * patchlevel.h -- * * Distributed at MAY-06-2009. * * This file does nothing except to define a "patch level" for TRF. * The patch level has the form "X.YpZ" where X.Y is the base * release, and Z is a serial number that is used to sequence * patches for a given release. Thus 7.4p1 is the first patch * to release 7.4, 7.4p2 is the patch that follows 7.4p1, and * so on. The "pZ" is omitted in an original new release, and * it is replaced with "bZ" ("aZ") for beta resp. alpha releases. * The patch level ensures that patches are applied in the correct * order and only to appropriate sources. * * Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net). * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * CVS $Id: patchlevel.h,v 1.5 2009/05/07 05:30:35 andreas_kupries Exp $ */ #define TRF_PATCH_LEVEL "2.1.4" trf2.1.4/generic/adler.c0000644000175000017500000001350711216344223014425 0ustar sergeisergei/* * adler.c -- * * Implements and registers message digest generator ADLER32. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: adler.c,v 1.8 2003/01/09 21:27:09 andreas_kupries Exp $ */ #include "transformInt.h" /* * Generator description * --------------------- * * The ADLER32 algorithm (contained in library 'zlib') * is used to compute a message digest. */ #define DIGEST_SIZE 4 /* byte == 32 bit */ #define CTX_TYPE uLong /* * Declarations of internal procedures. */ static void MDAdler_Start _ANSI_ARGS_ ((VOID* context)); static void MDAdler_Update _ANSI_ARGS_ ((VOID* context, unsigned int character)); static void MDAdler_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen)); static void MDAdler_Final _ANSI_ARGS_ ((VOID* context, VOID* digest)); static int MDAdler_Check _ANSI_ARGS_ ((Tcl_Interp* interp)); /* * Generator definition. */ static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */ "adler", sizeof (CTX_TYPE), DIGEST_SIZE, MDAdler_Start, MDAdler_Update, MDAdler_UpdateBuf, MDAdler_Final, MDAdler_Check }; #define ADLER (*((uLong*) context)) /* *------------------------------------------------------* * * TrfInit_ADLER -- * * ------------------------------------------------* * Register the generator implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_ADLER (interp) Tcl_Interp* interp; { return Trf_RegisterMessageDigest (interp, &mdDescription); } /* *------------------------------------------------------* * * MDAdler_Start -- * * ------------------------------------------------* * Initialize the internal state of the message * digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDAdler_Start (context) VOID* context; { START (MDAdler_Start); PRINT ("Context = %p, Zf = %p\n", context, &zf); /* call md specific initialization here */ ADLER = zf.zadler32 (0L, Z_NULL, 0); DONE (MDAdler_Start); } /* *------------------------------------------------------* * * MDAdler_Update -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a single character. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDAdler_Update (context, character) VOID* context; unsigned int character; { /* call md specific update here */ unsigned char buf = character; ADLER = zf.zadler32 (ADLER, &buf, 1); } /* *------------------------------------------------------* * * MDAdler_UpdateBuf -- * * ------------------------------------------------* * Update the internal state of the message digest * generator for a character buffer. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDAdler_UpdateBuf (context, buffer, bufLen) VOID* context; unsigned char* buffer; int bufLen; { /* call md specific update here */ ADLER = zf.zadler32 (ADLER, buffer, bufLen); } /* *------------------------------------------------------* * * MDAdler_Final -- * * ------------------------------------------------* * Generate the digest from the internal state of * the message digest generator. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static void MDAdler_Final (context, digest) VOID* context; VOID* digest; { /* call md specific finalization here */ uLong adler = ADLER; char* out = (char*) digest; /* BIGENDIAN output */ out [0] = (char) ((adler >> 24) & 0xff); out [1] = (char) ((adler >> 16) & 0xff); out [2] = (char) ((adler >> 8) & 0xff); out [3] = (char) ((adler >> 0) & 0xff); } /* *------------------------------------------------------* * * MDAdler_Check -- * * ------------------------------------------------* * Check for existence of libz, load it. * ------------------------------------------------* * * Sideeffects: * As of the called procedure. * * Result: * None. * *------------------------------------------------------* */ static int MDAdler_Check (interp) Tcl_Interp* interp; { int res; START (MDAdler_Check); res = TrfLoadZlib (interp); PRINT ("res = %d\n", res); DONE (MDAdler_Check); return res; } trf2.1.4/generic/rs-ecc/0000755000175000017500000000000011216344734014347 5ustar sergeisergeitrf2.1.4/generic/rs-ecc/gflib.c0000644000175000017500000000375211216343142015575 0ustar sergeisergei/* ecc Version 1.2 by Paul Flaherty (paulf@stanford.edu) Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* gflib.c Math Library for GF[256] This file contains a number of mathematical functions for GF[256]. Entry and result are always assumed to be in vector notation, since said notation allows for the zero element. Attempting to reciprocate the zero element results in process exit 42. */ #include "gf.h" /* Multiply two field elements */ unsigned char gfmul (mul1, mul2) unsigned char mul1, mul2; { unsigned char mul3; if (mul1 == 0 || mul2 == 0) mul3 = 0; else mul3 = e2v[(v2e[mul1] + v2e[mul2]) % 255]; return (mul3); } /* Add two field elements. Subtraction and addition are equivalent */ unsigned char gfadd (add1, add2) unsigned char add1, add2; { unsigned char add3; add3 = add1 ^ add2; return (add3); } /* Invert a field element, for division */ unsigned char gfinv (ivt) unsigned char ivt; { unsigned char ivtd; if (ivt == 0) exit (42); ivtd = e2v[255 - v2e[ivt]]; return (ivtd); } /* Exponentiation. Convert to exponential notation, mod 255 */ unsigned char gfexp (mant, powr) unsigned char mant, powr; { unsigned char expt; if (mant == 0) expt = 0; else expt = e2v[(v2e[mant] * powr) % 255]; return (expt); } trf2.1.4/generic/rs-ecc/rslib.c0000644000175000017500000002060211216343142015616 0ustar sergeisergei/* ecc Version 1.2 by Paul Flaherty (paulf@stanford.edu) Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* rslib.c Library of Reed - Solomon Routines This file contains the actual routines to implement a Reed - Solomon (255,249,7) code. The encoder uses a feedback shift register generator, which systematically encodes 249 bytes into a 255 byte block. The decoder is a classic Peterson algorithm. */ #include "ecc.h" /* aku: forward declaration of routines used before definition */ void polysolve (); /* Reed - Solomon Encoder. The Encoder uses a shift register algorithm, as detailed in _Applied Modern Algebra_ by Dornhoff and Hohn (p.446). Note that the message is reversed in the code array; this was done to allow for (emergency) recovery of the message directly from the data stream. */ void /* <-- aku */ rsencode (m, c) unsigned char m[249], c[255]; { unsigned char r[6], rtmp; int i, j; for (i = 0; i < 6; i++) r[i] = 0; for (i = 0; i < 249; i++) { c[254 - i] = m[i]; rtmp = gfadd (m[i], r[5]); for (j = 5; j > 0; j--) { r[j] = gfadd (gfmul (rtmp, g[j]), r[j - 1]); } r[0] = gfmul (rtmp, g[0]); } for (i = 0; i < 6; i++) { c[i] = r[i]; } } /* Polynomial Evaluator, used to determine the Syndrome Vector. This is relatively straightforward, and there are faster algorithms. */ unsigned char evalpoly (p, x) unsigned char p[255], x; { unsigned char y; int i; y = 0; for (i = 0; i < 255; i++) { y = gfadd (y, gfmul (p[i], gfexp (x, i))); } return (y); } /* Determine the Syndrome Vector. Note that in s[0] we return the OR of all of the syndromes; this allows for an easy check for the no - error condition. */ void /* <-- aku */ syndrome (c, s) unsigned char c[255], s[7]; { extern unsigned char e2v[256]; int i; s[0] = 0; for (i = 1; i < 7; i++) { s[i] = evalpoly (c, e2v[i]); s[0] = s[0] | s[i]; } } /* Determine the number of errors in a block. Since we have to find the determinant of the S[] matrix in order to determine singularity, we also return the determinant to be used by the Cramer's Rule correction algorithm. */ void /* <-- aku */ errnum (s, det, errs) unsigned char s[7], *det; int *errs; { *det = gfmul (s[2], gfmul (s[4], s[6])); *det = gfadd (*det, gfmul (s[2], gfmul (s[5], s[5]))); *det = gfadd (*det, gfmul (s[6], gfmul (s[3], s[3]))); *det = gfadd (*det, gfmul (s[4], gfmul (s[4], s[4]))); *errs = 3; if (*det != 0) return; *det = gfadd (gfmul (s[2], s[4]), gfexp (s[3], 2)); *errs = 2; if (*det != 0) return; *det = s[1]; *errs = 1; if (*det != 0) return; *errs = 4; } /* Full impementation of the three error correcting Peterson decoder. For t<6, it is faster than Massey - Berlekamp. It is also somewhat more intuitive. */ void /* <-- aku */ rsdecode (code, mesg, errcode) unsigned char code[255], mesg[249]; int *errcode; { extern unsigned char v2e[256]; unsigned char syn[7], deter, z[4], e0, e1, e2, n0, n1, n2, w0, w1, w2, x0, x[3]; int i, sols; *errcode = 0; /* First, get the message out of the code, so that even if we can't correct it, we return an estimate. */ for (i = 0; i < 249; i++) mesg[i] = code[254 - i]; syndrome (code, syn); if (syn[0] == 0) return; /* We now know we have at least one error. If there are no errors detected, we assume that something funny is going on, and so return with errcode 4, else pass the number of errors back via errcode. */ errnum (syn, &deter, errcode); if (*errcode == 4) return; /* Having obtained the syndrome, the number of errors, and the determinant, we now proceed to correct the block. If we do not find exactly the number of solutions equal to the number of errors, we have exceeded our error capacity, and return with the block uncorrected, and errcode 4. */ switch (*errcode) { case 1: x0 = gfmul (syn[2], gfinv (syn[1])); w0 = gfmul (gfexp (syn[1], 2), gfinv (syn[2])); if (v2e[x0] > 5) mesg[254 - v2e[x0]] = gfadd (mesg[254 - v2e[x0]], w0); return; case 2: z[0] = gfmul (gfadd (gfmul (syn[1], syn[3]), gfexp (syn[2], 2)), gfinv (deter)); z[1] = gfmul (gfadd (gfmul (syn[2], syn[3]), gfmul (syn[1], syn[4])), gfinv (deter)); z[2] = 1; z[3] = 0; polysolve (z, x, &sols); if (sols != 2) { *errcode = 4; return; } w0 = gfmul (z[0], syn[1]); w1 = gfadd (gfmul (z[0], syn[2]), gfmul (z[1], syn[1])); n0 = 254 - v2e[gfinv (x[0])]; n1 = 254 - v2e[gfinv (x[1])]; e0 = gfmul (gfadd (w0, gfmul (w1, x[0])), gfinv (z[1])); e1 = gfmul (gfadd (w0, gfmul (w1, x[1])), gfinv (z[1])); if (n0 < 249) mesg[n0] = gfadd (mesg[n0], e0); if (n1 < 249) mesg[n1] = gfadd (mesg[n1], e1); return; case 3: z[3] = 1; z[2] = gfmul (syn[1], gfmul (syn[4], syn[6])); z[2] = gfadd (z[2], gfmul (syn[1], gfmul (syn[5], syn[5]))); z[2] = gfadd (z[2], gfmul (syn[5], gfmul (syn[3], syn[3]))); z[2] = gfadd (z[2], gfmul (syn[3], gfmul (syn[4], syn[4]))); z[2] = gfadd (z[2], gfmul (syn[2], gfmul (syn[5], syn[4]))); z[2] = gfadd (z[2], gfmul (syn[2], gfmul (syn[3], syn[6]))); z[2] = gfmul (z[2], gfinv (deter)); z[1] = gfmul (syn[1], gfmul (syn[3], syn[6])); z[1] = gfadd (z[1], gfmul (syn[1], gfmul (syn[5], syn[4]))); z[1] = gfadd (z[1], gfmul (syn[4], gfmul (syn[3], syn[3]))); z[1] = gfadd (z[1], gfmul (syn[2], gfmul (syn[4], syn[4]))); z[1] = gfadd (z[1], gfmul (syn[2], gfmul (syn[3], syn[5]))); z[1] = gfadd (z[1], gfmul (syn[2], gfmul (syn[2], syn[6]))); z[1] = gfmul (z[1], gfinv (deter)); z[0] = gfmul (syn[2], gfmul (syn[3], syn[4])); z[0] = gfadd (z[0], gfmul (syn[3], gfmul (syn[2], syn[4]))); z[0] = gfadd (z[0], gfmul (syn[3], gfmul (syn[5], syn[1]))); z[0] = gfadd (z[0], gfmul (syn[4], gfmul (syn[4], syn[1]))); z[0] = gfadd (z[0], gfmul (syn[3], gfmul (syn[3], syn[3]))); z[0] = gfadd (z[0], gfmul (syn[2], gfmul (syn[2], syn[5]))); z[0] = gfmul (z[0], gfinv (deter)); polysolve (z, x, &sols); if (sols != 3) { *errcode = 4; return; } w0 = gfmul (z[0], syn[1]); w1 = gfadd (gfmul (z[0], syn[2]), gfmul (z[1], syn[1])); w2 = gfadd (gfmul (z[0], syn[3]), gfadd (gfmul (z[1], syn[2]), gfmul (z[2], syn[1]))); n0 = 254 - v2e[gfinv (x[0])]; n1 = 254 - v2e[gfinv (x[1])]; n2 = 254 - v2e[gfinv (x[2])]; e0 = gfadd (w0, gfadd (gfmul (w1, x[0]), gfmul (w2, gfexp (x[0], 2)))); e0 = gfmul (e0, gfinv (gfadd (z[1], gfexp (x[0], 2)))); e1 = gfadd (w0, gfadd (gfmul (w1, x[1]), gfmul (w2, gfexp (x[1], 2)))); e1 = gfmul (e1, gfinv (gfadd (z[1], gfexp (x[1], 2)))); e2 = gfadd (w0, gfadd (gfmul (w1, x[2]), gfmul (w2, gfexp (x[2], 2)))); e2 = gfmul (e2, gfinv (gfadd (z[1], gfexp (x[2], 2)))); if (n0 < 249) mesg[n0] = gfadd (mesg[n0], e0); if (n1 < 249) mesg[n1] = gfadd (mesg[n1], e1); if (n2 < 249) mesg[n2] = gfadd (mesg[n2], e2); return; default: *errcode = 4; return; } } /* Polynomial Solver. Simple exhaustive search, as solving polynomials is generally NP - Complete anyway. */ void /* <-- aku */ polysolve (polynom, roots, numsol) unsigned char polynom[4], roots[3]; int *numsol; { extern unsigned char e2v[256]; int i, j; unsigned char y; *numsol = 0; for (i = 0; i < 255; i++) { y = 0; for (j = 0; j < 4; j++) y = gfadd (y, gfmul (polynom[j], gfexp (e2v[i], j))); if (y == 0) { roots[*numsol] = e2v[i]; *numsol = *numsol + 1; } } } trf2.1.4/generic/rs-ecc/ecc.h0000644000175000017500000000212511216343142015242 0ustar sergeisergei/* ecc Version 1.2 by Paul Flaherty (paulf@stanford.edu) Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ecc.h Generator Polynomial Coefficients This header file contains an array which defines the generator polynomial for the Reed - Solomon Code (255,249,7). The polynomial was hand generated, using a set of calculator programs. */ static unsigned char g[6] = { 117, 49, 58, 158, 4, 126}; trf2.1.4/generic/rs-ecc/ecc.c0000644000175000017500000000531111216343142015235 0ustar sergeisergei/* ecc Version 1.2 by Paul Flaherty (paulf@stanford.edu) Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ecc.c Basic Software Tool for Encoding and Decoding Files. This is a simple stream encoder which uses the rslib routines to do something practical. It reads data from stdin in 248(encode) or 256(decode) blocks, and writes the corresponding encoded/decoded block onto stdout. An encoded block contains 248 data bytes, one length byte, six redundancy bytes, and a capital G byte as a sync marker to round it out to 256 bytes. */ #include #include main (argc, argv) int argc; char *argv[]; { int ec; if (argc != 2) { fprintf (stderr, "usage: ecc [-edv] \n"); exit (1); } if (strcmp ("-e", argv[1]) == 0) encode (); if (strcmp ("-d", argv[1]) == 0) decode (); if (strcmp ("-v", argv[1]) == 0) ver (); fprintf (stderr, "usage: ecc [-edv] \n"); exit (1); } ver () { extern char version[]; fprintf (stderr, "%s\n", version); exit (0); } encode () { unsigned char msg[249], coded[255]; int i, readme; for (i = 0; i < 249; i++) msg[i] = 0; readme = 248; while (readme == 248) { readme = fread (msg, 1, 248, stdin); msg[248] = readme; rsencode (msg, coded); fprintf (stdout, "G"); for (i = 254; i > -1; i--) fprintf (stdout, "%c", coded[i]); } exit (0); } decode () { int i, j, readme, bo, len; unsigned char msgs[249], cod[255]; j = 0; while (getc (stdin) == 71) { j++; for (i = 254; i > -1; i--) cod[i] = getc (stdin); rsdecode (cod, msgs, &bo); if (bo > 0 && bo < 4) fprintf (stderr, "ecc: %d byte error in block %d.\n", bo, j); if (bo == 4) fprintf (stderr, "ecc: unrecoverable error in block %d.\n", j); len = msgs[248]; for (i = 0; i < len; i++) putc (msgs[i], stdout); } if (getc (stdin) != EOF) { fprintf (stderr, "ecc: sync error in block %d.\n", j); exit (1); } exit (0); } trf2.1.4/generic/rs-ecc/gf.h0000644000175000017500000000672011216343142015111 0ustar sergeisergei/* ecc Version 1.2 by Paul Flaherty (paulf@stanford.edu) Copyright (C) 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* gf.h Galois Field [256] Elements This header file contains two arrays which transform field elements from exponential notation to vector (e2v) and vice versa (v2e). Note that there is no exponential notation for the zero vector, and that a^255 = a^0 = 1. */ unsigned char e2v[256] = { 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1}; unsigned char v2e[256] = { 255, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175}; trf2.1.4/generic/rs-ecc/Makefile.in0000644000175000017500000000526011216343142016407 0ustar sergeisergei# Makefile for ECC. -*- Indented-Text -*- # Copyright (C) 1992 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #### Start of system configuration section. #### srcdir = @srcdir@ VPATH = @srcdir@ CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ DEFS = @DEFS@ LIBS = @LIBS@ CFLAGS = -O LDFLAGS = -O CHARSET = @CHARSET@ prefix = /usr/local exec_prefix = $(prefix) bindir = $(exec_prefix)/bin datadir = $(prefix)/lib libdir = $(prefix)/lib infodir = $(prefix)/info # Where to install the manual pages. mandir = $(prefix)/man/man1 # Extension (not including `.') for the installed manual page filenames. manext = 1 #### End of system configuration section. #### SHELL = /bin/sh LOADLIBES = $(LIBS) DISTFILES = COPYING Makefile.in configure configure.in ecc.1 ecc.c ecc.h \ gf.h gflib.c rslib.c version.c .c.o: $(CC) -c -I. -I$(srcdir) $(DEFS) $(CPPFLAGS) $(CFLAGS) $< all: ecc ### targets required by GNU Coding standards ### #Makefile: Makefile.in config.status # ./config.status config.status: configure $(srcdir)/configure --srcdir=$(srcdir) --no-create configure: configure.in cd $(srcdir); autoconf TAGS: cd $(srcdir); etags clean: rm -f *.o core a.out ecc mostlyclean: clean distclean: clean rm -f Makefile config.status realclean: distclean rm -f TAGS dist: $(DISTFILES) echo ecc-`sed -e '/version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q version.c` > .fname rm -rf `cat .fname` mkdir `cat .fname` ln $(DISTFILES) `cat .fname` tar chZf `cat .fname`.tar.Z `cat .fname` rm -rf `cat .fname` .fname install: all -umask 002; mkdir $(bindir) $(mandir) $(INSTALL_PROGRAM) ecc $(bindir)/ecc -$(INSTALL_DATA) $(srcdir)/ecc.1 $(mandir)/ecc.$(manext) uninstall: force -cd $(bindir); rm -f ecc -cd $(mandir); rm -f ecc.$(manext) ### ecc-specific building targets ### ecc.info: ecc.texi cd $(srcdir); makeinfo ecc.texi ecc.dvi: ecc.texi cd $(srcdir); texi2dvi ecc.texi ecc: ecc.o version.o rslib.o gflib.o force: # Prevent GNU make v3 from overflowing arg limit on SysV. .NOEXPORT: trf2.1.4/generic/rs-ecc/COPYING0000644000175000017500000004307011216343142015376 0ustar sergeisergei GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. trf2.1.4/generic/rs-ecc/ecc.10000644000175000017500000000304111216343142015151 0ustar sergeisergei.TH ECC 1 "June 9,1992" .AT 3 .SH NAME ecc \-\- Reed \- Solomon Error Correcting Coder .SH SYNOPSIS .B ecc [ .B \-edv ] .SH DESCRIPTION .I Ecc reads blocks of bytes from stdin, applies the (255,249,7) Reed - Solomon Error Correcting block code, and writes the resulting block to stdout. Ecc is capable of correcting three byte errors in a block of 255 bytes, and is capable of detecting more severe errors. .SH OPTIONS .TP .B \-e Read blocks of 248 bytes or less from stdin, and encode them, generating six bytes of redundancy. A 256 byte code block is then written to stdout, consisting of an ASCII letter G, a length byte, 248 bytes read from stdin and padded as necessary, and the six redundancy bytes. .TP .B \-d Read blocks of 256 bytes from stdin, and decode them. Any errors discovered during the decoding process are reported to stderr. The number of bytes indicated by the length byte are then written to stdout. .TP .B \-v Write the .I ecc version number to stderr. .SH DIAGNOSTICS .TP .I "nn byte error in block xx." .I Ecc found nn error bytes in consecutive block xx, and was able to correct the errors. .TP .I "unrecoverable error in block xx." Four or more errors were detected in consecutive block xx. The flawed block is written uncorrected to stdout. .TP .I "sync error in block xx." The block sync character G was not found. This usually means bytes were added or subtracted from the stream of coded blocks. .SH AUTHOR Paul Flaherty (paulf@Stanford.EDU) .SH "SEE ALSO" uuencode(1),dd(1) .SH BUGS Doesn't automatically correct dropped bytes. trf2.1.4/generic/rs-ecc/configure.in0000644000175000017500000000020211216343142016642 0ustar sergeisergeidnl Process this file with autoconf to produce a configure script. AC_INIT(ecc.c) AC_PROG_CC AC_PROG_INSTALL AC_OUTPUT(Makefile) trf2.1.4/generic/rs-ecc/version.c0000644000175000017500000000004611216343142016170 0ustar sergeisergeichar version[] = "ECC version 1.2.1"; trf2.1.4/generic/rs-ecc/configure0000755000175000017500000001656411216343142016262 0ustar sergeisergei#!/bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf. # Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create] # [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET] # Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and # --with-PACKAGE unless this script has special code to handle it. for arg do # Handle --exec-prefix with a space before the argument. if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix= # Handle --host with a space before the argument. elif test x$next_host = xyes; then next_host= # Handle --prefix with a space before the argument. elif test x$next_prefix = xyes; then prefix=$arg; next_prefix= # Handle --srcdir with a space before the argument. elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir= else case $arg in # For backward compatibility, also recognize exact --exec_prefix. -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*) exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e) next_exec_prefix=yes ;; -gas | --gas | --ga | --g) ;; -host=* | --host=* | --hos=* | --ho=* | --h=*) ;; -host | --host | --hos | --ho | --h) next_host=yes ;; -nfp | --nfp | --nf) ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no) no_create=1 ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) next_prefix=yes ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*) srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s) next_srcdir=yes ;; -with-* | --with-*) package=`echo $arg|sed 's/-*with-//'` # Delete all the valid chars; see if any are left. if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then echo "configure: $package: invalid package name" >&2; exit 1 fi eval "with_`echo $package|sed s/-/_/g`=1" ;; *) ;; esac fi done trap 'rm -f conftest* core; exit 1' 1 3 15 rm -f conftest* compile='${CC-cc} $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1' # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. unique_file=ecc.c # Find the source files, if location was not specified. if test -z "$srcdir"; then srcdirdefaulted=yes # Try the directory containing this script, then `..'. prog=$0 confdir=`echo $prog|sed 's%/[^/][^/]*$%%'` test "X$confdir" = "X$prog" && confdir=. srcdir=$confdir if test ! -r $srcdir/$unique_file; then srcdir=.. fi fi if test ! -r $srcdir/$unique_file; then if test x$srcdirdefaulted = xyes; then echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2 else echo "configure: Can not find sources in \`${srcdir}'." 1>&2 fi exit 1 fi # Preserve a srcdir of `.' to avoid automounter screwups with pwd. # But we can't avoid them for `..', to make subdirectories work. case $srcdir in .|/*|~*) ;; *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute. esac if test -z "$CC"; then echo checking for gcc saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/gcc; then CC="gcc" break fi done IFS="$saveifs" fi test -z "$CC" && CC="cc" # Find out if we are using GNU C, under whatever name. cat > conftest.c < conftest.out 2>&1 if egrep yes conftest.out >/dev/null 2>&1; then GCC=1 # For later tests. fi rm -f conftest* # Make sure to not get the incompatible SysV /etc/install and # /usr/sbin/install, which might be in PATH before a BSD-like install, # or the SunOS /usr/etc/install directory, or the AIX /bin/install, # or the AFS install, which mishandles nonexistent args. (Sigh.) if test -z "$INSTALL"; then echo checking for install saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. case $dir in /etc|/usr/sbin|/usr/etc|/usr/afsws/bin) ;; *) if test -f $dir/install; then if grep dspmsg $dir/install >/dev/null 2>&1; then : # AIX else INSTALL="$dir/install -c" INSTALL_PROGRAM='$(INSTALL)' INSTALL_DATA='$(INSTALL) -m 644' break fi fi ;; esac done IFS="$saveifs" fi INSTALL=${INSTALL-cp} INSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'} INSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'} if test -n "$prefix"; then test -z "$exec_prefix" && exec_prefix='${prefix}' prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%" fi if test -n "$exec_prefix"; then prsub="$prsub s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%\ exec_prefix\\1=\\2$exec_prefix%" fi trap 'rm -f config.status; exit 1' 1 3 15 echo creating config.status rm -f config.status cat > config.status </dev/null`: # # $0 $* for arg do case "\$arg" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) exec /bin/sh $0 $* ;; *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; esac done trap 'rm -f Makefile; exit 1' 1 3 15 CC='$CC' INSTALL='$INSTALL' INSTALL_PROGRAM='$INSTALL_PROGRAM' INSTALL_DATA='$INSTALL_DATA' LIBS='$LIBS' srcdir='$srcdir' DEFS='$DEFS' prefix='$prefix' exec_prefix='$exec_prefix' prsub='$prsub' EOF cat >> config.status <<\EOF top_srcdir=$srcdir for file in .. Makefile; do if [ "x$file" != "x.." ]; then srcdir=$top_srcdir # Remove last slash and all that follows it. Not all systems have dirname. dir=`echo $file|sed 's%/[^/][^/]*$%%'` if test "$dir" != "$file"; then test "$top_srcdir" != . && srcdir=$top_srcdir/$dir test ! -d $dir && mkdir $dir fi echo creating $file rm -f $file echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file sed -e " $prsub s%@CC@%$CC%g s%@INSTALL@%$INSTALL%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@LIBS@%$LIBS%g s%@srcdir@%$srcdir%g s%@DEFS@%$DEFS% " $top_srcdir/${file}.in >> $file fi; done EOF chmod +x config.status test -n "$no_create" || ./config.status trf2.1.4/generic/uucode.c0000644000175000017500000004367511216344224014634 0ustar sergeisergei/* * uucode.c -- * * Implements and registers conversion from and to uuencoded representation. * * * Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) * All rights reserved. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * CVS: $Id: uucode.c,v 1.8 2009/05/07 04:57:27 andreas_kupries Exp $ */ #include "transformInt.h" /* * Converter description * --------------------- * * Encoding: * Each sequence of 3 bytes is expanded into 4 printable characters * using the 4 6bit-sequences contained in the 3 bytes. The mapping * from 6bit value to printable characters is done with the UU map. * Special processing is done for incomplete byte sequences at the * end of the input (1,2 bytes). * * Decoding: * Each sequence of 4 characters is mapped into 4 6bit values using * the reverse UU map and then concatenated to form 3 8bit bytes. * Special processing is done for incomplete character sequences at * the end of the input (1,2,3 bytes). */ /* * Declarations of internal procedures. */ static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, Trf_WriteProc *fun, Trf_Options optInfo, Tcl_Interp* interp, ClientData clientData)); static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, unsigned int character, Tcl_Interp* interp, ClientData clientData)); static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, Tcl_Interp* interp, ClientData clientData)); static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, ClientData clientData)); /* * Converter definition. */ static Trf_TypeDefinition convDefinition = { "uuencode", NULL, /* clientData not used by converters */ NULL, /* set later by Trf_InitUU, THREADING: serialize initialization */ { CreateEncoder, DeleteEncoder, Encode, NULL, FlushEncoder, ClearEncoder, NULL /* no MaxRead */ }, { CreateDecoder, DeleteDecoder, Decode, NULL, FlushDecoder, ClearDecoder, NULL /* no MaxRead */ }, TRF_RATIO (3, 4) }; /* * Definition of the control blocks for en- and decoder. */ typedef struct _EncoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (uuencode) */ unsigned char charCount; unsigned char buf [3]; } EncoderControl; typedef struct _DecoderControl_ { Trf_WriteProc* write; ClientData writeClientData; /* add conversion specific items here (uudecode) */ unsigned char charCount; unsigned char buf [4]; unsigned char expectFlush; } DecoderControl; /* * Character mapping for uuencode (bin -> ascii) * * Index this array by a 6-bit value to obtain the corresponding * 8-bit character. The last character (index 64) is the pad char (~) * | * 1 2 3 4 5 6 6 * 01 2345678901234567890123456789012345678901234567890123456789 01234 */ static CONST char* uuMap = "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_~"; /* uuMap: THREADING: constant, read-only => safe */ #define PAD '~' /* * Character mappings for uudecode (ascii -> bin) * * Index this array by a 8 bit value to get the 6-bit binary field * corresponding to that value. Any illegal characters have high bit set. */ #define Ccc (CONST char) /* Ccc = CONST char cast */ static CONST char uuMapReverse [] = { /* THREADING: constant, read-only => safe */ Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0001, Ccc 0002, Ccc 0003, Ccc 0004, Ccc 0005, Ccc 0006, Ccc 0007, Ccc 0010, Ccc 0011, Ccc 0012, Ccc 0013, Ccc 0014, Ccc 0015, Ccc 0016, Ccc 0017, Ccc 0020, Ccc 0021, Ccc 0022, Ccc 0023, Ccc 0024, Ccc 0025, Ccc 0026, Ccc 0027, Ccc 0030, Ccc 0031, Ccc 0032, Ccc 0033, Ccc 0034, Ccc 0035, Ccc 0036, Ccc 0037, Ccc 0040, Ccc 0041, Ccc 0042, Ccc 0043, Ccc 0044, Ccc 0045, Ccc 0046, Ccc 0047, Ccc 0050, Ccc 0051, Ccc 0052, Ccc 0053, Ccc 0054, Ccc 0055, Ccc 0056, Ccc 0057, Ccc 0060, Ccc 0061, Ccc 0062, Ccc 0063, Ccc 0064, Ccc 0065, Ccc 0066, Ccc 0067, Ccc 0070, Ccc 0071, Ccc 0072, Ccc 0073, Ccc 0074, Ccc 0075, Ccc 0076, Ccc 0077, Ccc 0000, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, /* */ Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200, Ccc 0200 }; #undef Ccc /* *------------------------------------------------------* * * TrfInit_UU -- * * ------------------------------------------------* * Register the conversion implemented in this file. * ------------------------------------------------* * * Sideeffects: * As of 'Trf_Register'. * * Result: * A standard Tcl error code. * *------------------------------------------------------* */ int TrfInit_UU (interp) Tcl_Interp* interp; { TrfLock; /* THREADING: serialize initialization */ convDefinition.options = Trf_ConverterOptions (); TrfUnlock; return Trf_Register (interp, &convDefinition); } /* *------------------------------------------------------* * * CreateEncoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data encoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateEncoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c; c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (uuencode) */ c->charCount = 0; memset (c->buf, '\0', 3); return (ClientData) c; } /* *------------------------------------------------------* * * DeleteEncoder -- * * ------------------------------------------------* * Destroy the control block of an encoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateEncoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* release conversion specific items here (uuencode) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Encode -- * * ------------------------------------------------* * Encode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Encode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (uuencode) */ c->buf [c->charCount] = character; c->charCount ++; if (c->charCount == 3) { unsigned char buf [4]; TrfSplit3to4 (c->buf, buf, 3); TrfApplyEncoding (buf, 4, uuMap); c->charCount = 0; memset (c->buf, '\0', 3); return c->write (c->writeClientData, buf, 4, interp); } return TCL_OK; } /* *------------------------------------------------------* * * FlushEncoder -- * * ------------------------------------------------* * Encode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushEncoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (uuencode) */ if (c->charCount > 0) { unsigned char buf [4]; TrfSplit3to4 (c->buf, buf, c->charCount); TrfApplyEncoding (buf, 4, uuMap); c->charCount = 0; memset (c->buf, '\0', 3); return c->write (c->writeClientData, buf, 4, interp); } return TCL_OK; } /* *------------------------------------------------------* * * ClearEncoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearEncoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { EncoderControl* c = (EncoderControl*) ctrlBlock; /* execute conversion specific code here (uuencode) */ c->charCount = 0; memset (c->buf, '\0', 3); } /* *------------------------------------------------------* * * CreateDecoder -- * * ------------------------------------------------* * Allocate and initialize the control block of a * data decoder. * ------------------------------------------------* * * Sideeffects: * Allocates memory. * * Result: * An opaque reference to the control block. * *------------------------------------------------------* */ static Trf_ControlBlock CreateDecoder (writeClientData, fun, optInfo, interp, clientData) ClientData writeClientData; Trf_WriteProc *fun; Trf_Options optInfo; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c; c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); c->write = fun; c->writeClientData = writeClientData; /* initialize conversion specific items here (uudecode) */ c->charCount = 0; memset (c->buf, '\0', 4); c->expectFlush = 0; return (ClientData) c; } /* *------------------------------------------------------* * * DeleteDecoder -- * * ------------------------------------------------* * Destroy the control block of an decoder. * ------------------------------------------------* * * Sideeffects: * Releases the memory allocated by 'CreateDecoder' * * Result: * None. * *------------------------------------------------------* */ static void DeleteDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* release conversion specific items here (uudecode) */ ckfree ((char*) c); } /* *------------------------------------------------------* * * Decode -- * * ------------------------------------------------* * Decode the given character and write the result. * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int Decode (ctrlBlock, character, interp, clientData) Trf_ControlBlock ctrlBlock; unsigned int character; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (uudecode) */ if (c->expectFlush) { /* * We had a quadruple with pad characters at the last call, * this had to be the last characters in input! coming here * now indicates, that the padding characters were in the * middle of the string, therefore illegal. */ if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal padding inside the string", (char*) NULL); } return TCL_ERROR; } c->buf [c->charCount] = character; c->charCount ++; if (c->charCount == 4) { int res, hasPadding; unsigned char buf [3]; hasPadding = 0; res = TrfReverseEncoding (c->buf, 4, uuMapReverse, PAD, &hasPadding); if (res != TCL_OK) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character found in input", (char*) NULL); } return res; } if (hasPadding) c->expectFlush = 1; TrfMerge4to3 (c->buf, buf); c->charCount = 0; memset (c->buf, '\0', 4); return c->write (c->writeClientData, buf, 3-hasPadding, interp); } return TCL_OK; } /* *------------------------------------------------------* * * FlushDecoder -- * * ------------------------------------------------* * Decode an incomplete character sequence (if possible). * ------------------------------------------------* * * Sideeffects: * As of the called WriteFun. * * Result: * Generated bytes implicitly via WriteFun. * A standard Tcl error code. * *------------------------------------------------------* */ static int FlushDecoder (ctrlBlock, interp, clientData) Trf_ControlBlock ctrlBlock; Tcl_Interp* interp; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (uudecode) */ /* * expectFlush && c->charcount > 0 impossible, catched * in 'Decode' already. */ if (c->charCount > 0) { /* * Convert, as if padded with the pad-character. */ int res, hasPadding; unsigned char buf [3]; hasPadding = 0; res = TrfReverseEncoding (c->buf, c->charCount, uuMapReverse, PAD, &hasPadding); if (res != TCL_OK) { if (interp) { Tcl_ResetResult (interp); Tcl_AppendResult (interp, "illegal character found in input", (char*) NULL); } return res; } TrfMerge4to3 (c->buf, buf); c->charCount = 0; memset (c->buf, '\0', 4); return c->write (c->writeClientData, buf, 3-hasPadding, interp); } return TCL_OK; } /* *------------------------------------------------------* * * ClearDecoder -- * * ------------------------------------------------* * Discard an incomplete character sequence. * ------------------------------------------------* * * Sideeffects: * See above. * * Result: * None. * *------------------------------------------------------* */ static void ClearDecoder (ctrlBlock, clientData) Trf_ControlBlock ctrlBlock; ClientData clientData; { DecoderControl* c = (DecoderControl*) ctrlBlock; /* execute conversion specific code here (uudecode) */ c->charCount = 0; memset (c->buf, '\0', 4); c->expectFlush = 0; } trf2.1.4/aclocal.m40000644000175000017500000000025411216343142013410 0ustar sergeisergei# # Include the TEA standard macro set # builtin(include,tclconfig/tcl.m4) # # Add here whatever m4 macros you want to define for your package # builtin(include,trf.m4) trf2.1.4/Makefile.in0000644000175000017500000004264611216343142013630 0ustar sergeisergei# Makefile.in -- # # This file is a Makefile for Trf TEA Extension. 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. # # Copyright (c) 1999 Scriptics Corporation. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: Makefile.in,v 1.10 2008/12/11 19:04:25 andreas_kupries Exp $ #======================================================================== # Add additional lines to handle any additional AC_SUBST cases that # have been added in a customized configure script. #======================================================================== zlibtcl_STUB_LIB_FILE = @zlibtcl_STUB_LIB_FILE@ zlibtcl_SRC_PATH = @zlibtcl_SRC_PATH@ zlibtcl_VERSION = @zlibtcl_VERSION@ SHLIB_SUFFIX = @SHLIB_SUFFIX@ TRF_TESTS = @TRF_TESTS@ #======================================================================== # Nothing of the variables below this line should need to be changed. # Please check the TARGETS section below to make sure the make targets # are correct. #======================================================================== #======================================================================== # The names of the source files is defined in the configure script. # The object files are used for linking into the final library. # This will be used when a dist target is added to the Makefile. # It is not important to specify the directory, as long as it is the # $(srcdir) or in the generic, win or unix subdirectory. #======================================================================== PKG_SOURCES = @PKG_SOURCES@ PKG_OBJECTS = @PKG_OBJECTS@ PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ #======================================================================== # PKG_TCL_SOURCES identifies Tcl runtime files that are associated with # this package that need to be installed, if any. #======================================================================== PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ #======================================================================== # This is a list of public header files to be installed, if any. #======================================================================== PKG_HEADERS = @PKG_HEADERS@ #======================================================================== # "PKG_LIB_FILE" refers to the library (dynamic or static as per # configuration options) composed of the named objects. #======================================================================== PKG_LIB_FILE = @PKG_LIB_FILE@ PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ lib_BINARIES = $(PKG_LIB_FILE) $(PKG_STUB_LIB_FILE) BINARIES = $(lib_BINARIES) SHELL = @SHELL@ srcdir = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ datadir = @datadir@ mandir = @mandir@ includedir = @includedir@ DESTDIR = PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION) pkgdatadir = $(datadir)/$(PKG_DIR) pkglibdir = $(libdir)/$(PKG_DIR) pkgincludedir = $(includedir)/$(PKG_DIR) top_builddir = . INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ CC = @CC@ CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ CFLAGS_WARNING = @CFLAGS_WARNING@ CLEANFILES = @CLEANFILES@ EXEEXT = @EXEEXT@ LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ MAKE_LIB = @MAKE_LIB@ MAKE_SHARED_LIB = @MAKE_SHARED_LIB@ MAKE_STATIC_LIB = @MAKE_STATIC_LIB@ MAKE_STUB_LIB = @MAKE_STUB_LIB@ OBJEXT = @OBJEXT@ RANLIB = @RANLIB@ RANLIB_STUB = @RANLIB_STUB@ SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_LD = @SHLIB_LD@ SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ STLIB_LD = @STLIB_LD@ TCL_DEFS = @TCL_DEFS@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_SRC_DIR = @TCL_SRC_DIR@ # This is necessary for packages that use private Tcl headers TCL_TOP_DIR_NATIVE = @TCL_TOP_DIR_NATIVE@ # Not used, but retained for reference of what libs Tcl required TCL_LIBS = @TCL_LIBS@ #======================================================================== # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our # package without installing. The other environment variables allow us # to test against an uninstalled Tcl. Add special env vars that you # require for testing here (like TCLX_LIBRARY). #======================================================================== EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR) TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \ @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \ PATH="$(EXTRA_PATH):$(PATH)" \ TCLLIBPATH="$(top_builddir)" TCLSH_PROG = @TCLSH_PROG@ TCLSH = $(TCLSH_ENV) $(TCLSH_PROG) SHARED_BUILD = @SHARED_BUILD@ INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ PKG_CFLAGS = @PKG_CFLAGS@ # TCL_DEFS is not strictly need here, but if you remove it, then you # must make sure that configure.in checks for the necessary components # that your library may use. TCL_DEFS can actually be a problem if # you do not compile with a similar machine setup as the Tcl core was # compiled with. #DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS) DEFS = @DEFS@ $(PKG_CFLAGS) CONFIG_CLEAN_FILES = Makefile CPPFLAGS = @CPPFLAGS@ LIBS = @PKG_LIBS@ @LIBS@ AR = @AR@ CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) #======================================================================== # Start of user-definable TARGETS section #======================================================================== #======================================================================== # TEA TARGETS. Please note that the "libraries:" target refers to platform # independent files, and the "binaries:" target inclues executable programs and # platform-dependent libraries. Modify these targets so that they install # the various pieces of your package. The make and install rules # for the BINARIES that you specified above have already been done. #======================================================================== all: binaries libraries doc #======================================================================== # The binaries target builds executable programs, Windows .dll's, unix # shared/static libraries, and any other platform-dependent files. # The list of targets to build for "binaries:" is specified at the top # of the Makefile, in the "BINARIES" variable. #======================================================================== binaries: $(BINARIES) pkgIndex.tcl-hand libraries: doc: install: all install-binaries install-libraries install-doc install-binaries: binaries install-lib-binaries install-bin-binaries #======================================================================== # This rule installs platform-independent files, such as header files. #======================================================================== install-libraries: libraries @mkdir -p $(DESTDIR)$(includedir) @echo "Installing header files in $(DESTDIR)$(includedir)" @list='$(PKG_HEADERS)'; for i in $$list; do \ echo "Installing $(srcdir)/$$i" ; \ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \ done; #======================================================================== # Install documentation. Unix manpages should go in the $(mandir) # directory. #======================================================================== install-doc: doc test: binaries libraries $(TCLSH) `@CYGPATH@ $(srcdir)/tea.tests/all.tcl` -constraints "$(TRF_TESTS)" $(TESTFLAGS) shell: binaries libraries @$(TCLSH) $(SCRIPT) gdb: $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT) depend: #======================================================================== # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable # mentioned above. That will ensure that this target is built when you # run "make binaries". # # The $(PKG_OBJECTS) objects are created and linked into the final # library. In most cases these object files will correspond to the # source files above. #======================================================================== $(PKG_LIB_FILE): $(PKG_OBJECTS) -rm -f $(PKG_LIB_FILE) ${MAKE_LIB} $(RANLIB) $(PKG_LIB_FILE) $(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS) -rm -f $(PKG_STUB_LIB_FILE) ${MAKE_STUB_LIB} $(RANLIB_STUB) $(PKG_STUB_LIB_FILE) #======================================================================== # We need to enumerate the list of .c to .o lines here. # # In the following lines, $(srcdir) refers to the toplevel directory # containing your extension. If your sources are in a subdirectory, # you will have to modify the paths to reflect this: # # Trf.$(OBJEXT): $(srcdir)/generic/Trf.c # $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/Trf.c` -o $@ # # Setting the VPATH variable to a list of paths will cause the makefile # to look into these paths when resolving .c to .obj dependencies. # As necessary, add $(srcdir):$(srcdir)/compat:.... #======================================================================== VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/md5-crypt:$(srcdir)/compat .c.@OBJEXT@: $(COMPILE) -c `@CYGPATH@ $<` -o $@ #======================================================================== # Create the pkgIndex.tcl file. # It is usually easiest to let Tcl do this for you with pkg_mkIndex, but # you may find that you need to customize the package. If so, either # modify the -hand version, or create a pkgIndex.tcl.in file and have # the configure script output the pkgIndex.tcl by editing configure.in. #======================================================================== pkgIndex.tcl: ( echo pkg_mkIndex . $(PKG_LIB_FILE) \; exit; ) | $(TCLSH) pkgIndex.tcl-hand: (echo 'package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \ [list load [file join $$dir $(PKG_LIB_FILE)]]'\ ) > pkgIndex.tcl #======================================================================== # Distribution creation # You may need to tweak this target to make it work correctly. #======================================================================== #COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar COMPRESS = gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR) DIST_ROOT = /tmp/dist DIST_DIR = $(DIST_ROOT)/$(PKG_DIR) dist-clean: rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.* dist: dist-clean doc mkdir -p $(DIST_DIR) cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/doc/license* \ $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \ $(DIST_DIR)/ chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4 chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in mkdir $(DIST_DIR)/tclconfig cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \ $(DIST_DIR)/tclconfig/ chmod 664 $(DIST_DIR)/tclconfig/tcl.m4 chmod +x $(DIST_DIR)/tclconfig/install-sh -list='htdocs/art demos generic library mac tests unix win tea.tests tools tools/rules'; \ for p in $$list; do \ if test -d $(srcdir)/$$p ; then \ mkdir -p $(DIST_DIR)/$$p; \ cp -p $(srcdir)/$$p/*.* $(srcdir)/$$p/* $(DIST_DIR)/$$p/; \ fi; \ done -list='doc'; \ for p in $$list; do \ if test -d $$p ; then \ mkdir -p $(DIST_DIR)/$$p; \ cp -p $$p/*.* $$p/* $(DIST_DIR)/$$p/; \ fi; \ done -mv $(DIST_DIR)/htdocs/art $(DIST_DIR)/doc/art rm -rf $(DIST_DIR)/htdocs (cd $(DIST_ROOT); $(COMPRESS);) dist_orig: rm -rf $(PKG_DIR)* ls -d $(srcdir)/* > __FILES mkdir $(PKG_DIR) cp -rf `cat __FILES | grep -v __FILES` $(PKG_DIR) rm __FILES find $(PKG_DIR) -name CVS -prune -exec rm -rf {} \; cd $(PKG_DIR) ; $(TCLSH_PROG) PREPARE -tar cf - $(PKG_DIR) | gzip --best > $(PKG_DIR).tar.gz -tar cf - $(PKG_DIR) | bzip2 > $(PKG_DIR).tar.bz2 -zip -r $(PKG_DIR).zip $(PKG_DIR) rm -rf $(PKG_DIR) #======================================================================== # Information copied over from the pre TEA 3.2 Makefile #======================================================================== zlibtcl_SRC_PATH = @zlibtcl_SRC_PATH@ zlibtcl_BUILD_PATH = @zlibtcl_BUILD_PATH@ zlibtcl_VERSION = @zlibtcl_VERSION@ SSL_LIB_DIR = @SSL_LIB_DIR@ SSL_INCLUDE_DIR = @SSL_INCLUDE_DIR@ ZLIB_LIB_DIR = @ZLIB_LIB_DIR@ ZLIB_INCLUDE_DIR = @ZLIB_INCLUDE_DIR@ BZ2_LIB_DIR = @BZ2_LIB_DIR@ BZ2_INCLUDE_DIR = @BZ2_INCLUDE_DIR@ Trf_INCLUDES = -I$(ZLIB_INCLUDE_DIR) \ -I$(BZ2_INCLUDE_DIR) \ -I$(SSL_INCLUDE_DIR) \ -DLIBZ_DEFAULTNAME=\"libz@SHLIB_SUFFIX@\" # $(Trf_INCLUDES) \ # -I"$(srcdir)/generic" \ # -I$(zlibtcl_SRC_PATH) \ # -I$(zlibtcl_BUILD_PATH) # -DZLIBTCL_VERSION=\"$(zlibtcl_VERSION)\" #======================================================================== # End of user-definable section #======================================================================== #======================================================================== # Don't modify the file to clean here. Instead, set the "CLEANFILES" # variable in configure.in #======================================================================== clean: -test -z "$(BINARIES)" || rm -f $(BINARIES) -rm -f *.$(OBJEXT) core *.core -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean: clean -rm -f *.tab.c -rm -f $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log config.status #======================================================================== # Install binary object libraries. On Windows this includes both .dll and # .lib files. Because the .lib files are not explicitly listed anywhere, # we need to deduce their existence from the .dll file of the same name. # Library files go into the lib directory. # In addition, this will generate the pkgIndex.tcl # file in the install location (assuming it can find a usable tclsh shell) # # You should not have to modify this target. #======================================================================== install-lib-binaries: @mkdir -p $(DESTDIR)$(pkglibdir) @list='$(lib_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \ stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \ if test "x$$stub" = "xstub"; then \ echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \ $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \ else \ echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \ $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \ fi; \ ext=`echo $$p|sed -e "s/.*\.//"`; \ if test "x$$ext" = "xdll"; then \ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ if test -f $$lib; then \ echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \ $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \ fi; \ fi; \ fi; \ done @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ if test -f $(srcdir)/$$p; then \ destp=`basename $$p`; \ echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \ fi; \ done @if test "x$(SHARED_BUILD)" = "x1"; then \ echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \ $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \ fi #======================================================================== # Install binary executables (e.g. .exe files and dependent .dll files) # This is for files that must go in the bin directory (located next to # wish and tclsh), like dependent .dll files on Windows. # # You should not have to modify this target, except to define bin_BINARIES # above if necessary. #======================================================================== install-bin-binaries: @mkdir -p $(DESTDIR)$(bindir) @list='$(bin_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ fi; \ done .SUFFIXES: .c .$(OBJEXT) Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status uninstall-binaries: list='$(lib_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ p=`basename $$p`; \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(bin_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/$$p; \ done #======================================================================== # # Target to regenerate header files and stub files from the *.decls tables. # #======================================================================== genstubs: $(TCLSH_PROG) \ $(srcdir)/tools/genStubs.tcl $(srcdir)/generic \ $(srcdir)/Trf.decls #======================================================================== # # Target to check that all exported functions have an entry in the stubs # tables. # #======================================================================== Trf_DECLS = \ $(srcdir)/trf.decls \ $(srcdir)/trfInt.decls checkstubs: -@for i in `nm -p $(Trf_LIB_FILE) | awk '$$2 ~ /T/ { print $$3 }' \ | sort -n`; do \ match=0; \ for j in $(Trf_DECLS); do \ if [ `grep -c $$i $$j` -gt 0 ]; then \ match=1; \ fi; \ done; \ if [ $$match -eq 0 ]; then echo $$i; fi \ done .PHONY: all binaries clean depend distclean doc install libraries test chantest # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: trf2.1.4/ANNOUNCE0000644000175000017500000000232011216343144012677 0ustar sergeisergeiHello world, I hereby announce trf 2.1.4. It is A loadable extension to Tcl providing commands for data conversion, message digests, zlib based compression, error-correction, channel-based manipulation of binary data. Trf extends the language at the C-level with so-called ``transformer''-procedures. With the help of some patches (*) to the core the package is able to intercept all read/write operations on designated channels, thus giving it the ability to transform the buffer contents as desired. This allows things like transparent encryption, compression, charset recoding, etc. Build upon this framework (and as proof of concept) a collection of tcl-level commands was implemented. Additionally some binary data support is put in as well. A separate package containing encryption transformation is available at the same site carrying this package. (*) The patches are only necessary for Tcl 8.0.x and 8.1.x. Since Tcl 8.2 the Trf patch is an official part of the core. Changes from 2.1p1 to 2.1.3 * Corrected inconsistency BUILD_Trf / BUILD_trf. The distribution can be found at Sincerely Andreas Kupries MAY-06-2009 trf2.1.4/tea.tests/0000755000175000017500000000000011216344734013471 5ustar sergeisergeitrf2.1.4/tea.tests/sha1_bb.test0000644000175000017500000000201711216344305015663 0ustar sergeisergei# -*- tcl -*- # Commands covered: sha1 one-way hash function # # This file contains a collection of tests for one or more of the commands # the BLOB-X extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: sha1_bb.test,v 1.1 1999/09/19 10:33:31 aku Exp $ foreach {i in digest} { 0 abc A9993E364706816ABA3E25717850C26C9CD0D89D 1 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq 84983E441C3BD26EBAAE4AA1F95129E5E54670F1 } { if {[info tclversion] < 8.0} { test sha1-4.$i-7.6 {sha1, immediate} {hasSSL} { exec_md sha1 [text2hex $in] } [string toupper $digest] } else { test sha1-4.$i-8.x {sha1, immediate} {hasSSL} { hex -m e [sha1 $in] } [string toupper $digest] } } ::tcltest::cleanupTests trf2.1.4/tea.tests/common_all.test0000644000175000017500000000360111216344305016504 0ustar sergeisergei# -*- tcl -*- # Commands covered: none, common behaviour of all commands as implemented in 'registry.c' # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: common_all.test,v 1.3 2000/11/18 22:42:32 aku Exp $ test common-1.0 {common behaviour, error checking} { catch {bin} msg; set msg } {bin: wrong # args} test common-1.1 {common behaviour, error checking} { catch {bin -in} msg; set msg } {bin: wrong # args, option "-in" requires an argument} test common-1.2 {common behaviour, error checking} { catch {bin -in stdout} msg; set msg } {bin: source-channel not readable} test common-1.3 {common behaviour, error checking} { catch {bin -out stdin} msg; set msg } {bin: destination-channel not writable} test common-1.4 {common behaviour, error checking} { catch {bin -in stdin -attach stdout} msg; set msg } {bin: inconsistent options, -in/-out not allowed with -attach} test common-1.5 {common behaviour, error checking} { catch {bin -out stdout -attach stdout} msg; set msg } {bin: inconsistent options, -in/-out not allowed with -attach} test common-1.6 {common behaviour, error checking} { catch {bin -out stdout} msg; set msg } {bin: wrong # args} test common-1.7 {common behaviour, error checking} { catch {bin -in stdin XXX} msg; set msg } {bin: wrong # args} test common-2.0 {common behaviour: -in, -out} { set m [memchan] bin -out $m -mode encode A seek $m 0 start set res [bin -in $m -mode decode] close $m set res } {A} ::tcltest::cleanupTests trf2.1.4/tea.tests/crc_bb.test0000644000175000017500000000145711216344305015605 0ustar sergeisergei# -*- tcl -*- # Commands covered: crc # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: crc_bb.test,v 1.1 1999/09/19 10:33:30 aku Exp $ foreach {i in digest} { 1 {hello world} B03CB7 } { if {[info tclversion] < 8.0} { test crc-4.$i-7.6 {crc, immediate} { exec_md crc [text2hex $in] } $digest } else { test crc-4.$i-8.x {crc, immediate} { hex -m e [crc $in] } $digest } } ::tcltest::cleanupTests trf2.1.4/tea.tests/rmd128_bb.test0000644000175000017500000000270011216344305016043 0ustar sergeisergei# -*- tcl -*- # Commands covered: ripemd128 # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: rmd128_bb.test,v 1.1 1999/09/19 10:33:30 aku Exp $ foreach {i in digest} { 0 {} cdf26213a150dc3ecb610f18f6b38b46 1 a 86be7afa339d0fc7cfc785e72f578d33 2 abc c14a12199c66e4ba84636b0f69144c77 3 {message digest} 9e327b3d6e523062afc1132d7df9d1b8 4 abcdefghijklmnopqrstuvwxyz fd2aa607f71dc8f510714922b371834e 5 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq a1aa0689d0fafa2ddc22e88b49133a06 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 d1e959eb179c911faea4624c60c5c702 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 3f45ef194732c2dbb2c4a2c769795fa3 } { if {[info tclversion] < 8.0} { test ripemd128-4.$i-7.6 {ripemd128, immediate} { exec_md ripemd128 [text2hex $in] } [string toupper $digest] } else { test ripemd128-4.$i-8.x {ripemd128, immediate} { hex -m e [ripemd128 $in] } [string toupper $digest] } } ::tcltest::cleanupTests trf2.1.4/tea.tests/common_md.test0000644000175000017500000000554311216344305016343 0ustar sergeisergei# -*- tcl -*- # Commands covered: none, common behaviour of message digests (dig_opt.c, digest.c) # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: common_md.test,v 1.2 2000/11/18 22:42:32 aku Exp $ # message digests: adler, crc, crc_zlib, haval, md5, md2, sha, rmd160, rmd128 # tests done with builtin digest 'crc'. foreach {i opt ovalue} { 0 mode absorb 1 matchflag XX 2 write-destination XX 3 read-destination XX } { test common.md-1.$i "common md, argument errors" { catch {crc -$opt $ovalue -in stdin -out stdout} msg set msg } {immediate: no options allowed} } test common.md-2.0 "common md, argument errors" { catch {crc -attach stdout} msg set msg } {attach: -mode not defined} test common.md-2.0 "common md, argument errors" { catch {crc -attach stdout -mode XXX} msg set msg } {unknown mode 'XXX', should be 'absorb', 'write' or 'transparent'} test common.md-2.1 "common md, argument errors" { catch {crc -attach stdin -mode absorb} msg set msg } {attach: -matchflag not defined} test common.md-2.2 "common md, argument errors" { catch {crc -attach stdout -mode write -matchflag XX} msg set msg } {attach: -matchflag not allowed} test common.md-2.3 "common md, argument errors" { catch {crc -attach stdout -mode write} msg set msg } {attach, external: -write-destination missing} test common.md-2.4 "common md, argument errors" { catch {crc -attach stdin -mode write} msg set msg } {attach, external: -read-destination missing} test common.md-2.5 "common md, argument errors" { catch {crc -attach stdout -mode write -write-type XX} msg set msg } {unknown target-type 'XX'} test common.md-2.6 "common md, argument errors" { catch {crc -attach stdout -mode write -write-type channel -write-destination stdin} msg set msg } {write destination channel 'stdin' not opened for writing} test common.md-2.7 "common md, argument errors" { catch {crc -attach stdin -mode write -read-type channel -read-destination stdin} msg set msg } {read destination channel 'stdin' not opened for writing} test common.md-2.8 "common md, argument errors" { catch {crc -attach stdout -mode write -write-type channel -write-destination XXX} msg set msg } {can not find channel named "XXX"} test common.md-2.9 "common md, argument errors" { catch {crc -attach stdin -mode write -read-type channel -read-destination XXX} msg set msg } {can not find channel named "XXX"} ::tcltest::cleanupTests trf2.1.4/tea.tests/crc_zlib_bb.test0000644000175000017500000000155511216344305016624 0ustar sergeisergei# -*- tcl -*- # Commands covered: crc-zlib # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: crc_zlib_bb.test,v 1.1 1999/09/19 10:33:30 aku Exp $ foreach {i in digest} { 0 {hello world} 85114A0D } { if {[info tclversion] < 8.0} { test crc_zlib-4.$i-7.6 {crc_zlib, immediate} {hasZlib} { exec_md crc-zlib [text2hex $in] } $digest } else { test crc_zlib-4.$i-8.x {crc_zlib, immediate} {hasZlib} { hex -m e [crc-zlib $in] } $digest } } ::tcltest::cleanupTests trf2.1.4/tea.tests/rs_ecc_bb.test0000644000175000017500000002445311216344305016275 0ustar sergeisergei# -*- tcl -*- # Commands covered: rs_ecc (Reed Solomon error correction coder) # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: rs_ecc_bb.test,v 1.1 1999/09/19 10:33:31 aku Exp $ proc defblock {name hexdata} { upvar $name x regsub -all { *} $hexdata {} hexdata regsub -all "\n" $hexdata {} hexdata # single long hex string now set x $hexdata } defblock in { 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff } defblock in_b { 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 a9 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 6f 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 12 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca c3 cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff } defblock out { ab e8 b0 ef 7c f7 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 cf ce cd cc cb ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 05 56 7c 70 ca d1 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff fe fd fc fb fa f9 f8 } # ab e8 b0 ef 7c f7 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef # ab e8 b0 ef 7d f7 ff f7 f6 f5 f4 13 f2 f1 f0 ef # * * * defblock out_err_a { ab e8 b0 ef 7d f7 ff f7 f6 f5 f4 13 f2 f1 f0 ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 cf ce cd cc cb ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 05 56 7c 70 ca d1 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff fe fd fc fb fa f9 f8 } # ab e8 b0 ef 7c f7 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef # ab e8 b0 ef 7d f7 ff f7 f6 f5 00 13 f2 f1 f0 ef # * * ** * defblock out_err_b { ab e8 b0 ef 7c f7 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 cf ce cd cc c3 ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 12 a1 a0 9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 6f 6e 6d 6c 6b 6a 6f 68 67 66 65 64 63 62 61 60 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 2f 2e 2d 2c 2b 2a a9 28 27 26 25 24 23 22 21 20 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 05 56 7c 70 ca d1 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff fe fd fc fb fa f9 f8 } # ---- test section ---- # differentiate tcl versions if {[info tclversion] < 8.0} { # 7.6, use channels to transfer information, we have embedded \0s. test rs-ecc-1.0-7.6 {encode, place ecc information} { set in_c [hex2chan $in] set out_c [memchan] fconfigure $out_c -translation binary hex -attach $out_c -mode encode rs_ecc -mode encode -in $in_c -out $out_c unstack $out_c seek $out_c 0 set txt [read $out_c] close $in_c close $out_c list [string length $txt] $txt } [list 1020 [string toupper $out]] ; # {} test rs-ecc-1.1-7.6 {decode without error recovery} { set in_c [hex2chan $out] set out_c [memchan] fconfigure $out_c -translation binary hex -attach $out_c -mode encode rs_ecc -mode decode -in $in_c -out $out_c unstack $out_c seek $out_c 0 set txt [read $out_c] close $in_c close $out_c list [string length $txt] $txt } [list 512 [string toupper $in]] ; # {} test rs-ecc-1.2-7.6 {decode with error recovery} { set in_c [hex2chan $out_err_a] set out_c [memchan] fconfigure $out_c -translation binary hex -attach $out_c -mode encode rs_ecc -mode decode -in $in_c -out $out_c unstack $out_c seek $out_c 0 set txt [read $out_c] close $in_c close $out_c list [string length $txt] $txt } [list 512 [string toupper $in]] ; # {} test rs-ecc-1.3-7.6 {decode, with partial recovery} { set in_c [hex2chan $out_err_b] set out_c [memchan] fconfigure $out_c -translation binary hex -attach $out_c -mode encode rs_ecc -mode decode -in $in_c -out $out_c unstack $out_c seek $out_c 0 set txt [read $out_c] close $in_c close $out_c list [string length $txt] $txt } [list 512 [string toupper $in_b]] ; # {} } else { # 8.x is able to work with embedded \0s. test rs-ecc-1.0-8.x {encode, place ecc information} { set txt [hex -mode encode [rs_ecc -mode encode [hex -mode decode $in]]] list [string length $txt] $txt } [list 1020 [string toupper $out]] ; # {} test rs-ecc-1.1-8.x {decode without error recovery} { set txt [hex -mode encode [rs_ecc -mode decode [hex -mode decode $out]]] list [string length $txt] $txt } [list 512 [string toupper $in]] ; # {} test rs-ecc-1.2-8.x {decode with error recovery} { set txt [hex -mode encode [rs_ecc -mode decode [hex -mode decode $out_err_a]]] list [string length $txt] $txt } [list 512 [string toupper $in]] ; # {} test rs-ecc-1.3-8.x {decode, with partial recovery} { set txt [hex -mode encode [rs_ecc -mode decode [hex -mode decode $out_err_b]]] list [string length $txt] $txt } [list 512 [string toupper $in_b]] ; # {} } # xx_cmp $in $in_b 32 ::tcltest::cleanupTests trf2.1.4/tea.tests/hex_bb.test0000644000175000017500000000310211216344305015607 0ustar sergeisergei# -*- tcl -*- # Commands covered: hex # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: hex_bb.test,v 1.1 1999/09/19 10:33:30 aku Exp $ set text {hello @ hello@} set text_c {hello @ helloP} set text_hex {68656C6C6F2020402068656C6C6F40} set text_hex_b {68656c6c6f2020402068656c6c6f40} set text_hex_c {68656c6c6f2020402068656c6c6f5} test hex-2.0 {hex, conversion errors} { catch {hex -mode decode 68656c6c6f2020402068656c6c6k40} msg set msg } {illegal character 'k' found in input} foreach {index string fullencode encode} { 1 {hello @ hello@} 68656C6C6F2020402068656C6C6F40 68656C6C6F2020402068656C6C6F40 2 {hello @ helloP} 68656C6C6F2020402068656C6C6F50 68656C6C6F2020402068656C6C6F5 } { test hex-3.$index {hex, encode string} { hex -mode encode $string } $fullencode ;#{} test hex-4.$index {hex, decode string} { hex -mode decode $encode } $string ;#{} # redundant tests following test hex-5.$index {hex, encode/decode identity} { hex -mode decode [hex -mode encode $string] } $string ;#{} test hex-6.$index {hex, decode/encode identity} { hex -mode encode [hex -mode decode $fullencode] } $fullencode ;#{} } ::tcltest::cleanupTests trf2.1.4/tea.tests/________0000644000175000017500000000155311216344305015061 0ustar sergeisergei# -*- tcl -*- # Commands covered: none! # # this file checks the integrity of the complete package # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: ________,v 1.1 1999/09/19 10:33:29 aku Exp $ cd ../unix foreach md {crc crc-zlib adler md5 sha haval ripemd128 ripemd160} { set fail [catch { exec ./tclsh ../tools/mdwrap -a $md -c digests.$md | sed -e {s/^/ /} >@ stdout } msg];#{} if {$fail} {puts "$md: $msg"} } cd ../tests if {0} { cd .. foreach md {crc crc-zlib adler md5 sha haval ripemd128 ripemd160} { set fail [catch { exec unix/tclsh tools/md -a $md -c digests.$md | sed -e {s/^/ /} >@ stdout } msg];#{} if {$fail} {puts "$md: $msg"} } cd tests } trf2.1.4/tea.tests/otp_md5_bb.test0000644000175000017500000000221711216344305016400 0ustar sergeisergei# -*- tcl -*- # Commands covered: otp_md5 # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: otp_md5_bb.test,v 1.2 1999/10/15 23:08:33 aku Exp $ # test suite from RFC 1321 (1..7) foreach {i in digest} { 0 {hello world} CD7D19006F442313 1 {} 3D9D854163F8F07A 2 a 3D02EC5BA98690C9 3 abc 46976FE5143330C2 4 {message digest} AB31464CD646F25D 5 abcdefghijklmnopqrstuvwxyz BE079ABBABF5053B 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 7415B7B44D36446A 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 FBA42E8C0AE47F2F } { test otp_md5-4.$i-8.x {otp_md5, immediate} { hex -m e -- [otp_md5 -- $in] } [string toupper $digest] } ::tcltest::cleanupTests trf2.1.4/tea.tests/transform_bb.test0000644000175000017500000000471511216344305017051 0ustar sergeisergei# -*- tcl -*- # Commands covered: transform # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1997 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: transform_bb.test,v 1.3 2001/08/21 05:51:33 tcl Exp $ proc identity {operation buffer} { global tracevar lappend tracevar "${operation}-[string length $buffer]" # no changes! set buffer } proc pfx {prefix operation buffer} { return $prefix$buffer } test transform-1.0 {transform behaviour, immediate write} { set tracevar "" lappend tracevar [transform -mode write -command identity foobarflabbergast] set tracevar } {create/write-0 write-17 flush/write-0 delete/write-0 foobarflabbergast} test transform-1.1 {transform behaviour, immediate read} { set tracevar "" lappend tracevar [transform -mode read -command identity foobarflabbergast] set tracevar } {create/read-0 read-17 flush/read-0 delete/read-0 foobarflabbergast} test transform-2.0 {transform behaviour, attached write} { set tracevar "" set out [memchan] transform -attach $out -command identity puts -nonewline $out foobarflabbergast close $out set tracevar } {create/write-0 create/read-0 query/ratio-0 write-17 flush/write-0 flush/read-0 delete/write-0 delete/read-0} test transform-2.1 {transform behaviour, attached read} { set tracevar "" set in [memchan] puts -nonewline $in foobarflabbergast seek $in 0 transform -attach $in -command identity read $in close $in set tracevar } {create/write-0 create/read-0 query/ratio-0 query/maxRead-0 read-17 query/maxRead-0 flush/read-0 flush/write-0 delete/write-0 delete/read-0} test transform-3.0 {More than one transform should work too} { set tracevar "" set out [memchan] transform -attach $out -command [list pfx a] transform -attach $out -command [list pfx b] puts -nonewline $out foo unstack $out unstack $out seek $out 0 set data [read $out] close $out set data } {abfooaba} ::tcltest::cleanupTests trf2.1.4/tea.tests/binio_bb.test0000644000175000017500000001015311216344305016127 0ustar sergeisergei# -*- tcl -*- # Commands covered: binio # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1997 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: binio_bb.test,v 1.1 1999/09/19 10:33:29 aku Exp $ # determine endianess of machine running these tests if {0} { proc endianess {} { set fh [open binio.test r] set e [fconfigure $fh -byteorder] close $fh return $e } proc choose {small big} { global endianess switch -- $endianess { smallendian {return $small} bigendian {return $big} } } set endianess [endianess] } test binio-1.0 {binio, errors} {binIO} { catch {binio} msg set msg } {wrong # args: should be "binio option channel ?arg arg...?"} test binio-1.1 {binio, errors} {binIO} { catch {binio blubber a} msg set msg } {binio blubber: channel expected as 2nd argument, got "a"} test binio-1.2 {binio, errors} {binIO} { catch {binio blubber stdin} msg set msg } {binio: bad option "blubber": should be one of copy, pack or unpack} test binio-1.3 {binio, errors} {binIO} { catch {binio copy stdin} msg set msg } {wrong # args: should be "binio copy inChannel outChannel ?chunkSize?"} test binio-1.4 {binio, errors} {binIO} { catch {binio pack stdout} msg set msg } {wrong # args: should be "binio pack outChannel format ?data1 data2 ...?"} test binio-1.5 {binio, errors} {binIO} { catch {binio unpack stdin} msg set msg } {wrong # args: should be "binio unpack outChannel format ?var1 var2 ...?"} test binio-1.6 {binio copy, errors} {binIO} { catch {binio copy stdout stdin} msg set msg } {channel "stdout" wasn't opened for reading} test binio-1.7 {binio copy, errors} {binIO} { catch {binio copy stdin stdin} msg set msg } {channel "stdin" wasn't opened for writing} test binio-1.8 {binio copy} {binIO} { set input [open test.binio r] set output [memchan] fconfigure $input -translation binary fconfigure $output -translation binary set n [binio copy $input $output] close $output close $input set n } {27} test binio-1.9 {binio unpack, %c} {binIO} { set input [open test.binio r] fconfigure $input -translation binary set n "" foreach i {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27} { binio unpack $input %c k lappend n $k } close $input set n } {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} test binio-1.10 {binio unpack, %X, smallendian} {binIO} { set input [open test.binio r] fconfigure $input -translation binary -byteorder smallendian set n "" foreach i {1 2 3 4 5 6 7 8 9 10 11 12 13} { binio unpack $input %X k lappend n $k } close $input set n } {0100 0302 0504 0706 0908 0b0a 0d0c 0f0e 1110 1312 1514 1716 1918} test binio-1.11 {binio unpack, %X, bigendian} {binIO} { set input [open test.binio r] fconfigure $input -translation binary -byteorder bigendian set n "" foreach i {1 2 3 4 5 6 7 8 9 10 11 12 13} { binio unpack $input %X k lappend n $k } close $input set n } {0001 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819} test binio-1.12 {binio unpack, %x, smallendian order} {binIO} { set input [open test.binio r] fconfigure $input -translation binary -byteorder smallendian set n "" foreach i {1 2 3 4 5 6} { binio unpack $input %x k lappend n $k } close $input set n } {03020100 07060504 0b0a0908 0f0e0d0c 13121110 17161514} test binio-1.13 {binio unpack, %x, bigendian order} {binIO} { set input [open test.binio r] fconfigure $input -translation binary -byteorder bigendian set n "" foreach i {1 2 3 4 5 6} { binio unpack $input %x k lappend n $k } close $input set n } {00010203 04050607 08090a0b 0c0d0e0f 10111213 14151617} ::tcltest::cleanupTests trf2.1.4/tea.tests/zip_bb.test0000644000175000017500000000474711216344305015645 0ustar sergeisergei# -*- tcl -*- # Commands covered: bin # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: zip_bb.test,v 1.4 1999/10/20 22:47:06 aku Exp $ set text "hello, hello!" set text_compressed_as_hex "789CCB48CDC9C9D751C800518A0021700496" set text_compressed_as_hex_with_nowrap "CB48CDC9C9D751C800518A00" # differentiate tcl versions if {[info tclversion] < 8.0} { # 7.6, use channels to transfer information, we have embedded \0s. test zip-1.0-7.6 {zip compression} {hasZlib} { set in [text2chan $text] set out [memchan] fconfigure $out -translation binary hex -attach $out -mode encode zip -mode compress -in $in -out $out unstack $out seek $out 0 set data [read $out] close $out close $in set data } $text_compressed_as_hex ; #{} test zip-1.1-7.6 {zip decompression} {hasZlib} { set in [hex2chan $text_compressed_as_hex] set out [memchan] seek $in 0 zip -mode decompress -in $in -out $out seek $out 0 set data [read $out] close $out close $in set data } $text ; #{} } else { # 8.x is able to work with embedded \0s. test zip-1.0-8.x {zip compression} {hasZlib} { hex -mode encode [zip -mode compress $text] } $text_compressed_as_hex ; #{} test zip-1.1-8.x {zip decompression} {hasZlib} { zip -mode decompress [hex -mode decode $text_compressed_as_hex] } $text ; #{} test zip-1.2-8.x {zip compression with nowrap} { hex -mode encode [zip -mode compress -nowrap true $text] } $text_compressed_as_hex_with_nowrap ; #{} test zip-1.3-8.x {zip decompression with nowrap} { zip -mode decompress -nowrap true [hex -mode decode $text_compressed_as_hex_with_nowrap] } $text ; #{} } set data [info commands] set zdata [zip -mode compress $data] makeFile {} zip test zip-2.0 {(De)compression while reading/writing from/to a file} {hasZlib} { write_zip zip $data read_zip zip } $data test zip-2.1 {(De)compression of binary information} {hasZlib} { write_file zip $zdata zip -mode decompress [read_file zip] } $data ::tcltest::cleanupTests trf2.1.4/tea.tests/README0000644000175000017500000000675411216344305014357 0ustar sergeisergeiTRF Test Suite --------------- $Id: README,v 1.1 1999/09/19 10:33:29 aku Exp $ This directory contains a set of validation tests of the TRF commands. Each of the files whose name ends in ".test" is intended to (fully) exercise one or a few Trf commands. The commands tested by a given file are listed in the first line of the file. You can run the tests in the following way: (*) start up tclsh in this directory, then "source" the test file (for example, type "source trf.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. 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: tclsh < trf.test > trf.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). trf2.1.4/tea.tests/rmd160_bb.test0000644000175000017500000000300011216344305016031 0ustar sergeisergei# -*- tcl -*- # Commands covered: ripemd160 # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: rmd160_bb.test,v 1.1 1999/09/19 10:33:31 aku Exp $ foreach {i in digest} { 0 {} 9C1185A5C5E9FC54612808977EE8F548B2258D31 1 a 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe 2 abc 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc 3 {message digest} 5d0689ef49d2fae572b881b123a85ffa21595f36 4 abcdefghijklmnopqrstuvwxyz f71c27109c692c1b56bbdceb5b9d2865b3708dbc 5 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq 12a053384a9c0c88e405a06c27dcf49ada62eb2b 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 b0e20b6e3116640286ed3a87a5713079b21f5189 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 9b752e45573d4b39f4dbd3323cab82bf63326bfb } { if {[info tclversion] < 8.0} { test ripemd160-4.$i-7.6 {ripemd160, immediate} { exec_md ripemd160 [text2hex $in] } [string toupper $digest] } else { test ripemd160-4.$i-8.x {ripemd160, immediate} { hex -m e [ripemd160 $in] } [string toupper $digest] } } ::tcltest::cleanupTests trf2.1.4/tea.tests/sha_bb.test0000644000175000017500000000176511216344305015613 0ustar sergeisergei# -*- tcl -*- # Commands covered: sha one-way hash function # # This file contains a collection of tests for one or more of the commands # the BLOB-X extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: sha_bb.test,v 1.1 1999/09/19 10:33:31 aku Exp $ foreach {i in digest} { 0 abc 0164b8a914cd2a5e74c4f7ff082c4d97f1edf880 1 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq d2516ee1acfa5baf33dfc1c471e438449ef134c8 } { if {[info tclversion] < 8.0} { test sha-4.$i-7.6 {sha, immediate} { exec_md sha [text2hex $in] } [string toupper $digest] } else { test sha-4.$i-8.x {sha, immediate} { hex -m e [sha $in] } [string toupper $digest] } } ::tcltest::cleanupTests trf2.1.4/tea.tests/common_seek.test0000644000175000017500000001554211216344305016672 0ustar sergeisergei# -*- tcl -*- # Commands covered: all, common behaviour of seeking # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1999 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: common_seek.test,v 1.2 1999/10/11 20:07:38 aku Exp $ makeFile {hex test data} seektests # A server socket for the tests, actually doing nothing. proc null {args} {} set echo [socket -server null 0] set eport [lindex [fconfigure $echo -sockname] 2] # ---------------------------------------------------------------------- # check computation of chosen and used policy, which is based upon # transforms below it, and of the base channel. test seek-1.0 {chosen policy, seekable transform, seekable base} { set f [open seektests r] hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {1 2} overideAllowed 1 identityForced 0} test seek-1.1 {chosen policy, seekable transform, unseekable base} { set f [socket localhost $eport] hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.2 {chosen policy, unseekable transform, seekable base} { set f [open seektests r] ascii85 -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {0 0} ratioChosen {0 0} overideAllowed 1 identityForced 0} test seek-1.4 {chosen policy, unseekable transform, unseekable base} { set f [socket localhost $eport] ascii85 -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {0 0} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.5 {chosen policy, seekable transforms, seekable base} { set f [open seektests r] base64 -attach $f -mode encode hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {1 2} overideAllowed 1 identityForced 0} test seek-1.6 {chosen policy, transform mixture, seekable base} { set f [open seektests r] ascii85 -attach $f -mode encode hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.7 {chosen policy, seekable transforms, unseekable base} { set f [socket localhost $eport] base64 -attach $f -mode encode hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.8 {chosen policy, transform mixture, unseekable base} { set f [socket localhost $eport] ascii85 -attach $f -mode encode hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.9 {chosen policy, all seekable, force identity} { set f [open seektests r] hex -attach $f -mode encode -seekpolicy identity set res [fconfigure $f -seekstate] close $f set res } {seekable 1 ratio {1 1} up 0 upBufStart 0 upBufEnd 0 down 0 downBase 0 downAhead 0 changed 0} test seek-1.10 {chosen policy, all seekable, force unseekable} { set f [open seektests r] hex -attach $f -mode encode -seekpolicy unseekable set res [fconfigure $f -seekstate] close $f set res } {seekable 0 ratio {0 0} up 0 upBufStart 0 upBufEnd 0 down 0 downBase 0 downAhead 0 changed 0} test seek-1.11 {chosen policy, all seekable, force error} { set f [open seektests r] catch {hex -attach $f -mode encode -seekpolicy unseek} res close $f set res } {Invalid value "unseek", must be one of 'unseekable', 'identity' or ''.} test seek-1.12 {chosen policy, unseekables, force error} { set f [open seektests r] ascii85 -attach $f -mode encode catch {hex -attach $f -mode encode -seekpolicy identity} res close $f set res } {It is not allowed to overide the seek policy used by this channel.} # ---------------------------------------------------------------------- # check seek restrictions set upon transforming and unseekable transforms. test seek-2.0 {seeking behind start of stream} { set f [open seektests r] hex -attach $f -mode decode catch {seek $f -1} res close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} test seek-2.1 {seeking relative to the end} { set f [open seektests r] hex -attach $f -mode decode catch {seek $f 0 end} res close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} test seek-2.2 {seeking modulo numBytesTransform} { set f [open seektests r] hex -attach $f -mode decode catch {seek $f 1 cur} res close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} test seek-2.3 {seeking modulo numBytesTransform} { set f [open seektests r] hex -attach $f -mode decode read $f 1 set fail [catch {seek $f 2 cur} res] close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} test seek-2.4 {seeking the unseekable} { set f [socket localhost $eport] hex -attach $f -mode decode catch {seek $f 1} res close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} # ---------------------------------------------------------------------- # check seek behaviour (discarding buffers, et. al). test seek-3.0 {picking up the base} { set f [open seektests r] read $f 3 hex -attach $f -mode decode set res [fconfigure $f -seekstate] close $f set res } {seekable 1 ratio {2 1} up 0 upBufStart 0 upBufEnd 0 down 3 downBase 3 downAhead 0 changed 0} test seek-3.1 {picking up the base, read ahead} { set f [open seektests r] read $f 3 hex -attach $f -mode decode read $f 2 set res [list [tell $f] [fconfigure $f -seekstate]] close $f set res } {2 {seekable 1 ratio {2 1} up 22 upBufStart 22 upBufEnd 22 down 14 downBase 3 downAhead 0 changed 0}} test seek-3.2 {resync, discard buffers} { set f [open seektests r] read $f 3 hex -attach $f -mode decode read $f 2 seek $f 2 cur set res [list [tell $f] [fconfigure $f -seekstate]] close $f set res } {4 {seekable 1 ratio {2 1} up 4 upBufStart 4 upBufEnd 4 down 5 downBase 3 downAhead 0 changed 0}} # ---------------------------------------------------------------------- close $echo ::tcltest::cleanupTests trf2.1.4/tea.tests/md5_crash.test0000644000175000017500000000232211216344305016230 0ustar sergeisergei# -*- tcl -*- # Commands covered: md5 - Try to crash it. # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: md5_crash.test,v 1.1 2003/03/27 07:51:05 andreas_kupries Exp $ # test suite from RFC 1321 (1..7) if {[info tclversion] < 8.0} { puts "Skipping crash test in pre-8.0 interpreter" return } test md5-5.0 {md5, crash} { # SF tcltrf Bug #667168, trf set f [open [::tcltest::makeFile {} debug.out] w] fconfigure $f -translation binary -encoding binary -buffering none md5 -attach $f -mode transparent -write-type var -write-dest ::md5 puts -nonewline $f [string repeat X 402] puts -nonewline $f [string repeat X 224] unstack $f close $f set res [hex -mode encode -- $::md5] ::tcltest::removeFile debug.out set res } {D6A0FFF1DFF65952747324F690FAF519} ::tcltest::cleanupTests trf2.1.4/tea.tests/oct_bb.test0000644000175000017500000000243511216344305015620 0ustar sergeisergei# -*- tcl -*- # Commands covered: oct # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: oct_bb.test,v 1.1 1999/09/19 10:33:30 aku Exp $ test oct-2.0 {oct, conversion errors} { catch {oct -mode decode 101010090010101010200} msg set msg } {illegal character '9' found in input} foreach {index string fullencode encode} { 1 hello 150145154154157 150145154154157 2 hellh 150145154154150 15014515415415 } { test oct-3.$index {oct, encode string} { oct -mode encode $string } $fullencode ;#{} test oct-4.$index {oct, decode string} { oct -mode decode $encode } $string ;#{} # redundant tests following test oct-5.$index {oct, encode/decode identity} { oct -mode decode [oct -mode encode $string] } $string ;#{} test oct-6.$index {oct, decode/encode identity} { oct -mode encode [oct -mode decode $fullencode] } $fullencode ;#{} } ::tcltest::cleanupTests trf2.1.4/tea.tests/bz2_bb.test0000644000175000017500000000342611216344305015531 0ustar sergeisergei# -*- tcl -*- # Commands covered: bz2 # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: bz2_bb.test,v 1.2 1999/09/20 21:28:12 aku Exp $ set text "hello, hello!" set text_compressed_as_hex "425A68393141592653592C546C72000003110060040244A0002129A3108603690E70A1E2EE48A70A12058A8D8E40" # differentiate tcl versions if {[info tclversion] < 8.0} { # 7.6, use channels to transfer information, we have embedded \0s. test bz2-1.0-7.6 {bz2 compression} {hasBz} { set in [text2chan $text] set out [memchan] fconfigure $out -translation binary hex -attach $out -mode encode bz2 -mode compress -in $in -out $out unstack $out seek $out 0 set data [read $out] close $out close $in set data } $text_compressed_as_hex ; #{} test bz2-1.1-7.6 {bz2 decompression} {hasBz} { set in [hex2chan $text_compressed_as_hex] set out [memchan] seek $in 0 bz2 -mode decompress -in $in -out $out seek $out 0 set data [read $out] close $out close $in set data } $text ; #{} } else { # 8.x is able to work with embedded \0s. test bz2-1.0-8.x {bz2 compression} {hasBz} { hex -mode encode [bz2 -mode compress $text] } $text_compressed_as_hex ; #{} test bz2-1.1-8.x {bz2 decompression} {hasBz} { bz2 -mode decompress [hex -mode decode $text_compressed_as_hex] } $text ; #{} } ::tcltest::cleanupTests trf2.1.4/tea.tests/md5_bb.test0000644000175000017500000000261411216344305015517 0ustar sergeisergei# -*- tcl -*- # Commands covered: md5 # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: md5_bb.test,v 1.1 1999/09/19 10:33:30 aku Exp $ # test suite from RFC 1321 (1..7) foreach {i in digest} { 0 {hello world} 5EB63BBBE01EEED093CB22BB8F5ACDC3 1 {} d41d8cd98f00b204e9800998ecf8427e 2 a 0cc175b9c0f1b6a831c399e269772661 3 abc 900150983cd24fb0d6963f7d28e17f72 4 {message digest} f96b697d7cb7938d525a2f31aaf161d0 5 abcdefghijklmnopqrstuvwxyz c3fcd3d76192e4007dfb496cca67e13b 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 d174ab98d277d9f5a5611c2c9f419d9f 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 57edf4a22be3c955ac49da2e2107b67a } { if {[info tclversion] < 8.0} { test md5-4.$i-7.6 {md5, immediate} { exec_md md5 [text2hex $in] } [string toupper $digest] } else { test md5-4.$i-8.x {md5, immediate} { hex -m e [md5 $in] } [string toupper $digest] } } ::tcltest::cleanupTests trf2.1.4/tea.tests/base64_bb.test0000644000175000017500000000341611216344305016117 0ustar sergeisergei# -*- tcl -*- # Commands covered: base64 # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: base64_bb.test,v 1.2 2003/03/28 00:57:42 andreas_kupries Exp $ test base64-2.0 {base64, ignore illegal characters} { set msg [base64 -mode decode aGV!bG8=] } {he[} foreach {index string fullencode encode} { 1 hello {aGVsbG8= } aGVsbG8= 2 hell {aGVsbA== } aGVsbA } { test base64-3.$index {base64, encode string} { base64 -mode encode $string } $fullencode ;#{} test base64-4.$index {base64, decode string} { base64 -mode decode $encode } $string ;#{} # redundant tests following test base64-5.$index {base64, encode/decode identity} { base64 -mode decode [base64 -mode encode $string] } $string ;#{} test base64-6.$index {base64, decode/encode identity} { base64 -mode encode [base64 -mode decode $fullencode] } $fullencode ;#{} } test base64-7.1 {base64, partial conversion for attachments} { puts -nonewline [set ma [memchan]] aGVsbA seek $ma 0 base64 -mode encode -attach $ma set data [read $ma] close $ma list [string length $data] $data } {4 hell} test base64-7.2 {base64, partial conversion for attachments} { puts -nonewline [set ma [memchan]] hello seek $ma 0 base64 -mode decode -attach $ma set data [read $ma] close $ma list [string length $data] $data } {9 {aGVsbG8= }} ::tcltest::cleanupTests trf2.1.4/tea.tests/common_conv.test0000644000175000017500000000230111216344305016675 0ustar sergeisergei# -*- tcl -*- # Commands covered: common behaviour of all conversions. # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: common_conv.test,v 1.2 2000/11/18 22:42:32 aku Exp $ # conversions: bin, hex, oct, base64, uuencode, ascii85 foreach c { bin hex oct base64 uuencode ascii85 } { test $c-1.0 "$c, argument errors" { catch {$c XXX} msg; set msg } {-mode option not set} test $c-1.1 "$c, argument errors" { catch {$c -mode} msg; set msg } "$c: wrong # args, all options require an argument" test $c-1.2 "$c, argument errors" { catch {$c -x x} msg; set msg } {unknown option '-x', should be '-mode'} test $c-1.3 "$c, argument errors" { catch {$c -m x} msg; set msg } {unknown mode 'x', should be 'encode' or 'decode'} } ::tcltest::cleanupTests trf2.1.4/tea.tests/uu_bb.test0000644000175000017500000000251011216344305015456 0ustar sergeisergei# -*- tcl -*- # Commands covered: uuencode # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: uu_bb.test,v 1.1 1999/09/19 10:33:31 aku Exp $ test uuencode-2.0 {uuencode, conversion errors} { catch {uuencode -mode decode aGV!bG8=} msg set msg } {illegal character found in input} foreach {index string fullencode encode} { 1 raoul @ stdout } msg];#{} if {$fail} {puts "$md: $msg"} } cd ../tests if {0} { cd .. foreach md {crc crc-zlib adler md5 sha haval ripemd128 ripemd160} { set fail [catch { exec unix/tclsh tools/md -a $md -c digests.$md | sed -e {s/^/ /} >@ stdout } msg];#{} if {$fail} {puts "$md: $msg"} } cd tests } trf2.1.4/tests/common.all.test0000644000175000017500000000365111216344305015660 0ustar sergeisergei# -*- tcl -*- # Commands covered: none, common behaviour of all commands as implemented in 'registry.c' # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: common.all.test,v 1.3 2000/11/18 22:42:33 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} test common-1.0 {common behaviour, error checking} { catch {bin} msg; set msg } {bin: wrong # args} test common-1.1 {common behaviour, error checking} { catch {bin -in} msg; set msg } {bin: wrong # args, option "-in" requires an argument} test common-1.2 {common behaviour, error checking} { catch {bin -in stdout} msg; set msg } {bin: source-channel not readable} test common-1.3 {common behaviour, error checking} { catch {bin -out stdin} msg; set msg } {bin: destination-channel not writable} test common-1.4 {common behaviour, error checking} { catch {bin -in stdin -attach stdout} msg; set msg } {bin: inconsistent options, -in/-out not allowed with -attach} test common-1.5 {common behaviour, error checking} { catch {bin -out stdout -attach stdout} msg; set msg } {bin: inconsistent options, -in/-out not allowed with -attach} test common-1.6 {common behaviour, error checking} { catch {bin -out stdout} msg; set msg } {bin: wrong # args} test common-1.7 {common behaviour, error checking} { catch {bin -in stdin XXX} msg; set msg } {bin: wrong # args} test common-2.0 {common behaviour: -in, -out} { set m [memchan] bin -out $m -mode encode A seek $m 0 start set res [bin -in $m -mode decode] close $m set res } {A} trf2.1.4/tests/base64.test0000644000175000017500000000527211216344305014706 0ustar sergeisergei# -*- tcl -*- # Commands covered: base64 # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: base64.test,v 1.5 2004/02/18 19:07:18 andreas_kupries Exp $ if {[string compare test [info procs test]] == 1} then {source defs} test base64-2.0 {base64, ignore illegal characters} { set msg [base64 -mode decode aGV!bG8=] } {he[} foreach {index string fullencode encode} { 1 hello {aGVsbG8= } aGVsbG8= 2 hell {aGVsbA== } aGVsbA } { test base64-3.$index {base64, encode string} { base64 -mode encode $string } $fullencode ;#{} test base64-4.$index {base64, decode string} { base64 -mode decode $encode } $string ;#{} # redundant tests following test base64-5.$index {base64, encode/decode identity} { base64 -mode decode [base64 -mode encode $string] } $string ;#{} test base64-6.$index {base64, decode/encode identity} { base64 -mode encode [base64 -mode decode $fullencode] } $fullencode ;#{} } test base64-7.1 {base64, partial conversion for attachments} { puts -nonewline [set ma [memchan]] aGVsbA seek $ma 0 base64 -mode encode -attach $ma set data [read $ma] close $ma list [string length $data] $data } {4 hell} test base64-7.2 {base64, partial conversion for attachments} { puts -nonewline [set ma [memchan]] hello seek $ma 0 base64 -mode decode -attach $ma set data [read $ma] close $ma list [string length $data] $data } {9 {aGVsbG8= }} test base64-7.3 {base64, original data, no transform} { puts -nonewline [set ma [memchan]] aGVsbA seek $ma 0 set data [read $ma] close $ma list [string length $data] $data } {6 aGVsbA} test base64-7.4 {base64, original data, no transform} { puts -nonewline [set ma [memchan]] hello seek $ma 0 set data [read $ma] close $ma list [string length $data] $data } {5 hello} set p [makeFile {aGVsbA} foo] test base64-7.5 {base64, partial conversion for attachments} { set ma [open $p r+] base64 -mode encode -attach $ma set data [read $ma] close $ma list [string length $data] $data } {4 hell} set p [makeFile {hell} foo] test base64-7.6 {base64, partial conversion for attachments} { set ma [open $p r+] base64 -mode decode -attach $ma set data [read $ma] close $ma list [string length $data] $data } {9 {aGVsbAo= }} trf2.1.4/tests/crc.test0000644000175000017500000000153011216344305014362 0ustar sergeisergei# -*- tcl -*- # Commands covered: crc # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: crc.test,v 1.3 1997/07/22 22:00:43 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} foreach {i in digest} { 1 {hello world} B03CB7 } { if {[info tclversion] < 8.0} { test crc-4.$i-7.6 {crc, immediate} { exec_md crc [text2hex $in] } $digest } else { test crc-4.$i-8.x {crc, immediate} { hex -m e [crc $in] } $digest } } trf2.1.4/tests/common.conv.test0000644000175000017500000000235511216344305016055 0ustar sergeisergei# -*- tcl -*- # Commands covered: common behaviour of all conversions. # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: common.conv.test,v 1.2 2000/11/18 22:42:33 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} # conversions: bin, hex, oct, base64, uuencode, ascii85 foreach c { bin hex oct base64 uuencode ascii85 } { test $c-1.0 "$c, argument errors" { catch {$c XXX} msg; set msg } {-mode option not set} test $c-1.1 "$c, argument errors" { catch {$c -mode} msg; set msg } "$c: wrong # args, all options require an argument" test $c-1.2 "$c, argument errors" { catch {$c -x x} msg; set msg } {unknown option '-x', should be '-mode'} test $c-1.3 "$c, argument errors" { catch {$c -m x} msg; set msg } {unknown mode 'x', should be 'encode' or 'decode'} } trf2.1.4/tests/md5.test0000644000175000017500000000266511216344305014312 0ustar sergeisergei# -*- tcl -*- # Commands covered: md5 # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: md5.test,v 1.4 1997/07/22 22:00:43 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} # test suite from RFC 1321 (1..7) foreach {i in digest} { 0 {hello world} 5EB63BBBE01EEED093CB22BB8F5ACDC3 1 {} d41d8cd98f00b204e9800998ecf8427e 2 a 0cc175b9c0f1b6a831c399e269772661 3 abc 900150983cd24fb0d6963f7d28e17f72 4 {message digest} f96b697d7cb7938d525a2f31aaf161d0 5 abcdefghijklmnopqrstuvwxyz c3fcd3d76192e4007dfb496cca67e13b 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 d174ab98d277d9f5a5611c2c9f419d9f 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 57edf4a22be3c955ac49da2e2107b67a } { if {[info tclversion] < 8.0} { test md5-4.$i-7.6 {md5, immediate} { exec_md md5 [text2hex $in] } [string toupper $digest] } else { test md5-4.$i-8.x {md5, immediate} { hex -m e [md5 $in] } [string toupper $digest] } } trf2.1.4/tests/transform.test0000644000175000017500000000541111216344306015631 0ustar sergeisergei# -*- tcl -*- # Commands covered: transform # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1997 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: transform.test,v 1.6 2001/08/21 05:51:33 tcl Exp $ if {[string compare test [info procs test]] == 1} then {source defs} proc 82 {a b} { if {[string compare [info tclversion] 8.2] < 0} { return $b } else { return $a } } proc identity {operation buffer} { global tracevar lappend tracevar "${operation}-[string length $buffer]" # no changes! set buffer } proc pfx {prefix operation buffer} { return $prefix$buffer } test transform-1.0 {transform behaviour, immediate write} { set tracevar "" lappend tracevar [transform -mode write -command identity foobarflabbergast] set tracevar } {create/write-0 write-17 flush/write-0 delete/write-0 foobarflabbergast} test transform-1.1 {transform behaviour, immediate read} { set tracevar "" lappend tracevar [transform -mode read -command identity foobarflabbergast] set tracevar } {create/read-0 read-17 flush/read-0 delete/read-0 foobarflabbergast} test transform-2.0 {transform behaviour, attached write} { set tracevar "" set out [memchan] transform -attach $out -command identity puts -nonewline $out foobarflabbergast close $out set tracevar } {create/write-0 create/read-0 query/ratio-0 write-17 flush/write-0 flush/read-0 delete/write-0 delete/read-0} test transform-2.1 {transform behaviour, attached read} { set tracevar "" set in [memchan] puts -nonewline $in foobarflabbergast seek $in 0 transform -attach $in -command identity read $in close $in set tracevar } [82 {create/write-0 create/read-0 query/ratio-0 query/maxRead-0 read-17 query/maxRead-0 flush/read-0 flush/write-0 delete/write-0 delete/read-0} {create/write-0 create/read-0 query/ratio-0 query/maxRead-0 read-17 query/maxRead-0 flush/read-0 query/maxRead-0 flush/write-0 delete/write-0 delete/read-0}] test transform-3.0 {More than one transform should work too} { set tracevar "" set out [memchan] transform -attach $out -command [list pfx a] transform -attach $out -command [list pfx b] puts -nonewline $out foo unstack $out unstack $out seek $out 0 set data [read $out] close $out set data } {abfooaba} trf2.1.4/tests/bin.test0000644000175000017500000000265411216344305014373 0ustar sergeisergei# -*- tcl -*- # Commands covered: bin # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: bin.test,v 1.2 1997/07/22 20:32:49 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} test bin-2.0 {bin, conversion errors} { catch {bin -mode decode 101010020010101010200} msg set msg } {illegal character '2' found in input} foreach {index string fullencode encode} { 1 hello 0110100001100101011011000110110001101111 0110100001100101011011000110110001101111 2 hell` 0110100001100101011011000110110001100000 01101000011001010110110001101100011 } { test bin-3.$index {bin, encode string} { bin -mode encode $string } $fullencode ;#{} test bin-4.$index {bin, decode string} { bin -mode decode $encode } $string ;#{} # redundant tests following test bin-5.$index {bin, encode/decode identity} { bin -mode decode [bin -mode encode $string] } $string ;#{} test bin-6.$index {bin, decode/encode identity} { bin -mode encode [bin -mode decode $fullencode] } $fullencode ;#{} } trf2.1.4/tests/README0000644000175000017500000000676011216344305013604 0ustar sergeisergeiTRF Test Suite --------------- $Id: README,v 1.1.1.1 1997/02/05 20:51:12 aku Exp $ This directory contains a set of validation tests of the TRF commands. Each of the files whose name ends in ".test" is intended to (fully) exercise one or a few Trf commands. The commands tested by a given file are listed in the first line of the file. You can run the tests in the following way: (*) start up tclsh in this directory, then "source" the test file (for example, type "source trf.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. 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: tclsh < trf.test > trf.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). trf2.1.4/tests/test.binio0000644000175000017500000000003311216344305014710 0ustar sergeisergei trf2.1.4/tests/ascii85.test0000644000175000017500000000231111216344305015056 0ustar sergeisergei# -*- tcl -*- # Commands covered: ascii85 # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: ascii85.test,v 1.1 1997/07/22 20:32:49 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} foreach {index string fullencode encode} { 1 flabbergast Ao(mb@V'Rm@<6M Ao(mb@V'Rm@<6M } { test ascii85-3.$index {ascii85, encode string} { ascii85 -mode encode $string } $fullencode ;#{} test ascii85-4.$index {ascii85, decode string} { ascii85 -mode decode $encode } $string ;#{} # redundant tests following test ascii85-5.$index {ascii85, encode/decode identity} { ascii85 -mode decode [ascii85 -mode encode $string] } $string ;#{} test ascii85-6.$index {ascii85, decode/encode identity} { ascii85 -mode encode [ascii85 -mode decode $fullencode] } $fullencode ;#{} } trf2.1.4/tests/sha1.test0000644000175000017500000000207011216344305014447 0ustar sergeisergei# -*- tcl -*- # Commands covered: sha1 one-way hash function # # This file contains a collection of tests for one or more of the commands # the BLOB-X extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: sha1.test,v 1.2 1999/06/15 18:10:44 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} foreach {i in digest} { 0 abc A9993E364706816ABA3E25717850C26C9CD0D89D 1 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq 84983E441C3BD26EBAAE4AA1F95129E5E54670F1 } { if {[info tclversion] < 8.0} { test sha1-4.$i-7.6 {sha1, immediate} {hasSSL} { exec_md sha1 [text2hex $in] } [string toupper $digest] } else { test sha1-4.$i-8.x {sha1, immediate} {hasSSL} { hex -m e [sha1 $in] } [string toupper $digest] } } trf2.1.4/tests/crc_zlib.test0000644000175000017500000000162611216344305015410 0ustar sergeisergei# -*- tcl -*- # Commands covered: crc-zlib # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: crc_zlib.test,v 1.4 1999/06/15 18:10:42 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} foreach {i in digest} { 0 {hello world} 85114A0D } { if {[info tclversion] < 8.0} { test crc_zlib-4.$i-7.6 {crc_zlib, immediate} {hasZlib} { exec_md crc-zlib [text2hex $in] } $digest } else { test crc_zlib-4.$i-8.x {crc_zlib, immediate} {hasZlib} { hex -m e [crc-zlib $in] } $digest } } trf2.1.4/tests/common.md.test0000644000175000017500000000561711216344305015514 0ustar sergeisergei# -*- tcl -*- # Commands covered: none, common behaviour of message digests (dig_opt.c, digest.c) # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: common.md.test,v 1.2 2000/11/18 22:42:33 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} # message digests: adler, crc, crc_zlib, haval, md5, md2, sha, rmd160, rmd128 # tests done with builtin digest 'crc'. foreach {i opt ovalue} { 0 mode absorb 1 matchflag XX 2 write-destination XX 3 read-destination XX } { test common.md-1.$i "common md, argument errors" { catch {crc -$opt $ovalue -in stdin -out stdout} msg set msg } {immediate: no options allowed} } test common.md-2.0 "common md, argument errors" { catch {crc -attach stdout} msg set msg } {attach: -mode not defined} test common.md-2.1 "common md, argument errors" { catch {crc -attach stdout -mode XXX} msg set msg } {unknown mode 'XXX', should be 'absorb', 'write' or 'transparent'} test common.md-2.2 "common md, argument errors" { catch {crc -attach stdin -mode absorb} msg set msg } {attach: -matchflag not defined} test common.md-2.3 "common md, argument errors" { catch {crc -attach stdout -mode write -matchflag XX} msg set msg } {attach: -matchflag not allowed} test common.md-2.4 "common md, argument errors" { catch {crc -attach stdout -mode write} msg set msg } {attach, external: -write-destination missing} test common.md-2.5 "common md, argument errors" { catch {crc -attach stdin -mode write} msg set msg } {attach, external: -read-destination missing} test common.md-2.6 "common md, argument errors" { catch {crc -attach stdout -mode write -write-type XX} msg set msg } {unknown target-type 'XX'} test common.md-2.7 "common md, argument errors" { catch {crc -attach stdout -mode write -write-type channel -write-destination stdin} msg set msg } {write destination channel 'stdin' not opened for writing} test common.md-2.8 "common md, argument errors" { catch {crc -attach stdin -mode write -read-type channel -read-destination stdin} msg set msg } {read destination channel 'stdin' not opened for writing} test common.md-2.9 "common md, argument errors" { catch {crc -attach stdout -mode write -write-type channel -write-destination XXX} msg set msg } {can not find channel named "XXX"} test common.md-2.10 "common md, argument errors" { catch {crc -attach stdin -mode write -read-type channel -read-destination XXX} msg set msg } {can not find channel named "XXX"} trf2.1.4/tests/common_seek.test0000644000175000017500000001711311216344305016116 0ustar sergeisergei# -*- tcl -*- # Commands covered: all, common behaviour of seeking # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1999 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: common_seek.test,v 1.3 1999/10/27 21:18:24 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} #makeFile {hex test data} seektests exec echo {hex test data} > seektests # A server socket for the tests, actually doing nothing. proc null {args} {} set echo [socket -server null 0] set eport [lindex [fconfigure $echo -sockname] 2] proc 82 {a b} { if {[string compare [info tclversion] 8.2] < 0} { return $b } else { return $a } } # ---------------------------------------------------------------------- # check computation of chosen and used policy, which is based upon # transforms below it, and of the base channel. test seek-1.0 {chosen policy, seekable transform, seekable base} { set f [open seektests r] hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } [82 {ratioNatural {1 2} ratioChosen {1 2} overideAllowed 1 identityForced 0} {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0}] test seek-1.1 {chosen policy, seekable transform, unseekable base} { set f [socket localhost $eport] hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.2 {chosen policy, unseekable transform, seekable base} { set f [open seektests r] ascii85 -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } [82 {ratioNatural {0 0} ratioChosen {0 0} overideAllowed 1 identityForced 0} {ratioNatural {0 0} ratioChosen {0 0} overideAllowed 0 identityForced 0}] test seek-1.4 {chosen policy, unseekable transform, unseekable base} { set f [socket localhost $eport] ascii85 -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {0 0} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.5 {chosen policy, seekable transforms, seekable base} { set f [open seektests r] base64 -attach $f -mode encode hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } [82 {ratioNatural {1 2} ratioChosen {1 2} overideAllowed 1 identityForced 0} {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0}] test seek-1.6 {chosen policy, transform mixture, seekable base} { set f [open seektests r] ascii85 -attach $f -mode encode hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.7 {chosen policy, seekable transforms, unseekable base} { set f [socket localhost $eport] base64 -attach $f -mode encode hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0} test seek-1.8 {chosen policy, transform mixture, unseekable base} { set f [socket localhost $eport] ascii85 -attach $f -mode encode hex -attach $f -mode encode set res [fconfigure $f -seekcfg] close $f set res } {ratioNatural {1 2} ratioChosen {0 0} overideAllowed 0 identityForced 0} if {[82 1 0]} { test seek-1.9 {chosen policy, all seekable, force identity} { set f [open seektests r] hex -attach $f -mode encode -seekpolicy identity set res [fconfigure $f -seekstate] close $f set res } {seekable 1 ratio {1 1} up 0 upBufStart 0 upBufEnd 0 down 0 downBase 0 downAhead 0 changed 0} test seek-1.10 {chosen policy, all seekable, force unseekable} { set f [open seektests r] hex -attach $f -mode encode -seekpolicy unseekable set res [fconfigure $f -seekstate] close $f set res } {seekable 0 ratio {0 0} up 0 upBufStart 0 upBufEnd 0 down 0 downBase 0 downAhead 0 changed 0} } test seek-1.11 {chosen policy, all seekable, force error} { set f [open seektests r] catch {hex -attach $f -mode encode -seekpolicy unseek} res close $f set res } [82 {Invalid value "unseek", must be one of 'unseekable', 'identity' or ''.} {It is not allowed to overide the seek policy used by this channel.}] test seek-1.12 {chosen policy, unseekables, force error} { set f [open seektests r] ascii85 -attach $f -mode encode catch {hex -attach $f -mode encode -seekpolicy identity} res close $f set res } {It is not allowed to overide the seek policy used by this channel.} # ---------------------------------------------------------------------- # check seek restrictions set upon transforming and unseekable transforms. test seek-2.0 {seeking behind start of stream} { set f [open seektests r] hex -attach $f -mode decode catch {seek $f -1} res close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} test seek-2.1 {seeking relative to the end} { set f [open seektests r] hex -attach $f -mode decode catch {seek $f 0 end} res close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} test seek-2.2 {seeking modulo numBytesTransform} { set f [open seektests r] hex -attach $f -mode decode catch {seek $f 1 cur} res close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} test seek-2.3 {seeking modulo numBytesTransform} { set f [open seektests r] hex -attach $f -mode decode read $f 1 set fail [catch {seek $f 2 cur} res] close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} test seek-2.4 {seeking the unseekable} { set f [socket localhost $eport] hex -attach $f -mode decode catch {seek $f 1} res close $f regsub $f $res XXXX res set res } {error during seek on "XXXX": invalid argument} # ---------------------------------------------------------------------- # check seek behaviour (discarding buffers, et. al). test seek-3.0 {picking up the base} { set f [open seektests r] read $f 3 hex -attach $f -mode decode set res [fconfigure $f -seekstate] close $f set res } [82 {seekable 1 ratio {2 1} up 0 upBufStart 0 upBufEnd 0 down 3 downBase 3 downAhead 0 changed 0} {seekable 0 ratio {0 0} up 0 upBufStart 0 upBufEnd 0 down 0 downBase 0 downAhead 0 changed 0}] test seek-3.1 {picking up the base, read ahead} { set f [open seektests r] read $f 3 hex -attach $f -mode decode read $f 2 set res [list [tell $f] [fconfigure $f -seekstate]] close $f set res } [82 {2 {seekable 1 ratio {2 1} up 22 upBufStart 22 upBufEnd 22 down 14 downBase 3 downAhead 0 changed 0}} {2 {seekable 0 ratio {0 0} up 22 upBufStart 22 upBufEnd 22 down 11 downBase 0 downAhead 0 changed 0}}] if {[82 1 0]} { test seek-3.2 {resync, discard buffers} { set f [open seektests r] read $f 3 hex -attach $f -mode decode read $f 2 seek $f 2 cur set res [list [tell $f] [fconfigure $f -seekstate]] close $f set res } {4 {seekable 1 ratio {2 1} up 4 upBufStart 4 upBufEnd 4 down 5 downBase 3 downAhead 0 changed 0}} } # ---------------------------------------------------------------------- close $echo #::tcltest::cleanupTests trf2.1.4/tests/otp_words.test0000644000175000017500000000517111216344305015640 0ustar sergeisergei# -*- tcl -*- # Commands covered: otp_words # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: otp_words.test,v 1.1 1999/05/30 11:45:48 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} test otp_words-1.0 {otp_words, conversion errors} { catch {otp_words -mode encode XX} msg set msg } {input string must be a multiple of 64-bits} test otp_words-1.1 {otp_words, conversion errors} { catch {otp_words -mode encode XXXXYYYYZ} msg set msg } {input string must be a multiple of 64-bits} test otp_words-1.2 {otp_words, conversion errors} { catch {otp_words -mode decode 101010090010101010200} msg set msg } {word too long} test otp_words-1.3 {otp_words, conversion errors} { catch {otp_words -mode decode XXXX} msg set msg } {too few words} test otp_words-1.4 {otp_words, conversion errors} { catch {otp_words -mode decode {XXXX XXXX}} msg set msg } {empty word} test otp_words-1.5 {otp_words, conversion errors} { catch {otp_words -mode decode {XXX YYY ZZZ AAA BBB CCC}} msg set msg } {unknown word "XXX"} foreach {index string encode} { 1 {9E87 6134 D904 99DD} {INCH SEA ANNE LONG AHEM TOUR} 2 {7965 E054 36F5 029F} {EASE OIL FUM CURE AWRY AVIS} 3 {50FE 1962 C496 5880} {BAIL TUFT BITS GANG CHEF THY} 4 {8706 6DD9 644B F206} {FULL PEW DOWN ONCE MORT ARC} 5 {7CD3 4C10 40AD D14B} {FACT HOOF AT FIST SITE KENT} 6 {5AA3 7A81 F212 146C} {BODE HOP JAKE STOW JUT RAP} 7 {F205 7539 43DE 4CF9} {ULAN NEW ARMY FUSE SUIT EYED} 8 {DDCD AC95 6F23 4937} {SKIM CULT LOB SLAM POE HOWL} 9 {B203 E28F A525 BE47} {LONG IVY JULY AJAR BOND LEE} } { regsub -all { } $string {} ostring set ostring [hex -mode decode $ostring] test otp_words-2.$index {otp_words, encode string} { otp_words -mode encode $ostring } $encode ;#{} test otp_words-3.$index {otp_words, decode string} { otp_words -mode decode $encode } $ostring ;#{} # redundant tests following test otp_words-4.$index {otp_words, encode/decode identity} { otp_words -mode decode [otp_words -mode encode $ostring] } $ostring ;#{} test otp_words-5.$index {otp_words, decode/encode identity} { otp_words -mode encode [otp_words -mode decode $encode] } $encode ;#{} } trf2.1.4/tests/rs_ecc.test0000644000175000017500000002422711216344305015061 0ustar sergeisergei# -*- tcl -*- # Commands covered: rs_ecc (Reed Solomon error correction coder) # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: rs_ecc.test,v 1.2 1997/07/22 20:32:52 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} defblock in { 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff } defblock in_b { 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 a9 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 6f 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 12 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca c3 cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff } defblock out { ab e8 b0 ef 7c f7 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 cf ce cd cc cb ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 05 56 7c 70 ca d1 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff fe fd fc fb fa f9 f8 } # ab e8 b0 ef 7c f7 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef # ab e8 b0 ef 7d f7 ff f7 f6 f5 f4 13 f2 f1 f0 ef # * * * defblock out_err_a { ab e8 b0 ef 7d f7 ff f7 f6 f5 f4 13 f2 f1 f0 ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 cf ce cd cc cb ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 05 56 7c 70 ca d1 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff fe fd fc fb fa f9 f8 } # ab e8 b0 ef 7c f7 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef # ab e8 b0 ef 7d f7 ff f7 f6 f5 00 13 f2 f1 f0 ef # * * ** * defblock out_err_b { ab e8 b0 ef 7c f7 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 e0 df de dd dc db da d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 cf ce cd cc c3 ca c9 c8 c7 c6 c5 c4 c3 c2 c1 c0 bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 12 a1 a0 9f 9e 9d 9c 9b 9a 99 98 97 96 95 94 93 92 91 90 8f 8e 8d 8c 8b 8a 89 88 87 86 85 84 83 82 81 80 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 6f 6e 6d 6c 6b 6a 6f 68 67 66 65 64 63 62 61 60 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 2f 2e 2d 2c 2b 2a a9 28 27 26 25 24 23 22 21 20 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 05 56 7c 70 ca d1 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff fe fd fc fb fa f9 f8 } # ---- test section ---- # differentiate tcl versions if {[info tclversion] < 8.0} { # 7.6, use channels to transfer information, we have embedded \0s. test rs-ecc-1.0-7.6 {encode, place ecc information} { set in_c [hex2chan $in] set out_c [memchan] fconfigure $out_c -translation binary hex -attach $out_c -mode encode rs_ecc -mode encode -in $in_c -out $out_c unstack $out_c seek $out_c 0 set txt [read $out_c] close $in_c close $out_c list [string length $txt] $txt } [list 1020 [string toupper $out]] ; # {} test rs-ecc-1.1-7.6 {decode without error recovery} { set in_c [hex2chan $out] set out_c [memchan] fconfigure $out_c -translation binary hex -attach $out_c -mode encode rs_ecc -mode decode -in $in_c -out $out_c unstack $out_c seek $out_c 0 set txt [read $out_c] close $in_c close $out_c list [string length $txt] $txt } [list 512 [string toupper $in]] ; # {} test rs-ecc-1.2-7.6 {decode with error recovery} { set in_c [hex2chan $out_err_a] set out_c [memchan] fconfigure $out_c -translation binary hex -attach $out_c -mode encode rs_ecc -mode decode -in $in_c -out $out_c unstack $out_c seek $out_c 0 set txt [read $out_c] close $in_c close $out_c list [string length $txt] $txt } [list 512 [string toupper $in]] ; # {} test rs-ecc-1.3-7.6 {decode, with partial recovery} { set in_c [hex2chan $out_err_b] set out_c [memchan] fconfigure $out_c -translation binary hex -attach $out_c -mode encode rs_ecc -mode decode -in $in_c -out $out_c unstack $out_c seek $out_c 0 set txt [read $out_c] close $in_c close $out_c list [string length $txt] $txt } [list 512 [string toupper $in_b]] ; # {} } else { # 8.x is able to work with embedded \0s. test rs-ecc-1.0-8.x {encode, place ecc information} { set txt [hex -mode encode [rs_ecc -mode encode [hex -mode decode $in]]] list [string length $txt] $txt } [list 1020 [string toupper $out]] ; # {} test rs-ecc-1.1-8.x {decode without error recovery} { set txt [hex -mode encode [rs_ecc -mode decode [hex -mode decode $out]]] list [string length $txt] $txt } [list 512 [string toupper $in]] ; # {} test rs-ecc-1.2-8.x {decode with error recovery} { set txt [hex -mode encode [rs_ecc -mode decode [hex -mode decode $out_err_a]]] list [string length $txt] $txt } [list 512 [string toupper $in]] ; # {} test rs-ecc-1.3-8.x {decode, with partial recovery} { set txt [hex -mode encode [rs_ecc -mode decode [hex -mode decode $out_err_b]]] list [string length $txt] $txt } [list 512 [string toupper $in_b]] ; # {} } # xx_cmp $in $in_b 32 trf2.1.4/tests/md5_crash.test0000644000175000017500000000230411216344305015460 0ustar sergeisergei# -*- tcl -*- # Commands covered: md5 - Try to crash it. # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: md5_crash.test,v 1.1 2003/03/27 07:51:05 andreas_kupries Exp $ # test suite from RFC 1321 (1..7) if {[info tclversion] < 8.0} { puts "Skipping crash test in pre-8.0 interpreter" return } test md5-5.0 {md5, crash} { # SF tcltrf Bug #667168, trf set f [open [makeFile {} debug.out] w] fconfigure $f -translation binary -encoding binary -buffering none md5 -attach $f -mode transparent -write-type var -write-dest ::md5 puts -nonewline $f [string repeat X 402] puts -nonewline $f [string repeat X 224] unstack $f close $f removeFile debug.out set res [hex -mode encode -- $::md5] set res } {D6A0FFF1DFF65952747324F690FAF519} catch {::tcltest::cleanupTests} trf2.1.4/tests/hex.test0000644000175000017500000000315211216344305014401 0ustar sergeisergei# -*- tcl -*- # Commands covered: hex # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: hex.test,v 1.2 1997/07/22 20:32:50 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} set text {hello @ hello@} set text_c {hello @ helloP} set text_hex {68656C6C6F2020402068656C6C6F40} set text_hex_b {68656c6c6f2020402068656c6c6f40} set text_hex_c {68656c6c6f2020402068656c6c6f5} test hex-2.0 {hex, conversion errors} { catch {hex -mode decode 68656c6c6f2020402068656c6c6k40} msg set msg } {illegal character 'k' found in input} foreach {index string fullencode encode} { 1 {hello @ hello@} 68656C6C6F2020402068656C6C6F40 68656C6C6F2020402068656C6C6F40 2 {hello @ helloP} 68656C6C6F2020402068656C6C6F50 68656C6C6F2020402068656C6C6F5 } { test hex-3.$index {hex, encode string} { hex -mode encode $string } $fullencode ;#{} test hex-4.$index {hex, decode string} { hex -mode decode $encode } $string ;#{} # redundant tests following test hex-5.$index {hex, encode/decode identity} { hex -mode decode [hex -mode encode $string] } $string ;#{} test hex-6.$index {hex, decode/encode identity} { hex -mode encode [hex -mode decode $fullencode] } $fullencode ;#{} } trf2.1.4/tests/uu.test0000644000175000017500000000256111216344306014252 0ustar sergeisergei# -*- tcl -*- # Commands covered: uuencode # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: uu.test,v 1.1 1997/07/22 20:32:52 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} test uuencode-2.0 {uuencode, conversion errors} { catch {uuencode -mode decode aGV!bG8=} msg set msg } {illegal character found in input} foreach {index string fullencode encode} { 1 raoul 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} { set ok 0 foreach test $TESTS { if {[string match $test $name]} { set ok 1 break } } if {!$ok} { 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} { 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} { if {$VERBOSE} { 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 return $name } 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 stdout "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 } catch {file delete -force tmp} } if {($tcl_platform(platform) == "windows") && ($testConfig(stdio) == 0)} { puts stdout "(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 stdout "(will skip tests that use sockets)" } # -- attention procs -- # utilities for easy specification and use of constant values (hex) proc defblock {name hexdata} { upvar $name x regsub -all { *} $hexdata {} hexdata regsub -all "\n" $hexdata {} hexdata # single long hex string now set x $hexdata } proc defblock_decimal {name list_of_decimals} { upvar $name $name set hex "" foreach i $list_of_decimals {append hex [format %02x $i]} defblock $name $hex } proc hex2chan {hexdata} { set x [memchan] fconfigure $x -translation binary hex -attach $x -mode decode puts -nonewline $x $hexdata unstack $x seek $x 0 return $x } proc text2hex {data} { set x [memchan] fconfigure $x -translation binary hex -attach $x -mode encode puts -nonewline $x $data unstack $x seek $x 0 set data [read $x] close $x return $data } proc text2chan {data} { set x [memchan] fconfigure $x -translation binary puts -nonewline $x $data seek $x 0 return $x } if {[info tclversion] < 8.0} { proc exec_md {md hexinput} { set in [memchan] hex -attach $in -m d puts -nonewline $in $hexinput unstack $in seek $in 0 set out [memchan] hex -attach $out -m e $md -in $in -out $out close $in unstack $out seek $out 0 set res [read -nonewline $out] close $out set res } } else { proc exec_md {md hexinput} { error "don't use exec_md with tcl 8.x and higher" } } proc xx_cmp {a b blocksize} { set bsi [expr {$blocksize - 1}] while {([string length $a] > 0) || ([string length $b] > 0)} { set af [string range $a 0 $bsi] set bf [string range $b 0 $bsi] set a [string range $a $blocksize end] set b [string range $b $blocksize end] if {0 != [string compare $af $bf]} { puts -nonewline stdout "* " } else { puts -nonewline stdout " " } puts stdout "$af $bf" } } proc string_rep {n text} { # @comment Replicates times the string . # @argument text: string to be replicated # @argument n: number of replications # @result replicated times # no replication required ? if {$n <= 0} {return ""} # use iteration to build up the result set result "" for {} {$n > 0} {incr n -1} {append result $text} return $result } proc defConstraints {args} { global testConfig foreach k $args { set testConfig($k) 1 } } proc read_file {file} { set fd [open $file] fconfigure $fd -translation binary set data [read $fd] close $fd return $data } proc write_file {file data} { set fd [open $file w] fconfigure $fd -translation binary puts -nonewline $fd $data close $fd } proc read_zip {file} { set fd [open $file] fconfigure $fd -translation binary zip -attach $fd -mode compress fconfigure $fd -translation binary set data [read $fd] close $fd return $data } proc write_zip {file data} { set fd [open $file w] fconfigure $fd -translation binary zip -attach $fd -mode compress fconfigure $fd -translation binary puts -nonewline $fd $data close $fd } trf2.1.4/tests/otpmd5.test0000644000175000017500000000252411216344305015027 0ustar sergeisergei# -*- tcl -*- # Commands covered: otp_md5 # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: otpmd5.test,v 1.1 1999/05/30 11:45:49 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} # test suite from RFC 1321 (1..7) foreach {i in digest} { 0 {hello world} CD7D19006F442313 1 {} 3D9D854163F8F07A 2 a 3D02EC5BA98690C9 3 abc 46976FE5143330C2 4 {message digest} AB31464CD646F25D 5 abcdefghijklmnopqrstuvwxyz BE079ABBABF5053B 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 7415B7B44D36446A 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 FBA42E8C0AE47F2F } { if {[info tclversion] < 8.0} { test otp_md5-4.$i-7.6 {otp_md5, immediate} { exec_md otp_md5 [text2hex $in] } [string toupper $digest] } else { test otp_md5-4.$i-8.x {otp_md5, immediate} { hex -m e [otp_md5 $in] } [string toupper $digest] } } trf2.1.4/tests/bz2.test0000644000175000017500000000347711216344305014324 0ustar sergeisergei# -*- tcl -*- # Commands covered: bz2 # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: bz2.test,v 1.3 1999/09/20 21:28:12 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} set text "hello, hello!" set text_compressed_as_hex "425A68393141592653592C546C72000003110060040244A0002129A3108603690E70A1E2EE48A70A12058A8D8E40" # differentiate tcl versions if {[info tclversion] < 8.0} { # 7.6, use channels to transfer information, we have embedded \0s. test bz2-1.0-7.6 {bz2 compression} {hasBz} { set in [text2chan $text] set out [memchan] fconfigure $out -translation binary hex -attach $out -mode encode bz2 -mode compress -in $in -out $out unstack $out seek $out 0 set data [read $out] close $out close $in set data } $text_compressed_as_hex ; #{} test bz2-1.1-7.6 {bz2 decompression} {hasBz} { set in [hex2chan $text_compressed_as_hex] set out [memchan] seek $in 0 bz2 -mode decompress -in $in -out $out seek $out 0 set data [read $out] close $out close $in set data } $text ; #{} } else { # 8.x is able to work with embedded \0s. test bz2-1.0-8.x {bz2 compression} {hasBz} { hex -mode encode [bz2 -mode compress $text] } $text_compressed_as_hex ; #{} test bz2-1.1-8.x {bz2 decompression} {hasBz} { bz2 -mode decompress [hex -mode decode $text_compressed_as_hex] } $text ; #{} } trf2.1.4/tests/rmd128.test0000644000175000017500000000415111216344305014632 0ustar sergeisergei# -*- tcl -*- # Commands covered: ripemd128 # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: rmd128.test,v 1.5 2005/10/06 18:05:46 andreas_kupries Exp $ if {[string compare test [info procs test]] == 1} then {source defs} set vectors { 0 {} cdf26213a150dc3ecb610f18f6b38b46 1 a 86be7afa339d0fc7cfc785e72f578d33 2 abc c14a12199c66e4ba84636b0f69144c77 3 {message digest} 9e327b3d6e523062afc1132d7df9d1b8 4 abcdefghijklmnopqrstuvwxyz fd2aa607f71dc8f510714922b371834e 5 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq a1aa0689d0fafa2ddc22e88b49133a06 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 d1e959eb179c911faea4624c60c5c702 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 3f45ef194732c2dbb2c4a2c769795fa3 } lappend vectors \ 20 [binary format H* 3627140572635041beaf9c8dfaebd8c9363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636] {4eb9e2f034b961f464647021b99291ef} \ 21 [binary format H* 3627140572635041beaf9c8dfaebd8c93636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636] {aaabc4b1b3479d49f0ad1c69f19c1405} \ 22 [binary format H* 3627140572635041beaf9c8dfaebd8c936363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636] {c36ba14a9db833269732dda3edb63e27} \ foreach {i in digest} $vectors { if {[info tclversion] < 8.0} { test ripemd128-4.$i-7.6 {ripemd128, immediate} { exec_md ripemd128 [text2hex $in] } [string toupper $digest] } else { test ripemd128-4.$i-8.x {ripemd128, immediate} { hex -mode encode [ripemd128 -- $in] } [string toupper $digest] } } trf2.1.4/tests/oct.test0000644000175000017500000000250711216344305014405 0ustar sergeisergei# -*- tcl -*- # Commands covered: oct # # This file contains a collection of tests for one or more of the trf # commands of the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1995 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: oct.test,v 1.2 1997/07/22 20:32:51 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} test oct-2.0 {oct, conversion errors} { catch {oct -mode decode 101010090010101010200} msg set msg } {illegal character '9' found in input} foreach {index string fullencode encode} { 1 hello 150145154154157 150145154154157 2 hellh 150145154154150 15014515415415 } { test oct-3.$index {oct, encode string} { oct -mode encode $string } $fullencode ;#{} test oct-4.$index {oct, decode string} { oct -mode decode $encode } $string ;#{} # redundant tests following test oct-5.$index {oct, encode/decode identity} { oct -mode decode [oct -mode encode $string] } $string ;#{} test oct-6.$index {oct, decode/encode identity} { oct -mode encode [oct -mode decode $fullencode] } $fullencode ;#{} } trf2.1.4/tests/adler.test0000644000175000017500000000157611216344305014714 0ustar sergeisergei# -*- tcl -*- # Commands covered: adler # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: adler.test,v 1.4 1999/06/15 18:10:40 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} foreach {i in digest} { 0 {hello world} 1A0B045D } { if {[info tclversion] < 8.0} { test adler-4.$i-7.6 {adler, immediate} {hasZlib} { exec_md adler [text2hex $in] } $digest } else { test adler-4.$i-8.x {adler, immediate} {hasZlib} { hex -m e [adler $in] } $digest } } trf2.1.4/tests/all0000644000175000017500000000044411216344305013410 0ustar sergeisergei# -*- tcl -*- # 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. # # CVS: $Id: all,v 1.1.1.1 1997/02/05 20:51:13 aku Exp $ foreach i [lsort [glob *.test]] { puts stdout $i source $i } trf2.1.4/tests/md2.test0000644000175000017500000000260311216344305014277 0ustar sergeisergei# -*- tcl -*- # Commands covered: md2 # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: md2.test,v 1.3 1999/06/15 18:10:43 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} # test suite from RFC 1319 foreach {i in digest} { 1 {} 8350e5a3e24c153df2275c9f80692773 2 a 32ec01ec4a6dac72c0ab96fb34c0b5d1 3 abc da853b0d3f88d99b30283a69e6ded6bb 4 {message digest} ab4f496bfb2a530b219ff33031fe06b0 5 abcdefghijklmnopqrstuvwxyz 4e8ddff3650292ab5a4108c3aa47940b 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 da33def2a42df13975352846c30338cd 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 d5976f79d83d3a0dc9806c3c66f3efd8 } { if {[info tclversion] < 8.0} { test md2-4.$i-7.6 {md2, immediate} {hasSSL} { exec_md md2 [text2hex $in] } [string toupper $digest] } else { test md2-4.$i-8.x {md2, immediate} {hasSSL} { hex -m e [md2 $in] } [string toupper $digest] } } trf2.1.4/tests/haval.test0000644000175000017500000000264011216344305014711 0ustar sergeisergei# -*- tcl -*- # Commands covered: haval one-way # # This file contains a collection of tests for one or more of the commands # the TRF extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: haval.test,v 1.4 1997/07/22 22:00:43 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} foreach {i in digest} { 1 {} 4F6938531F0BC8991F62DA7BBD6F7DE3FAD44562B8C6F4EBF146D5B4E46F7C17 2 a 47C838FBB4081D9525A0FF9B1E2C05A98F625714E72DB289010374E27DB021D8 3 HAVAL 91850C6487C9829E791FC5B58E98E372F3063256BB7D313A93F1F83B426AEDCC 4 0123456789 63238D99C02BE18C3C5DB7CCE8432F51329012C228CCC17EF048A5D0FD22D4AE 5 abcdefghijklmnopqrstuvwxyz 72FAD4BDE1DA8C8332FB60561A780E7F504F21547B98686824FC33FC796AFA76 6 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 899397D96489281E9E76D5E65ABAB751F312E06C06C07C9C1D42ABD31BB6A404 } { if {[info tclversion] < 8.0} { test haval-4.$i-7.6 {haval, immediate} { exec_md haval [text2hex $in] } $digest } else { test haval-4.$i-8.x {haval, immediate} { hex -m e [haval $in] } $digest } } trf2.1.4/tests/otpsha1.test0000644000175000017500000000204711216344305015176 0ustar sergeisergei# -*- tcl -*- # Commands covered: otp_sha1 one-way hash function # # This file contains a collection of tests for one or more of the commands # the BLOB-X extension. Sourcing this file into Tcl runs the # tests and generates output for errors. No output means no errors were # found. # # Copyright (c) 1996 Andreas Kupries (andreas_kupries@users.sourceforge.net) # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # $Id: otpsha1.test,v 1.2 1999/06/15 18:10:44 aku Exp $ if {[string compare test [info procs test]] == 1} then {source defs} foreach {i in digest} { 0 abc DAC3778F0643563F 1 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq 140470DB8BFB6AE5 } { if {[info tclversion] < 8.0} { test otp_sha1-4.$i-7.6 {otp_sha1, immediate} {hasSSL} { exec_md otp_sha1 [text2hex $in] } [string toupper $digest] } else { test otp_sha1-4.$i-8.x {otp_sha1, immediate} {hasSSL} { hex -m e [otp_sha1 $in] } [string toupper $digest] } } trf2.1.4/testshell0000644000175000017500000000360111216344361013505 0ustar sergeisergei#!/usr/local/bin/tclsh # -*- tcl -*- # Generic test application for all test suites # # This file contains a top-level script to run all of the tests # in an extension. Execute it by invoking "tclsh testshell -testdir ... -load". # # Derived from tcl 8.2/all.tcl, Copyright (c) 1998-1999 by Scriptics Corporation. # Copyright (c) 1999 by andreas Kupries # # All rights reserved. # # CVS $Id: testshell,v 1.1 2002/08/27 03:51:05 tcl Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { # Initialize autoloader, then load the commands and initialize # the package (constraints and command line argument processing). package require tcltest namespace import ::tcltest::* } # Directory containing the tests specified via '-testDir'. # Scripts to load the commands to test in '-load' / '-loadfile'. set ::tcltest::testSingleFile false puts stdout "Tests running in interp: [info nameofexecutable]" puts stdout "Tests running in working dir: $::tcltest::testsDirectory" 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" } if {[llength $::tcltest::skipFiles] > 0} { puts stdout "Skipping test files that match: $::tcltest::skipFiles" } if {[llength $::tcltest::matchFiles] > 0} { puts stdout "Only sourcing test files that match: $::tcltest::matchFiles" } ::tcltest::loadTestedCommands set timeCmd {clock format [clock seconds]} puts stdout "Tests began at [eval $timeCmd]" # Source each of the specified tests foreach file [lsort [::tcltest::getMatchingFiles]] { set tail [file tail $file] puts stdout $tail if {[catch {source $file} msg]} { puts stdout $msg } } # cleanup puts stdout "\nTests ended at [eval $timeCmd]" ::tcltest::cleanupTests 1 return trf2.1.4/LSM0000644000175000017500000000320611216344361012132 0ustar sergeisergeiBegin3 Title: trf Version: 2.1.4 Entered-date: MAY-06-2009 Description: A loadable extension to Tcl providing commands for data conversion, message digests, zlib based compression, error-correction, channel-based manipulation of binary data. Trf extends the language at the C-level with so-called ``transformer''-procedures. With the help of some patches (*) to the core the package is able to intercept all read/write operations on designated channels, thus giving it the ability to transform the buffer contents as desired. This allows things like transparent encryption, compression, charset recoding, etc. Build upon this framework (and as proof of concept) a collection of tcl-level commands was implemented. Additionally some binary data support is put in as well. A separate package containing encryption transformation is available at the same site carrying this package. (*) The patches are only necessary for Tcl 8.0.x and 8.1.x. Since Tcl 8.2 the Trf patch is an official part of the core. Keywords: tcl, conversion, message digests, data compression, error-correction, binary io, crc, md2, md5, sha, sha-1, haval, adler, ripemd-160, dual, hexadecimal, octal, uuencode, base64, ascii85, reed-solomon, zlib, otp_md5, otp_sha1, otp_words Author: Andreas Kupries (andreas_kupries@users.sourceforge.net) Maintained-by: Andreas Kupries (andreas_kupries@users.sourceforge.net) Platforms: tcl 8.0 or higher, plus-patches as of Dec 5, 1996 or later (optional), memchan 1.0 or higher (required by testsuite), zlib-1.0.4 or higher (optional, 1.2.4 is current), Copying-policy: BSD-Style, see 'tcl'-license End trf2.1.4/trf.m40000644000175000017500000003521511216343142012612 0ustar sergeisergei#------------------------------------------------------------------------ # TEA_PATH_CONFIG -- # # Locate the ${1}Config.sh file and perform a sanity check on # the ${1} compile flags. These are used by packages like # [incr Tk] that load *Config.sh files from more than Tcl and Tk. # # Normally aborts if the package could not be found. This can be # supressed by specifying a second argument with a value of "optional". # # Arguments: # $1 Name of the package to look for. # $2 Optional: Flag. If present and $2 == "optional" # then the script will _not_ abort when failing to # find the package. # # Results: # # Adds the following arguments to configure: # --with-$1=... # # Defines the following vars: # $1_BIN_DIR Full path to the directory containing # the $1Config.sh file # Contains a shell comment if nothing was found # HAVE_$1_PACKAGE Boolean 1 = Package found. #------------------------------------------------------------------------ AC_DEFUN(TEA_PATH_CONFIG_X, [ # # Ok, lets find the $1 configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-$1 # if test x"${no_$1}" = x ; then # we reset no_$1 in case something fails here no_$1=true AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval}) AC_MSG_CHECKING([for $1 configuration]) AC_CACHE_VAL(ac_cv_c_$1config,[ # First check to see if --with-$1 was specified. if test x"${with_$1config}" != x ; then if test -f "${with_$1config}/$1Config.sh" ; then ac_cv_c_$1config=`(cd ${with_$1config}; pwd)` else AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh]) fi fi # then check for a private $1 installation if test x"${ac_cv_c_$1config}" = x ; then for i in \ ../$1 \ `ls -dr ../$1[[8-9]].[[0-9]]* 2>/dev/null` \ ../../$1 \ `ls -dr ../../$1[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../$1 \ `ls -dr ../../../$1[[8-9]].[[0-9]]* 2>/dev/null` \ ${srcdir}/../$1 \ `ls -dr ${srcdir}/../$1[[8-9]].[[0-9]]* 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi if test -f "$i/unix/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_$1config}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_$1config}" = x ; then $1_BIN_DIR="# no $1 configs found" AC_MSG_WARN("Cannot find $1 configuration definitions") if test "X$2" != "Xoptional" ; then exit 0 fi HAVE_$1_PACKAGE=0 else no_$1= $1_BIN_DIR=${ac_cv_c_$1config} AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh]) HAVE_$1_PACKAGE=1 AC_DEFINE([HAVE_$1_PACKAGE]) fi fi ]) AC_DEFUN(TRF_FIND_ZLIB_SSL, [ AC_ARG_WITH(zlib, [ --with-zlib=DIR zlib.h resides in DIR/include, libz resides in DIR/lib], [ZLIB_LIB_DIR=$withval/lib; ZLIB_INCLUDE_DIR=$withval/include], []) dnl AC_ARG_WITH(zlib-include-dir, [ --with-zlib-include-dir=DIR zlib.h resides in DIR], [ZLIB_INCLUDE_DIR=$withval], []) dnl AC_ARG_WITH(zlib-lib-dir, [ --with-zlib-lib-dir=DIR libz resides in DIR], [ZLIB_LIB_DIR=$withval], []) AC_ARG_WITH(ssl, [ --with-ssl=DIR md2.h/sha1.h reside in DIR/include, libcrypto resides in DIR/lib], [SSL_LIB_DIR=$withval/lib; SSL_INCLUDE_DIR=$withval/include], []) dnl AC_ARG_WITH(ssl-include-dir, [ --with-ssl-include-dir=DIR md2.h/sha1.h reside in DIR], [SSL_INCLUDE_DIR=$withval], []) dnl AC_ARG_WITH(ssl-lib-dir, [ --with-ssl-lib-dir=DIR libcrypto resides in DIR], [SSL_LIB_DIR=$withval], []) AC_ARG_WITH(bz2, [ --with-bz2=DIR bzlib.h resides in DIR/include, libbz2 resides in DIR/lib], [BZ2_LIB_DIR=$withval/lib; BZ2_INCLUDE_DIR=$withval/include], []) dnl AC_ARG_WITH(bz2-include-dir, [ --with-bz2-include-dir=DIR bzlib.h resides in DIR], [BZ2_INCLUDE_DIR=$withval], []) dnl AC_ARG_WITH(bz2-lib-dir, [ --with-bz2-lib-dir=DIR libbz2 resides in DIR], [BZ2_LIB_DIR=$withval], []) AC_ARG_ENABLE(static-zlib, [ --enable-static-zlib link 'zlib' statically], [STATIC_ZLIB=$enableval], [STATIC_ZLIB=no]) AC_ARG_ENABLE(static-bzlib, [ --enable-static-bzlib link 'bzlib' statically], [STATIC_BZLIB=$enableval], [STATIC_BZLIB=no]) AC_ARG_ENABLE(static-md5, [ --enable-static-md5 link 'md5' statically], [STATIC_MD5=$enableval], [STATIC_MD5=no]) AC_ARG_ENABLE(trf_debug, [ --enable-trf-debug enable debugging output], [trf_debug=$enableval], [trf_debug=no]) AC_ARG_ENABLE(stream_debug, [ --enable-stream-debug enable debugging of IO streams], [stream_debug=$enableval], [stream_debug=no]) dnl ---------------------------------------------------------------- dnl dnl Crossover between --with-zlib-include-dir and --with-zlib-lib-dir dnl Setting one, but not the other will cause automatic definition dnl of the missing part. if test "X" = "X$ZLIB_LIB_DIR" -a "X" != "X$ZLIB_INCLUDE_DIR" then ZLIB_LIB_DIR="$ZLIB_INCLUDE_DIR/../lib" fi if test "X" = "X$ZLIB_INCLUDE_DIR" -a "X" != "X$ZLIB_LIB_DIR" then ZLIB_INCLUDE_DIR="$ZLIB_LIB_DIR/../include" fi dnl ---------------------------------------------------------------- dnl dnl Crossover between --with-bz2-include-dir and --with-bz2-lib-dir dnl Setting one, but not the other will cause automatic definition dnl of the missing part. if test "X" = "X$BZ2_LIB_DIR" -a "X" != "X$BZ2_INCLUDE_DIR" then BZ2_LIB_DIR="$BZ2_INCLUDE_DIR/../lib" fi if test "X" = "X$BZ2_INCLUDE_DIR" -a "X" != "X$BZ2_LIB_DIR" then BZ2_INCLUDE_DIR="$BZ2_LIB_DIR/../include" fi dnl ---------------------------------------------------------------- dnl dnl Crossover between --with-ssl-include-dir and --with-ssl-lib-dir dnl Setting one, but not the other will cause automatic definition dnl of the missing part. if test "X" = "X$SSL_LIB_DIR" -a "X" != "X$SSL_INCLUDE_DIR" then SSL_LIB_DIR="$SSL_INCLUDE_DIR/../lib" fi if test "X" = "X$SSL_INCLUDE_DIR" -a "X" != "X$SSL_LIB_DIR" then SSL_INCLUDE_DIR="$SSL_LIB_DIR/../include" fi dnl ---------------------------------------------------------------- dnl dnl Locate zlib.h dnl dnl Searches: dnl ZLIB_INCLUDE_DIR (--with-zlib, --with-zlib-include-dir) dnl TCL_INCLUDE_DIR (--with-tcl, --with-tcl-include-dir) dnl $prefix/include (--prefix) dnl /usr/local/include dnl /usr/include dnl AC_CACHE_CHECK(for directory with zlib.h, trf_cv_path_ZLIB_INCLUDE_DIR, [trf_cv_path_ZLIB_INCLUDE_DIR="" places="$ZLIB_INCLUDE_DIR \ $TCL_INCLUDE_DIR \ $prefix/include \ /usr/local/include \ /usr/include" for dir in $places; do if test -r $dir/zlib.h ; then trf_cv_path_ZLIB_INCLUDE_DIR=$dir break fi done]) dnl dnl verify success of search dnl if test -z "$trf_cv_path_ZLIB_INCLUDE_DIR" ; then AC_MSG_ERROR(not found; falling back to compat/ headers; use --with-zlib=DIR or --with-zlib-include-dir=DIR) ZLIB_INCLUDE_DIR="\".\"" else ZLIB_INCLUDE_DIR="\"`${CYGPATH} $trf_cv_path_ZLIB_INCLUDE_DIR`\"" eval AC_DEFINE_UNQUOTED(HAVE_ZLIB_H, 1) TRF_TESTS="$TRF_TESTS hasZlib" fi dnl AC_SUBST(ZLIB_INCLUDE_DIR) dnl ---------------------------------------------------------------- dnl dnl Locate zlib library dnl Searches: dnl ZLIB_LIB_DIR (--with-zlib, --with-zlib-lib-dir) dnl TCL_LIB_DIR (--with-tcl, --with-tcl-lib-dir) dnl $exec_prefix/lib (--exec-prefix) dnl $prefix/lib (--prefix) dnl /usr/local/lib dnl /usr/lib dnl AC_CACHE_CHECK(for libz library, trf_cv_lib_ZLIB_LIB_DIR, [trf_cv_lib_ZLIB_LIB_DIR="" places="$ZLIB_LIB_DIR \ $TCL_LIB_DIR \ $exec_prefix/lib \ $prefix/lib \ /usr/local/lib \ /usr/lib" for dir in $places; do if test -n "$trf_cv_lib_ZLIB_LIB_DIR"; then break fi for libsuff in .so ".so.*" .sl .a .dylib; do if test -n "$trf_cv_lib_ZLIB_LIB_DIR"; then break fi if test -f "$dir/libz$libsuff"; then trf_cv_lib_ZLIB_LIB_DIR="$dir" ZLIB_LIB_DIR="$dir" fi done done]) if test -z "$trf_cv_lib_ZLIB_LIB_DIR" ; then AC_MSG_WARN(not found; use --with-zlib-lib-dir=path) ZLIB_LIB_DIR="\".\"" else ZLIB_LIB_DIR="`${CYGPATH} $trf_cv_lib_ZLIB_LIB_DIR`" fi AC_SUBST(ZLIB_LIB_DIR) dnl AC_CACHE_VAL(trf_cv_ZLIB_LIB_DIR, [trf_cv_ZLIB_LIB_DIR="$ZLIB_LIB_DIR"]) dnl ---------------------------------------------------------------- dnl dnl Locate md2.h / sha1.h dnl dnl Searches: dnl SSL_INCLUDE_DIR (--with-ssl, --with-ssl-include-dir) dnl TCL_INCLUDE_DIR (--with-tcl, --with-tcl-include-dir) dnl $prefix/include (--prefix) dnl /usr/local/ssl/include dnl /usr/local/include dnl /usr/include dnl AC_CACHE_CHECK(for directory with ssl.h, trf_cv_path_SSL_INCLUDE_DIR, [trf_cv_path_SSL_INCLUDE_DIR="" places="$SSL_INCLUDE_DIR \ $TCL_INCLUDE_DIR \ $prefix/include \ /usr/local/ssl/include \ /usr/local/include \ /usr/include" for dir in $places; do if test -r $dir/openssl/md2.h ; then trf_cv_path_SSL_INCLUDE_DIR=$dir TRF_DEFS="$TRF_DEFS -DOPENSSL_SUB" break fi if test -r $dir/openssl/sha1.h ; then trf_cv_path_SSL_INCLUDE_DIR=$dir TRF_DEFS="$TRF_DEFS -DOPENSSL_SUB" break fi if test -r $dir/md2.h ; then trf_cv_path_SSL_INCLUDE_DIR=$dir break fi if test -r $dir/sha1.h ; then trf_cv_path_SSL_INCLUDE_DIR=$dir break fi done]) dnl dnl verify success of search dnl if echo "$TRF_DEFS" | grep -q OPENSSL_SUB; then AC_DEFINE_UNQUOTED(OPENSSL_SUB, 1) fi if test -z "$trf_cv_path_SSL_INCLUDE_DIR" ; then AC_MSG_WARN(not found; falling back compat/ headers; use --with-ssl=DIR or --with-ssl-include-dir=DIR) SSL_INCLUDE_DIR="\".\"" else SSL_INCLUDE_DIR="\"`${CYGPATH} $trf_cv_path_SSL_INCLUDE_DIR`\"" if test "${TEA_PLATFORM}" = "windows" ; then AC_MSG_WARN([Squashing SSL / Windows]) SSL_INCLUDE_DIR="\".\"" else eval AC_DEFINE_UNQUOTED(HAVE_SSL_H, 1) eval AC_DEFINE_UNQUOTED(HAVE_MD2_H, 1) eval AC_DEFINE_UNQUOTED(HAVE_MD5_H, 1) eval AC_DEFINE_UNQUOTED(HAVE_SHA_H, 1) #DEFS="$DEFS -DHAVE_SSL_H -DHAVE_MD2_H -DHAVE_SHA_H" TRF_TESTS="$TRF_TESTS hasSSL" fi fi dnl AC_SUBST(SSL_INCLUDE_DIR) dnl ---------------------------------------------------------------- dnl dnl Locate ssl library dnl Searches: dnl SSL_LIB_DIR (--with-ssl, --with-ssl-lib-dir) dnl TCL_LIB_DIR (--with-tcl, --with-tcl-lib-dir) dnl $exec_prefix/lib (--exec-prefix) dnl $prefix/lib (--prefix) dnl /usr/local/ssl/lib dnl /usr/local/lib dnl /usr/lib dnl AC_CACHE_CHECK(for ssl libcrypto library (for message digests), trf_cv_lib_SSL_LIB_DIR, [trf_cv_lib_SSL_LIB_DIR="" places="$SSL_LIB_DIR \ $TCL_LIB_DIR \ $exec_prefix/lib \ $prefix/lib \ /usr/local/ssl/lib \ /usr/local/lib \ /usr/lib" for dir in $places; do if test -n "$trf_cv_lib_SSL_LIB_DIR"; then break fi for libsuff in .so ".so.*" .sl .a .dylib; do if test -n "$trf_cv_lib_SSL_LIB_DIR"; then break fi if test -f $dir/libcrypto$libsuff; then trf_cv_lib_SSL_LIB_DIR="$dir" SSL_LIB_DIR="$dir" fi done done]) if test -z "$trf_cv_lib_SSL_LIB_DIR" ; then AC_MSG_WARN(not found; use --with-ssl-lib-dir=path) SSL_LIB_DIR="\".\"" else SSL_LIB_DIR="`${CYGPATH} $trf_cv_lib_SSL_LIB_DIR`" fi AC_SUBST(SSL_LIB_DIR) dnl AC_CACHE_VAL(trf_cv_SSL_LIB_DIR, [trf_cv_SSL_LIB_DIR="$SSL_LIB_DIR"]) dnl ---------------------------------------------------------------- dnl dnl Locate bzlib.h dnl dnl Searches: dnl BZ2_INCLUDE_DIR (--with-bz2, --with-bz2-include-dir) dnl TCL_INCLUDE_DIR (--with-tcl, --with-tcl-include-dir) dnl $prefix/include (--prefix) dnl /usr/local/include dnl /usr/include dnl AC_CACHE_CHECK(for directory with bzlib.h, trf_cv_path_BZ2_INCLUDE_DIR, [trf_cv_path_BZ2_INCLUDE_DIR="" places="$BZ2_INCLUDE_DIR \ $TCL_INCLUDE_DIR \ $prefix/include \ /usr/local/include \ /usr/include" for dir in $places; do if test -r $dir/bzlib.h ; then trf_cv_path_BZ2_INCLUDE_DIR=$dir break fi done]) dnl dnl verify success of search dnl if test -z "$trf_cv_path_BZ2_INCLUDE_DIR" ; then AC_MSG_WARN(not found; falling back to compat/ headers; use --with-bz2=DIR or --with-bz2-include-dir=DIR) BZ2_INCLUDE_DIR="\".\"" else BZ2_INCLUDE_DIR="\"`${CYGPATH} $trf_cv_path_BZ2_INCLUDE_DIR`\"" eval AC_DEFINE_UNQUOTED(HAVE_BZ2_H, 1) fi dnl AC_SUBST(BZ2_INCLUDE_DIR) dnl ---------------------------------------------------------------- dnl dnl Locate bz2 library dnl Searches: dnl BZ2_LIB_DIR (--with-bz2, --with-bz2-lib-dir) dnl TCL_LIB_DIR (--with-tcl, --with-tcl-lib-dir) dnl $exec_prefix/lib (--exec-prefix) dnl $prefix/lib (--prefix) dnl /usr/local/bz2/lib dnl /usr/local/lib dnl /usr/lib dnl AC_CACHE_CHECK(for bz2 compressor library, trf_cv_lib_BZ2_LIB_DIR, [trf_cv_lib_BZ2_LIB_DIR="" places="$BZ2_LIB_DIR \ $TCL_LIB_DIR \ $exec_prefix/lib \ $prefix/lib \ /usr/local/bz2/lib \ /usr/local/lib \ /usr/lib \ /lib" for dir in $places; do if test -n "$trf_cv_lib_BZ2_LIB_DIR"; then break fi for libsuff in .so ".so.*" .sl .a .dylib; do if test -n "$trf_cv_lib_BZ2_LIB_DIR"; then break fi if test -f $dir/libbz2$libsuff; then trf_cv_lib_BZ2_LIB_DIR="$dir" BZ2_LIB_DIR="$dir" fi done done]) if test -z "$trf_cv_lib_BZ2_LIB_DIR" ; then AC_MSG_WARN(not found; use --with-bz2-lib-dir=path) BZ2_LIB_DIR=. else TRF_TESTS="$TRF_TESTS hasBz" BZ2_LIB_DIR="`${CYGPATH} $trf_cv_lib_BZ2_LIB_DIR`" fi AC_SUBST(BZ2_LIB_DIR) dnl AC_CACHE_VAL(trf_cv_BZ2_LIB_DIR, [trf_cv_BZ2_LIB_DIR="$BZ2_LIB_DIR"]) if test "x$ZLIB_STATIC" = "xyes" then eval AC_DEFINE_UNQUOTED(ZLIB_STATIC_BUILD, 1) fi if test "x$BZLIB_STATIC" = "xyes" then eval AC_DEFINE_UNQUOTED(BZLIB_STATIC_BUILD, 1) fi if test "x$MD5_STATIC" = "xyes" then eval AC_DEFINE_UNQUOTED(MD5_STATIC_BUILD, 1) fi if test "x$trf_debug" = "xyes" then eval AC_DEFINE_UNQUOTED(TRF_DEBUG, 1) fi if test "x$stream_debug" = "xyes" then eval AC_DEFINE_UNQUOTED(TRF_STREAM_DEBUG, 1) fi AC_SUBST(TRF_TESTS) AC_HAVE_HEADERS(dlfcn.h stdlib.h features.h) ]) trf2.1.4/DEPENDENCIES0000644000175000017500000000001411216343142013313 0ustar sergeisergeitcl memchan trf2.1.4/configure.in0000644000175000017500000002760511216343142014072 0ustar sergeisergeidnl dnl Process this file with autoconf to produce a configure script. dnl AC_REVISION($Id: configure.in,v 1.16 2009/05/07 05:30:34 andreas_kupries Exp $) AC_INIT([Trf],[2.1.4]) TEA_INIT([3.7]) AC_CONFIG_AUX_DIR(tclconfig) #-------------------------------------------------------------------- # Configure script for package 'trf', as distributed at November 20, 2001. # TEA compliant. #-------------------------------------------------------------------- #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- TEA_PATH_TCLCONFIG TEA_LOAD_TCLCONFIG TEA_PATH_CONFIG_X(zlibtcl,optional) if test $HAVE_zlibtcl_PACKAGE -gt 0 ; then TEA_LOAD_CONFIG(zlibtcl) #-------------------------------------------------------------------- # Compute an absolute path to the src directory of 'zlibtcl'. We # need the special 'zlib.h' header which routes through # 'zlibtcl.h' to splice the stub definitions into the unchanged # sources of png. #-------------------------------------------------------------------- case $zlibtcl_SRC_DIR in /*) zlibtcl_SRC_PATH=$zlibtcl_SRC_DIR ;; *) # SRC_DIR relative, splice with BUILD_PATH zlibtcl_SRC_PATH="`dirname $zlibtcl_BUILD_STUB_LIB_PATH`/$zlibtcl_SRC_DIR" esac zlibtcl_BUILD_PATH="`dirname $zlibtcl_BUILD_STUB_LIB_PATH`" if test "${TEA_PLATFORM}" = "windows" ; then zlibtcl_SRC_PATH="`$CYGPATH $zlibtcl_SRC_PATH`" zlibtcl_BUILD_PATH="`$CYGPATH $zlibtcl_BUILD_PATH`" fi fi AC_SUBST(zlibtcl_SRC_PATH) AC_SUBST(zlibtcl_BUILD_PATH) AC_SUBST(zlibtcl_VERSION) #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- TEA_PREFIX #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- TEA_SETUP_COMPILER #----------------------------------------------------------------------- # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- TEA_ADD_SOURCES([zlib.c bz2lib.c loadman.c init.c registry.c unstack.c load.c crypt.c]) TEA_ADD_SOURCES([convert.c util.c ref_opt.c]) TEA_ADD_SOURCES([bincode.c hexcode.c octcode.c]) TEA_ADD_SOURCES([uucode.c b64code.c asc85code.c]) TEA_ADD_SOURCES([otpcode.c qpcode.c reflect.c]) TEA_ADD_SOURCES([dig_opt.c digest.c]) TEA_ADD_SOURCES([crc.c crc_zlib.c adler.c]) TEA_ADD_SOURCES([md5dig.c haval.c sha.c md2.c sha1.c]) TEA_ADD_SOURCES([rmd160.c rmd128.c]) TEA_ADD_SOURCES([otpmd5.c otpsha1.c]) TEA_ADD_SOURCES([rs_ecc.c]) TEA_ADD_SOURCES([zip_opt.c zip.c bz2_opt.c bz2.c]) TEA_ADD_SOURCES([trfStubInit.c]) TEA_ADD_HEADERS([generic/transform.h generic/trfDecls.h]) TEA_ADD_INCLUDES([-I\"\${srcdir}\"]) TEA_ADD_INCLUDES([-I\"\${srcdir}/generic\"]) TEA_ADD_INCLUDES([-I\"\${zlibtcl_SRC_PATH}\"]) TEA_ADD_INCLUDES([-I\"\${zlibtcl_BUILD_PATH}\"]) TEA_ADD_INCLUDES([-I\${ZLIB_INCLUDE_DIR}]) TEA_ADD_INCLUDES([-I\${SSL_INCLUDE_DIR}]) TEA_ADD_INCLUDES([-DLIBZ_DEFAULTNAME=\\\"libz\${SHLIB_SUFFIX}\\\"]) AC_SUBST(SHLIB_SUFFIX) TEA_ADD_LIBS([]) TEA_ADD_CFLAGS([]) TEA_ADD_CFLAGS([-DZLIBTCL_VERSION=\\\"${zlibtcl_VERSION}\\\"]) TEA_ADD_STUB_SOURCES([trfStubLib.c]) dnl TEA_ADD_SOURCES([trfStubLib.c]) TEA_ADD_TCL_SOURCES([]) #-------------------------------------------------------------------- # If ltoa is present, use it to convert integer values into strings. # If not, sprintf is used, which is slower and requires more code. #-------------------------------------------------------------------- AC_C_BIGENDIAN AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long int) AC_CHECK_FUNCS(ltoa) if test "${TEA_PLATFORM}" = "windows" ; then AC_MSG_CHECKING([for main in -lcrypt]) AC_MSG_RESULT([no (Windows)]) HAS_LIBCRYPT=0 elif test "`uname -s`" = "Darwin"; then AC_CHECK_LIB(System, crypt, HAS_LIBCRYPT=1, HAS_LIBCRYPT=0) else AC_CHECK_LIB(crypt, main, HAS_LIBCRYPT=1, HAS_LIBCRYPT=0) AC_CHECK_LIB(crypt, md5_init_ctx, HAS_LIBCRYPT_MD5=1, HAS_LIBCRYPT_MD5=0) fi # ----------------------------------------------------------------------- AC_MSG_CHECKING(if assert needs __eprintf) cat > conftest.$ac_ext <&5 if test "x`nm conftest.o |grep __eprintf`" != "x"; then AC_MSG_RESULT(yes) TEA_ADD_SOURCES([compat/_eprintf.c]) else AC_MSG_RESULT(no) fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT* | *CYGWIN_98* | *CYGWIN_95* | MINGW32_NT*) # On windows tclLoadWin.c depends on internal headers. Darn. TEA_PRIVATE_TCL_HEADERS ;; *) # Everywhere else we can stick with the public ones. TEA_PUBLIC_TCL_HEADERS ;; esac #TEA_PUBLIC_TCL_HEADERS #TEA_PRIVATE_TCL_HEADERS #-------------------------------------------------------------------- # A few miscellaneous platform-specific items: # # We have to define a special symbol for Windows (BUILD_Trf in this # case) so that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # We can add more files to clean if our extension creates any extra # files in the future. # # Define any extra compiler flags in the PACKAGE_CFLAGS variable. # These will be appended to the current set of compiler flags for # your system. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then AC_DEFINE(BUILD_Trf) CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch" else CLEANFILES="pkgIndex.tcl" fi AC_SUBST(CLEANFILES) #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # So far only Tcl responds to this one. #-------------------------------------------------------------------- TEA_ENABLE_THREADS #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- TEA_ENABLE_SHARED #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- TEA_CONFIG_CFLAGS #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- TEA_ENABLE_SYMBOLS #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. #-------------------------------------------------------------------- AC_DEFINE(USE_TCL_STUBS) AC_DEFINE(USE_ZLIBTCL_STUBS) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- TEA_MAKE_LIB #-------------------------------------------------------------------- # __CHANGE__ # Add platform libs to LIBS or SHLIB_LD_LIBS as necessary. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then TEA_ADD_LIBS([\"`${CYGPATH} ${zlibtcl_STUB_LIB_PATH}`\"]) else TEA_ADD_LIBS([${zlibtcl_STUB_LIB_SPEC}]) fi #-------------------------------------------------------------------- # Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl # file during the install process. Don't run the TCLSH_PROG through # ${CYGPATH} because it's being used directly by make. # Require that we use a tclsh shell version 8.2 or later since earlier # versions have bugs in the pkg_mkIndex routine. # Add WISH as well if this is a Tk extension. #-------------------------------------------------------------------- TEA_PROG_TCLSH #-------------------------------------------------------------------- # Propagate the information about the required loader file. #-------------------------------------------------------------------- case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT* | *CYGWIN_98* | *CYGWIN_95* | MINGW32_NT*) TEA_ADD_SOURCES([compat/tclLoadWin.c]) ;; *Darwin) ;; *) if test "x${DL_OBJS}" != "xtclLoadDl.o" then TEA_ADD_SOURCES([compat/`basename ${DL_OBJS} .o`.c]) fi ;; esac #-------------------------------------------------------------------- # Locate supporting libraries #-------------------------------------------------------------------- TRF_FIND_ZLIB_SSL #-------------------------------------------------------------------- # MD5 handling... # Cases: # (1) libcrypt not present => compile, use that name. # (2) libcrypt present, contains Md5 => nothing to do # (3) libcrypt present, no Md5 => compile, name = libmd5crypt #-------------------------------------------------------------------- MD5_LIB_FILE="" if test \( $HAS_LIBCRYPT -eq 0 \) then # (1) ## MD5_LIB_FILE=libcrypt$TCL_SHLIB_SUFFIX ## TRF_DEFS="$TRF_DEFS -DCRYPT_LIB_NAME=\\\"NONE\\\"" eval AC_DEFINE_UNQUOTED(MD5_STATIC_BUILD, 1) TEA_ADD_SOURCES([md5-crypt/crypt-entry.c md5-crypt/md5-crypt.c md5-crypt/md5.c compat/stpncpy.c]) elif test "`uname -s`" != "Darwin"; then # (2,3) if test \( $HAS_LIBCRYPT_MD5 -eq 0 \) then # (3) ## MD5_LIB_FILE=libmd5crypt$TCL_SHLIB_SUFFIX ## TRF_DEFS="$TRF_DEFS -DCRYPT_LIB_NAME=\\\"NONE\\\"" # Sun Solaris is special, we may not use -lcrypt ! # Verified for: SunOS 5.5.1 (Solaris 2.5) # SunOS 5.6 (Solaris 2.6) ## case "`uname -s`" in ## SunOS*) ;; ## *) LIBS="-lcrypt $LIBS" ## SHLIB_LD_LIBS="-lcrypt $SHLIB_LD_LIBS" ## ;; ## esac eval AC_DEFINE_UNQUOTED(MD5_STATIC_BUILD, 1) TEA_ADD_SOURCES([md5-crypt/crypt-entry.c md5-crypt/md5-crypt.c md5-crypt/md5.c compat/stpncpy.c]) fi fi AC_SUBST(MD5_LIB_FILE) #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- AC_OUTPUT([Makefile test.setup]) #-------------------------------------------------------------------- trf2.1.4/compat/0000755000175000017500000000000011216344734013042 5ustar sergeisergeitrf2.1.4/compat/bzlib.h0000644000175000017500000001613011216343142014306 0ustar sergeisergei /*-------------------------------------------------------------*/ /*--- Public header file for the library. ---*/ /*--- bzlib.h ---*/ /*-------------------------------------------------------------*/ /*-- This file is a part of bzip2 and/or libbzip2, a program and library for lossless, block-sorting data compression. Copyright (C) 1996-1998 Julian R Seward. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. Julian Seward, Guildford, Surrey, UK. jseward@acm.org bzip2/libbzip2 version 0.9.0c of 18 October 1998 This program is based on (at least) the work of: Mike Burrows David Wheeler Peter Fenwick Alistair Moffat Radford Neal Ian H. Witten Robert Sedgewick Jon L. Bentley For more information on these sources, see the manual. --*/ #ifndef _BZLIB_H #define _BZLIB_H #define BZ_RUN 0 #define BZ_FLUSH 1 #define BZ_FINISH 2 #define BZ_OK 0 #define BZ_RUN_OK 1 #define BZ_FLUSH_OK 2 #define BZ_FINISH_OK 3 #define BZ_STREAM_END 4 #define BZ_SEQUENCE_ERROR (-1) #define BZ_PARAM_ERROR (-2) #define BZ_MEM_ERROR (-3) #define BZ_DATA_ERROR (-4) #define BZ_DATA_ERROR_MAGIC (-5) #define BZ_IO_ERROR (-6) #define BZ_UNEXPECTED_EOF (-7) #define BZ_OUTBUFF_FULL (-8) typedef struct { char *next_in; unsigned int avail_in; unsigned int total_in; char *next_out; unsigned int avail_out; unsigned int total_out; void *state; void *(*bzalloc)(void *,int,int); void (*bzfree)(void *,void *); void *opaque; } bz_stream; #ifndef BZ_IMPORT #define BZ_EXPORT #endif #ifdef _WIN32 # include # include # ifdef small /* windows.h define small to char */ # undef small # endif # ifdef BZ_EXPORT # define BZ_API(func) WINAPI func # define BZ_EXTERN extern # else /* import windows dll dynamically */ # define BZ_API(func) (WINAPI * func) # define BZ_EXTERN # endif #else # define BZ_API(func) func # define BZ_EXTERN extern #endif /*-- Core (low-level) library functions --*/ BZ_EXTERN int BZ_API(bzCompressInit) ( bz_stream* strm, int blockSize100k, int verbosity, int workFactor ); BZ_EXTERN int BZ_API(bzCompress) ( bz_stream* strm, int action ); BZ_EXTERN int BZ_API(bzCompressEnd) ( bz_stream* strm ); BZ_EXTERN int BZ_API(bzDecompressInit) ( bz_stream *strm, int verbosity, int small ); BZ_EXTERN int BZ_API(bzDecompress) ( bz_stream* strm ); BZ_EXTERN int BZ_API(bzDecompressEnd) ( bz_stream *strm ); /*-- High(er) level library functions --*/ #ifndef BZ_NO_STDIO #define BZ_MAX_UNUSED 5000 typedef void BZFILE; BZ_EXTERN BZFILE* BZ_API(bzReadOpen) ( int* bzerror, FILE* f, int verbosity, int small, void* unused, int nUnused ); BZ_EXTERN void BZ_API(bzReadClose) ( int* bzerror, BZFILE* b ); BZ_EXTERN void BZ_API(bzReadGetUnused) ( int* bzerror, BZFILE* b, void** unused, int* nUnused ); BZ_EXTERN int BZ_API(bzRead) ( int* bzerror, BZFILE* b, void* buf, int len ); BZ_EXTERN BZFILE* BZ_API(bzWriteOpen) ( int* bzerror, FILE* f, int blockSize100k, int verbosity, int workFactor ); BZ_EXTERN void BZ_API(bzWrite) ( int* bzerror, BZFILE* b, void* buf, int len ); BZ_EXTERN void BZ_API(bzWriteClose) ( int* bzerror, BZFILE* b, int abandon, unsigned int* nbytes_in, unsigned int* nbytes_out ); #endif /*-- Utility functions --*/ BZ_EXTERN int BZ_API(bzBuffToBuffCompress) ( char* dest, unsigned int* destLen, char* source, unsigned int sourceLen, int blockSize100k, int verbosity, int workFactor ); BZ_EXTERN int BZ_API(bzBuffToBuffDecompress) ( char* dest, unsigned int* destLen, char* source, unsigned int sourceLen, int small, int verbosity ); /*-- Code contributed by Yoshioka Tsuneo (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp), to support better zlib compatibility. This code is not _officially_ part of libbzip2 (yet); I haven't tested it, documented it, or considered the threading-safeness of it. If this code breaks, please contact both Yoshioka and me. --*/ BZ_EXTERN const char * BZ_API(bzlibVersion) ( void ); #ifndef BZ_NO_STDIO BZ_EXTERN BZFILE * BZ_API(bzopen) ( const char *path, const char *mode ); BZ_EXTERN BZFILE * BZ_API(bzdopen) ( int fd, const char *mode ); BZ_EXTERN int BZ_API(bzread) ( BZFILE* b, void* buf, int len ); BZ_EXTERN int BZ_API(bzwrite) ( BZFILE* b, void* buf, int len ); BZ_EXTERN int BZ_API(bzflush) ( BZFILE* b ); BZ_EXTERN void BZ_API(bzclose) ( BZFILE* b ); BZ_EXTERN const char * BZ_API(bzerror) ( BZFILE *b, int *errnum ); #endif #endif /*-------------------------------------------------------------*/ /*--- end bzlib.h ---*/ /*-------------------------------------------------------------*/ trf2.1.4/compat/tclLoadMac.c0000644000175000017500000001474411216343142015213 0ustar sergeisergei/* * tclLoadMac.c -- * * This procedure provides a version of the dlopen() function for use * on the Macintosh. This procedure will only work with systems * that use the Code Fragment Manager. * * Adapted from tclMacLoad.c in the Tcl 7.6 distribution. */ #include #include #include #include #include #include "transformInt.h" #if GENERATINGPOWERPC #define OUR_ARCH_TYPE kPowerPCCFragArch #else #define OUR_ARCH_TYPE kMotorola68KCFragArch #endif /* * The following data structure defines the structure of a code fragment * resource. We can cast the resource to be of this type to access * any fields we need to see. */ struct CfrgHeader { long res1; long res2; long version; long res3; long res4; long filler1; long filler2; long itemCount; char arrayStart; /* Array of externalItems begins here. */ }; typedef struct CfrgHeader CfrgHeader, *CfrgHeaderPtr, **CfrgHeaderPtrHand; /* * The below structure defines a cfrag item within the cfrag resource. */ struct CfrgItem { OSType archType; long updateLevel; long currVersion; long oldDefVersion; long appStackSize; short appSubFolder; char usage; char location; long codeOffset; long codeLength; long res1; long res2; short itemSize; Str255 name; /* This is actually variable sized. */ }; typedef struct CfrgItem CfrgItem; /* *---------------------------------------------------------------------- * * dlopen -- * * This function is an implementation of dlopen() for the Mac. * * Results: * Returns the handle of the newly loaded library, or NULL on * failure. * * Side effects: * Loads the specified library into the process. * *---------------------------------------------------------------------- */ static Str255 errName; VOID * dlopen(path, mode) CONST char *path; int mode; { ConnectionID connID; Ptr dummy; OSErr err; FSSpec fileSpec; short fragFileRef, saveFileRef; Handle fragResource; UInt32 offset = 0; UInt32 length = kWholeFork; char packageName[255]; CONST char* pkgGuess; char* p; /* * First thing we must do is infer the package name from the file * name. This is kind of dumb since the caller actually knows * this value, it just doesn't give it to us. */ if ((pkgGuess = strrchr(path,':')) != NULL) { pkgGuess++; } else { pkgGuess = path; } if (!strncmp(pkgGuess,"lib",3)) { pkgGuess+=3; } strcpy(packageName,pkgGuess); p = packageName; if ((*p) && islower(UCHAR(*p++))) { packageName[0] = (char) toupper(UCHAR(packageName[0])); } while (isalpha(UCHAR(*p)) || (*p == '_')) { if (isupper(UCHAR(*p))) { *p = (char) tolower(UCHAR(*p)); } p++; } *p = 0; err = FSpLocationFromPath(strlen(path), (char *) path, &fileSpec); if (err != noErr) { strcpy((char *) errName, "file not found"); return (VOID *) NULL; } /* * 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); HLock(fragResource); if (ResError() == noErr) { CfrgItem* srcItem; long itemCount, index; Ptr itemStart; itemCount = (*(CfrgHeaderPtrHand)fragResource)->itemCount; itemStart = &(*(CfrgHeaderPtrHand)fragResource)->arrayStart; for (index = 0; index < itemCount; index++, itemStart += srcItem->itemSize) { srcItem = (CfrgItem*)itemStart; if (srcItem->archType != OUR_ARCH_TYPE) continue; if (!strncasecmp(packageName, (char *) srcItem->name + 1, srcItem->name[0])) { offset = srcItem->codeOffset; length = srcItem->codeLength; } } } /* * Close the resource file. If the extension wants to reopen the * resource fork it should use the tclMacLibrary.c file during it's * construction. */ HUnlock(fragResource); ReleaseResource(fragResource); CloseResFile(fragFileRef); UseResFile(saveFileRef); } /* * Now we can attempt to load the fragement using the offset & length * obtained from the resource. We don't worry about the main entry point * as we are going to search for specific entry points passed to us. */ c2pstr(packageName); err = GetDiskFragment(&fileSpec, offset, length, (StringPtr) packageName, kLoadLib, &connID, &dummy, errName); if (err != fragNoErr) { p2cstr(errName); return (VOID *) NULL; } return (VOID *) connID; } /* *---------------------------------------------------------------------- * * dlsym -- * * This function is an alternative for the system function * GetProcAddress. It returns the address of a * symbol, give the handle returned by dlopen(). * * Results: * Returns the address of the symbol in the dll. * * Side effects: * None. * *---------------------------------------------------------------------- */ VOID * dlsym(handle, symbol) VOID *handle; CONST char *symbol; { VOID *procPtr; char sym1[255]; OSErr err; SymClass symClass; strcpy(sym1, symbol); c2pstr(sym1); err = FindSymbol((ConnectionID) handle, (StringPtr) sym1, (Ptr *) &procPtr, &symClass); if (err != fragNoErr || symClass == kDataCFragSymbol) { procPtr = (VOID *) NULL; } return procPtr; } /* *---------------------------------------------------------------------- * * dlerror -- * * This function returns a string describing the error which * occurred in dlopen(). * * Results: * Returns an error message. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * dlerror() { return (char *) errName; } /* *---------------------------------------------------------------------- * * dlclose -- * * Not implemented yet. * * Results: * Always returns 0 (= O.K.) * * Side effects: * None * *---------------------------------------------------------------------- */ int dlclose(handle) VOID *handle; { return 0; } trf2.1.4/compat/tclLoadShl.c0000644000175000017500000000277611216343142015243 0ustar sergeisergei/* * 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 /* * On some HP machines, dl.h defines EXTERN; remove that definition. */ #ifdef EXTERN # undef EXTERN #endif #include "transformInt.h" #ifndef DYNAMIC_PATH # define DYNAMIC_PATH 0 #endif VOID *dlopen(path, mode) CONST char *path; #if defined(__hpux) && defined(__ia64) int mode; #else unsigned int mode; #endif { int flags, length; if (path == (char *) NULL) { return (VOID *) PROG_HANDLE; } flags = ((mode & RTLD_NOW) ? BIND_IMMEDIATE : BIND_DEFERRED) | DYNAMIC_PATH; #ifdef BIND_VERBOSE length = strlen(path); if ((length > 2) && !(strcmp(path+length-3,".sl"))) { flags |= BIND_VERBOSE; } #endif return (VOID *) shl_load(path, flags, 0L); } VOID *dlsym(handle, symbol) VOID *handle; CONST char *symbol; { VOID *address; if (shl_findsym((shl_t *)&handle, symbol, (short) TYPE_UNDEFINED, &address) != 0) { address = NULL; } return address; } char *dlerror() { return Tcl_ErrnoMsg(errno); } int dlclose(handle) VOID *handle; { return shl_unload((shl_t) handle); } trf2.1.4/compat/tclLoadNone.c0000644000175000017500000001413611216343142015405 0ustar sergeisergei/* * 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.5 96/02/15 11:43:01 */ #include "tcl.h" #include "compat/dlfcn.h" extern int adler32 (); extern int compress (); extern int crc32 (); extern int get_crc_table (); extern int gzclose (); extern int gzdopen (); extern int gzerror (); extern int gzflush (); extern int gzopen (); extern int gzread (); extern int gzwrite (); extern int uncompress (); extern int deflate (); extern int _tr_align (); extern int _tr_flush_block (); extern int _tr_init (); extern int _tr_stored_block (); extern int _tr_tally (); extern int zcalloc (); extern int zcfree (); extern int zlib (); extern int inflate (); extern int inflate_blocks (); extern int inflate_blocks_free (); extern int inflate_blocks_new (); extern int inflate_blocks_reset (); extern int inflate_set_dictionary (); extern int inflate_trees_bits (); extern int inflate_trees_dynamic (); extern int inflate_trees_fixed (); extern int inflate_trees_free (); extern int inflate_codes (); extern int inflate_codes_free (); extern int inflate_codes_new (); extern int inflate_flush (); extern int inflate_fast (); extern int des_3cbc_encrypt (); extern int des_cbc_cksum (); extern int des_cbc_encrypt (); extern int des_ncbc_encrypt (); extern int des_pcbc_encrypt (); extern int des_quad_cksum (); extern int des_ede3_cfb64_encrypt (); extern int des_cfb64_encrypt (); extern int des_cfb_encrypt (); extern int des_ecb3_encrypt (); extern int des_ecb_encrypt (); extern int des_encrypt (); extern int des_encrypt2 (); extern int des_ede3_cbc_encrypt (); extern int des_enc_read (); extern int des_enc_write (); extern int crypt (); extern int des_ede3_ofb64_encrypt (); extern int des_ofb64_encrypt (); extern int des_ofb_encrypt (); extern int des_random_key (); extern int des_random_seed (); extern int des_read_2passwords (); extern int des_read_password (); extern int des_read_pw_string (); extern int des_is_weak_key (); extern int des_key_sched (); extern int des_set_key (); extern int des_set_odd_parity (); extern int _des_crypt (); extern int des_string_to_2keys (); extern int des_string_to_key (); extern int des_cblock_print_file (); static struct { char * name; int (*value)(); }dictionary [] = { { "adler32", adler32 }, { "compress", compress }, { "crc32", crc32 }, { "get_crc_table", get_crc_table }, { "gzclose", gzclose }, { "gzdopen", gzdopen }, { "gzerror", gzerror }, { "gzflush", gzflush }, { "gzopen", gzopen }, { "gzread", gzread }, { "gzwrite", gzwrite }, { "uncompress", uncompress }, { "deflate", deflate }, { "_tr_align", _tr_align }, { "_tr_flush_block", _tr_flush_block }, { "_tr_init", _tr_init }, { "_tr_stored_block", _tr_stored_block }, { "_tr_tally", _tr_tally }, { "zcalloc", zcalloc }, { "zcfree", zcfree }, { "zlib", zlib }, { "inflate", inflate }, { "inflate_blocks", inflate_blocks }, { "inflate_blocks_free", inflate_blocks_free }, { "inflate_blocks_new", inflate_blocks_new }, { "inflate_blocks_reset", inflate_blocks_reset }, { "inflate_set_dictionary", inflate_set_dictionary }, { "inflate_trees_bits", inflate_trees_bits }, { "inflate_trees_dynamic", inflate_trees_dynamic }, { "inflate_trees_fixed", inflate_trees_fixed }, { "inflate_trees_free", inflate_trees_free }, { "inflate_codes", inflate_codes }, { "inflate_codes_free", inflate_codes_free }, { "inflate_codes_new", inflate_codes_new }, { "inflate_flush", inflate_flush }, { "inflate_fast", inflate_fast }, { "des_3cbc_encrypt", des_3cbc_encrypt }, { "des_cbc_cksum", des_cbc_cksum }, { "des_cbc_encrypt", des_cbc_encrypt }, { "des_ncbc_encrypt", des_ncbc_encrypt }, { "des_pcbc_encrypt", des_pcbc_encrypt }, { "des_quad_cksum", des_quad_cksum }, { "des_ede3_cfb64_encrypt", des_ede3_cfb64_encrypt }, { "des_cfb64_encrypt", des_cfb64_encrypt }, { "des_cfb_encrypt", des_cfb_encrypt }, { "des_ecb3_encrypt", des_ecb3_encrypt }, { "des_ecb_encrypt", des_ecb_encrypt }, { "des_encrypt", des_encrypt }, { "des_encrypt2", des_encrypt2 }, { "des_ede3_cbc_encrypt", des_ede3_cbc_encrypt }, { "des_enc_read", des_enc_read }, { "des_enc_write", des_enc_write }, { "crypt", crypt }, { "des_ede3_ofb64_encrypt", des_ede3_ofb64_encrypt }, { "des_ofb64_encrypt", des_ofb64_encrypt }, { "des_ofb_encrypt", des_ofb_encrypt }, { "des_random_key", des_random_key }, { "des_random_seed", des_random_seed }, { "des_read_2passwords", des_read_2passwords }, { "des_read_password", des_read_password }, { "des_read_pw_string", des_read_pw_string }, { "des_is_weak_key", des_is_weak_key }, { "des_key_sched", des_key_sched }, { "des_set_key", des_set_key }, { "des_set_odd_parity", des_set_odd_parity }, { "_des_crypt", _des_crypt }, { "des_string_to_2keys", des_string_to_2keys }, { "des_string_to_key", des_string_to_key }, { "des_cblock_print_file", des_cblock_print_file }, { 0, 0 } }; /* *---------------------------------------------------------------------- * * dlopen -- * dlsym -- * dlerror -- * dlclose -- * * Dummy functions, in case our system doesn't support * dynamic loading. * * Results: * NULL for dlopen() and dlsym(). Error for other functions. * * Side effects: * None * *---------------------------------------------------------------------- */ VOID *dlopen(path, mode) CONST char *path; int mode; { return (VOID *) 1; } VOID *dlsym(handle, symbol) VOID *handle; CONST char *symbol; { int i; for (i = 0; dictionary [i] . name != 0; ++i) { if (!strcmp (symbol, dictionary [i] . name)) { return (VOID *) dictionary [i].value; } } return (VOID *) NULL; } char *dlerror() { return "dynamic loading is not currently available on this system"; } int dlclose(handle) VOID *handle; { return 0; } trf2.1.4/compat/zconf.h0000644000175000017500000001725611216343142014335 0ustar sergeisergei/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-1998 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id: zconf.h,v 1.2 1999/09/27 16:37:37 aku Exp $ */ #ifndef _ZCONF_H #define _ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. */ #ifdef Z_PREFIX # define deflateInit_ z_deflateInit_ # define deflate z_deflate # define deflateEnd z_deflateEnd # define inflateInit_ z_inflateInit_ # define inflate z_inflate # define inflateEnd z_inflateEnd # define deflateInit2_ z_deflateInit2_ # define deflateSetDictionary z_deflateSetDictionary # define deflateCopy z_deflateCopy # define deflateReset z_deflateReset # define deflateParams z_deflateParams # define inflateInit2_ z_inflateInit2_ # define inflateSetDictionary z_inflateSetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateReset z_inflateReset # define compress z_compress # define compress2 z_compress2 # define uncompress z_uncompress # define adler32 z_adler32 # define crc32 z_crc32 # define get_crc_table z_get_crc_table # define Byte z_Byte # define uInt z_uInt # define uLong z_uLong # define Bytef z_Bytef # define charf z_charf # define intf z_intf # define uIntf z_uIntf # define uLongf z_uLongf # define voidpf z_voidpf # define voidp z_voidp #endif #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) # define WIN32 #endif #if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) # ifndef __32BIT__ # define __32BIT__ # endif #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #if defined(MSDOS) && !defined(__32BIT__) # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) # define STDC #endif #if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) # ifndef STDC # define STDC # endif #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const # endif #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) # define NO_DUMMY_DECL #endif /* Old Borland C incorrectly complains about missing returns: */ #if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) # define NEED_DUMMY_RETURN #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif #endif #if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) # ifndef __32BIT__ # define SMALL_MEDIUM # define FAR _far # endif #endif /* Compile with -DZLIB_DLL for Windows DLL support */ #if defined(ZLIB_DLL) # if defined(_WINDOWS) || defined(WINDOWS) # ifdef FAR # undef FAR # endif # include # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR _cdecl _export # endif # endif # if defined (__BORLANDC__) # if (__BORLANDC__ >= 0x0500) && defined (WIN32) # include # define ZEXPORT __declspec(dllexport) WINAPI # define ZEXPORTRVA __declspec(dllexport) WINAPIV # else # if defined (_Windows) && defined (__DLL__) # define ZEXPORT _export # define ZEXPORTVA _export # endif # endif # endif #endif #if defined (__BEOS__) # if defined (ZLIB_DLL) # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef FAR # define FAR #endif #if !defined(MACOS) && !defined(TARGET_OS_MAC) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #ifdef HAVE_UNISTD_H # include /* for off_t */ # include /* for SEEK_* and off_t */ # define z_off_t off_t #endif #ifndef SEEK_SET # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) # pragma map(deflateInit_,"DEIN") # pragma map(deflateInit2_,"DEIN2") # pragma map(deflateEnd,"DEEND") # pragma map(inflateInit_,"ININ") # pragma map(inflateInit2_,"ININ2") # pragma map(inflateEnd,"INEND") # pragma map(inflateSync,"INSY") # pragma map(inflateSetDictionary,"INSEDI") # pragma map(inflate_blocks,"INBL") # pragma map(inflate_blocks_new,"INBLNE") # pragma map(inflate_blocks_free,"INBLFR") # pragma map(inflate_blocks_reset,"INBLRE") # pragma map(inflate_codes_free,"INCOFR") # pragma map(inflate_codes,"INCO") # pragma map(inflate_fast,"INFA") # pragma map(inflate_flush,"INFLU") # pragma map(inflate_mask,"INMA") # pragma map(inflate_set_dictionary,"INSEDI2") # pragma map(inflate_copyright,"INCOPY") # pragma map(inflate_trees_bits,"INTRBI") # pragma map(inflate_trees_dynamic,"INTRDY") # pragma map(inflate_trees_fixed,"INTRFI") # pragma map(inflate_trees_free,"INTRFR") #endif #endif /* _ZCONF_H */ trf2.1.4/compat/stdlib.h0000644000175000017500000000325611216343142014472 0ustar sergeisergei/* * 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 extern void abort _ANSI_ARGS_((void)); extern double atof _ANSI_ARGS_((CONST char *string)); extern int atoi _ANSI_ARGS_((CONST char *string)); extern long atol _ANSI_ARGS_((CONST char *string)); extern char * calloc _ANSI_ARGS_((unsigned int numElements, unsigned int size)); extern void exit _ANSI_ARGS_((int status)); extern int free _ANSI_ARGS_((char *blockPtr)); extern char * getenv _ANSI_ARGS_((CONST char *name)); extern char * malloc _ANSI_ARGS_((unsigned int numBytes)); extern void qsort _ANSI_ARGS_((VOID *base, int n, int size, int (*compar)(CONST VOID *element1, CONST VOID *element2))); extern char * realloc _ANSI_ARGS_((char *ptr, unsigned int numBytes)); extern double strtod _ANSI_ARGS_((CONST char *string, char **endPtr)); extern long strtol _ANSI_ARGS_((CONST char *string, char **endPtr, int base)); extern unsigned long strtoul _ANSI_ARGS_((CONST char *string, char **endPtr, int base)); #endif /* _STDLIB */ trf2.1.4/compat/stpncpy.c0000644000175000017500000000413711216343142014703 0ustar sergeisergei/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This is almost copied from strncpy.c, written by Torbjorn Granlund. */ #include #ifdef HAVE_CONFIG_H # include #endif #ifdef _LIBC # include #else # include #endif #ifndef weak_alias # define __stpncpy stpncpy #endif /* Copy no more than N characters of SRC to DEST, returning the address of the terminating '\0' in DEST, if any, or else DEST + N. */ char * __stpncpy (dest, src, n) char *dest; const char *src; size_t n; { char c; char *s = dest; if (n >= 4) { size_t n4 = n >> 2; for (;;) { c = *src++; *dest++ = c; if (c == '\0') break; c = *src++; *dest++ = c; if (c == '\0') break; c = *src++; *dest++ = c; if (c == '\0') break; c = *src++; *dest++ = c; if (c == '\0') break; if (--n4 == 0) goto last_chars; } n -= dest - s; goto zero_fill; } last_chars: n &= 3; if (n == 0) return dest; for (;;) { c = *src++; --n; *dest++ = c; if (c == '\0') break; if (n == 0) return dest; } zero_fill: while (n-- > 0) dest[n] = '\0'; return dest - 1; } #ifdef weak_alias weak_alias (__stpncpy, stpncpy) #endif trf2.1.4/compat/zlib.h0000644000175000017500000011770211216343142014153 0ustar sergeisergei/* zlib.h -- interface of the 'zlib' general purpose compression library version 1.1.3, July 9th, 1998 Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifndef _ZLIB_H #define _ZLIB_H #include "zconf.h" #ifdef __cplusplus extern "C" { #endif #define ZLIB_VERSION "1.1.3" /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough (for example if an input file is mmap'ed), or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: ascii or binary */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 /* Allowed flush values; see deflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative * values are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_ASCII 1 #define Z_UNKNOWN 2 /* Possible values of the data_type field */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade the compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least 0.1% larger than avail_in plus 12 bytes. If deflate does not return Z_STREAM_END, then it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update data_type if it can make a good guess about the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). */ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. If next_in is not Z_NULL and avail_in is large enough (the exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may some introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much output as possible to the output buffer. The flushing behavior of inflate is not specified for values of the flush parameter other than Z_SYNC_FLUSH and Z_FINISH, but the current implementation actually flushes as much output as possible anyway. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all the uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH is never required, but can be used to inform inflate that a faster routine may be used for the single inflate() call. If a preset dictionary is needed at this point (see inflateSetDictionary below), inflate sets strm-adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then call inflateSync to look for a good compression block. */ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy)); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no string match). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid method). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. This function must be called immediately after deflateInit, deflateInit2 or deflateReset, before any call of deflate. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size in deflate or deflate2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. Upon return of this function, strm->adler is set to the Adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The Adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent (for example if deflate has already been called for this stream or if the compression method is bsort). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy)); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ /* ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative memLevel). msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from reading the zlib header if present: this will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unchanged.) */ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the Adler32 value returned by this call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect Adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until a full flush point (see above the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being NULL). */ /* utility functions */ /* The following utility functions are implemented on top of the basic stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can easily be modified if you need special options. */ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least 0.1% larger than sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. This function can be used to compress a whole file at once if the input file is mmap'ed. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. */ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least 0.1% larger than sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. This function can be used to decompress a whole file at once if the input file is mmap'ed. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted. */ typedef voidp gzFile; ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); /* Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman only compression as in "wb1h". (See the description of deflateInit2 for more information about the strategy parameter.) gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. gzopen returns NULL if the file could not be opened or if there was insufficient memory to allocate the (de)compression state; errno can be checked to distinguish the two cases (if errno is zero, the zlib error is Z_MEM_ERROR). */ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* gzdopen() associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (in the file has been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd), mode) closes the file descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). gzdopen returns NULL if there was insufficient memory to allocate the (de)compression state. */ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. */ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If the input file was not in gzip format, gzread copies the given number of bytes into the buffer. gzread returns the number of uncompressed bytes actually read (0 for end of file, -1 for error). */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len)); /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes actually written (0 in case of error). */ ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); /* Converts, formats, and writes the args to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written (0 in case of error). */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. The string is then terminated with a null character. gzgets returns buf, or Z_NULL in case of error. */ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. */ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. */ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush returns Z_OK if the flush parameter is Z_FINISH and all output could be flushed. gzflush should be called only when strictly necessary because it can degrade compression. */ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence)); /* Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. */ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); /* Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream. gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* Returns 1 when EOF has previously been detected reading the given input stream, otherwise zero. */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* Flushes all pending output if necessary, closes the compressed file and deallocates all the (de)compression state. The return value is the zlib error number (see function gzerror below). */ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. */ /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. */ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example: uLong adler = adler32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running crc with the bytes buf[0..len-1] and return the updated crc. If buf is NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example: uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, int stream_size)); ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); #define deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit(strm) \ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) #if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; /* hack for buggy compilers */ #endif ZEXTERN const char * ZEXPORT zError OF((int err)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); #ifdef __cplusplus } #endif #endif /* _ZLIB_H */ trf2.1.4/compat/_eprintf.c0000644000175000017500000000050011216343142014777 0ustar sergeisergei#include #include /* This is used by the `assert' macro. */ void __eprintf (string, expression, line, filename) CONST char *string; CONST char *expression; int line; CONST char *filename; { fprintf (stderr, string, expression, line, filename); fflush (stderr); abort (); } trf2.1.4/compat/tclLoadWin.c0000644000175000017500000001104611216343142015240 0ustar sergeisergei/* * tclLoadWin.c -- * * This procedure provides a version of dlopen() that * works with the Windows "LoadLibrary" and "GetProcAddress" * API for dynamic loading. * */ /*#include */ #include "transformInt.h" /* * taken from "tcl/win/tclWinPort.h" * enable usage of procedure internal to tcl */ #ifdef USE_TCL_STUBS #include "tclWinInt.h" #else EXTERN void TclWinConvertError _ANSI_ARGS_((DWORD errCode)); #endif typedef struct LibraryList { HINSTANCE handle; struct LibraryList *nextPtr; } LibraryList; static LibraryList *libraryList = NULL; /* List of currently loaded DLL's. */ /* * Declarations for functions that are only used in this file. */ static void UnloadLibraries _ANSI_ARGS_((ClientData clientData)); /* *---------------------------------------------------------------------- * * dlopen -- * * This function is an alternative for the functions * TclWinLoadLibrary and TclWinGetTclInstance. 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. If path is NULL, the global library instance handle * is returned. * * Side effects: * Loads the specified library into the process. * *---------------------------------------------------------------------- */ VOID *dlopen(path, mode) CONST char *path; int mode; { VOID *handle; LibraryList *ptr; static int initialized = 0; if (!initialized) { initialized = 1; Tcl_CreateExitHandler((Tcl_ExitProc *) UnloadLibraries, (ClientData) &libraryList); } handle = (VOID *) LoadLibrary(path); if (handle != NULL) { ptr = (LibraryList*) ckalloc(sizeof(LibraryList)); ptr->handle = (HINSTANCE) handle; ptr->nextPtr = libraryList; libraryList = ptr; } return handle; } /* *---------------------------------------------------------------------- * * dlclose -- * * This function is an alternative for the function * FreeLibrary. It is responsible for removing library * handles from the library list and remove the dll * from memory. * * Results: * -1 on error, 0 on success. * * Side effects: * Removes the specified library from the process. * *---------------------------------------------------------------------- */ int dlclose(handle) VOID *handle; { LibraryList *ptr, *prevPtr; ptr = libraryList; prevPtr = NULL; while (ptr != NULL) { if (ptr->handle == (HINSTANCE) handle) { #ifndef BUGS_ON_EXIT FreeLibrary((HINSTANCE) handle); #endif if (prevPtr) { prevPtr->nextPtr = ptr->nextPtr; } else { libraryList = ptr->nextPtr; } ckfree((char*) ptr); return 0; } prevPtr = ptr; ptr = ptr->nextPtr; } return -1; } /* *---------------------------------------------------------------------- * * dlsym -- * * This function is an alternative for the system function * GetProcAddress. It returns the address of a * symbol, give the handle returned by dlopen(). * * Results: * Returns the address of the symbol in the dll. * * Side effects: * None. * *---------------------------------------------------------------------- */ VOID *dlsym(handle, symbol) VOID *handle; CONST char *symbol; { /* DEBUG */ VOID* res; /* printf ("dlsym (%p,%p='%s')\n", handle, symbol, symbol); */ res = (VOID *) GetProcAddress((HINSTANCE) handle, symbol); /* printf ("\taddress = %p\n", res); */ return res; /* DEBUG */ } /* *---------------------------------------------------------------------- * * dlerror -- * * This function returns a string describing the error which * occurred in dlopen(). * * Results: * Returns an error message. * * Side effects: * errno is set. * *---------------------------------------------------------------------- */ char * dlerror() { TclWinConvertError(GetLastError()); return (char*) Tcl_ErrnoMsg(Tcl_GetErrno()); } /* *---------------------------------------------------------------------- * * 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(clientData) ClientData clientData; { LibraryList *ptr; LibraryList *list = *((LibraryList **) clientData); while (list != NULL) { FreeLibrary(list->handle); ptr = list->nextPtr; ckfree((char*) list); list = ptr; } } trf2.1.4/compat/tclLoadDyld.c0000644000175000017500000001107311216343142015377 0ustar sergeisergei/* * tclLoadDyld.c -- * * This procedure provides a version of the TclLoadFile that * works with Apple's dyld dynamic loading. This file * provided by Wilfredo Sanchez (wsanchez@apple.com). * This works on Mac OS X. * * Copyright (c) 1995 Apple Computer, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclLoadDyld.c,v 1.1 2005/07/25 20:52:00 andreas_kupries Exp $ */ #include #include #include "tcl.h" typedef struct Tcl_DyldModuleHandle { struct Tcl_DyldModuleHandle *nextModuleHandle; NSModule module; } Tcl_DyldModuleHandle; typedef struct Tcl_DyldLoadHandle { const struct mach_header *dyld_lib; Tcl_DyldModuleHandle *firstModuleHandle; } Tcl_DyldLoadHandle; /* *---------------------------------------------------------------------- * * TclpDlopen -- * * Dynamically loads a binary code file into memory and returns * a handle to the new code. * * Results: * A standard Tcl completion code. If an error occurs, an error * message is left in the interpreter's result. * * Side effects: * New code suddenly appears in memory. * *---------------------------------------------------------------------- */ VOID * dlopen(path, flags) CONST char *path; int flags; { Tcl_DyldLoadHandle *dyldLoadHandle; const struct mach_header *dyld_lib; dyld_lib = NSAddImage(path, NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_RETURN_ON_ERROR); if (!dyld_lib) { return NULL; } dyldLoadHandle = (Tcl_DyldLoadHandle *) ckalloc(sizeof(Tcl_DyldLoadHandle)); if (!dyldLoadHandle) return NULL; dyldLoadHandle->dyld_lib = dyld_lib; dyldLoadHandle->firstModuleHandle = NULL; return (Tcl_LoadHandle) dyldLoadHandle; } char * dlerror() { NSLinkEditErrors editError; char *name, *msg; NSLinkEditError(&editError, &errno, &name, &msg); return msg; } /* *---------------------------------------------------------------------- * * TclpFindSymbol -- * * Looks up a symbol, by name, through a handle associated with * a previously loaded piece of code (shared library). * * Results: * Returns a pointer to the function associated with 'symbol' if * it is found. Otherwise returns NULL and may leave an error * message in the interp's result. * *---------------------------------------------------------------------- */ VOID *dlsym(handle, symbol) VOID *handle; CONST char *symbol; { NSSymbol nsSymbol; CONST char *native; Tcl_DString newName, ds; Tcl_PackageInitProc* proc = NULL; Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) handle; /* * dyld adds an underscore to the beginning of symbol names. */ native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds); Tcl_DStringInit(&newName); Tcl_DStringAppend(&newName, "_", 1); native = Tcl_DStringAppend(&newName, native, -1); nsSymbol = NSLookupSymbolInImage(dyldLoadHandle->dyld_lib, native, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); if(nsSymbol) { Tcl_DyldModuleHandle *dyldModuleHandle; proc = NSAddressOfSymbol(nsSymbol); dyldModuleHandle = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle)); if (dyldModuleHandle) { dyldModuleHandle->module = NSModuleForSymbol(nsSymbol); dyldModuleHandle->nextModuleHandle = dyldLoadHandle->firstModuleHandle; dyldLoadHandle->firstModuleHandle = dyldModuleHandle; } } Tcl_DStringFree(&newName); Tcl_DStringFree(&ds); return proc; } /* *---------------------------------------------------------------------- * * 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 dissapears from memory. * Note that this is a no-op on older (OpenStep) versions of dyld. * *---------------------------------------------------------------------- */ int dlclose(handle) VOID *handle; { Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) handle; Tcl_DyldModuleHandle *dyldModuleHandle = dyldLoadHandle->firstModuleHandle; void *ptr; while (dyldModuleHandle) { NSUnLinkModule(dyldModuleHandle->module, NSUNLINKMODULE_OPTION_NONE); ptr = dyldModuleHandle; dyldModuleHandle = dyldModuleHandle->nextModuleHandle; ckfree(ptr); } ckfree(dyldLoadHandle); } trf2.1.4/compat/md2.h0000644000175000017500000000665311216343142013677 0ustar sergeisergei/* lib/md/md2.h */ /* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au) * All rights reserved. * * This file is part of an SSL implementation written * by Eric Young (eay@mincom.oz.au). * The implementation was written so as to conform with Netscapes SSL * specification. This library and applications are * FREE FOR COMMERCIAL AND NON-COMMERCIAL USE * as long as the following conditions are aheared to. * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. If this code is used in a product, * Eric Young should be given attribution as the author of the parts used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Eric Young (eay@mincom.oz.au) * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 THE AUTHOR OR CONTRIBUTORS 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. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * * Always modify md2.org since md2.h is automatically generated from * it during SSLeay configuration. * * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ #ifndef HEADER_MD2_H #define HEADER_MD2_H #ifdef __cplusplus extern "C" { #endif #define MD2_DIGEST_LENGTH 16 #define MD2_BLOCK 16 #define MD2_INT unsigned int typedef struct MD2state_st { int num; unsigned char data[MD2_BLOCK]; MD2_INT cksm[MD2_BLOCK]; MD2_INT state[MD2_BLOCK]; } MD2_CTX; #ifndef NOPROTO char *MD2_options(void); void MD2_Init(MD2_CTX *c); void MD2_Update(MD2_CTX *c, register unsigned char *data, unsigned long len); void MD2_Final(unsigned char *md, MD2_CTX *c); unsigned char *MD2(unsigned char *d, unsigned long n,unsigned char *md); #else char *MD2_options(); void MD2_Init(); void MD2_Update(); void MD2_Final(); unsigned char *MD2(); #endif #ifdef __cplusplus } #endif #endif trf2.1.4/compat/tclLoadDld.c0000644000175000017500000000373511216343142015214 0ustar sergeisergei/* * tclLoadDld.c -- * * This procedure provides a version of dlopen() 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.4 96/02/15 11:58:46 */ #include "transformInt.h" #include "dld.h" /* *---------------------------------------------------------------------- * * dlopen -- * * This function is an implementation of dlopen() using * the dld library. * * Results: * Returns the handle of the newly loaded library, or NULL on * failure. * * Side effects: * Loads the specified library into the process. * *---------------------------------------------------------------------- */ static int returnCode = 0; extern char *tclExecutableName; VOID *dlopen(path, mode) CONST char *path; int mode; { static int firstTime = 1; /* * The dld package needs to know the pathname to the tcl binary. * If that's not know, return an error. */ returnCode = 0; if (firstTime) { if (tclExecutableName == NULL) { return (VOID *) NULL; } returnCode = dld_init(tclExecutableName); if (returnCode != 0) { return (VOID *) NULL; } firstTime = 0; } if ((path != NULL) && ((returnCode = dld_link(path)) != 0)) { return (VOID *) NULL; } return (VOID *) 1; } VOID * dlsym(handle, symbol) VOID *handle; CONST char *symbol; { return (VOID *) dld_get_func(symbol); } char * dlerror() { if (tclExecutableName == NULL) { return "don't know name of application binary file, so can't initialize dynamic loader"; } return dld_strerror(returnCode); } int dlclose(handle) VOID *handle; { return 0; } trf2.1.4/compat/dlfcn.h0000644000175000017500000000307011216343142014271 0ustar sergeisergei/* * dlfcn.h -- * * This file provides a replacement for the header file "dlfcn.h" * on systems where dlfcn.h is missing. It's primary use is for * AIX, where Tcl emulates the dl library. * * This file is subject to the following copyright notice, which is * different from the notice used elsewhere in Tcl but rougly * equivalent in meaning. * * Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH * 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 */ #ifndef __dlfcn_h__ #define __dlfcn_h__ #ifndef _TCL #include #endif #ifdef __cplusplus extern "C" { #endif /* * Mode flags for the dlopen routine. */ #define RTLD_LAZY 1 /* lazy function call binding */ #define RTLD_NOW 2 /* immediate function call binding */ #define RTLD_GLOBAL 0x100 /* allow symbols to be global */ /* * Declarations used for dynamic linking support routines. */ VOID *dlopen _ANSI_ARGS_((const char *path, int mode)); VOID *dlsym _ANSI_ARGS_((void *handle, const char *symbol)); char *dlerror _ANSI_ARGS_((void)); int dlclose _ANSI_ARGS_((void *handle)); #ifdef __cplusplus } #endif #endif /* __dlfcn_h__ */ trf2.1.4/compat/tclLoadAout.c0000644000175000017500000003565111216343142015423 0ustar sergeisergei/* * tclLoadAout.c -- * * This procedure provides a version of dlopen() that * provides pseudo-static linking using version-7 compatible * a.out files described in either sys/exec.h or sys/a.out.h. * * 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 * and Design Engineering (MADE) Initiative through ARPA contract * F33615-94-C-4400. * * SCCS: @(#) tclLoadAout.c 1.7 96/02/15 11:58:53 */ #include "transformInt.h" #include #include #include #include #ifdef HAVE_EXEC_AOUT_H # include #endif /* * Some systems describe the a.out header in sys/exec.h, and some in * a.out.h. */ #ifdef USE_SYS_EXEC_H #include #endif #ifdef USE_A_OUT_H #include #endif #ifdef USE_SYS_EXEC_AOUT_H #include #define a_magic a_midmag #endif EXTERN char *tclExecutableName; #define UCHAR(c) ((unsigned char) (c)) /* * TCL_LOADSHIM is the amount by which to shim the break when loading */ #ifndef TCL_LOADSHIM #define TCL_LOADSHIM 0x4000L #endif /* * TCL_LOADALIGN must be a power of 2, and is the alignment to which * to force the origin of load modules */ #ifndef TCL_LOADALIGN #define TCL_LOADALIGN 0x4000L #endif /* * TCL_LOADMAX is the maximum size of a load module, and is used as * a sanity check when loading */ #ifndef TCL_LOADMAX #define TCL_LOADMAX 2000000L #endif /* * Kernel calls that appear to be missing from the system .h files: */ extern char * brk _ANSI_ARGS_((char *)); extern char * sbrk _ANSI_ARGS_((size_t)); /* * The static variable SymbolTableFile contains the file name where the * result of the last link was stored. The file is kept because doing so * allows one load module to use the symbols defined in another. */ static char * SymbolTableFile = NULL; /* * Prototypes for procedures referenced only in this file: */ static int FindLibraries _ANSI_ARGS_((CONST char *fileName, Tcl_DString *buf)); static void UnlinkSymbolTable _ANSI_ARGS_((void)); static void Seterror _ANSI_ARGS_((char *message)); static int GuessPackageName _ANSI_ARGS_((CONST char *fileName, Tcl_DString *bufPtr)); static char *errorMessage = NULL; /* *---------------------------------------------------------------------- * * dlopen -- * * Dynamically loads a binary code file into memory. * * Results: * A handle which can be used in later calls to dlsym(), * or NULL when the attempt fails. * * Side effects: * New code suddenly appears in memory. * * * Bugs: * This function does not attempt to handle the case where the * BSS segment is not executable. It will therefore fail on * Encore Multimax, Pyramid 90x, and similar machines. The * reason is that the mprotect() kernel call, which would * otherwise be employed to mark the newly-loaded text segment * executable, results in a system crash on BSD/386. * * In an effort to make it fast, this function eschews the * technique of linking the load module once, reading its header * to determine its size, allocating memory for it, and linking * it again. Instead, it `shims out' memory allocation by * placing the module TCL_LOADSHIM bytes beyond the break, * and assuming that any malloc() calls required to run the * linker will not advance the break beyond that point. If * the break is advanced beyonnd that point, the load will * 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. *---------------------------------------------------------------------- */ VOID * dlopen(path, flags) CONST char *path; int flags; { 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 = -1; /* 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 */ int status; /* Status return from Tcl_ calls */ char *p, *q; Tcl_Interp *interp = NULL; Tcl_DString fullPath; errno = 0; if (errorMessage) { ckfree(errorMessage); errorMessage = NULL; } /* Find the file that contains the symbols for the run-time link. */ if (SymbolTableFile != NULL) { inputSymbolTable = SymbolTableFile; } else if (tclExecutableName == NULL) { Seterror("can't find the tclsh executable"); goto error; } else { inputSymbolTable = tclExecutableName; } /* Construct the `ld' command that builds the relocated module */ interp = Tcl_CreateInterp(); Tcl_DStringInit (&fullPath); if (Tcl_GetPathType(path) == TCL_PATH_RELATIVE) { p = getenv("LD_LIBRARY_PATH"); while (p) { if ((q = strchr(p,':')) == NULL) { q = p; while(*q) q++; } if (p == q) break; Tcl_DStringAppend(&fullPath, p, q-p); Tcl_DStringAppend(&fullPath, "/", 1); Tcl_DStringAppend(&fullPath, path, -1); if (access(Tcl_DStringValue(&fullPath), F_OK) != -1) { break; } Tcl_DStringSetLength(&fullPath, 0); p = q; if (*p) p++; } } if (*Tcl_DStringValue(&fullPath) == 0) { Tcl_DStringAppend(&fullPath, path, -1); } tmpnam (relocatedFileName); Tcl_DStringInit (&linkCommandBuf); Tcl_DStringAppend (&linkCommandBuf, "exec ld -o ", -1); Tcl_DStringAppend (&linkCommandBuf, relocatedFileName, -1); #if defined(__mips) || defined(mips) Tcl_DStringAppend (&linkCommandBuf, " -G 0 ", -1); #endif Tcl_DStringAppend (&linkCommandBuf, " -u TclLoadDictionary_", -1); GuessPackageName(Tcl_DStringValue(&fullPath), &linkCommandBuf); Tcl_DStringAppend (&linkCommandBuf, " -A ", -1); Tcl_DStringAppend (&linkCommandBuf, inputSymbolTable, -1); Tcl_DStringAppend (&linkCommandBuf, " -N -T XXXXXXXX ", -1); Tcl_DStringAppend (&linkCommandBuf, Tcl_DStringValue(&fullPath), -1); p = getenv("LD_LIBRARY_PATH"); while (p) { if ((q = strchr(p,':')) == NULL) { q = p; while(*q) q++; } if (p == q) break; Tcl_DStringAppend(&linkCommandBuf, " -L", 3); Tcl_DStringAppend(&linkCommandBuf, p, q-p); p = q; if (*p) p++; } Tcl_DStringAppend (&linkCommandBuf, " ", -1); if (FindLibraries (Tcl_DStringValue(&fullPath), &linkCommandBuf) != TCL_OK) { Tcl_DStringFree (&linkCommandBuf); Tcl_DStringFree (&fullPath); goto error; } Tcl_DStringFree (&fullPath); linkCommand = Tcl_DStringValue (&linkCommandBuf); /* Determine the starting address, and plug it into the command */ startAddress = (char *) (((unsigned long) sbrk (0) + TCL_LOADSHIM + TCL_LOADALIGN - 1) & (- TCL_LOADALIGN)); p = strstr (linkCommand, "-T") + 3; sprintf (p, "%08lx", (long) startAddress); p [8] = ' '; /* Run the linker */ status = Tcl_Eval (interp, linkCommand); Tcl_DStringFree (&linkCommandBuf); if (status != 0) { Seterror(interp->result); errno = 0; goto error; } /* Open the linker's result file and read the header */ relocatedFd = open (relocatedFileName, O_RDONLY); if (relocatedFd < 0) { goto ioError; } status= read (relocatedFd, (char *) & relocatedHead, sizeof relocatedHead); if (status < sizeof relocatedHead) { goto ioError; } /* Check the magic number */ if (relocatedHead.a_magic != OMAGIC) { Seterror("bad magic number in intermediate file"); goto failure; } /* Make sure that memory allocation is still consistent */ if ((unsigned long) sbrk (0) > (unsigned long) startAddress) { Seterror("can't load, memory allocation is inconsistent"); goto failure; } /* Make sure that the relocated module's size is reasonable */ relocatedSize = relocatedHead.a_text + relocatedHead.a_data + relocatedHead.a_bss; if (relocatedSize > TCL_LOADMAX) { Seterror("module too big to load"); goto failure; } /* Advance the break to protect the loaded module */ (void) brk (startAddress + relocatedSize); /* Seek to the start of the module's text */ #if defined(__mips) || defined(mips) status = lseek (relocatedFd, N_TXTOFF (relocatedHead.ex_f, relocatedHead.ex_o), SEEK_SET); #else status = lseek (relocatedFd, N_TXTOFF (relocatedHead), SEEK_SET); #endif if (status < 0) { goto ioError; } /* Read in the module's text and data */ relocatedSize = relocatedHead.a_text + relocatedHead.a_data; if (read (relocatedFd, startAddress, relocatedSize) < relocatedSize) { brk (startAddress); ioError: Seterror("error on intermediate file: "); failure: (void) unlink (relocatedFileName); goto error; } /* Close the intermediate file. */ (void) close (relocatedFd); /* Arrange things so that intermediate symbol tables eventually get * deleted. If the flag RTLD_GLOBAL is not set, just keep the * old file. */ if (flags & RTLD_GLOBAL) { if (SymbolTableFile != NULL) { UnlinkSymbolTable (); } else { atexit (UnlinkSymbolTable); } SymbolTableFile = ckalloc (strlen (relocatedFileName) + 1); strcpy (SymbolTableFile, relocatedFileName); } else { (void) unlink (relocatedFileName); } return (VOID *) startAddress; error: if (relocatedFd>=0) { close (relocatedFd); } if (interp) { Tcl_DeleteInterp(interp); } return NULL; } /* *---------------------------------------------------------------------- * * dlsym -- * * This function returns the address of a * symbol, give the handle returned by dlopen(). * * Results: * Returns the address of the symbol in the dll. * * Side effects: * None. * *---------------------------------------------------------------------- */ VOID *dlsym(handle, symbol) VOID *handle; CONST char *symbol; { if ((handle != NULL) && (symbol != NULL)) { return ((VOID * (*) _ANSI_ARGS_((CONST char *))) handle) (symbol); } else { return (VOID *) NULL; } } /* *---------------------------------------------------------------------- * * dlerror -- * * This function returns a string describing the error which * occurred in dlopen(). * * Results: * Returns an error message. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * dlerror() { char *err, *msg; if (errorMessage && errno) { err = Tcl_ErrnoMsg(errno); msg = ckalloc(strlen(errorMessage)+strlen(err)+1); strcpy(msg, errorMessage); strcat(msg, err); ckfree(errorMessage); errorMessage = msg; } return errorMessage; } /* *---------------------------------------------------------------------- * * dlclose -- * * Just a dummy function, only for compatibility. There is no * way to remove dll's from memory. * * Results: * Always returns 0 (= O.K.) * * Side effects: * None * *---------------------------------------------------------------------- */ int dlclose(handle) VOID *handle; { return 0; } static void Seterror(message) char *message; { if (errorMessage) { ckfree(errorMessage); } errorMessage = ckalloc(strlen(message)+1); strcpy(errorMessage, message); return; } /* *------------------------------------------------------------------------ * * 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 (fileName, buf) CONST char * fileName; /* Name of the load module */ Tcl_DString * buf; /* Buffer where the -l an -L flags */ { FILE * f; /* The load module */ int c = EOF; /* Byte from the load module */ char * p; /* Open the load module */ if ((f = fopen (fileName, "rb")) == NULL) { Seterror(""); return TCL_ERROR; } /* Search for the library list in the load module */ p = "@LIBS: "; while (*p != '\0' && (c = getc (f)) != EOF) { if (c == *p) { ++p; } else { p = "@LIBS: "; if (c == *p) { ++p; } } } /* No library list -- this must be an ill-formed module */ if (c == EOF) { Seterror("is not a Tcl load module."); (void) fclose (f); return TCL_ERROR; } /* Accumulate the library list */ while ((c = getc (f)) != '\0' && c != EOF) { char cc = c; Tcl_DStringAppend (buf, &cc, 1); } (void) fclose (f); if (c == EOF) { Seterror("Library directory ends prematurely"); return TCL_ERROR; } return TCL_OK; } /* *------------------------------------------------------------------------ * * UnlinkSymbolTable -- * * Remove the symbol table file from the last dynamic link. * * Results: * None. * * Side effects: * The symbol table file from the last dynamic link is removed. * This function is called when (a) a new symbol table is present * because another dynamic link is complete, or (b) the process * is exiting. *------------------------------------------------------------------------ */ static void UnlinkSymbolTable () { (void) unlink (SymbolTableFile); ckfree (SymbolTableFile); SymbolTableFile = NULL; } /* *---------------------------------------------------------------------- * * GuessPackageName -- * * Determinsed the package name from the file name. The package * name is appended to the dynamic string, if possible. * * Results: * Returns 1 if the guess succeeds, 0 otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int GuessPackageName(fileName, bufPtr) CONST 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. */ { CONST char *p,*pkgGuess; char *r; if ((pkgGuess = strrchr(fileName,'/')) != NULL) { pkgGuess++; } else { pkgGuess = fileName; } if (!strncmp(pkgGuess,"lib",3)) { pkgGuess+=3; } for (p = pkgGuess; (*p) && (*p != '.') && (!isdigit(UCHAR(*p))); p++) { /* Empty loop body. */ } if ((p>pkgGuess+2) && !strncmp(p-2,"_G0.",4)) { p-=2; } if (p == pkgGuess) { return 0; } Tcl_DStringAppend(bufPtr,pkgGuess, p-pkgGuess); r = Tcl_DStringValue(bufPtr); r += strlen(r) - (p-pkgGuess); if (islower(UCHAR(*r))) { *r = (char) toupper(UCHAR(*r)); } while (*(++r)) { if (isupper(UCHAR(*r))) { *r = (char) tolower(UCHAR(*r)); } } return 1; } trf2.1.4/compat/sha.h0000644000175000017500000001017311216343142013760 0ustar sergeisergei/* crypto/sha/sha.h */ /* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@mincom.oz.au). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@mincom.oz.au). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@mincom.oz.au)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@mincom.oz.au)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 THE AUTHOR OR CONTRIBUTORS 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. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ #ifndef HEADER_SHA_H #define HEADER_SHA_H #ifdef __cplusplus extern "C" { #endif #define SHA_CBLOCK 64 #define SHA_LBLOCK 16 #define SHA_BLOCK 16 #define SHA_LAST_BLOCK 56 #define SHA_LENGTH_BLOCK 8 #define SHA_DIGEST_LENGTH 20 typedef struct SHAstate_st { unsigned long h0,h1,h2,h3,h4; unsigned long Nl,Nh; unsigned long data[SHA_LBLOCK]; int num; } SHA_CTX; #ifndef NOPROTO void SHA_Init(SHA_CTX *c); void SHA_Update(SHA_CTX *c, unsigned char *data, unsigned long len); void SHA_Final(unsigned char *md, SHA_CTX *c); unsigned char *SHA(unsigned char *d, unsigned long n,unsigned char *md); void SHA1_Init(SHA_CTX *c); void SHA1_Update(SHA_CTX *c, unsigned char *data, unsigned long len); void SHA1_Final(unsigned char *md, SHA_CTX *c); unsigned char *SHA1(unsigned char *d, unsigned long n,unsigned char *md); #else void SHA_Init(); void SHA_Update(); void SHA_Final(); unsigned char *SHA(); void SHA1_Init(); void SHA1_Update(); void SHA1_Final(); unsigned char *SHA1(); #endif #ifdef __cplusplus } #endif #endif trf2.1.4/compat/tclLoadAix.c0000644000175000017500000003170511216343142015230 0ustar sergeisergei/* * tclLoadAix.c -- * * This file implements the dlopen and dlsym APIs under the * AIX operating system, to enable the Tcl "load" command to * work. This code was provided by Jens-Uwe Mager. * * This file is subject to the following copyright notice, which is * different from the notice used elsewhere in Tcl. The file has * been modified to incorporate the file dlfcn.h in-line. * * Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH * 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 * This is an unpublished work copyright (c) 1992 HELIOS Software GmbH * 30159 Hannover, Germany */ #include #include #include #include #include #include #include #include /* * We simulate dlopen() et al. through a call to load. Because AIX has * no call to find an exported symbol we read the loader section of the * loaded module and build a list of exported symbols and their virtual * address. */ typedef struct { char *name; /* the symbols's name */ VOID *addr; /* its relocated virtual address */ } Export, *ExportPtr; /* * To be able to intialize, a library may provide a dl_info structure * that contains functions to be called to initialize and terminate. */ struct dl_info { void (*init) _ANSI_ARGS_((void)); void (*fini) _ANSI_ARGS_((void)); }; /* * The VOID * handle returned from dlopen is actually a ModulePtr. */ typedef struct Module { struct Module *next; char *name; /* module name for refcounting */ int refCnt; /* the number of references */ VOID *entry; /* entry point from load */ struct dl_info *info; /* optional init/terminate functions */ struct dl_info *cdtors; /* optional C++ constructors */ int nExports; /* the number of exports found */ ExportPtr exports; /* the array of exports */ } Module, *ModulePtr; /* * We keep a list of all loaded modules to be able to call the fini * handlers and destructors at atexit() time. */ static ModulePtr modList; /* * The last error from one of the dl* routines is kept in static * variables here. Each error is returned only once to the caller. */ static char errbuf[BUFSIZ]; static int errvalid; static void caterr _ANSI_ARGS_((char *)); static int readExports _ANSI_ARGS_((ModulePtr)); static void terminate _ANSI_ARGS_((void)); static VOID *findMain _ANSI_ARGS_((void)); VOID * dlopen(path, mode) const char *path; int mode; { register ModulePtr mp; static VOID *mainModule; /* * Upon the first call register a terminate handler that will * close all libraries. Also get a reference to the main module * for use with loadbind. */ if (!mainModule) { if ((mainModule = findMain()) == NULL) return NULL; atexit(terminate); } /* * Scan the list of modules if we have the module already loaded. */ for (mp = modList; mp; mp = mp->next) if (strcmp(mp->name, path) == 0) { mp->refCnt++; return (VOID *) mp; } if ((mp = (ModulePtr)calloc(1, sizeof(*mp))) == NULL) { errvalid++; strcpy(errbuf, "calloc: "); strcat(errbuf, strerror(errno)); return (VOID *) NULL; } mp->name = malloc((unsigned) (strlen(path) + 1)); strcpy(mp->name, path); /* * load should be declared load(const char *...). Thus we * cast the path to a normal char *. Ugly. */ if ((mp->entry = (VOID *)load((char *)path, L_NOAUTODEFER, NULL)) == NULL) { free(mp->name); free(mp); errvalid++; strcpy(errbuf, "dlopen: "); strcat(errbuf, path); strcat(errbuf, ": "); /* * If AIX says the file is not executable, the error * can be further described by querying the loader about * the last error. */ if (errno == ENOEXEC) { char *tmp[BUFSIZ/sizeof(char *)]; if (loadquery(L_GETMESSAGES, tmp, sizeof(tmp)) == -1) strcpy(errbuf, strerror(errno)); else { char **p; for (p = tmp; *p; p++) caterr(*p); } } else strcat(errbuf, strerror(errno)); return (VOID *) NULL; } mp->refCnt = 1; mp->next = modList; modList = mp; if (loadbind(0, mainModule, mp->entry) == -1) { dlclose(mp); errvalid++; strcpy(errbuf, "loadbind: "); strcat(errbuf, strerror(errno)); return (VOID *) NULL; } /* * If the user wants global binding, loadbind against all other * loaded modules. */ if (mode & RTLD_GLOBAL) { register ModulePtr mp1; for (mp1 = mp->next; mp1; mp1 = mp1->next) if (loadbind(0, mp1->entry, mp->entry) == -1) { dlclose(mp); errvalid++; strcpy(errbuf, "loadbind: "); strcat(errbuf, strerror(errno)); return (VOID *) NULL; } } if (readExports(mp) == -1) { dlclose(mp); return (VOID *) NULL; } /* * If there is a dl_info structure, call the init function. */ if (mp->info = (struct dl_info *)dlsym(mp, "dl_info")) { if (mp->info->init) (*mp->info->init)(); } else errvalid = 0; /* * If the shared object was compiled using xlC we will need * to call static constructors (and later on dlclose destructors). */ if (mp->cdtors = (struct dl_info *) dlsym(mp, "__cdtors")) { while (mp->cdtors->init) { (*mp->cdtors->init)(); mp->cdtors++; } } else errvalid = 0; return (VOID *) mp; } /* * Attempt to decipher an AIX loader error message and append it * to our static error message buffer. */ static void caterr(s) 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; } } VOID * dlsym(handle, symbol) VOID *handle; CONST char *symbol; { register ModulePtr mp = (ModulePtr)handle; register ExportPtr ep; register int i; /* * Could speed up the search, but I assume that one assigns * the result to function pointers anyways. */ for (ep = mp->exports, i = mp->nExports; i; i--, ep++) if (strcmp(ep->name, symbol) == 0) return ep->addr; errvalid++; strcpy(errbuf, "dlsym: undefined symbol "); strcat(errbuf, symbol); return NULL; } char * dlerror() { if (errvalid) { errvalid = 0; return errbuf; } return NULL; } int dlclose(handle) VOID *handle; { register ModulePtr mp = (ModulePtr)handle; int result; register ModulePtr mp1; if (--mp->refCnt > 0) return 0; if (mp->info && mp->info->fini) (*mp->info->fini)(); if (mp->cdtors) while (mp->cdtors->fini) { (*mp->cdtors->fini)(); mp->cdtors++; } result = unload(mp->entry); if (result == -1) { errvalid++; strcpy(errbuf, strerror(errno)); } if (mp->exports) { register ExportPtr ep; register int i; for (ep = mp->exports, i = mp->nExports; i; i--, ep++) if (ep->name) free(ep->name); free(mp->exports); } if (mp == modList) modList = mp->next; else { for (mp1 = modList; mp1; mp1 = mp1->next) if (mp1->next == mp) { mp1->next = mp->next; break; } } free(mp->name); free(mp); return result; } static void terminate() { while (modList) dlclose(modList); } /* * Build the export table from the XCOFF .loader section. */ static int readExports(mp) ModulePtr mp; { LDFILE *ldp = NULL; SCNHDR sh, shdata; LDHDR *lhp; char *ldbuf; LDSYM *ls; int i; ExportPtr ep; if ((ldp = ldopen(mp->name, ldp)) == NULL) { struct ld_info *lp; char *buf; int size = 4*1024; if (errno != ENOENT) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); return -1; } /* * The module might be loaded due to the LIBPATH * environment variable. Search for the loaded * module using L_GETINFO. */ if ((buf = malloc(size)) == NULL) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); return -1; } while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) { free(buf); size += 4*1024; if ((buf = malloc(size)) == NULL) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); return -1; } } if (i == -1) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); free(buf); return -1; } /* * Traverse the list of loaded modules. The entry point * returned by load() does actually point to the data * segment origin. */ lp = (struct ld_info *)buf; while (lp) { if (lp->ldinfo_dataorg == mp->entry) { ldp = ldopen(lp->ldinfo_filename, ldp); break; } if (lp->ldinfo_next == 0) lp = NULL; else lp = (struct ld_info *)((char *)lp + lp->ldinfo_next); } free(buf); if (!ldp) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); return -1; } } if (TYPE(ldp) != U802TOCMAGIC) { errvalid++; strcpy(errbuf, "readExports: bad magic"); while(ldclose(ldp) == FAILURE) ; return -1; } /* * Get the padding for the data section. This is needed for * AIX 4.1 compilers. This is used when building the final * function pointer to the exported symbol. */ if (ldnshread(ldp, _DATA, &shdata) != SUCCESS) { errvalid++; strcpy(errbuf, "readExports: cannot read data section header"); while(ldclose(ldp) == FAILURE) ; return -1; } if (ldnshread(ldp, _LOADER, &sh) != SUCCESS) { errvalid++; strcpy(errbuf, "readExports: cannot read loader section header"); while(ldclose(ldp) == FAILURE) ; return -1; } /* * We read the complete loader section in one chunk, this makes * finding long symbol names residing in the string table easier. */ if ((ldbuf = (char *)malloc(sh.s_size)) == NULL) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); while(ldclose(ldp) == FAILURE) ; return -1; } if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK) { errvalid++; strcpy(errbuf, "readExports: cannot seek to loader section"); free(ldbuf); while(ldclose(ldp) == FAILURE) ; return -1; } if (FREAD(ldbuf, sh.s_size, 1, ldp) != 1) { errvalid++; strcpy(errbuf, "readExports: cannot read loader section"); free(ldbuf); while(ldclose(ldp) == FAILURE) ; return -1; } lhp = (LDHDR *)ldbuf; ls = (LDSYM *)(ldbuf+LDHDRSZ); /* * Count the number of exports to include in our export table. */ for (i = lhp->l_nsyms; i; i--, ls++) { if (!LDR_EXPORT(*ls)) continue; mp->nExports++; } if ((mp->exports = (ExportPtr)calloc(mp->nExports, sizeof(*mp->exports))) == NULL) { errvalid++; strcpy(errbuf, "readExports: "); strcat(errbuf, strerror(errno)); free(ldbuf); while(ldclose(ldp) == FAILURE) ; return -1; } /* * Fill in the export table. All entries are relative to * the entry point we got from load. */ ep = mp->exports; ls = (LDSYM *)(ldbuf+LDHDRSZ); for (i = lhp->l_nsyms; i; i--, ls++) { char *symname; char tmpsym[SYMNMLEN+1]; if (!LDR_EXPORT(*ls)) continue; if (ls->l_zeroes == 0) symname = ls->l_offset+lhp->l_stoff+ldbuf; else { /* * The l_name member is not zero terminated, we * must copy the first SYMNMLEN chars and make * sure we have a zero byte at the end. */ strncpy(tmpsym, ls->l_name, SYMNMLEN); tmpsym[SYMNMLEN] = '\0'; symname = tmpsym; } ep->name = malloc((unsigned) (strlen(symname) + 1)); strcpy(ep->name, symname); ep->addr = (VOID *)((unsigned long)mp->entry + ls->l_value - shdata.s_vaddr); ep++; } free(ldbuf); while(ldclose(ldp) == FAILURE) ; return 0; } /* * Find the main modules entry point. This is used as export pointer * for loadbind() to be able to resolve references to the main part. */ static VOID * findMain() { struct ld_info *lp; char *buf; int size = 4*1024; int i; VOID *ret; if ((buf = malloc(size)) == NULL) { errvalid++; strcpy(errbuf, "findMain: "); strcat(errbuf, strerror(errno)); return NULL; } while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) { free(buf); size += 4*1024; if ((buf = malloc(size)) == NULL) { errvalid++; strcpy(errbuf, "findMain: "); strcat(errbuf, strerror(errno)); return NULL; } } if (i == -1) { errvalid++; strcpy(errbuf, "findMain: "); strcat(errbuf, strerror(errno)); free(buf); return NULL; } /* * The first entry is the main module. The entry point * returned by load() does actually point to the data * segment origin. */ lp = (struct ld_info *)buf; ret = lp->ldinfo_dataorg; free(buf); return ret; } trf2.1.4/tools/0000755000175000017500000000000011216344734012717 5ustar sergeisergeitrf2.1.4/tools/fixhbline0000744000175000017500000000220511216343142014602 0ustar sergeisergei#!/usr/local/bin/tclsh # -*- tcl -*- # this one needs no path. # fixes the '#!... path' for the given script #argv = {tclsh_path wish_path appscript} foreach {tclsh_path wish_path appscript} $argv {break;} set fail [catch {set fin [open $appscript r]}] if {$fail} { # appscript does not exist exit 1 } if {[gets $fin ipPath] < 0} { # appscript is empty exit 2 } if {![regexp {^#!} $ipPath]} { # appscript is no application close $fin exit 3 } if {[regexp {wish} $ipPath]} { # wish application if {{} == $wish_path} { # wish was not found exit 5 } set fout [open $appscript.[pid] w] puts $fout "#!$wish_path" fcopy $fin $fout close $fin close $fout file rename -force $appscript.[pid] $appscript exit 0 } if {[regexp {tclsh} $ipPath]} { # tclsh application if {{} == $wish_path} { # tclsh was not found exit 6 } set fout [open $appscript.[pid] w] puts $fout "#!$tclsh_path" fcopy $fin $fout close $fin close $fout file rename -force $appscript.[pid] $appscript exit 0 } # appscript is no tclsh/wish application exit 4 trf2.1.4/tools/mmencode0000744000175000017500000000253311216343142014425 0ustar sergeisergei#!/usr/local/bin/tclsh # demonstration application, encodes the incoming byte stream to base64 package require Trf # line buffer for parcel below. set line "" proc parcel {max cmd buffer} { # this transformation takes the incoming byte stream and parcels it into # lines of at most $max characters each. The last line is possibly shorter. # only the write part is implemented. # # hm, this could be generalized into a transformation parceling the input # into packets and adding some sort of frame around these. #puts stderr "$max $cmd [string length $buffer]" global line switch -- $cmd { create/write { set line "" } delete/write { set line "" } write { append line $buffer set res "" while {[string length $line] > $max} { append res "[string range $line 0 [expr {$max-1}]]\n" set line [string range $line $max end] } return $res } flush/write { if {[string length $line] > 0} { set res "$line\n" set line "" return $res } else { return {} } } clear/write { set line "" } } } transform -attach stdout -command {parcel 72} base64 -attach stdout -mode encode fconfigure stdin -translation binary fcopy stdin stdout close stdout # close is *required* to flush out the internal buffers. # This is not done during a simple exit :-( exit trf2.1.4/tools/install-sh0000744000175000017500000000421211216343142014710 0ustar sergeisergei#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5; it is not part of GNU. # # $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" instcmd="$mvprog" chmodcmd="" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; *) if [ x"$src" = x ] then src=$1 else dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp # and set any options; do chmod last to preserve setuid bits if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $doit $rmcmd $dst $doit $mvcmd $dsttmp $dst exit 0 trf2.1.4/tools/demo0000744000175000017500000003571211216343142013567 0ustar sergeisergei#!/usr/local/bin/wish # -*- tcl -*- # demo of trf features wm withdraw . wm title . "Trf demonstration" package require Trf set fdata { R0lGODlhPABaAPcAAP////76+vz09v7p6/3W1/3M0fzGyfu1uPmstfiVmPiJi/R2ePRpdfZn a/FZZPFUWPNMVe06Q+02O+wsNO0jKe5FS/Xx8V10ZlFXS6GjnhQTD0dVSPmlp+oZHuoVGukR FekNEugGC+siJikuHSk9Md3h3muVqURJPHqAdOcFC+odI+ojKOokKesjKOcLEhk2KihENmJo XW8wLQsoG0hjUfgXGfoNExcnHThGOCg3Kv0HB7IVF0ZLQ/QeI1NGN7IrLf4aHAQKBjVQPZVI V/4kJgACAjlURvQjKJEuKyRoU3FNWDc9M/0dJPwaJ/4kKnQTFhJJNBpGN6lCTwUWFfFaZgYo JM4rMAcRCvqXpylSUPm7wjQ4LOUlKokpHhYpJe9JVukcKU02LYYPEo5qdv3Z6fMhJScpI04V FM0bJ/8UFfY8S7Kn00Y6qzEvo9LF8gAGigAJlFJTkQAbkwAaoxg4OM8VGIaF0AAdlAAcmwIU jFMVbwo2KPvt9v/i2RMek1w4Q7A2Sv8jGVllw9jo9lZew/9JSQojm/OuzZWw12wmZREraDpK QvF4ilBKtAohowkVKv0yMdm+7SQRh1QHU2d30gALoKUXVdM/YD5HGP+hnQAVlUsnjnddtsxn k8+DuiwPDjYsJM4uRTRKr44TULKy57BLhneX3G6kv6vT4hFqkQcZbyZmhzRxlFVnh5nS5i6U xhlFVy8mXnFXcAeKtRiDqw6GrhN3rukVKwMVWEsoHYlNZBiKtip3nCJSasDS3Sp9pRp7pSEA X3u3zkdtjyaDq1IZIy97pyeItDOSuRFTbe5WWht1miNkezGJtA0pNhdPjy2CqzCDrDOKqSlW cRE0RekiKOYVF0eMshOTx4o4SAOVxTQZJBZgffl8hOnS/1NacBmi1I9wiZAYLjwyn2pIPiBQ yLUZKQ9FVGlnhvltEvuQCHSjYO43I//WAP/vAOoMK/ZYGbGcBv/IANilE/+vApCiWeRfJBB6 wjWVn/9AA6hlRGhnbWgdIdePlp2tvgAAACH+ISAgSW1wb3J0ZWQgZnJvbSBHSUYgaW1hZ2U6 IGJnLmdpZgAsAAAAADwAWgDH/////vr6/PT2/unr/dbX/czR/MbJ+7W4+ay1+JWY+ImL9HZ4 9Gl19mdr8Vlk8VRY80xV7TpD7TY77Cw07SMp7kVL9fHxXXRmUVdLoaOeFBMPR1VI+aWn6hke 6hUa6REV6Q0S6AYL6yImKS4dKT0x3eHea5WpREk8eoB05wUL6h0j6iMo6iQp6yMo5wsSGTYq KEQ2YmhdbzAtCygbSGNR+BcZ+g0TFycdOEY4KDcq/QcHshUXRktD9B4jU0Y3sist/hocBAoG NVA9lUhX/iQmAAICOVRG9CMokS4rJGhTcU1YNz0z/R0k/Bon/iQqdBMWEkk0GkY3qUJPBRYV 8VpmBigkziswBxEK+penKVJQ+bvCNDgs5SUqiSkeFikl70lW6RwpTTYthg8Sjmp2/dnp8yEl JykjThUUzRsn/xQV9jxLsqfTRjqrMS+j0sXyAAaKAAmUUlORABuTABqjGDg4zxUYhoXQAB2U ABybAhSMUxVvCjYo++32/+LZEx6TXDhDsDZK/yMZWWXD2Oj2Vl7D/0lJCiOb867NlbDXbCZl EStoOkpC8XiKUEq0CiGjCRUq/TIx2b7tJBGHVAdTZ3fSAAugpRdV0z9gPkcY/6GdABWVSyeO d122zGeTz4O6LA8ONiwkzi5FNEqvjhNQsrLnsEuGd5fcbqS/q9PiEWqRBxlvJmaHNHGUVWeH mdLmLpTGGUVXLyZecVdwB4q1GIOrDoauE3eu6RUrAxVYSygdiU1kGIq2KnecIlJqwNLdKn2l GnulIQBfe7fOR22PJoOrUhkjL3unJ4i0M5K5EVNt7lZaG3WaI2R7MYm0DSk2F0+PLYKrMIOs M4qpKVZxETRF6SIo5hUXR4yyE5PHijhIA5XFNBkkFmB9+XyE6dL/U1pwGaLUj3CJkBguPDKf akg+IFDItRkpD0VUaWeG+W0S+5AIdKNg7jcj/9YA/+8A6gwr9lgZsZwG/8gA2KUT/68CkKJZ 5F8kEHrCNZWf/0ADqGVEaGdtaB0h14+Wna2+AAAACP4AAQAAAAAAAAAAAAQIIECAgAEDCBQw cABBggQKFjBo4OABhAgSJlCgUEEBAQAAAAAAAAAAAAAAAACwcAGDBQAAMmjYkAFChxYrVqxY sWLFihUrVqzwMAFAAQ8rVITAAgAAARUqVqxYsWLFihUrVqxYsaLFkSMrnOwogiOLDyZMNNA4 AQMHDhwnFIBYsWLFihUrVqxYsWKFigkNPKRIAMCFihUrVqxY0cHFAQBu2rx58wZOHCtMjjhx UsTLiQ04NuQoUgSNEycsWHiQIKCABxUsVqxYsWLFihUrVqxYoUJFgAgeVqxQ8WEAoTd37ty5 g2cOICAyfnCBwMQJkhc4Tv4EQePEAxUELkSsWLFCBQgCAAI8+MBixYoVK1asWLFixYoVK6yw wgorrNBBIYLAcccdd9xxxx134KHIIopcAgAVO8DAgxFnOEEBCyussMIKK6ywwgospKAAAAAA gEAKIqywwgorrLDCCiussMIKLYggAgspJADAKXH4McckCVDyxhx4SEKEFVbIEAYJJCxiBA5N HMHCCiussMIKK6ywAgseSAAAAAAAkEAKIqywwgorMGHFMsTwUossOshyTC+wMHMKL80444Us xzQTBC6VPINML0X8IMQLRiyRwxJRdOHECiussMIKK6ywAgsfVAAAAAAIIIEHLKwAhAis0AIN NP68SBNNM6tUsUgTR6zQQQNsaKIHAwDAkQcccRBDTDTRHOMFEkLQAYMMP5CwRA4zoEFECyus sMIKKoBgAAAAFOCBCkykYYUstBADTTOrTFHFDkessMIKK6zQAREFiALHJAeY8oYcbxxSiA66 7BLNMcNwgQMM5DjhhBM7eAEDDieAskQOL4ShRAAWJKBDGmmkkQYQXPDyCzTINJOMDE2AAQ88 7Nyywi3stHMLCx9QoQUIK6wAhjzzlHMMMtQU8cgP8EBCRAtltHDEERpEkQMXTvRwwyI5QOAB C1KIkAYQLZSRxjfHNBNNL8a8csw5VtTQwwossMDCCius0EMaVpyzS/400ESDzCpTTFGME05w scIKK6ywwgorrLDCCiuskEICAFCgQgcegBBCCDro4AIINXQADDHA9NMPML9EY8wvxkATzS+8 8AINL7aEo8AqwPBiiywQPADBBBJIMIEHHnjgAQgffPABCCCAkIIKA1DQwgorrMACCyuswAIL K6ywwgorrLDCCiussMIKK6ywwgorrLDCCiussMIKK6ywwgossLCCCh300IMPPwBCD3oQBCHA YAhAIEIRjHCCBoCAAixYwQpWsIIVrGAFK2DBB74AABV0oAMqAAACUqCCFaxgBStYwQpWIIIP hMADLviACFZwBDDcwAhGCMMRnCCGKZwAA/4wwMASblCEIBRBA2M4wAdEsIIVrGAFK1jBClaw ghWsYAUsCEEC+OACFbBgBStQAQj64IY35OEOd7jDHfDgByfUoQg3EAIJcpADIeAAB0X4wwHU 8AERsGAFK2BBChQAAAFQoAMsWMEKVrCCFaxgBStYwQpWIAIRqKEFK1iBCoBAhjnI4Q53uMMd 7nCHO9xhDnl4RBGuAAMc4GALdDiDEyjAghWsYAUrWMEKVsACD0gAAAAAwAJCwIIVrGAFK1jB ClawghWsYAUrWMEKVrACFYggEHqYwx3wkIhOOEIOd7gDHjThiR984hNbIAEobtCEI7RgBStY wQpWsIIVrGAFKv74AAEAAAAAHCAEK1jBClawghWsYAUtWMEK0qCLXfCiFn9QgCts0Ysg4EIN vthFLzSAB02wAQBfSIMTnOAEISwBBkhgwgpWsIIVrGAFK1jBClgAggUAAAAAAEADQLACJlgB EKEABBfSwAVgEIMXv4gGNJrRjGPswhjLsMUvaEELaEQjGtGIRiqykYY0hOIa2thGGk6AAyOA gglHWMEKVrCCFaxgBR3oAAAAAIAB1KAGUgDENKQhCyvIghjNWIUzkgEIJqxgBR2YAAD60AlH aCIUAfCDJu5whzfYwQTAgEYziHEMbOwiHOLIAQ4WsYRFLOEFMmDCEVawghRwAAAAOP6ADdKQ Bi6g4xesIAY0otELbnDjCGVYwQpWsIIVrGAFYABDD1TAAgBYAg1EYAELyhAIWhAjGsewxS52 wQp0SCEXMICBCJzQAw0YAQYvgAEOtrAFBoCABSIAQhpksYtjQCMa0eAFMl7xjHnAgwLpYAcY bgGPdrADDCwAQTe0EIIVpMEeu2jGMXQxhHrgAxjYYMURRLCCFbTgCC1YwRFW4IQnVEEDGZCA CiiwghWsAAhWoIU2hmEFK9CCGMZohjGiEQ0N9OIXrzgHNY7Bi2QgIxrGiEY0WLGMX/RAB4Cg xSy4cIQVrGAFK1jBClawghWsYAUrYEEIFgCACYAgBCFIQf4KUpCCFIQABB/wgAc60AEVqEAF KlDBClbAghWwgAIrWAEFKMCCFrSgBS0QQQdC4AIJJEAAAAAAAAQwgAEUwAAvgEEMEpAAGcyA BhiQgAhasIIVrGAFK1jBClawghWsYAUiUEEHRLCCFaxABSAAQQdEsIIVrGAFK1jBClawghWs YAUrWMEKVrACJzwBClGQAhCc8IQpGGEDP0ACDDZwggd4oAUrWMEKVrCCFaxgBStYgQo6AAAD pEAFHVABAABQgRS4QAUrWMEKVrCCFaxgBStYwQpWcAQuZMEHTDiCE55wBRrAAAYwMMIJTnAC HGggCEFYAAhYwIIVrGAFK1jBCv5WsIIVdOALCAiBClwwAC2kQAUsWMEKVrCCFXjABQoAAAAA AAAARMADK3DCE4qwBCG8IAwwEMISToCDIBThDGhwAhE8MIAEgGAFK1jBClawghWsYAUrWIEI RKACD4ABAA4AwQpWsIIViCAEDACAHd7wBjnI4Q54wMMJMGAEHvzACUwIAw5OgIMrFAENTmAB C1jAAhaAwAEBOIAHVMCCFaxgBStYwQpWsIIVrGAFIgABGRQQAhasYAUd6EAABPEGOdzhDne4 wxz0EIgjsMAJaAjCFE6wBCNsoQhisAEVAOCAD7BgBSsQQQgOAIABqKADLFjBClawghWsYAUr WMEKVv6gghUcQgUqWMEKQpAARLwBD3e4wx3ugIdE6EEROTjBBnIAg0W8gAdbmIEYnMCCFbBA BSuwAiuwAivQAR4AAAAgABLgASywAiuwAiuwAiuwAiuwAiuwAiuwAiuwAivAAh1QCIjwBndw B3dwB3dwB3dwB3dwB3MwCQQAAHUAAzlwAl6ABk7AAiuwAiuwAiuwAiuwAiwAAlQAAAAAAA3g AiywAiuwAiuwAiuwAiuwAiuwAiuwAiuwAivAAiJABI2gCXdwB3nQBo2QB3eAB4sQBltwAktg BkvAA0tQBU/gBCuwAiuwAiuwAiuwAiuwAiIQAgcAAAAAAAmQAiuwAiuwAv4rsAIrsAIrsAIr sAIrsAIrwAIhwAEMoAOjMAd3kAdqQApvIAd3cAd4UApO0AEUwARIkAU4YAY9cAQrsAIrsAIr sAIrsAIrsAId4AEAAAAAAAAHkAIisAIrsAIrsAIrsAIrsAIiIAKrwAqt0AopkAmukApTMAVy gAZa8AqwEASG4AixkAMwAAMwEAUkgAM4EAUyQAQisAIrsAIrsAIrsAIrwAIgQAUAAAAAAAAJ kAIssAIrsAIrwARWMAzD0ApWkAZAwAvE8Aup0Am+YAu9EATFAAHGcAwa8Ah4AAeEgAzJ8AlO wAQr8AKLgAMvcARHsAIrsAIrsAIrsAIrwAIgoP4MAAAAAAAACxACLLACK7ACLMACTMAFwEAM xgAMvCALtBAN0RAN0RAN0WAMxhANxtAMvDANzIAM0eAFUQAFe5ALuUANMkACOAADaOAE1bAC K7ACK7ACK8ACHTABAAAAABAAD/ABLVAGq0ALxMALtFALQ6ALtBAN0dAMx8ANPAAGRIAFmjAH k9AN3vAGq9AM0gAN0LAL0UAM2JAMO/ADMJADoLAEOQAKTnAEK7ACK7ACK7ACKvABAgAAACAA EuABLMACFNACQNADw0AMxhANzfALy/ADTdACIqACHhAIiTAHwUAFAQAHciAJo+AHyxAN0NAM ODACXWANXRALtfANI/7AAziQBV3ABEewAiuwAiIQAgcAAAAwAB6gBKkwC8cADcYQDcYADdFg DLRADmmwAiuwAivwAYVACm+gCXNgCQPQCHmAB3ngBwRQBr9ADNBwDMMABGkACnvgBblwBD9A AjCwBGYQBTIABk4QAgoAAABwAB+gAizAAivQA0DwC8RgDMbwCr/QAWWwAiuwAiuwAiuwAh4A CZ4wDg3gBm+AB6UACR1QBkDwC8fQDMxADdRADVUQBFPQAaCQAzDwAz8QBVswAmGwATiQA1uQ ANmgDdowC7twDMQADdBgDF7QC8RwBD3AAiuwAiuwAitwC+zQDiwABiGgBYwQAizAAisABv49 8AvHcAyw4A6B0AMi4AQysAdhcARH4ARi8AIkEAZEwARBAANLsAAgsAIrsAIrIAI2oAu70Ayr sArU4Az20A63wAXqAAYscAvs0A63wAIq0AFkEAEewALvoA71YAvG0AzNgAyr4AxBMAVgcAQr sAJH0AIvAAU/cAROIAZVYAYx0AAgUAZDsAvasAvDMAS6QAvG0Ayw8ALMkAyhkAZgQAEsAAa3 8A63wAIroAIigAVgkAahsAvHgAy9UATF0ARN0ARMwAQtwAIrsAIrsAIrsAItsAItQAQ7EAMC AAEdQAEisAIswAJlkAb7gA3HcAzGYAzRQAe9QA2rAA7TkA1WQP4ETAAEVjAEXpAKx9AM0YAM vWAOrbALx0AHQcAPTkABK7ACK7ACK7ACK7ACK7ACK8ACKaAAADABLUABK7ACPfAN2jAMRMAE IpAGUrAL0AANxgAN0AAN0dAMv2AMzRAN0QAN0dAMxiALu0AMv/ALvCACQFAGQFAGK8ACLMAC LLACK7ACK7ACK7ACK8ACIKAMAnAABHAAB8ABCZAAC7AADfAAFSABEtABHeABHuABH/ABIAAC IQACIPABHuABHdABIiACIiACHgACItAABQAAAAAAAAAAAAAAAAAAAAAAI0ACJQAAAmACGnAC KCACIiACKyACIiACLMACLMACLMACFP7AAizAAiLAAizAAiuwAiuwAivAAizAAizAAiuwAiuw AiuwAivAAirwASnQARPgATUAAjbwATYAAjeAAzlgAzqwAy9AAzwgASqwAiuwAiuwAiuwAiuw AiuwAiuwAiuwAiuwAiuwAiuwAizAAiuwAiuwAiuwAiuwAiuwAiuwAiuwAiuwAivAAitwBEiQ BEpwBEdwBEGwBDhwAkzQBEVgBBsQASqwAiuwAiuwAiuwAiuwAiuwAisgAh/AAlSwAiKwAh0A AgyQACzgASuwAiuwAiuwAiuwAiuwAiuwAiuwAiuwAivgBE9QBRsgBFbgBDtwBTjAAzAAAzlw AjzwAB6wAv4rsAIrsAIrsAIrsAIrsAIiEAJaAAAR8AErEAJUAAAAwAEMoAIrsAIrsAIrsAIr sAIrsAIrsAIUwAQ/IAJHcAROUAQzIAQwYAVWQAI4YAQ4cAIncAJb0AAfsAIrsAIrsAIrsAIr sAIrwAIfEAEAQAUgsAIpoAAA8AApoAIrsAIrsAIrsAIrsAIiIAIisAIrsAJO0AVREAU+4ARO cARF4AUncAJCsAEXsAE3EARFUARB0AAgwAIrsAIrsAIrsAIrsAIrwAIfQAVkAAIqEAILAAAT 8AErsAIrsAIrsAIr0AEpUAEHQAYFUAEgIAJHUAZBkAM8YAQ+4ARWQAM4cAInYP4GRVAERXAG aJAGBLAAILACK7ACK7ACK7ACK7ACK7ACKhABCQACHhABAKAGH7ACK7ACK7ACK+ABLnAAABAA a8AGbbAGB5AGInAETnAGQXACQmAEWyAEJ2AGRRAEZ+AETkABHqACA5AAICACK7ACK7ACK7AC K7ACK8ACKjABX9ABLjAACBACK7ACK7ACK6ACIJAAAbAGb/AGciAHcjAHdCAEMnAETOAEdaAB QpADW7ABQVAEaOAER8ACLMACHlABAsABH6ACK7ACK7ACK7ACK7ACK7ACK7ACLPABXwAAYNAB K7ACK7ACHyABAGAHb5AHd3AHd3AHc6AHT7AHOIADMP4QBlYgBBuAAUtQBGIABC3AAizAAizA AimwAABwAB+gAiuwAiuwAiuwAiuwAiuwAiuwAiuQAgagBSnAAiuwAiIAAgsAAHjwBndwB3dw B3gwB4AQCE6ABkXwAjwgBFtgBidwA0XgBHwAABPQASuwAiuwAimQAABQAB2gAiuwAiuwAiuw AiuwAiuwAivAAirwAWRABR/AAivQAiGgAIPwBnlwB3dwB3eAB37gBERABD0gAkSABkGwBFuA ATNwBk5QAxEAABPQASuwAiygAi5gAADQBx6gAiuwAiuwAiuwAiuwAiuwAivAAiqgAmSwAiqw AizwAYXAB3CQB3dwB3dwB/6GoAeBgARQAAUwYAI/0ANhAAMY4AVX4ARHoAIMIAEdsAIrsAIs oAIfwAcAMAAe0AEssAIrsAIrsAIrsAIrsAIrsAIi0AKMoAIisAIi8AEF0AhvcAd3cAd3cAd4 MAeOMAdToAE4cAInsAE4cAJGEARH4AQrsAIrsAIrsAIrsAIs0AEiAAAAIAAS4AEssAIrsAIr sAIrsAIrsAIrsAIrsAIrsAIrwAIdAAmRAAdycAd3cAd3cAd3cAd3cAdzIAmMgAJFYAQbgAMz 8AROsAIrsAIrsAIrsAIrsAIs8AEVAAAAIAAV8AEssAIrsAIrsAIrsAIrsAIrsAIrsAIrsAIr wP4CHlAIlPAGd3AHd3AHd3AHd4AHeDAHlWAJAKAFOsADOEACU3AER7ACK7ACK7ACK7ACK7AC LBACCwAAABAADwACLLACK7ACK7ACK7ACK7ACK7ACK7ACK7ACK8ACHQAJjZAHd3AHdyAHhnAH dzAHioAJOAADJPACeyAES0ACSOAEK7ACK7ACK7ACK7ACK7ACK5ACmQAAAAAACxACLLACK7AC K7ACK7ACK7ACK7ACK7ACK7ACKyACLRAIm4AHd3AHecAJbZAHd4AHeeAFRfACMJADOIADObAH XeAEK7ACK7ACK7ACK7ACK8ACKuACBgAAAAAACpACLLACK7ACK7ACK/6wAiuwAiuwAiuwAiuw AioQASoQCIkwB3gAB6FwCHhwB3eAB5ogChwABEzgBEhgBFuQA0dwBCuwAiuwAiuwAiuwAiuw AirwAQIAAAABAECCFCxWrFixYsWKFStWrFixYsUKFik4AGhgac4cPQ1MvbmDZ06iQECYOOGC BAcPEiqOrFixYsWKFStWrGDRQQQAAAAAHEghYsWKFStWrFixYkWLI0BapEmjgwOqVFc0zBl1 wJQiVXNCIYESBQYMEjmWkPCCxsmKFStWrFixYgULFi4gAAAAAMCBECtWrFixYsWKFStatAAi axatWi4yubIFK4iqWwBewQqCZw4uH7k+ff76dOYEjhddiKxYsWLFihUrVrBgEWIBAAAAACAI sWLFihUrRDABkgZIICCAav36tWqBK2C9ggRTIwyYFw134HBClOoThSNHSOSIAqpJixUrVqxY sWIFCxYhGAAAAABAghQsVqxYsQKIklm0avHiAohljuEllQzWAIaXID5x4JhjNMBljjx4QaaK HZxAYoMctsABBzSOWGGFFVZYYYUVWGABBGUAAAAAABYIgYUVVlhhBRHSkKUWY3ipBRApdmmG F16IgSaaV145pplmssAFD2mQyWILGGAgwYwRRsgBhjCYOGKFFVZYYYUVVmDBAwkAAAAAABZw gQURegACCCB6SP5Dll2iWYWXX6KJBppooImmGWmiiSaaaJppJhpkkvlEhjOs4eIabLKAgQcY kHBihRVWWGGFFVZgoQMPAAAAgAAecKEMFXiZpZZZfvlBB11oiSYaaJrhZRlqpOjkjUomYcSV VKSJJppojhlGBF2wwSYLG5CAgYQcvEDCiRVWWGGFFVZgQYUPBAAAAAEe+KAFIERghZZofuEF GGCgiSYabpLJJo0egOjGjzkm6YaPN+B4hhhooIGGmGaW+eEHGJZ4gQQccPBCBidaWGGFFVZY QYUPBgAAAAEk8ICFFVZIowxWaIEmmmiiiQabaSZgYgUKOoCkkUr0oCKANzTxg4gxjv6Jphlj cMgBhjB+AKIOGEZYwogwnDhihRVWWEEEFwoAAAABjvAAiDSAACINHYagBZpmpqHGDCbKWKGD LxjQYZQ54FADADnyMASPN0SRBppmmCnmD1ZmAUcaHszgYQkcYJCBiSNWWGGFEA4AAIABbBhC m12OOWaXWn4hBhpjjgGGiR5WWEGEEAwYRBRNNEEDgHHeuOOONw4JpxZojGlmF2OkSCOMF7wI I4ctliBhDySccEKEFBIAAIACbKjBClmA2YUYaKKJphloUsmGiRVWWGGFamxAgJI3/JikAEre uAMOTjLRYZhdoNllCB1k2GOPMFhwAhNkkAMS4CAHXvCCDP500A0AAKAAHVDBClrAhDRwgRfQ iAYskkEMJxxhBStYwQpWIIIPQOIQ5QhGJkjxhjw0IgEfSAMgdkEMZKziCiO4gTl2IA4nIGEP QjDDC3KwBBLgAAY3eEEMDvABFYgACEBIQxp4AY1mNGMV56hBGVawghWsYAUrWIEIagAGPVyC D5WQRCBqsIIy1IAYxzBGM5Dxile8Yha62MELohAGJjjhCRvYAg5wsAUcLIEDNhjCMHaxi2Mc oxnRaAYzqOGMHpRhBStYwQpWsAIWpEMdLQCDBwZQiBq0gAUs6IEKfnGMZqxiHYCoBhDSsAMo REEGTHBCD2YghBeY4wc5wMEWEv7wg2/IQhayGAYtfgENaEDjFdgYAhBWcItbgGEFKwADO9px ixWEAAtYCAELVvCOdMDDGMcwhjPi4YQm9KAJLADFD5ywAic8IQpRQIITjhCEHGyhGyBYAQtE wAUg9IAXv2jGKuiQjGk0gR7wgEc7VsCCW7CjHbdYQQcmQIYOqGAF76BHPbARjWaswhlBmMII unCEI6xgBUcowxSygAQnHKEHN8DBFhYAAhasYAU9SIMVfnGMaETjEdO4Rz3acYt3gIEFLLgF O9pxCzCsIAQIYAQIVtADdeDDFsc4hi1s8YpmpMIZPTjCClbQAifgIAxMOIITnjAFM2SgAR8o AxCs0P4KbGBjF8T4RTSa0YxnUAMD6UgHO27BAi6kQx3wWMEKOhCBAnRABUBoxS6asQsZ5EMd +YCHPgABhBasYAUrWMERWtACFhyBC1B4QQmU4QEuzAIYsuACEGxQBmD8ohmr6IUzaLGLUACB AixgAQu4wAIWrEAEKviCE+pAi2NEoxmrCMIUiuGEI4hABCtYwQpWsIIVrGAFK1hBC1pggwMA AAIeEAETyrACFrSgB0DYxzGiEY1mNCMa1EhGMobgBCAwoQxHOAITgFCDISSDFs1oBjF+QYxX 9CIIVSjGEVqwghWsYAUrWMEKVrCCFaxgBSlIAAAioAIWrGAFKxBBGgCxC/5sEKMVwIhGNJrR C1i8YhVTSAU3jOGMXqSCGssgRjOgAQ1enOMHQNAFMbBBDTE4YQUrWMEKVrCCFaxgBStYwQpY EAIGAEACKljBClbQAyC0QhutAAIQ0gCIX0AjGtGIRjSMEY1orIIOvICGMZoRjWgQgxi/+MUv aqGLNACBC7oQQRlWsIIVrGAFK1jBClawghWsgAUgUIYAKNACFrCAAkyQhSyYUAMVdCANrdjF MVaxCl4YIxrRiAY0ohGNaEDDGNBYxSrQoARg/IIXtciGDj7wAQ94wAMd6IAKOqACFahABSoQ gQpEAIIKCIACE6iAMhjQDQVwAAEHIAAB/PGLX0CcwgIWuAY0jMELXvDCGMZgxSmuAQ1e8AIR APCFMXghDV8EIAACEMAABDCAAQxgAAMgAAEIUAADHMAABzhAAAICADs= } label .logo -anchor ne -bd 2 -relief raised \ -image [image create photo -data $fdata] entry .input -relief sunken -border 2 -textvariable input ;#-width 70 frame .output -relief raised -border 2 button .quit -text Quit -command exit button .demo -text Demo -command startAnimation pack .logo -side left -expand 0 -fill both pack .input -side top -expand 1 -fill x -ipadx 1m -ipady 1m pack .output -side top -expand 1 -fill both pack .quit -side left -expand 0 -padx 2m -pady 2m pack .demo -side left -expand 0 -padx 2m -pady 2m foreach {r m t} { 0 rep Input: 1 zip {uuencode Zip:} 2 hex Hex: 3 b64 Base64: 4 md5 {hex'd MD5 Hash:} } { label .output.l$m -anchor w -text $t label .output.x$m -anchor e -text "__" entry .output.$m -relief sunken -border 2 -width 100 -textvariable out$m grid .output.l$m -row $r -column 1 -sticky swen grid .output.x$m -row $r -column 2 -sticky swen grid .output.$m -row $r -column 3 -sticky swen -ipadx 1m -ipady 1m } proc startAnimation {} { global input set input "" animate 300 \ "Hello world, this is a demonstration \ of the Trf extension to tcl, a package for transforming \ data in various ways, as can be seen below" } proc animate {delay text} { global input set first [string range $text 0 0] set text [string range $text 1 end] if {$first == {}} { return } after $delay [list animate $delay $text] append input $first } proc trf {args} { global input outhex outmd5 outb64 outzip outrep # do various transformations on the current input # executed for every change # # convert to HEX # convert into Base64 # compute MD5 message digest (display in HEX) # compress using ZIP (display in UUencoded form) set temp [zip -mode compress -level 9 $input] set mtmp [md5 $input] set outrep $input set outhex [hex -mode encode $input] set outb64 [base64 -mode encode $input] set outmd5 [hex -mode encode $mtmp] set outzip [uuencode -mode encode $temp] set i [string length $outrep] set zi [string length $temp] # count length of real hash and zip, not the encoded forms .output.xrep configure -text $i .output.xhex configure -text [string length $outhex] .output.xb64 configure -text [string length $outb64] .output.xmd5 configure -text [string length $mtmp] .output.xzip configure -text $zi if {$zi < $i} { # indicate real compression in interface .output.xzip configure -bg seagreen .output.xrep configure -bg [.output.xhex cget -bg] } else { .output.xzip configure -bg [.output.xhex cget -bg] .output.xrep configure -bg coral } } proc out {args} { catch {trf $args} msg if {$msg != {}} {puts "error > $msg"} } trace variable input w trf focus .input wm deiconify . trf2.1.4/tools/mmdecode0000744000175000017500000000134211216343142014410 0ustar sergeisergei#!/usr/local/bin/tclsh # demonstration application, decodes the incoming byte stream from base64 package require Trf # line buffer for parcel below. proc join {cmd buffer} { #puts stderr "$cmd [string length buffer] $buffer" switch -- $cmd { create/write { set line "" } delete/write { set line "" } write { regsub -all "\[\n\r\]" $buffer {} buffer return $buffer } flush/write { return "" } clear/write { set line "" } } } fconfigure stdout -translation binary base64 -attach stdout -mode decode transform -attach stdout -command join fcopy stdin stdout close stdout # close is *required* to flush out the internal buffers. # This is not done during a simple exit :-( exit trf2.1.4/tools/md0000744000175000017500000001312111216343142013231 0ustar sergeisergei#!../tclsh # -*- tcl -*- # # md = Message Digest # superset of md5sum, with more message digests. # # options: -b = read files as binary => no effect here # -v = verbose operation, print filenames during check # -c = check mode, read digests and filenames from stdin # -c file = as above, but read information from specified FILE # -a alg = use algorithm ALG to compute or check digests # default is md5. # possibilities: md5, haval, sha, crc, crc-zlib, adler # -z = compress generated listing, decompress read listing # # without -c enter generator mode. interpret all non-option arguments # as filenames and generate digests for them. if there are no files, # generate a digest of stdin. the generated information is written to # stdout. package require Trf if {[info tclversion] < 8.0} { package require -exact Memchan 1.2 } else { package require Memchan } # --- internal library --- --- --- --- --- --- --- --- --- proc usage {args} { global argv0 puts stdout "" puts stdout "\tusage: $argv0 \[-b] \[-v] \[-c \[file]] \[-a alg] \[-z] file..." puts stdout "" puts stdout "\t-h\t\tproduce this help" puts stdout "\t-b\t\tirrelevant, for compatibility only" puts stdout "\t-v\t\tbe more verbose in check mode" puts stdout "\t-z\t\tde/compress read/generated digest file" puts stdout "\t-c\t\tenter check mode, read data from stdin" puts stdout "\t-c file\t\tenter check mode, read data from file" puts stdout "\t-a alg\t\tuse specified algorithm to generate/check digests" puts stdout "" puts stdout "\tallowed algorithms are: md5, haval, sha, crc, crc-zlib, adler, ripemd160, ripemd128" puts stdout "" exit } proc lshift {varnameOfList} { upvar $varnameOfList list if {[llength $list] == 0} {return ""} else { set first [lindex $list 0] set list [lreplace $list 0 0] return $first } } proc handle_command_line {} { global md mode verbose check_src files zip global argc argv while {$argc > 0} { set arg [lshift argv] incr argc -1 switch -glob -- $arg { -h {usage} -b {} -v {set verbose 1} -a { set md [lshift argv] incr argc -1 } -c { if {$argc > 0} { set check_src [lshift argv] incr argc -1 } set mode check } -z {set zip 1} -* {usage} default {lappend files $arg} } } } proc gen-hash {} { global md files zip if {{} == $files} {usage} set out stdout if {$zip} { fconfigure stdout -translation binary catch {fconfigure stdout -encoding binary} zip -attach stdout -mode compress } foreach f $files { set fname $f if {0 != [string compare stdin $f]} {set f [open $f r]} fconfigure $f -translation binary catch {fconfigure $f -encoding binary} hex -attach [set digest [memchan]] -mode encode $md -attach $f -mode write -read-dest $digest -read-type channel read $f close $f #transform remove $digest head unstack $digest seek $digest 0 if {0 == [string compare stdin $f]} { puts $out "[string tolower [read $digest]]" } else { puts $out "[string tolower [read $digest]]\t$fname" } close $digest } close $out } proc check-hash {} { global md verbose check_src zip set files 0 set failed 0 set missing 0 set in_name $check_src if {0 != [string compare stdin $check_src]} { set check_src [open $check_src r] } puts "performing $md check of incoming digests ($in_name)" if {$zip} { fconfigure $check_src -translation binary catch {fconfigure $check_src -encoding binary} zip -attach $check_src -mode compress # on write, aka decompress for read } while {! [eof $check_src]} { set n [gets $check_src line] if {$n < 0} {break} set old_digest [lshift line] set fname [lshift line] incr files set res [catch {set f [open $fname r]} msg] if {$res} { incr missing puts "$fname inaccessible, check skipped: $msg" continue } if {$verbose} {puts -nonewline stdout "checking $fname ... "; flush stdout} fconfigure $f -translation binary catch {fconfigure $f -encoding binary} hex -attach [set digest [memchan]] -mode encode $md -attach $f -mode write -read-dest $digest -read-type channel read $f close $f #transform remove $digest head unstack $digest seek $digest 0 set new_digest [string tolower [read $digest]] close $digest if {0 != [string compare $old_digest $new_digest]} { puts -nonewline stdout "\r " puts stdout "\rcheck failed \[$new_digest -- $old_digest] for $fname" incr failed } elseif {$verbose} { puts -nonewline stdout "\r " puts stdout "\rok: $fname" } flush stdout } close $check_src if {$missing == $files} { puts stdout "all files missing" } elseif {$missing == 1} { puts stdout "missing $missing file out of $files" } elseif {$missing > 0} { puts stdout "missing $missing files out of $files" } if {$failed == $files} { puts stdout "$md check failed for all files" } elseif {$failed == 1} { puts stdout "$md check failed for $failed file out of $files" } elseif {$failed > 0} { puts stdout "$md check failed for $failed files out of $files" } } # --- application --- --- --- --- --- --- --- --- --- # flags: set md md5 set mode gen set verbose 0 set check_src stdin set files "" set zip 0 handle_command_line set res [catch {${mode}-hash} msg] if {$res} {puts stdout $msg} exit 0 trf2.1.4/tools/genStubs.tcl0000744000175000017500000005155111216343142015215 0ustar sergeisergei# 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.1 1999/09/20 21:07:26 aku 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 platformList decl # Check for duplicate declarations, then add the declaration and # bump the lastNum counter if necessary. foreach platform $platformList { 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] foreach platform $platformList { 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] # Always write out the file with LF termination fconfigure $out -translation lf 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 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 "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n" append text "extern ${capName}Stubs *${name}StubsPtr;\n" append text "#ifdef __cplusplus\n}\n#endif\n" emitMacros $name text rewriteFile [file join $outDir ${name}Decls.h] $text return } # genStubs::emitStubs -- # # This function emits the body of the 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" set sep " " foreach sub $hooks($name) { append text $sep "&${sub}Stubs" set sep ",\n " } append text "\n\};\n" } append text "\n${capName}Stubs ${name}Stubs = \{\n" append text " TCL_STUB_MAGIC,\n" if {[info exists hooks($name)]} { append text " &${name}StubHooks,\n" } else { append text " NULL,\n" } forAllStubs $name makeInit 1 text {" NULL, /* $i */\n"} append text "\};\n" return } # genStubs::emitInits -- # # This function emits the body of the 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 # Assuming that dependencies only go one level deep, we need to emit # all of the leaves first to avoid needing forward declarations. set leaves {} set roots {} foreach name [lsort [array names interfaces]] { if {[info exists hooks($name)]} { lappend roots $name } else { lappend leaves $name } } foreach name $leaves { emitInit $name text } foreach name $roots { emitInit $name text } rewriteFile [file join $outDir ${libraryName}StubInit.c] $text } # genStubs::init -- # # 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 trf2.1.4/tools/mdwrap0000744000175000017500000000027711216343142014133 0ustar sergeisergei# -*- tcl -*- package require Memchan ; # should be ok, we are in 'unix' cd .. ; # back to top dir (digests.* is there) source tools/md ; # jump to the regular app trf2.1.4/tools/ldAout.tcl0000644000175000017500000001502711216344361014654 0ustar sergeisergei# ldAout.tcl -- # # This "tclldAout" procedure in this script acts as a replacement # for the "ld" command when linking an object file that will be # loaded dynamically into Tcl or Tk using pseudo-static linking. # # Parameters: # The arguments to the script are the command line options for # an "ld" command. # # Results: # The "ld" command is parsed, and the "-o" option determines the # module name. ".a" and ".o" options are accumulated. # 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.11 96/09/17 09:02:20 # # 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 # and Design Engineering (MADE) Initiative through ARPA contract # F33615-94-C-4400. # # modified 12/19/1996 by Andreas Kupries (andreas_kupries@users.sourceforge.net) /aku/ # to allow usage for arbitrary libraries proc tclLdAout {{cc {}} {shlib_suffix {}} {shlib_cflags none}} { global env global argv if {$cc==""} { set cc $env(CC) } # if only two parameters are supplied there is assumed that the # only shlib_suffix is missing. This parameter is anyway available # as "info sharedlibextension" too, so there is no need to transfer # 3 parameters to the function tclLdAout. For compatibility, this # function now accepts both 2 and 3 parameters. if {$shlib_suffix==""} { set shlib_cflags $env(SHLIB_CFLAGS) } else { if {$shlib_cflags=="none"} { set shlib_cflags $shlib_suffix } } # seenDotO is nonzero if a .o or .a file has been seen set seenDotO 0 # minusO is nonzero if the last command line argument was "-o". set minusO 0 # head has command line arguments up to but not including the first # .o or .a file. tail has the rest of the arguments. set head {} set tail {} # nmCommand is the "nm" command that lists global symbols from the # object files. set nmCommand {|nm -g} # entryProtos is the table of prototypes found in the # module. set entryProtos {} # entryPoints is the table of entries found in the # module. set entryPoints {} # libraries is the list of -L and -l flags to the linker. set libraries {} set libdirs {} # Process command line arguments foreach a $argv { if {!$minusO && [regexp {\.[ao]$} $a]} { set seenDotO 1 lappend nmCommand $a } 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 # /aku/ use ALL globals, not only XX_(Safe)?Init set f [open $nmCommand r] while {[gets $f l] >= 0} { if [regexp {[0-9A-Fa-f]+ T[ ]*([a-zA-Z0-9_]*)} $l trash symbol] { append entryProtos {extern int } $symbol { (); } \n append entryPoints { } \{ { "} $symbol {", } $symbol { } \} , \n } } close $f if {$entryPoints==""} { error "No entry point found in objects" } # Compose a C function that resolves the entry points and # embeds the required libraries in the object code. set C {#include } append C \n append C {char TclLoadLibraries_} $modName { [] =} \n append C { "@LIBS: } $libraries {";} \n append C $entryProtos append C {static struct } \{ \n append C { char * name;} \n append C { int (*value)();} \n append C \} {dictionary [] = } \{ \n append C $entryPoints append C \{ 0, 0 \} \n \} \; \n append C {typedef struct Tcl_Interp Tcl_Interp;} \n append C {typedef int Tcl_PackageInitProc (Tcl_Interp *);} \n append C {Tcl_PackageInitProc *} \n append C TclLoadDictionary_ $modName { (symbol)} \n append C { char * symbol;} \n append C {{ int i; for (i = 0; dictionary [i] . name != 0; ++i) { if (!strcmp (symbol, dictionary [i] . name)) { return dictionary [i].value; } } return 0; }} \n # Write the C module and compile it set cFile tcl$modName.c set f [open $cFile w] puts -nonewline $f $C close $f set ccCommand "$cc -c $shlib_cflags $cFile" puts stderr $ccCommand eval exec $ccCommand # 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 if [catch "exec $ldCommand" msg] { puts stderr $msg } if {$shlib_suffix == ".a"} { exec ranlib $outputFile } # Clean up working files exec /bin/rm $cFile [file rootname $cFile].o } trf2.1.4/tools/findinpath0000744000175000017500000000053511216343142014762 0ustar sergeisergei#!/usr/local/bin/tclsh # -*- tcl -*- # needs no '#!' path # find an application via PATH, like 'which' set app [lindex $argv 0] set path [split $env(PATH) :] foreach p $path { set papp [file join $p $app] if {[file exists $papp]} { puts $papp exit 0 } } # not found -- no error, fixhbline will check for empty name #exit 1 exit 0 trf2.1.4/tools/check_manifest0000744000175000017500000000113511216343142015576 0ustar sergeisergei#!/usr/local/bin/tclsh # -*- tcl -*- # check the manifest against the current contents of the directory set manifest [lindex $argv 0] rename file ori_file proc file {name} { global files set files($name) 1 if {! [ori_file exists $name]} { puts stdout "missing: $name" } } # read manifest and check existence of all listed files source $manifest # now backwards: find all files and check # for files not listed in the manifest set list [exec find . -print] regsub -all "\n" $list { } list foreach f $list { if {[catch {set files($f)}]} { puts stdout "new: $f" } } trf2.1.4/tools/mkinstalldirs0000744000175000017500000000121111216343142015506 0ustar sergeisergei#!/bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Last modified: 1994-03-25 # Public domain errstatus=0 for file in ${1+"$@"} ; do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d in ${1+"$@"} ; do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || errstatus=$? fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here trf2.1.4/app/0000755000175000017500000000000011216344734012337 5ustar sergeisergeitrf2.1.4/app/tclAppInit.c0000644000175000017500000000600411216344361014546 0ustar sergeisergei/* * tclAppInit.c -- * * Provides a default version of the main program and Tcl_AppInit * procedure for Tcl applications (with Tcl-Trf). * * Copyright (c) 1993 The Regents of the University of California. * Copyright (c) 1994-1995 Sun Microsystems, Inc. * Modified Oct 1996-1997 Andreas Kupries (andreas_kupries@users.sourceforge.net) * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ static char cvs_id[] = "$Id: tclAppInit.c,v 1.1.1.1 1997/02/05 20:51:00 aku Exp $"; #include "tcl.h" #include "transform.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; /* *---------------------------------------------------------------------- * * main -- * * This is the main program for the application. * * Results: * None: Tcl_Main never returns here, so this procedure never * returns either. * * Side effects: * Whatever the application does. * *---------------------------------------------------------------------- */ int main(argc, argv) int argc; /* Number of command-line arguments. */ char **argv; /* Values of command-line arguments. */ { Tcl_Main(argc, argv, Tcl_AppInit); /* Needed only to prevent compiler warning. */ return 0; } /* *---------------------------------------------------------------------- * * 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. * *---------------------------------------------------------------------- */ int Tcl_AppInit(interp) Tcl_Interp *interp; /* Interpreter for application. */ { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Call the init procedures for included packages. Each call should * look like this: * * if (Mod_Init(interp) == TCL_ERROR) { * return TCL_ERROR; * } * * where "Mod" is the name of the module. */ if (TCL_OK != Trf_Init (interp)) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Trf", Trf_Init, Trf_SafeInit); /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ /* * Specify a user-specific startup file to invoke if the application * is run interactively. Typically the startup file is "~/.apprc" * where "app" is the name of the application. If this line is deleted * then no user-specific startup file will be run under any conditions. */ Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); return TCL_OK; } trf2.1.4/DESCRIPTION0000644000175000017500000000404311216343142013256 0ustar sergeisergei# -*- tcl -*- extension trf { description { A loadable extension to Tcl providing commands for data conversion, message digests, zlib based compression, error-correction, channel-based manipulation of binary data. Trf extends the language at the C-level with so-called ``transformer''-procedures. With the help of some patches (*) to the core the package is able to intercept all read/write operations on designated channels, thus giving it the ability to transform the buffer contents as desired. This allows things like transparent encryption, compression, charset recoding, etc. Build upon this framework (and as proof of concept) a collection of tcl-level commands was implemented. Additionally some binary data support is put in as well. A separate package containing encryption transformation is available at the same site carrying this package. (*) The patches are only necessary for Tcl 8.0.x and 8.1.x. Since Tcl 8.2 the Trf patch is an official part of the core. } keywords { tcl, conversion, message digests, data compression, error-correction, binary io, crc, md2, md5, sha, sha-1, haval, adler, ripemd-160, dual, hexadecimal, octal, uuencode, base64, ascii85, reed-solomon, zlib, otp_md5, otp_sha1, otp_words } author {Andreas Kupries (andreas_kupries@users.sourceforge.net)} maintenance {Andreas Kupries (andreas_kupries@users.sourceforge.net)} version 2.1.4 copying-policy {BSD-Style, see 'tcl'-license} date {MAY-06-2009} primary-urls { http://tcltrf.sourceforge.net/ } development-platform {Linux 2.0.29, gcc 2.7.2.3} platforms { Linux 2.0.29 (gcc 2.7.2.3) Development system IRIX 6.2 (cc only) ULTRIX 4.1 (both cc and gcc) ULTRIX 4.4 (cc 3.0) HP-UX-9 (both cc and gcc) HP-UX-10.2 Solaris 2.5 (gcc only) Other machines and OS's should work too. } dependencies { tcl 8.0 or higher, plus-patches as of Dec 5, 1996 or later (optional), memchan 1.0 or higher (required by testsuite), zlib-1.0.4 or higher (optional, 1.2.4 is current), } } trf2.1.4/ChangeLog.short0000644000175000017500000002044511216343142014464 0ustar sergeisergeiChanges from 2.1p1 to 2.1.3 * Corrected inconsistency BUILD_Trf / BUILD_trf. Changes from 2.1 to 2.1p1 * Fixes in some tools used during installation (findinpath, fixhbline). * [zip] is now able to handle additional data behind the compressed stream. By not reading it. No infinite loop for that case anymore. This also means that a pure-tcl version of gzip should be possible. Any takers ? * Merged patch from Dave Bodenstab to make the error messages better. * Uptodate binaries for Windows, via crosscompiling mingw gcc. Changes from 2.0p7 to 2.1 * Adapted to the rewrite of the stacked channel functionality in 8.3.2. A single binary should now support all stubbed cores (8.1 upward) by switching its behaviour at runtime. Some voodoo is used to make sure that it is not relevant which version of the core was used to create that all-purpose binary. Only the 8.0.x series requires a separate binary because it is not stubbed. Changes from 2.0p6 to 2.0p7 * Bugfixes for - usage of wrong strings in the script 'transform'. - wrong variable in makefile - a buffer overun in the quoted-printable encoding. - static library support. * Patch from Jan Nijtmans for usage of TEA build chain with mingw32. * Added a link to the TclAH extension (Authentication Hashes) to the documentation. Changes from 2.0p5 to 2.0p6 * Bugfixes - in the TEA configure related to md5-crypt (Sigh). - A memory leak. * Better/more support for building Trf as static library. Changes from 2.0p4 to 2.0p5 * Bugfix in the TEA configure related to md5-crypt. Changes from 2.0p3 to 2.0p4 * Bugfix in the TEA makefile. Changes from 2.0 to 2.0p3 * Fixed several small bugs. * Fixed some annoying bugs related to the changes made to MD5. Changes from 1.8 to 2.0 * Dropped support for Tcl 7.6. * Added support for TEA compliant building of this extension, see the subdirectory 'tea'. This requires at least Tcl/Tk 8.2. The old built facilities (unix, win) still exist and are still usable. Nevertheless TEA is the prefered way for Unix and Windows. * Added stubs, i.e. Trf now exports its own stub table. Thanks to Jan Nijtmans for providing the basic changes to get me started. * Revamped the way Trf is handling seek requests for transforms. **BEHAVIOURAL INCOMPATIBILITY** **BINARY INCOMPATIBILITY** (Trf_TypeDefinition's extended) See doc/html/trf_seek.html * Added vector for querying the max number of bytes to read. **BINARY INCOMPATIBILITY** (Trf_TypeDefinition's extended) * Squashed the bug in the 'bzip' (de)compressor. Squashed other bugs reported by Matt Newman * Added compile time options to link zlib / bzlib statically. --enable-static-zlib, -DZLIB_STATIC_BUILD --enable-static-bzlib, -DBZLIB_STATIC_BUILD * MD5 functionality is now loaded on demand. The source of the necessary shared library is part of the distribution and compiled if required (glibc2 Linux systems already have it). * New commands: md5crypt, crypt, use in password authentication. New option: -nowrap for 'zip' transformation. See documentation. * 'transform': Added operations 'query/maxRead' and 'query/ratio'. Changes from 1.7 to 1.8 * Marshall Rose made the 'base64' encoding MIME compliant and additionally donated his 'quoted-printable' converter. * Jan Nijtmans donated the 'bzip2' (de)compressor transform. It is unfortunately not yet complete, the decompressor is not working. * Rewrote the base code to handle the inclusion of the patch into the Tcl core (since 8.2) and the associated changes to the semantics of some of the functions. It now especially automagically distinguishes between unpatched 8.0, patched 8.0, unpatched 8.1, patched 8.1, 8.2 and beyond, and adapts itself accordingly, either at compile time (8.0.x) or runtime (8.1 and beyond). Changes from 1.6 to 1.7 * Headers now usable with a C++ compiler. * Marshall Rose donated code to implement the otp variants of md5 and sha1, according to RFC 2289. * The option processor now understands '--', it will stop the treatment of the following arguments as options. Again from Marshall Rose. * The patchkit for Tcl 8.1 is usable for Tcl 8.1.1 too. No new patchkit was made. * Made **thread-safe** if compiled against a thread-enabled 8.1. (Mutex used to serialize access to all written global variables) Changes from 1.6 to 1.6 * Added the patch kit for tcl 8.1 final Changes from 1.5 to 1.6 * The following information is valid only if Trf is used in conjunction with a 8.1 interpreter, as that is currently the only one implementing stubs. It is known that trf requires a patch to the core for full functionality (stacked channels). The core had to be patched to allow compilation of Trf, and its execution. Taking advantage of the new stub-mechanism Trf is now able to check for the existence of its patches at runtime. If loaded by an unpatched interpreter it will disable the features relying on the patch (-attach option of transforms, unstack), but run unimpeded otherwise. Due to some magic with #define and #ifdef it is now even possible to compile Trf against unpatched core without causing harm, the resulting library will have the complete functionality. Changes from 1.4 to 1.5 * Better handling of 'fileevent' and blocking-mode for transforms. Initial patch by Matt Newman (). * Fixed a nasty problem with my patch to the tcl core. Caused a crash if one tried to attach a transform to a new socket inside its accept script. Reason: Unwanted interaction between my handling of the refCount for the channel and tcl itself. Found by Matt Newman. Reworked all patchkits, except for 8.0[ab]*. Changes from 1.3 to 1.4 * Upgraded core patches for 8.1b2 and 8.0.4/5. * Added detection and usage of stubs. Changes from 1.2 to 1.3 * *No* functional changes. * Fixed several char / unsigned char mismatches and other nits reported by Larry Virden and his UltraSparc compiler. * Added technical explanation of the inner workings to the documentation, + images. * Upgraded core patches for 8.1b1 * Extended configure with options for the explicit definition of the location of the zlib and crypto libraries. Added intelligence to all pairs of location-options to derive their values from each other if only one of them is specified. Suggested by Larry Virden . * Added windows binary distribution. Changes from 1.1 to 1.2 * Moved all encryption aware code and definitions into a separate package, TrfCrypt. This allows the inclusion of the base package into the consortium CD ROM (and the upload to Neosoft). Changes from 1.0 to 1.1 * Adapted to C-API changes between 8.0 and 8.1 Added patches for Tcl 8.1a2 * Compiles now with Tcl 7.6, 8.0 and 8.1a2 * binio is more reclusive, it and its support (byteorder patch) will be removed in the next release. Please use the official 'binary' command of Tcl 8.x instead. Changes from b3 to final: * **** WARNING to all users of earlier versions **** The script API was rewritten to take advantage of the Tcl 8.x object API. The ability to operate on channels was retained, albeit under a different syntax. Please reread the manual, at least chapter 5 (Available commands). *a Extended C-level API allows for (block)cipher specific option processing. * A general transformation was added, under the name 'transform'. It reflects the underlying functionality up into the script level. * Added ciphers: <> ROT, for the fun of it. <> SAFER, by the author of IDEA. (uses *a) Changes from b2 to b3: * 'binio' command supported, but not included by default, because of equivalent functionality in 8.0b1, see 'binary' and 'fcopy'. Configure option '--enable-binio'. * Reorganized code into generic and os dependent parts. * Added Windows port. * Some bug fixes. * More algorithms: RC2, MD2, SHA-1 (SSLeay required) RIPEMD-160 * Commands created use the object-interface of tcl8.0b1 now. Runs with 7.6 nevertheless, BUT NOT with 8.0a1 or a2. Changes from b1 to b2: * The patches to the core are enhanced to associate channels with byteorder information. * A new command 'binio' to pack and/or unpack binary information and to copy between channels (the latter is essentially 'unsupported0'). (Un)packing will reorder bytes as needed, using the information mentioned above. trf2.1.4/test.setup.in0000644000175000017500000000157211216343142014222 0ustar sergeisergei# -*- tcl -*- # Script to load the commands to test, and the necessary prerequisites. package require Memchan proc read_file {file} { set fd [open $file] fconfigure $fd -translation binary set data [read $fd] close $fd return $data } proc write_file {file data} { set fd [open $file w] fconfigure $fd -translation binary puts -nonewline $fd $data close $fd } proc read_zip {file} { set fd [open $file] fconfigure $fd -translation binary zip -attach $fd -mode compress fconfigure $fd -translation binary set data [read $fd] close $fd return $data } proc write_zip {file data} { set fd [open $file w] fconfigure $fd -translation binary zip -attach $fd -mode compress fconfigure $fd -translation binary puts -nonewline $fd $data close $fd } # -- and the commands to test -- load ./@PKG_LIB_FILE@ trf2.1.4/configure0000755000175000017500000146042511216343144013474 0ustar sergeisergei#! /bin/sh # From configure.in Id: configure.in. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for Trf 2.1.4. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='Trf' PACKAGE_TARNAME='trf' PACKAGE_VERSION='2.1.4' PACKAGE_STRING='Trf 2.1.4' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias CYGPATH EXEEXT PKG_LIB_FILE PKG_STUB_LIB_FILE PKG_STUB_SOURCES PKG_STUB_OBJECTS PKG_TCL_SOURCES PKG_HEADERS PKG_INCLUDES PKG_LIBS PKG_CFLAGS TCL_VERSION TCL_BIN_DIR TCL_SRC_DIR TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_LIBS TCL_DEFS TCL_EXTRA_CFLAGS TCL_LD_FLAGS TCL_SHLIB_LD_LIBS zlibtcl_VERSION zlibtcl_BIN_DIR zlibtcl_SRC_DIR zlibtcl_LIB_FILE zlibtcl_LIB_SPEC zlibtcl_STUB_LIB_FILE zlibtcl_STUB_LIB_SPEC zlibtcl_STUB_LIB_PATH zlibtcl_SRC_PATH zlibtcl_BUILD_PATH CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE RANLIB GREP EGREP MATH_LIBS PKG_SOURCES PKG_OBJECTS SHLIB_SUFFIX TCL_INCLUDES TCL_TOP_DIR_NATIVE CLEANFILES TCL_THREADS SHARED_BUILD AR CELIB_DIR LIBOBJS DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS LD_LIBRARY_PATH_VAR CFLAGS_DEFAULT LDFLAGS_DEFAULT TCL_DBGX MAKE_LIB MAKE_SHARED_LIB MAKE_STATIC_LIB MAKE_STUB_LIB RANLIB_STUB TCLSH_PROG ZLIB_INCLUDE_DIR ZLIB_LIB_DIR SSL_INCLUDE_DIR SSL_LIB_DIR BZ2_INCLUDE_DIR BZ2_LIB_DIR TRF_TESTS MD5_LIB_FILE LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Trf 2.1.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/trf] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Trf 2.1.4:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-threads build with threads --enable-shared build and link with shared libraries (default: on) --enable-64bit enable 64bit support (default: off) --enable-64bit-vis enable 64bit Sparc VIS support (default: off) --disable-rpath disable rpath support (default: on) --enable-wince enable Win/CE support (where applicable) --enable-load allow dynamic loading and "load" command (default: on) --enable-symbols build with debugging symbols (default: off) --enable-static-zlib link 'zlib' statically --enable-static-bzlib link 'bzlib' statically --enable-static-md5 link 'md5' statically --enable-trf-debug enable debugging output --enable-stream-debug enable debugging of IO streams Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tcl directory containing tcl configuration (tclConfig.sh) --with-zlibtcl directory containing zlibtcl configuration (zlibtclConfig.sh) --with-tclinclude directory containing the public Tcl header files --with-celib=DIR use Windows/CE support library from DIR --with-zlib=DIR zlib.h resides in DIR/include, libz resides in DIR/lib --with-zlib-include-dir=DIR zlib.h resides in DIR --with-zlib-lib-dir=DIR libz resides in DIR --with-ssl=DIR md2.h/sha1.h reside in DIR/include, libcrypto resides in DIR/lib --with-ssl-include-dir=DIR md2.h/sha1.h reside in DIR --with-ssl-lib-dir=DIR libcrypto resides in DIR --with-bz2=DIR bzlib.h resides in DIR/include, libbz2 resides in DIR/lib --with-bz2-include-dir=DIR bzlib.h resides in DIR --with-bz2-lib-dir=DIR libbz2 resides in DIR Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Trf configure 2.1.4 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Trf $as_me 2.1.4, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # TEA extensions pass this us the version of TEA they think they # are compatible with. TEA_VERSION="3.7" { echo "$as_me:$LINENO: checking for correct TEA configuration" >&5 echo $ECHO_N "checking for correct TEA configuration... $ECHO_C" >&6; } if test x"${PACKAGE_NAME}" = x ; then { { echo "$as_me:$LINENO: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&5 echo "$as_me: error: The PACKAGE_NAME variable must be defined by your TEA configure.in" >&2;} { (exit 1); exit 1; }; } fi if test x"3.7" = x ; then { { echo "$as_me:$LINENO: error: TEA version not specified." >&5 echo "$as_me: error: TEA version not specified." >&2;} { (exit 1); exit 1; }; } elif test "3.7" != "${TEA_VERSION}" ; then { echo "$as_me:$LINENO: result: warning: requested TEA version \"3.7\", have \"${TEA_VERSION}\"" >&5 echo "${ECHO_T}warning: requested TEA version \"3.7\", have \"${TEA_VERSION}\"" >&6; } else { echo "$as_me:$LINENO: result: ok (TEA ${TEA_VERSION})" >&5 echo "${ECHO_T}ok (TEA ${TEA_VERSION})" >&6; } fi case "`uname -s`" in *win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*) # Extract the first word of "cygpath", so it can be a program name with args. set dummy cygpath; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CYGPATH+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CYGPATH"; then ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CYGPATH="cygpath -w" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" fi fi CYGPATH=$ac_cv_prog_CYGPATH if test -n "$CYGPATH"; then { echo "$as_me:$LINENO: result: $CYGPATH" >&5 echo "${ECHO_T}$CYGPATH" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) CYGPATH=echo EXEEXT="" TEA_PLATFORM="unix" ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi # This package name must be replaced statically for AC_SUBST to work # Substitute STUB_LIB_FILE in case package creates a stub library too. # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... ac_aux_dir= for ac_dir in tclconfig "$srcdir"/tclconfig; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in tclconfig \"$srcdir\"/tclconfig" >&5 echo "$as_me: error: cannot find install-sh or install.sh in tclconfig \"$srcdir\"/tclconfig" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. #-------------------------------------------------------------------- # Configure script for package 'trf', as distributed at November 20, 2001. # TEA compliant. #-------------------------------------------------------------------- #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tcl was given. if test "${with_tcl+set}" = set; then withval=$with_tcl; with_tclconfig=${withval} fi { echo "$as_me:$LINENO: checking for Tcl configuration" >&5 echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6; } if test "${ac_cv_c_tclconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case ${with_tclconfig} in */tclConfig.sh ) if test -f ${with_tclconfig}; then { echo "$as_me:$LINENO: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'` fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 echo "$as_me: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" { { echo "$as_me:$LINENO: error: Can't find Tcl configuration definitions" >&5 echo "$as_me: error: Can't find Tcl configuration definitions" >&2;} { (exit 1); exit 1; }; } else no_tcl= TCL_BIN_DIR=${ac_cv_c_tclconfig} { echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5 echo "${ECHO_T}found ${TCL_BIN_DIR}/tclConfig.sh" >&6; } fi fi { echo "$as_me:$LINENO: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5 echo $ECHO_N "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... $ECHO_C" >&6; } if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then { echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6; } . "${TCL_BIN_DIR}/tclConfig.sh" else { echo "$as_me:$LINENO: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5 echo "${ECHO_T}could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; } fi # eval is required to do the TCL_DBGX substitution eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TCL_BIN_DIR}/Makefile" ; then TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} elif test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tcl.framework installed in an arbitary location. case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then for i in "`cd ${TCL_BIN_DIR}; pwd`" \ "`cd ${TCL_BIN_DIR}/../..; pwd`"; do if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}" break fi done fi if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}" TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" fi ;; esac fi # eval is required to do the TCL_DBGX substitution eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" # TEA specific: # # Ok, lets find the zlibtcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-zlibtcl # if test x"${no_zlibtcl}" = x ; then # we reset no_zlibtcl in case something fails here no_zlibtcl=true # Check whether --with-zlibtcl was given. if test "${with_zlibtcl+set}" = set; then withval=$with_zlibtcl; with_zlibtclconfig=${withval} fi { echo "$as_me:$LINENO: checking for zlibtcl configuration" >&5 echo $ECHO_N "checking for zlibtcl configuration... $ECHO_C" >&6; } if test "${ac_cv_c_zlibtclconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-zlibtcl was specified. if test x"${with_zlibtclconfig}" != x ; then if test -f "${with_zlibtclconfig}/zlibtclConfig.sh" ; then ac_cv_c_zlibtclconfig=`(cd ${with_zlibtclconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_zlibtclconfig} directory doesn't contain zlibtclConfig.sh" >&5 echo "$as_me: error: ${with_zlibtclconfig} directory doesn't contain zlibtclConfig.sh" >&2;} { (exit 1); exit 1; }; } fi fi # then check for a private zlibtcl installation if test x"${ac_cv_c_zlibtclconfig}" = x ; then for i in \ ../zlibtcl \ `ls -dr ../zlibtcl[8-9].[0-9]* 2>/dev/null` \ ../../zlibtcl \ `ls -dr ../../zlibtcl[8-9].[0-9]* 2>/dev/null` \ ../../../zlibtcl \ `ls -dr ../../../zlibtcl[8-9].[0-9]* 2>/dev/null` \ ${srcdir}/../zlibtcl \ `ls -dr ${srcdir}/../zlibtcl[8-9].[0-9]* 2>/dev/null` \ ; do if test -f "$i/zlibtclConfig.sh" ; then ac_cv_c_zlibtclconfig=`(cd $i; pwd)` break fi if test -f "$i/unix/zlibtclConfig.sh" ; then ac_cv_c_zlibtclconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_zlibtclconfig}" = x ; then for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ ; do if test -f "$i/zlibtclConfig.sh" ; then ac_cv_c_zlibtclconfig=`(cd $i; pwd)` break fi done fi fi if test x"${ac_cv_c_zlibtclconfig}" = x ; then zlibtcl_BIN_DIR="# no zlibtcl configs found" { echo "$as_me:$LINENO: WARNING: \"Cannot find zlibtcl configuration definitions\"" >&5 echo "$as_me: WARNING: \"Cannot find zlibtcl configuration definitions\"" >&2;} if test "Xoptional" != "Xoptional" ; then exit 0 fi HAVE_zlibtcl_PACKAGE=0 else no_zlibtcl= zlibtcl_BIN_DIR=${ac_cv_c_zlibtclconfig} { echo "$as_me:$LINENO: result: found $zlibtcl_BIN_DIR/zlibtclConfig.sh" >&5 echo "${ECHO_T}found $zlibtcl_BIN_DIR/zlibtclConfig.sh" >&6; } HAVE_zlibtcl_PACKAGE=1 cat >>confdefs.h <<\_ACEOF #define HAVE_zlibtcl_PACKAGE 1 _ACEOF fi fi if test $HAVE_zlibtcl_PACKAGE -gt 0 ; then { echo "$as_me:$LINENO: checking for existence of ${zlibtcl_BIN_DIR}/zlibtclConfig.sh" >&5 echo $ECHO_N "checking for existence of ${zlibtcl_BIN_DIR}/zlibtclConfig.sh... $ECHO_C" >&6; } if test -f "${zlibtcl_BIN_DIR}/zlibtclConfig.sh" ; then { echo "$as_me:$LINENO: result: loading" >&5 echo "${ECHO_T}loading" >&6; } . "${zlibtcl_BIN_DIR}/zlibtclConfig.sh" else { echo "$as_me:$LINENO: result: file not found" >&5 echo "${ECHO_T}file not found" >&6; } fi # # If the zlibtcl_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable zlibtcl_LIB_SPEC will be set to the value # of zlibtcl_BUILD_LIB_SPEC. An extension should make use of zlibtcl_LIB_SPEC # instead of zlibtcl_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f "${zlibtcl_BIN_DIR}/Makefile" ; then { echo "$as_me:$LINENO: WARNING: Found Makefile - using build library specs for zlibtcl" >&5 echo "$as_me: WARNING: Found Makefile - using build library specs for zlibtcl" >&2;} zlibtcl_LIB_SPEC=${zlibtcl_BUILD_LIB_SPEC} zlibtcl_STUB_LIB_SPEC=${zlibtcl_BUILD_STUB_LIB_SPEC} zlibtcl_STUB_LIB_PATH=${zlibtcl_BUILD_STUB_LIB_PATH} fi #-------------------------------------------------------------------- # Compute an absolute path to the src directory of 'zlibtcl'. We # need the special 'zlib.h' header which routes through # 'zlibtcl.h' to splice the stub definitions into the unchanged # sources of png. #-------------------------------------------------------------------- case $zlibtcl_SRC_DIR in /*) zlibtcl_SRC_PATH=$zlibtcl_SRC_DIR ;; *) # SRC_DIR relative, splice with BUILD_PATH zlibtcl_SRC_PATH="`dirname $zlibtcl_BUILD_STUB_LIB_PATH`/$zlibtcl_SRC_DIR" esac zlibtcl_BUILD_PATH="`dirname $zlibtcl_BUILD_STUB_LIB_PATH`" if test "${TEA_PLATFORM}" = "windows" ; then zlibtcl_SRC_PATH="`$CYGPATH $zlibtcl_SRC_PATH`" zlibtcl_BUILD_PATH="`$CYGPATH $zlibtcl_BUILD_PATH`" fi fi #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then { echo "$as_me:$LINENO: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5 echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;} prefix=${TCL_PREFIX} else { echo "$as_me:$LINENO: --prefix defaulting to /usr/local" >&5 echo "$as_me: --prefix defaulting to /usr/local" >&6;} prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then if test x"${TCL_EXEC_PREFIX}" != x; then { echo "$as_me:$LINENO: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5 echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;} exec_prefix=${TCL_EXEC_PREFIX} else { echo "$as_me:$LINENO: --exec-prefix defaulting to ${prefix}" >&5 echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;} exec_prefix=$prefix fi fi #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create # the basic setup necessary to compile executables. #----------------------------------------------------------------------- # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. # If the user did not set CFLAGS, set it now to keep # the AC_PROG_CC macro from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { echo "$as_me:$LINENO: result: $RANLIB" >&5 echo "${ECHO_T}$RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 echo "${ECHO_T}$ac_ct_RANLIB" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. #------------------------------------------------------------------------ # 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" -a -n "$GCC"; then { echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5 echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6; } if test "${tcl_cv_cc_pipe+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_cc_pipe=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_cc_pipe=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS=$hold_cflags fi { echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5 echo "${ECHO_T}$tcl_cv_cc_pipe" >&6; } if test $tcl_cv_cc_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac if test "${TEA_PLATFORM}" = "unix" ; then #-------------------------------------------------------------------- # 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"). #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for sin" >&5 echo $ECHO_N "checking for sin... $ECHO_C" >&6; } if test "${ac_cv_func_sin+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define sin to an innocuous variant, in case declares sin. For example, HP-UX 11i declares gettimeofday. */ #define sin innocuous_sin /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sin (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef sin /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sin (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_sin || defined __stub___sin choke me #endif int main () { return sin (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_sin=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_sin=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 echo "${ECHO_T}$ac_cv_func_sin" >&6; } if test $ac_cv_func_sin = yes; then MATH_LIBS="" else MATH_LIBS="-lm" fi { echo "$as_me:$LINENO: checking for main in -lieee" >&5 echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6; } if test "${ac_cv_lib_ieee_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lieee $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_ieee_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ieee_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5 echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6; } if test $ac_cv_lib_ieee_main = yes; then MATH_LIBS="-lieee $MATH_LIBS" fi #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for main in -linet" >&5 echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6; } if test "${ac_cv_lib_inet_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_inet_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_inet_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 echo "${ECHO_T}$ac_cv_lib_inet_main" >&6; } if test $ac_cv_lib_inet_main = yes; then LIBS="$LIBS -linet" fi if test "${ac_cv_header_net_errno_h+set}" = set; then { echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6; } if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking net/errno.h usability" >&5 echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking net/errno.h presence" >&5 echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for net/errno.h" >&5 echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6; } if test "${ac_cv_header_net_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_net_errno_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6; } fi if test $ac_cv_header_net_errno_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_NET_ERRNO_H 1 _ACEOF fi #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 { echo "$as_me:$LINENO: checking for connect" >&5 echo $ECHO_N "checking for connect... $ECHO_C" >&6; } if test "${ac_cv_func_connect+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define connect to an innocuous variant, in case declares connect. For example, HP-UX 11i declares gettimeofday. */ #define connect innocuous_connect /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef connect /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char connect (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_connect || defined __stub___connect choke me #endif int main () { return connect (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_connect=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_connect=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 echo "${ECHO_T}$ac_cv_func_connect" >&6; } if test $ac_cv_func_connect = yes; then tcl_checkSocket=0 else tcl_checkSocket=1 fi if test "$tcl_checkSocket" = 1; then { echo "$as_me:$LINENO: checking for setsockopt" >&5 echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6; } if test "${ac_cv_func_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define setsockopt to an innocuous variant, in case declares setsockopt. For example, HP-UX 11i declares gettimeofday. */ #define setsockopt innocuous_setsockopt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char setsockopt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef setsockopt /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setsockopt (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_setsockopt || defined __stub___setsockopt choke me #endif int main () { return setsockopt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_setsockopt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 echo "${ECHO_T}$ac_cv_func_setsockopt" >&6; } if test $ac_cv_func_setsockopt = yes; then : else { echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6; } if test "${ac_cv_lib_socket_setsockopt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setsockopt (); int main () { return setsockopt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_socket_setsockopt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_setsockopt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6; } if test $ac_cv_lib_socket_setsockopt = yes; then LIBS="$LIBS -lsocket" else tcl_checkBoth=1 fi fi fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" { echo "$as_me:$LINENO: checking for accept" >&5 echo $ECHO_N "checking for accept... $ECHO_C" >&6; } if test "${ac_cv_func_accept+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define accept to an innocuous variant, in case declares accept. For example, HP-UX 11i declares gettimeofday. */ #define accept innocuous_accept /* System header to define __stub macros and hopefully few prototypes, which can conflict with char accept (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef accept /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char accept (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_accept || defined __stub___accept choke me #endif int main () { return accept (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_accept=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_accept=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5 echo "${ECHO_T}$ac_cv_func_accept" >&6; } if test $ac_cv_func_accept = yes; then tcl_checkNsl=0 else LIBS=$tk_oldLibs fi fi { echo "$as_me:$LINENO: checking for gethostbyname" >&5 echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6; } if test "${ac_cv_func_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define gethostbyname to an innocuous variant, in case declares gethostbyname. For example, HP-UX 11i declares gettimeofday. */ #define gethostbyname innocuous_gethostbyname /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef gethostbyname /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_gethostbyname || defined __stub___gethostbyname choke me #endif int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6; } if test $ac_cv_func_gethostbyname = yes; then : else { echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6; } if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6; } if test $ac_cv_lib_nsl_gethostbyname = yes; then LIBS="$LIBS -lnsl" fi fi # TEA specific: Don't perform the eval of the libraries here because # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' { echo "$as_me:$LINENO: checking dirent.h" >&5 echo $ECHO_N "checking dirent.h... $ECHO_C" >&6; } if test "${tcl_cv_dirent_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_dirent_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_dirent_h=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5 echo "${ECHO_T}$tcl_cv_dirent_h" >&6; } if test $tcl_cv_dirent_h = no; then cat >>confdefs.h <<\_ACEOF #define NO_DIRENT_H 1 _ACEOF fi # TEA specific: if test "${ac_cv_header_errno_h+set}" = set; then { echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6; } if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking errno.h usability" >&5 echo $ECHO_N "checking errno.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking errno.h presence" >&5 echo $ECHO_N "checking errno.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: errno.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: errno.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: errno.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: errno.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: errno.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: errno.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: errno.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: errno.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for errno.h" >&5 echo $ECHO_N "checking for errno.h... $ECHO_C" >&6; } if test "${ac_cv_header_errno_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_errno_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_errno_h" >&5 echo "${ECHO_T}$ac_cv_header_errno_h" >&6; } fi if test $ac_cv_header_errno_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_ERRNO_H 1 _ACEOF fi if test "${ac_cv_header_float_h+set}" = set; then { echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6; } if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking float.h usability" >&5 echo $ECHO_N "checking float.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking float.h presence" >&5 echo $ECHO_N "checking float.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for float.h" >&5 echo $ECHO_N "checking for float.h... $ECHO_C" >&6; } if test "${ac_cv_header_float_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_float_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 echo "${ECHO_T}$ac_cv_header_float_h" >&6; } fi if test $ac_cv_header_float_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_FLOAT_H 1 _ACEOF fi if test "${ac_cv_header_values_h+set}" = set; then { echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6; } if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking values.h usability" >&5 echo $ECHO_N "checking values.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking values.h presence" >&5 echo $ECHO_N "checking values.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for values.h" >&5 echo $ECHO_N "checking for values.h... $ECHO_C" >&6; } if test "${ac_cv_header_values_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_values_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 echo "${ECHO_T}$ac_cv_header_values_h" >&6; } fi if test $ac_cv_header_values_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_VALUES_H 1 _ACEOF fi if test "${ac_cv_header_limits_h+set}" = set; then { echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6; } if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking limits.h usability" >&5 echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking limits.h presence" >&5 echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: limits.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for limits.h" >&5 echo $ECHO_N "checking for limits.h... $ECHO_C" >&6; } if test "${ac_cv_header_limits_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_limits_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 echo "${ECHO_T}$ac_cv_header_limits_h" >&6; } fi if test $ac_cv_header_limits_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIMITS_H 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define NO_LIMITS_H 1 _ACEOF fi if test "${ac_cv_header_stdlib_h+set}" = set; then { echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6; } if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking stdlib.h usability" >&5 echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking stdlib.h presence" >&5 echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for stdlib.h" >&5 echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6; } if test "${ac_cv_header_stdlib_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_stdlib_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6; } fi if test $ac_cv_header_stdlib_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtol" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtoul" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strtod" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STDLIB_H 1 _ACEOF fi if test "${ac_cv_header_string_h+set}" = set; then { echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6; } if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking string.h usability" >&5 echo $ECHO_N "checking string.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking string.h presence" >&5 echo $ECHO_N "checking string.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for string.h" >&5 echo $ECHO_N "checking for string.h... $ECHO_C" >&6; } if test "${ac_cv_header_string_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_string_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 echo "${ECHO_T}$ac_cv_header_string_h" >&6; } fi if test $ac_cv_header_string_h = yes; then tcl_ok=1 else tcl_ok=0 fi cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strstr" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "strerror" >/dev/null 2>&1; then : else tcl_ok=0 fi rm -f conftest* # See also memmove check below for a place where NO_STRING_H can be # set and why. if test $tcl_ok = 0; then cat >>confdefs.h <<\_ACEOF #define NO_STRING_H 1 _ACEOF fi if test "${ac_cv_header_sys_wait_h+set}" = set; then { echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6; } if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking sys/wait.h usability" >&5 echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking sys/wait.h presence" >&5 echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for sys/wait.h" >&5 echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6; } if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_sys_wait_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } fi if test $ac_cv_header_sys_wait_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_SYS_WAIT_H 1 _ACEOF fi if test "${ac_cv_header_dlfcn_h+set}" = set; then { echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6; } if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6; } if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6; } fi if test $ac_cv_header_dlfcn_h = yes; then : else cat >>confdefs.h <<\_ACEOF #define NO_DLFCN_H 1 _ACEOF fi # OS/390 lacks sys/param.h (and doesn't need it, by chance). for ac_header in sys/param.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Let the user call this, because if it triggers, they will # need a compat/strtod.c that is correct. Users can also # use Tcl_GetDouble(FromObj) instead. #TEA_BUGGY_STRTOD fi #----------------------------------------------------------------------- # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- vars="zlib.c bz2lib.c loadman.c init.c registry.c unstack.c load.c crypt.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="convert.c util.c ref_opt.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="bincode.c hexcode.c octcode.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="uucode.c b64code.c asc85code.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="otpcode.c qpcode.c reflect.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="dig_opt.c digest.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="crc.c crc_zlib.c adler.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="md5dig.c haval.c sha.c md2.c sha1.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="rmd160.c rmd128.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="otpmd5.c otpsha1.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="rs_ecc.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="zip_opt.c zip.c bz2_opt.c bz2.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="trfStubInit.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done vars="generic/transform.h generic/trfDecls.h" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find header file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find header file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_HEADERS="$PKG_HEADERS $i" done vars="-I\"\${srcdir}\"" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done vars="-I\"\${srcdir}/generic\"" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done vars="-I\"\${zlibtcl_SRC_PATH}\"" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done vars="-I\"\${zlibtcl_BUILD_PATH}\"" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done vars="-I\${ZLIB_INCLUDE_DIR}" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done vars="-I\${SSL_INCLUDE_DIR}" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done vars="-DLIBZ_DEFAULTNAME=\\\"libz\${SHLIB_SUFFIX}\\\"" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done vars="" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done PKG_CFLAGS="$PKG_CFLAGS " PKG_CFLAGS="$PKG_CFLAGS -DZLIBTCL_VERSION=\\\"${zlibtcl_VERSION}\\\"" vars="trfStubLib.c" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find stub source file '$i'" >&5 echo "$as_me: error: could not find stub source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done vars="" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then { { echo "$as_me:$LINENO: error: could not find tcl source file '${srcdir}/$i'" >&5 echo "$as_me: error: could not find tcl source file '${srcdir}/$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done #-------------------------------------------------------------------- # If ltoa is present, use it to convert integer values into strings. # If not, sprintf is used, which is slower and requires more code. #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } if test "${ac_cv_c_bigendian+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # See if sys/param.h defines the BYTE_ORDER macro. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # It does not; compile a test program. if test "$cross_compiling" = yes; then # try to guess the endianness by grepping values into an object file ac_cv_c_bigendian=unknown cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { _ascii (); _ebcdic (); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; no) ;; *) { { echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac { echo "$as_me:$LINENO: checking for int" >&5 echo $ECHO_N "checking for int... $ECHO_C" >&6; } if test "${ac_cv_type_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_int=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 echo "${ECHO_T}$ac_cv_type_int" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of int" >&5 echo $ECHO_N "checking size of int... $ECHO_C" >&6; } if test "${ac_cv_sizeof_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_int=$ac_lo;; '') if test "$ac_cv_type_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_int=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef int ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_int=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF { echo "$as_me:$LINENO: checking for long int" >&5 echo $ECHO_N "checking for long int... $ECHO_C" >&6; } if test "${ac_cv_type_long_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_long_int=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_long_int=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_long_int" >&5 echo "${ECHO_T}$ac_cv_type_long_int" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { echo "$as_me:$LINENO: checking size of long int" >&5 echo $ECHO_N "checking size of long int... $ECHO_C" >&6; } if test "${ac_cv_sizeof_long_int+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=0 ac_mid=0 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr $ac_mid + 1` if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=-1 ac_mid=-1 while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_lo=$ac_mid; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_hi=`expr '(' $ac_mid ')' - 1` if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi ac_mid=`expr 2 '*' $ac_mid` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; int main () { static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; test_array [0] = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_hi=$ac_mid else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_lo=`expr '(' $ac_mid ')' + 1` fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in ?*) ac_cv_sizeof_long_int=$ac_lo;; '') if test "$ac_cv_type_long_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long_int=0 fi ;; esac else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef long int ac__type_sizeof_; static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (((long int) (sizeof (ac__type_sizeof_))) < 0) { long int i = longval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%ld\n", i); } else { unsigned long int i = ulongval (); if (i != ((long int) (sizeof (ac__type_sizeof_)))) return 1; fprintf (f, "%lu\n", i); } return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_sizeof_long_int=`cat conftest.val` else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) if test "$ac_cv_type_long_int" = yes; then { { echo "$as_me:$LINENO: error: cannot compute sizeof (long int) See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute sizeof (long int) See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } else ac_cv_sizeof_long_int=0 fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.val fi { echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_int" >&5 echo "${ECHO_T}$ac_cv_sizeof_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_INT $ac_cv_sizeof_long_int _ACEOF for ac_func in ltoa do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "${TEA_PLATFORM}" = "windows" ; then { echo "$as_me:$LINENO: checking for main in -lcrypt" >&5 echo $ECHO_N "checking for main in -lcrypt... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: no (Windows)" >&5 echo "${ECHO_T}no (Windows)" >&6; } HAS_LIBCRYPT=0 elif test "`uname -s`" = "Darwin"; then { echo "$as_me:$LINENO: checking for crypt in -lSystem" >&5 echo $ECHO_N "checking for crypt in -lSystem... $ECHO_C" >&6; } if test "${ac_cv_lib_System_crypt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lSystem $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char crypt (); int main () { return crypt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_System_crypt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_System_crypt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_System_crypt" >&5 echo "${ECHO_T}$ac_cv_lib_System_crypt" >&6; } if test $ac_cv_lib_System_crypt = yes; then HAS_LIBCRYPT=1 else HAS_LIBCRYPT=0 fi else { echo "$as_me:$LINENO: checking for main in -lcrypt" >&5 echo $ECHO_N "checking for main in -lcrypt... $ECHO_C" >&6; } if test "${ac_cv_lib_crypt_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_crypt_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_main" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_main" >&6; } if test $ac_cv_lib_crypt_main = yes; then HAS_LIBCRYPT=1 else HAS_LIBCRYPT=0 fi { echo "$as_me:$LINENO: checking for md5_init_ctx in -lcrypt" >&5 echo $ECHO_N "checking for md5_init_ctx in -lcrypt... $ECHO_C" >&6; } if test "${ac_cv_lib_crypt_md5_init_ctx+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char md5_init_ctx (); int main () { return md5_init_ctx (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_crypt_md5_init_ctx=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_md5_init_ctx=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_md5_init_ctx" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_md5_init_ctx" >&6; } if test $ac_cv_lib_crypt_md5_init_ctx = yes; then HAS_LIBCRYPT_MD5=1 else HAS_LIBCRYPT_MD5=0 fi fi # ----------------------------------------------------------------------- { echo "$as_me:$LINENO: checking if assert needs __eprintf" >&5 echo $ECHO_N "checking if assert needs __eprintf... $ECHO_C" >&6; } cat > conftest.$ac_ext <&5 if test "x`nm conftest.o |grep __eprintf`" != "x"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } vars="compat/_eprintf.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT* | *CYGWIN_98* | *CYGWIN_95* | MINGW32_NT*) # On windows tclLoadWin.c depends on internal headers. Darn. { echo "$as_me:$LINENO: checking for Tcl public headers" >&5 echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6; } # Check whether --with-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval=$with_tclinclude; with_tclinclude=${withval} fi if test "${ac_cv_c_tclh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5 echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;} { (exit 1); exit 1; }; } fi else if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "${TCL_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then { { echo "$as_me:$LINENO: error: tcl.h not found. Please specify its location with --with-tclinclude" >&5 echo "$as_me: error: tcl.h not found. Please specify its location with --with-tclinclude" >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5 echo "${ECHO_T}${ac_cv_c_tclh}" >&6; } fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh} { echo "$as_me:$LINENO: checking for Tcl private include files" >&5 echo $ECHO_N "checking for Tcl private include files... $ECHO_C" >&6; } TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}` TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\" # Check to see if tclPort.h isn't already with the public headers # Don't look for tclInt.h because that resides with tcl.h in the core # sources, but the Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tclh}/tclWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then result="private headers found with public headers" else TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\" if test "${TEA_PLATFORM}" = "windows"; then TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\" else TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TCL_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -d "${TCL_BIN_DIR}/Headers" -a \ -d "${TCL_BIN_DIR}/PrivateHeaders"; then TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}" else TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TCL_INCLUDES}" else if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then { { echo "$as_me:$LINENO: error: Cannot find private header tclInt.h in ${TCL_SRC_DIR}" >&5 echo "$as_me: error: Cannot find private header tclInt.h in ${TCL_SRC_DIR}" >&2;} { (exit 1); exit 1; }; } fi result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}" fi fi { echo "$as_me:$LINENO: result: ${result}" >&5 echo "${ECHO_T}${result}" >&6; } ;; *) # Everywhere else we can stick with the public ones. { echo "$as_me:$LINENO: checking for Tcl public headers" >&5 echo $ECHO_N "checking for Tcl public headers... $ECHO_C" >&6; } # Check whether --with-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval=$with_tclinclude; with_tclinclude=${withval} fi if test "${ac_cv_c_tclh+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else { { echo "$as_me:$LINENO: error: ${with_tclinclude} directory does not contain tcl.h" >&5 echo "$as_me: error: ${with_tclinclude} directory does not contain tcl.h" >&2;} { (exit 1); exit 1; }; } fi else if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "${TCL_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi fi # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then { { echo "$as_me:$LINENO: error: tcl.h not found. Please specify its location with --with-tclinclude" >&5 echo "$as_me: error: tcl.h not found. Please specify its location with --with-tclinclude" >&2;} { (exit 1); exit 1; }; } else { echo "$as_me:$LINENO: result: ${ac_cv_c_tclh}" >&5 echo "${ECHO_T}${ac_cv_c_tclh}" >&6; } fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" ;; esac #TEA_PUBLIC_TCL_HEADERS #TEA_PRIVATE_TCL_HEADERS #-------------------------------------------------------------------- # A few miscellaneous platform-specific items: # # We have to define a special symbol for Windows (BUILD_Trf in this # case) so that we create the export library with the dll. # # Windows creates a few extra files that need to be cleaned up. # We can add more files to clean if our extension creates any extra # files in the future. # # Define any extra compiler flags in the PACKAGE_CFLAGS variable. # These will be appended to the current set of compiler flags for # your system. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then cat >>confdefs.h <<\_ACEOF #define BUILD_Trf 1 _ACEOF CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch" else CLEANFILES="pkgIndex.tcl" fi #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # So far only Tcl responds to this one. #-------------------------------------------------------------------- # Check whether --enable-threads was given. if test "${enable_threads+set}" = set; then enableval=$enable_threads; tcl_ok=$enableval else tcl_ok=yes fi if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants: # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention cat >>confdefs.h <<\_ACEOF #define USE_THREAD_ALLOC 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF if test "`uname -s`" = "SunOS" ; then cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF fi cat >>confdefs.h <<\_ACEOF #define _THREAD_SAFE 1 _ACEOF { echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6; } if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6; } if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the same # library, as some systems hide it there until pthread.h is # defined. We could alternatively do an AC_TRY_COMPILE with # pthread.h, but that will work with libpthread really doesn't # exist, like AIX 4.2. [Bug: 4359] { echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6; } if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char __pthread_mutex_init (); int main () { return __pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_pthread___pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread___pthread_mutex_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6; } if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else { echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6; } if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_pthreads_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthreads_pthread_mutex_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6; } if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else { echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6; } if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_c_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_pthread_mutex_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6; } if test $ac_cv_lib_c_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then { echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6; } if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_c_r_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_r_pthread_mutex_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6; } if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 { echo "$as_me:$LINENO: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5 echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;} fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output { echo "$as_me:$LINENO: checking for building with threads" >&5 echo $ECHO_N "checking for building with threads... $ECHO_C" >&6; } if test "${TCL_THREADS}" = 1; then cat >>confdefs.h <<\_ACEOF #define TCL_THREADS 1 _ACEOF { echo "$as_me:$LINENO: result: yes (default)" >&5 echo "${ECHO_T}yes (default)" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then { echo "$as_me:$LINENO: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&5 echo "$as_me: WARNING: Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads." >&2;} fi ;; *) if test "${TCL_THREADS}" = "1"; then { echo "$as_me:$LINENO: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&5 echo "$as_me: WARNING: --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core." >&2;} fi ;; esac #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking how to build libraries" >&5 echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6; } # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then enableval=$enable_shared; tcl_ok=$enableval else tcl_ok=yes fi if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then { echo "$as_me:$LINENO: result: shared" >&5 echo "${ECHO_T}shared" >&6; } SHARED_BUILD=1 else { echo "$as_me:$LINENO: result: static" >&5 echo "${ECHO_T}static" >&6; } SHARED_BUILD=0 cat >>confdefs.h <<\_ACEOF #define STATIC_BUILD 1 _ACEOF fi #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- # Step 0.a: Enable 64 bit support? { echo "$as_me:$LINENO: checking if 64bit support is requested" >&5 echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6; } # Check whether --enable-64bit was given. if test "${enable_64bit+set}" = set; then enableval=$enable_64bit; do64bit=$enableval else do64bit=no fi { echo "$as_me:$LINENO: result: $do64bit" >&5 echo "${ECHO_T}$do64bit" >&6; } # Step 0.b: Enable Solaris 64 bit VIS support? { echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5 echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6; } # Check whether --enable-64bit-vis was given. if test "${enable_64bit_vis+set}" = set; then enableval=$enable_64bit_vis; do64bitVIS=$enableval else do64bitVIS=no fi { echo "$as_me:$LINENO: result: $do64bitVIS" >&5 echo "${ECHO_T}$do64bitVIS" >&6; } # Force 64bit on with VIS if test "$do64bitVIS" = "yes"; then do64bit=yes fi # Step 0.c: Check if visibility support is available. Do this here so # that platform specific alternatives can be used below if this fails. { echo "$as_me:$LINENO: checking if compiler supports visibility \"hidden\"" >&5 echo $ECHO_N "checking if compiler supports visibility \"hidden\"... $ECHO_C" >&6; } if test "${tcl_cv_cc_visibility_hidden+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern __attribute__((__visibility__("hidden"))) void f(void); void f(void) {} int main () { f(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_cc_visibility_hidden=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_cc_visibility_hidden=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi { echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5 echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6; } if test $tcl_cv_cc_visibility_hidden = yes; then cat >>confdefs.h <<\_ACEOF #define MODULE_SCOPE extern __attribute__((__visibility__("hidden"))) _ACEOF fi # Step 0.d: Disable -rpath support? { echo "$as_me:$LINENO: checking if rpath support is requested" >&5 echo $ECHO_N "checking if rpath support is requested... $ECHO_C" >&6; } # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then enableval=$enable_rpath; doRpath=$enableval else doRpath=yes fi { echo "$as_me:$LINENO: result: $doRpath" >&5 echo "${ECHO_T}$doRpath" >&6; } # TEA specific: Cross-compiling options for Windows/CE builds? if test "${TEA_PLATFORM}" = windows; then { echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5 echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6; } # Check whether --enable-wince was given. if test "${enable_wince+set}" = set; then enableval=$enable_wince; doWince=$enableval else doWince=no fi { echo "$as_me:$LINENO: result: $doWince" >&5 echo "${ECHO_T}$doWince" >&6; } fi # Step 1: set the variable "system" to hold the name and version number # for the system. { echo "$as_me:$LINENO: checking system version" >&5 echo $ECHO_N "checking system version... $ECHO_C" >&6; } if test "${tcl_cv_sys_version+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # TEA specific: if test "${TEA_PLATFORM}" = "windows" ; then tcl_cv_sys_version=windows elif test -f /usr/lib/NextStep/software_version; then tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5 echo "$as_me: WARNING: can't find uname command" >&2;} tcl_cv_sys_version=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then tcl_cv_sys_version=MP-RAS-`awk '{print $3}' /etc/.relid` fi if test "`uname -s`" = "AIX" ; then tcl_cv_sys_version=AIX-`uname -v`.`uname -r` fi fi fi fi { echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5 echo "${ECHO_T}$tcl_cv_sys_version" >&6; } system=$tcl_cv_sys_version # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } if test $ac_cv_lib_dl_dlopen = yes; then have_dl=yes else have_dl=no fi # Require ranlib early so we can override it in special cases below. # Step 3: set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case. do64bit_ok=no LDFLAGS_ORIG="$LDFLAGS" # When ld needs options to work in 64-bit mode, put them in # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load] # is disabled by the user. [Bug 1016796] LDFLAGS_ARCH="" TCL_EXPORT_FILE_SUFFIX="" UNSHARED_LIB_SUFFIX="" # TEA specific: use PACKAGE_VERSION instead of VERSION TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g CFLAGS_OPTIMIZE=-O if test "$GCC" = yes; then # TEA specific: CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall -Wno-implicit-int" else CFLAGS_WARNING="" fi TCL_NEEDS_EXP_FILE=0 TCL_BUILD_EXP_FILE="" TCL_EXP_FILE="" # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { echo "$as_me:$LINENO: result: $AR" >&5 echo "${ECHO_T}$AR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" case $system in # TEA specific: windows) # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs # MACHINE is IX86 for LINK, but this is used by the manifest, # which requires x86|amd64|ia64. MACHINE="X86" if test "$do64bit" != "no" ; then if test "x${MSSDK}x" = "xx" ; then MSSDK="C:/Progra~1/Microsoft Platform SDK" fi MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` PATH64="" case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build PATH64="${MSSDK}/Bin/Win64/x86/AMD64" ;; ia64) MACHINE="IA64" PATH64="${MSSDK}/Bin/Win64" ;; esac if test ! -d "${PATH64}" ; then { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5 echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;} { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5 echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;} do64bit="no" else { echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6; } do64bit_ok="yes" fi fi if test "$doWince" != "no" ; then if test "$do64bit" != "no" ; then { { echo "$as_me:$LINENO: error: Windows/CE and 64-bit builds incompatible" >&5 echo "$as_me: error: Windows/CE and 64-bit builds incompatible" >&2;} { (exit 1); exit 1; }; } fi if test "$GCC" = "yes" ; then { { echo "$as_me:$LINENO: error: Windows/CE and GCC builds incompatible" >&5 echo "$as_me: error: Windows/CE and GCC builds incompatible" >&2;} { (exit 1); exit 1; }; } fi # First, look for one uninstalled. # the alternative search directory is invoked by --with-celib if test x"${no_celib}" = x ; then # we reset no_celib in case something fails here no_celib=true # Check whether --with-celib was given. if test "${with_celib+set}" = set; then withval=$with_celib; with_celibconfig=${withval} fi { echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5 echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6; } if test "${ac_cv_c_celibconfig+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # First check to see if --with-celibconfig was specified. if test x"${with_celibconfig}" != x ; then if test -d "${with_celibconfig}/inc" ; then ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` else { { echo "$as_me:$LINENO: error: ${with_celibconfig} directory doesn't contain inc directory" >&5 echo "$as_me: error: ${with_celibconfig} directory doesn't contain inc directory" >&2;} { (exit 1); exit 1; }; } fi fi # then check for a celib library if test x"${ac_cv_c_celibconfig}" = x ; then for i in \ ../celib-palm-3.0 \ ../celib \ ../../celib-palm-3.0 \ ../../celib \ `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \ ${srcdir}/../celib-palm-3.0 \ ${srcdir}/../celib \ `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \ ; do if test -d "$i/inc" ; then ac_cv_c_celibconfig=`(cd $i; pwd)` break fi done fi fi if test x"${ac_cv_c_celibconfig}" = x ; then { { echo "$as_me:$LINENO: error: Cannot find celib support library directory" >&5 echo "$as_me: error: Cannot find celib support library directory" >&2;} { (exit 1); exit 1; }; } else no_celib= CELIB_DIR=${ac_cv_c_celibconfig} CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` { echo "$as_me:$LINENO: result: found $CELIB_DIR" >&5 echo "${ECHO_T}found $CELIB_DIR" >&6; } fi fi # Set defaults for common evc4/PPC2003 setup # Currently Tcl requires 300+, possibly 420+ for sockets CEVERSION=420; # could be 211 300 301 400 420 ... TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... ARCH=ARM; # could be ARM MIPS X86EM ... PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" if test "$doWince" != "yes"; then # If !yes then the user specified something # Reset ARCH to allow user to skip specifying it ARCH= eval `echo $doWince | awk -F, '{ \ if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \ if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \ if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \ if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \ }'` if test "x${ARCH}" = "x" ; then ARCH=$TARGETCPU; fi fi OSVERSION=WCE$CEVERSION; if test "x${WCEROOT}" = "x" ; then WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" if test ! -d "${WCEROOT}" ; then WCEROOT="C:/Program Files/Microsoft eMbedded Tools" fi fi if test "x${SDKROOT}" = "x" ; then SDKROOT="C:/Program Files/Windows CE Tools" if test ! -d "${SDKROOT}" ; then SDKROOT="C:/Windows CE Tools" fi fi WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5 echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;} { (exit 1); exit 1; }; } doWince="no" else # We could PATH_NOSPACE these, but that's not important, # as long as we quote them when used. CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" fi CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" fi fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi if test "$do64bit" != "no" ; then # All this magic is necessary for the Win64 SDK RC1 - hobbs CC="\"${PATH64}/cl.exe\"" CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" RC="\"${MSSDK}/bin/rc.exe\"" lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 vars="bufferoverflowU.lib" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done elif test "$doWince" != "no" ; then CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" if test "${TARGETCPU}" = "X86"; then CC="\"${CEBINROOT}/cl.exe\"" else CC="\"${CEBINROOT}/cl${ARCH}.exe\"" fi CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" arch=`echo ${ARCH} | awk '{print tolower($0)}'` defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" if test "${SHARED_BUILD}" = "1" ; then # Static CE builds require static celib as well defs="${defs} _DLL" fi for i in $defs ; do cat >>confdefs.h <<_ACEOF #define $i 1 _ACEOF done cat >>confdefs.h <<_ACEOF #define _WIN32_WCE $CEVERSION _ACEOF cat >>confdefs.h <<_ACEOF #define UNDER_CE $CEVERSION _ACEOF CFLAGS_DEBUG="-nologo -Zi -Od" CFLAGS_OPTIMIZE="-nologo -Ox" lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" LINKBIN="\"${CEBINROOT}/link.exe\"" else RC="rc" lflags="-nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode RC="windres" CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" SHLIB_LD="$CC -shared" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # and also # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx # This essentially turns it all on. LDFLAGS_DEBUG="-debug -debugtype:cv" LDFLAGS_OPTIMIZE="-release" if test "$doWince" != "no" ; then LDFLAGS_CONSOLE="-link ${lflags}" LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} else LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi fi SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots # Bogus to avoid getting this turned off DL_OBJS="tclLoadNone.obj" ;; AIX-*) if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r) # ok ... ;; *) CC=${CC}_r ;; esac { echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5 echo "${ECHO_T}Using $CC for compiling with threads" >&6; } fi LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" LD_LIBRARY_PATH_VAR="LIBPATH" # Check to enable 64-bit flags for compiler/linker on AIX 4+ if test "$do64bit" = yes -a "`uname -v`" -gt 3; then if test "$GCC" = yes; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS_ARCH="-q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" fi fi if test "`uname -m`" = ia64; then # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" if test "$GCC" = yes; then CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' else CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' else if test "$GCC" = yes; then SHLIB_LD='${CC} -shared' else SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry" fi SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} TCL_NEEDS_EXP_FILE=1 # TEA specific: use PACKAGE_VERSION instead of VERSION TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp' fi # AIX v<=4.1 has some different flags than 4.2+ if test "$system" = "AIX-4.1" -o "`uname -v`" -lt 4; then case " $LIBOBJS " in *" tclLoadAix.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS tclLoadAix.$ac_objext" ;; esac DL_LIBS="-lld" fi # On AIX <=v4 systems, libbsd.a has to be linked in to support # non-blocking file IO. This library has to be linked in after # the MATH_LIBS or it breaks the pow() function. The way to # insure proper sequencing, is to add it to the tail of MATH_LIBS. # This library also supplies gettimeofday. # # AIX does not have a timezone field in struct tm. When the AIX # bsd library is used, the timezone global and the gettimeofday # methods are to be avoided for timezone deduction instead, we # deduce the timezone by comparing the localtime result on a # known GMT value. { echo "$as_me:$LINENO: checking for gettimeofday in -lbsd" >&5 echo $ECHO_N "checking for gettimeofday in -lbsd... $ECHO_C" >&6; } if test "${ac_cv_lib_bsd_gettimeofday+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gettimeofday (); int main () { return gettimeofday (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_bsd_gettimeofday=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_gettimeofday=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gettimeofday" >&5 echo "${ECHO_T}$ac_cv_lib_bsd_gettimeofday" >&6; } if test $ac_cv_lib_bsd_gettimeofday = yes; then libbsd=yes else libbsd=no fi if test $libbsd = yes; then MATH_LIBS="$MATH_LIBS -lbsd" cat >>confdefs.h <<\_ACEOF #define USE_DELTA_FOR_TZ 1 _ACEOF fi ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -nostart' SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" #----------------------------------------------------------- # Check for inet_ntoa in -lbind, for BeOS (which also needs # -lsocket, even if the network functions are in -lnet which # is always linked to, for compatibility. #----------------------------------------------------------- { echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5 echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6; } if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbind $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_ntoa (); int main () { return inet_ntoa (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_bind_inet_ntoa=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bind_inet_ntoa=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5 echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6; } if test $ac_cv_lib_bind_inet_ntoa = yes; then LIBS="$LIBS -lbind -lsocket" fi ;; 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" CC_SEARCH_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" LDFLAGS="$LDFLAGS -export-dynamic" CC_SEARCH_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" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; HP-UX-*.11.*) # Use updated header definitions where possible cat >>confdefs.h <<\_ACEOF #define _XOPEN_SOURCE_EXTENDED 1 _ACEOF # TEA specific: Needed by Tcl, but not most extensions #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?]) #LIBS="$LIBS -lxnet" # Use the XOPEN network library if test "`uname -m`" = ia64; then SHLIB_SUFFIX=".so" # Use newer C++ library for C++ extensions #if test "$GCC" != "yes" ; then # CPPFLAGS="-AA" #fi else SHLIB_SUFFIX=".sl" fi { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS='${LIBS}' DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi if test "$GCC" = yes; then SHLIB_LD='${CC} -shared' SHLIB_LD_LIBS='${LIBS}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} fi # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = "yes"; then if test "$GCC" = yes; then case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' SHLIB_LD_LIBS='${LIBS}' if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} ;; esac else do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS_ARCH="+DD64" fi fi ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi ;; IRIX-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi if test "$GCC" = yes; then CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" else case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" fi ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = yes; then if test "$GCC" = yes; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5 echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} else do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS_ARCH="-64" fi fi ;; Linux*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" # TEA specific: CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings # when you inline the string and math operations. Turn this off to # get rid of the warnings. #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}' DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} if test "`uname -m`" = "alpha"; then CFLAGS="$CFLAGS -mieee" fi if test $do64bit = yes; then { echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5 echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6; } if test "${tcl_cv_cc_m64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_cc_m64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_cc_m64=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi { echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5 echo "${ECHO_T}$tcl_cv_cc_m64" >&6; } if test $tcl_cv_cc_m64 = yes; then CFLAGS="$CFLAGS -m64" do64bit_ok=yes fi fi # The combo of gcc + glibc has a bug related to inlining of # functions like strtod(). The -fno-builtin flag should address # this problem but it does not work. The -fno-inline flag is kind # of overkill but it works. Disable inlining only when one of the # files in compat/*.c is being linked in. if test x"${USE_COMPAT}" != x; then CFLAGS="$CFLAGS -fno-inline" fi ;; GNU*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" SHLIB_LD='${CC} -shared' DL_OBJS="" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" if test "`uname -m`" = "alpha"; then CFLAGS="$CFLAGS -mieee" fi ;; Lynx*) SHLIB_CFLAGS="-fPIC" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; MP-RAS-*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,-Bexport" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; NetBSD-1.*|FreeBSD-[1-2].*) SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi { echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6; } if test "${tcl_cv_ld_elf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then tcl_cv_ld_elf=yes else tcl_cv_ld_elf=no fi rm -f conftest* fi { echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5 echo "${ECHO_T}$tcl_cv_ld_elf" >&6; } if test $tcl_cv_ld_elf = yes; then SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' else SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' fi # Ancient FreeBSD doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; OpenBSD-*) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' { echo "$as_me:$LINENO: checking for ELF" >&5 echo $ECHO_N "checking for ELF... $ECHO_C" >&6; } if test "${tcl_cv_ld_elf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ELF__ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "yes" >/dev/null 2>&1; then tcl_cv_ld_elf=yes else tcl_cv_ld_elf=no fi rm -f conftest* fi { echo "$as_me:$LINENO: result: $tcl_cv_ld_elf" >&5 echo "${ECHO_T}$tcl_cv_ld_elf" >&6; } if test $tcl_cv_ld_elf = yes; then LDFLAGS=-Wl,-export-dynamic else LDFLAGS="" fi # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; NetBSD-*|FreeBSD-*) # FreeBSD 3.* and greater have ELF. # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} if test "${TCL_THREADS}" = "1"; then # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" fi case $system in FreeBSD-3.*) # FreeBSD-3 doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' TCL_LIB_VERSIONS_OK=nodots ;; esac ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" # To avoid discrepancies between what headers configure sees during # preprocessing tests and compiling tests, move any -isysroot and # -mmacosx-version-min flags from CFLAGS to CPPFLAGS: CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`" CFLAGS="`echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`" if test $do64bit = yes; then case `arch` in ppc) { echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5 echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6; } if test "${tcl_cv_cc_arch_ppc64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_cc_arch_ppc64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_cc_arch_ppc64=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi { echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5 echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6; } if test $tcl_cv_cc_arch_ppc64 = yes; then CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" do64bit_ok=yes fi ;; i386) { echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5 echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6; } if test "${tcl_cv_cc_arch_x86_64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch x86_64" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_cc_arch_x86_64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_cc_arch_x86_64=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi { echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5 echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6; } if test $tcl_cv_cc_arch_x86_64 = yes; then CFLAGS="$CFLAGS -arch x86_64" do64bit_ok=yes fi ;; *) { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5 echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};; esac else # Check for combined 32-bit and 64-bit fat build if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then fat_32_64=yes fi fi # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}' { echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6; } if test "${tcl_cv_ld_single_module+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_ld_single_module=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_single_module=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi { echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5 echo "${ECHO_T}$tcl_cv_ld_single_module" >&6; } if test $tcl_cv_ld_single_module = yes; then SHLIB_LD="${SHLIB_LD} -Wl,-single_module" fi # TEA specific: link shlib with current and compatiblity version flags vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([0-9]\{1,5\}\)\(\(\.[0-9]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d` SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}" SHLIB_LD_LIBS='${LIBS}' SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then LDFLAGS="$LDFLAGS -prebind" fi LDFLAGS="$LDFLAGS -headerpad_max_install_names" { echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6; } if test "${tcl_cv_ld_search_paths_first+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_ld_search_paths_first=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_search_paths_first=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi { echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5 echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6; } if test $tcl_cv_ld_search_paths_first = yes; then LDFLAGS="$LDFLAGS -Wl,-search_paths_first" fi if test "$tcl_cv_cc_visibility_hidden" != yes; then cat >>confdefs.h <<\_ACEOF #define MODULE_SCOPE __private_extern__ _ACEOF fi CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" # TEA specific: for combined 32 & 64 bit fat builds of Tk # extensions, verify that 64-bit build is possible. if test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"; then if test "${TEA_WINDOWINGSYSTEM}" = x11; then { echo "$as_me:$LINENO: checking for 64-bit X11" >&5 echo $ECHO_N "checking for 64-bit X11... $ECHO_C" >&6; } if test "${tcl_cv_lib_x11_64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include" LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { XrmInitialize(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_lib_x11_64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_lib_x11_64=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done fi { echo "$as_me:$LINENO: result: $tcl_cv_lib_x11_64" >&5 echo "${ECHO_T}$tcl_cv_lib_x11_64" >&6; } fi # remove 64-bit arch flags from CFLAGS et al. if configuration # does not support 64-bit. if test "${TEA_WINDOWINGSYSTEM}" = aqua -o "$tcl_cv_lib_x11_64" = no; then { echo "$as_me:$LINENO: Removing 64-bit architectures from compiler & linker flags" >&5 echo "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;} for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' done fi fi ;; NEXTSTEP-*) SHLIB_CFLAGS="" SHLIB_LD='${CC} -nostdlib -r' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadNext.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy cat >>confdefs.h <<\_ACEOF #define _OE_SOCKETS 1 _ACEOF ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SHLIB_CFLAGS="" # Hack: make package name same as library name SHLIB_LD='ld -R -export :' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadOSF.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" if test "$SHARED_BUILD" = 1; then SHLIB_LD="ld -shared" else SHLIB_LD="ld -non_shared" fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" if test "$SHARED_BUILD" = 1; then SHLIB_LD='ld -shared -expect_unresolved "*"' else SHLIB_LD='ld -non_shared -expect_unresolved "*"' fi SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi if test "$GCC" = yes; then CFLAGS="$CFLAGS -mieee" else CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" fi # see pthread_intro(3) for pthread support on osf1, k.furukawa if test "${TCL_THREADS}" = 1; then CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` if test "$GCC" = yes; then LIBS="$LIBS -lpthread -lmach -lexc" else CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" fi fi ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" # dlopen is in -lc on QNX DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. if test "$GCC" = yes; then SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" else SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" fi SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SINIX*5.4*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SunOS-4*) SHLIB_CFLAGS="-PIC" SHLIB_LD="ld" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} # 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 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; SunOS-5.[0-6]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF SHLIB_CFLAGS="-KPIC" # 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 "$GCC" = yes; then SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} else SHLIB_LD="/usr/ccs/bin/ld -G -z text" CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} fi ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker if test "$do64bit" = yes; then arch=`isainfo` if test "$arch" = "sparcv9 sparc"; then if test "$GCC" = yes; then if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} else do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" SHLIB_CFLAGS="-fPIC" fi else do64bit_ok=yes if test "$do64bitVIS" = yes; then CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS_ARCH="-xarch=v9a" else CFLAGS="$CFLAGS -xarch=v9" LDFLAGS_ARCH="-xarch=v9" fi # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" fi else if test "$arch" = "amd64 i386"; then if test "$GCC" = yes; then case $system in SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*) do64bit_ok=yes CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};; esac else do64bit_ok=yes case $system in SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*) CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64";; esac fi else { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5 echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} fi 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 "$GCC" = yes; then SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} if test "$do64bit_ok" = yes; then if test "$arch" = "sparcv9 sparc"; then # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" else if test "$arch" = "amd64 i386"; then # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" fi fi fi else case $system in SunOS-5.[1-9][0-9]*) SHLIB_LD='${CC} -G -z text ${LDFLAGS}';; *) SHLIB_LD='/usr/ccs/bin/ld -G -z text';; esac CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi ;; 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 # that don't grok the -Bexport option. Test that it does. { echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5 echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6; } if test "${tcl_cv_ld_Bexport+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-Bexport" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then tcl_cv_ld_Bexport=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_ld_Bexport=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi { echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5 echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6; } if test $tcl_cv_ld_Bexport = yes; then LDFLAGS="$LDFLAGS -Wl,-Bexport" fi CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; esac if test "$do64bit" = yes -a "$do64bit_ok" = no; then { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} fi # Step 4: disable dynamic loading if requested via a command-line switch. # Check whether --enable-load was given. if test "${enable_load+set}" = set; then enableval=$enable_load; tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = no; then DL_OBJS="" fi if test "x$DL_OBJS" != x; then BUILD_DLTEST="\$(DLTEST_TARGETS)" else { echo "$as_me:$LINENO: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5 echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;} SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" DL_OBJS="tclLoadNone.o" DL_LIBS="" LDFLAGS="$LDFLAGS_ORIG" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" BUILD_DLTEST="" fi LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then case $system in AIX-*) ;; BSD/OS*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*) ;; Darwin-*) ;; SCO_SV-3.2*) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac fi if test "$SHARED_LIB_SUFFIX" = ""; then # TEA specific: use PACKAGE_VERSION instead of VERSION SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}' fi if test "$UNSHARED_LIB_SUFFIX" = ""; then # TEA specific: use PACKAGE_VERSION instead of VERSION UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a' fi # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary { echo "$as_me:$LINENO: checking for required early compiler flags" >&5 echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6; } tcl_flags="" if test "${tcl_cv_flag__isoc99_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_flag__isoc99_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _ISOC99_SOURCE 1 #include int main () { char *p = (char *)strtoll; char *q = (char *)strtoull; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_flag__isoc99_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__isoc99_source=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _ISOC99_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _ISOC99_SOURCE" fi if test "${tcl_cv_flag__largefile64_source+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_flag__largefile64_source=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE64_SOURCE 1 #include int main () { struct stat64 buf; int i = stat64("/", &buf); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_flag__largefile64_source=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__largefile64_source=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _LARGEFILE64_SOURCE 1 _ACEOF tcl_flags="$tcl_flags _LARGEFILE64_SOURCE" fi if test "${tcl_cv_flag__largefile_source64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *)open64; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_flag__largefile_source64=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE_SOURCE64 1 #include int main () { char *p = (char *)open64; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_flag__largefile_source64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_flag__largefile_source64=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define _LARGEFILE_SOURCE64 1 _ACEOF tcl_flags="$tcl_flags _LARGEFILE_SOURCE64" fi if test "x${tcl_flags}" = "x" ; then { echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6; } else { echo "$as_me:$LINENO: result: ${tcl_flags}" >&5 echo "${ECHO_T}${tcl_flags}" >&6; } fi { echo "$as_me:$LINENO: checking for 64-bit integer type" >&5 echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6; } if test "${tcl_cv_type_64bit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { __int64 value = (__int64) 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_type_64bit=__int64 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_type_64bit="long long" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { switch (0) { case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; } ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_type_64bit=${tcl_type_64bit} else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "${tcl_cv_type_64bit}" = none ; then cat >>confdefs.h <<\_ACEOF #define TCL_WIDE_INT_IS_LONG 1 _ACEOF { echo "$as_me:$LINENO: result: using long" >&5 echo "${ECHO_T}using long" >&6; } elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # TEA specific: We actually want to use the default tcl.h checks in # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* { echo "$as_me:$LINENO: result: using Tcl header defaults" >&5 echo "${ECHO_T}using Tcl header defaults" >&6; } else cat >>confdefs.h <<_ACEOF #define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit} _ACEOF { echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5 echo "${ECHO_T}${tcl_cv_type_64bit}" >&6; } # Now check for auxiliary declarations { echo "$as_me:$LINENO: checking for struct dirent64" >&5 echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6; } if test "${tcl_cv_struct_dirent64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct dirent64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_struct_dirent64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_dirent64=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5 echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6; } if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_DIRENT64 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct stat64" >&5 echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6; } if test "${tcl_cv_struct_stat64+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct stat64 p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_struct_stat64=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_struct_stat64=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5 echo "${ECHO_T}$tcl_cv_struct_stat64" >&6; } if test "x${tcl_cv_struct_stat64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_STAT64 1 _ACEOF fi for ac_func in open64 lseek64 do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for off64_t" >&5 echo $ECHO_N "checking for off64_t... $ECHO_C" >&6; } if test "${tcl_cv_type_off64_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { off64_t offset; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then tcl_cv_type_off64_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 tcl_cv_type_off64_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_type_off64_t}" = "xyes" && \ test "x${ac_cv_func_lseek64}" = "xyes" && \ test "x${ac_cv_func_open64}" = "xyes" ; then cat >>confdefs.h <<\_ACEOF #define HAVE_TYPE_OFF64_T 1 _ACEOF { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for build with symbols" >&5 echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6; } # Check whether --enable-symbols was given. if test "${enable_symbols+set}" = set; then enableval=$enable_symbols; tcl_ok=$enableval else tcl_ok=no fi DBGX="" if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then { echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 echo "${ECHO_T}yes (standard debugging)" >&6; } fi fi # TEA specific: if test "${TEA_PLATFORM}" != "windows" ; then LDFLAGS_DEFAULT="${LDFLAGS}" fi if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then cat >>confdefs.h <<\_ACEOF #define TCL_MEM_DEBUG 1 _ACEOF fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then { echo "$as_me:$LINENO: result: enabled symbols mem debugging" >&5 echo "${ECHO_T}enabled symbols mem debugging" >&6; } else { echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 echo "${ECHO_T}enabled $tcl_ok debugging" >&6; } fi fi #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. #-------------------------------------------------------------------- cat >>confdefs.h <<\_ACEOF #define USE_TCL_STUBS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_ZLIBTCL_STUBS 1 _ACEOF #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)" MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\"" fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" if test "$GCC" = "yes"; then PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE} fi # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}" fi eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi #-------------------------------------------------------------------- # __CHANGE__ # Add platform libs to LIBS or SHLIB_LD_LIBS as necessary. #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then vars="\"`${CYGPATH} ${zlibtcl_STUB_LIB_PATH}`\"" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done else vars="${zlibtcl_STUB_LIB_SPEC}" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done fi #-------------------------------------------------------------------- # Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl # file during the install process. Don't run the TCLSH_PROG through # ${CYGPATH} because it's being used directly by make. # Require that we use a tclsh shell version 8.2 or later since earlier # versions have bugs in the pkg_mkIndex routine. # Add WISH as well if this is a Tk extension. #-------------------------------------------------------------------- { echo "$as_me:$LINENO: checking for tclsh" >&5 echo $ECHO_N "checking for tclsh... $ECHO_C" >&6; } if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" fi list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TCL_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`/" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}" fi { echo "$as_me:$LINENO: result: ${TCLSH_PROG}" >&5 echo "${ECHO_T}${TCLSH_PROG}" >&6; } #-------------------------------------------------------------------- # Propagate the information about the required loader file. #-------------------------------------------------------------------- case "`uname -s`" in *win32* | *WIN32* | *CYGWIN_NT* | *CYGWIN_98* | *CYGWIN_95* | MINGW32_NT*) vars="compat/tclLoadWin.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done ;; *Darwin) ;; *) if test "x${DL_OBJS}" != "xtclLoadDl.o" then vars="compat/`basename ${DL_OBJS} .o`.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done fi ;; esac #-------------------------------------------------------------------- # Locate supporting libraries #-------------------------------------------------------------------- # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then withval=$with_zlib; ZLIB_LIB_DIR=$withval/lib; ZLIB_INCLUDE_DIR=$withval/include fi # Check whether --with-zlib-include-dir was given. if test "${with_zlib_include_dir+set}" = set; then withval=$with_zlib_include_dir; ZLIB_INCLUDE_DIR=$withval fi # Check whether --with-zlib-lib-dir was given. if test "${with_zlib_lib_dir+set}" = set; then withval=$with_zlib_lib_dir; ZLIB_LIB_DIR=$withval fi # Check whether --with-ssl was given. if test "${with_ssl+set}" = set; then withval=$with_ssl; SSL_LIB_DIR=$withval/lib; SSL_INCLUDE_DIR=$withval/include fi # Check whether --with-ssl-include-dir was given. if test "${with_ssl_include_dir+set}" = set; then withval=$with_ssl_include_dir; SSL_INCLUDE_DIR=$withval fi # Check whether --with-ssl-lib-dir was given. if test "${with_ssl_lib_dir+set}" = set; then withval=$with_ssl_lib_dir; SSL_LIB_DIR=$withval fi # Check whether --with-bz2 was given. if test "${with_bz2+set}" = set; then withval=$with_bz2; BZ2_LIB_DIR=$withval/lib; BZ2_INCLUDE_DIR=$withval/include fi # Check whether --with-bz2-include-dir was given. if test "${with_bz2_include_dir+set}" = set; then withval=$with_bz2_include_dir; BZ2_INCLUDE_DIR=$withval fi # Check whether --with-bz2-lib-dir was given. if test "${with_bz2_lib_dir+set}" = set; then withval=$with_bz2_lib_dir; BZ2_LIB_DIR=$withval fi # Check whether --enable-static-zlib was given. if test "${enable_static_zlib+set}" = set; then enableval=$enable_static_zlib; STATIC_ZLIB=$enableval else STATIC_ZLIB=no fi # Check whether --enable-static-bzlib was given. if test "${enable_static_bzlib+set}" = set; then enableval=$enable_static_bzlib; STATIC_BZLIB=$enableval else STATIC_BZLIB=no fi # Check whether --enable-static-md5 was given. if test "${enable_static_md5+set}" = set; then enableval=$enable_static_md5; STATIC_MD5=$enableval else STATIC_MD5=no fi # Check whether --enable-trf_debug was given. if test "${enable_trf_debug+set}" = set; then enableval=$enable_trf_debug; trf_debug=$enableval else trf_debug=no fi # Check whether --enable-stream_debug was given. if test "${enable_stream_debug+set}" = set; then enableval=$enable_stream_debug; stream_debug=$enableval else stream_debug=no fi if test "X" = "X$ZLIB_LIB_DIR" -a "X" != "X$ZLIB_INCLUDE_DIR" then ZLIB_LIB_DIR="$ZLIB_INCLUDE_DIR/../lib" fi if test "X" = "X$ZLIB_INCLUDE_DIR" -a "X" != "X$ZLIB_LIB_DIR" then ZLIB_INCLUDE_DIR="$ZLIB_LIB_DIR/../include" fi if test "X" = "X$BZ2_LIB_DIR" -a "X" != "X$BZ2_INCLUDE_DIR" then BZ2_LIB_DIR="$BZ2_INCLUDE_DIR/../lib" fi if test "X" = "X$BZ2_INCLUDE_DIR" -a "X" != "X$BZ2_LIB_DIR" then BZ2_INCLUDE_DIR="$BZ2_LIB_DIR/../include" fi if test "X" = "X$SSL_LIB_DIR" -a "X" != "X$SSL_INCLUDE_DIR" then SSL_LIB_DIR="$SSL_INCLUDE_DIR/../lib" fi if test "X" = "X$SSL_INCLUDE_DIR" -a "X" != "X$SSL_LIB_DIR" then SSL_INCLUDE_DIR="$SSL_LIB_DIR/../include" fi { echo "$as_me:$LINENO: checking for directory with zlib.h" >&5 echo $ECHO_N "checking for directory with zlib.h... $ECHO_C" >&6; } if test "${trf_cv_path_ZLIB_INCLUDE_DIR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else trf_cv_path_ZLIB_INCLUDE_DIR="" places="$ZLIB_INCLUDE_DIR \ $TCL_INCLUDE_DIR \ $prefix/include \ /usr/local/include \ /usr/include" for dir in $places; do if test -r $dir/zlib.h ; then trf_cv_path_ZLIB_INCLUDE_DIR=$dir break fi done fi { echo "$as_me:$LINENO: result: $trf_cv_path_ZLIB_INCLUDE_DIR" >&5 echo "${ECHO_T}$trf_cv_path_ZLIB_INCLUDE_DIR" >&6; } if test -z "$trf_cv_path_ZLIB_INCLUDE_DIR" ; then { { echo "$as_me:$LINENO: error: not found; falling back to compat/ headers; use --with-zlib=DIR or --with-zlib-include-dir=DIR" >&5 echo "$as_me: error: not found; falling back to compat/ headers; use --with-zlib=DIR or --with-zlib-include-dir=DIR" >&2;} { (exit 1); exit 1; }; } ZLIB_INCLUDE_DIR="\".\"" else ZLIB_INCLUDE_DIR="\"`${CYGPATH} $trf_cv_path_ZLIB_INCLUDE_DIR`\"" eval cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF TRF_TESTS="$TRF_TESTS hasZlib" fi { echo "$as_me:$LINENO: checking for libz library" >&5 echo $ECHO_N "checking for libz library... $ECHO_C" >&6; } if test "${trf_cv_lib_ZLIB_LIB_DIR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else trf_cv_lib_ZLIB_LIB_DIR="" places="$ZLIB_LIB_DIR \ $TCL_LIB_DIR \ $exec_prefix/lib \ $prefix/lib \ /usr/local/lib \ /usr/lib" for dir in $places; do if test -n "$trf_cv_lib_ZLIB_LIB_DIR"; then break fi for libsuff in .so ".so.*" .sl .a .dylib; do if test -n "$trf_cv_lib_ZLIB_LIB_DIR"; then break fi if test -f "$dir/libz$libsuff"; then trf_cv_lib_ZLIB_LIB_DIR="$dir" ZLIB_LIB_DIR="$dir" fi done done fi { echo "$as_me:$LINENO: result: $trf_cv_lib_ZLIB_LIB_DIR" >&5 echo "${ECHO_T}$trf_cv_lib_ZLIB_LIB_DIR" >&6; } if test -z "$trf_cv_lib_ZLIB_LIB_DIR" ; then { echo "$as_me:$LINENO: WARNING: not found; use --with-zlib-lib-dir=path" >&5 echo "$as_me: WARNING: not found; use --with-zlib-lib-dir=path" >&2;} ZLIB_LIB_DIR="\".\"" else ZLIB_LIB_DIR="`${CYGPATH} $trf_cv_lib_ZLIB_LIB_DIR`" fi { echo "$as_me:$LINENO: checking for directory with ssl.h" >&5 echo $ECHO_N "checking for directory with ssl.h... $ECHO_C" >&6; } if test "${trf_cv_path_SSL_INCLUDE_DIR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else trf_cv_path_SSL_INCLUDE_DIR="" places="$SSL_INCLUDE_DIR \ $TCL_INCLUDE_DIR \ $prefix/include \ /usr/local/ssl/include \ /usr/local/include \ /usr/include" for dir in $places; do if test -r $dir/openssl/md2.h ; then trf_cv_path_SSL_INCLUDE_DIR=$dir TRF_DEFS="$TRF_DEFS -DOPENSSL_SUB" break fi if test -r $dir/openssl/sha1.h ; then trf_cv_path_SSL_INCLUDE_DIR=$dir TRF_DEFS="$TRF_DEFS -DOPENSSL_SUB" break fi if test -r $dir/md2.h ; then trf_cv_path_SSL_INCLUDE_DIR=$dir break fi if test -r $dir/sha1.h ; then trf_cv_path_SSL_INCLUDE_DIR=$dir break fi done fi { echo "$as_me:$LINENO: result: $trf_cv_path_SSL_INCLUDE_DIR" >&5 echo "${ECHO_T}$trf_cv_path_SSL_INCLUDE_DIR" >&6; } if echo "$TRF_DEFS" | grep -q OPENSSL_SUB; then cat >>confdefs.h <<_ACEOF #define OPENSSL_SUB 1 _ACEOF fi if test -z "$trf_cv_path_SSL_INCLUDE_DIR" ; then { echo "$as_me:$LINENO: WARNING: not found; falling back compat/ headers; use --with-ssl=DIR or --with-ssl-include-dir=DIR" >&5 echo "$as_me: WARNING: not found; falling back compat/ headers; use --with-ssl=DIR or --with-ssl-include-dir=DIR" >&2;} SSL_INCLUDE_DIR="\".\"" else SSL_INCLUDE_DIR="\"`${CYGPATH} $trf_cv_path_SSL_INCLUDE_DIR`\"" if test "${TEA_PLATFORM}" = "windows" ; then { echo "$as_me:$LINENO: WARNING: Squashing SSL / Windows" >&5 echo "$as_me: WARNING: Squashing SSL / Windows" >&2;} SSL_INCLUDE_DIR="\".\"" else eval cat >>confdefs.h <<_ACEOF #define HAVE_SSL_H 1 _ACEOF eval cat >>confdefs.h <<_ACEOF #define HAVE_MD2_H 1 _ACEOF eval cat >>confdefs.h <<_ACEOF #define HAVE_MD5_H 1 _ACEOF eval cat >>confdefs.h <<_ACEOF #define HAVE_SHA_H 1 _ACEOF #DEFS="$DEFS -DHAVE_SSL_H -DHAVE_MD2_H -DHAVE_SHA_H" TRF_TESTS="$TRF_TESTS hasSSL" fi fi { echo "$as_me:$LINENO: checking for ssl libcrypto library (for message digests)" >&5 echo $ECHO_N "checking for ssl libcrypto library (for message digests)... $ECHO_C" >&6; } if test "${trf_cv_lib_SSL_LIB_DIR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else trf_cv_lib_SSL_LIB_DIR="" places="$SSL_LIB_DIR \ $TCL_LIB_DIR \ $exec_prefix/lib \ $prefix/lib \ /usr/local/ssl/lib \ /usr/local/lib \ /usr/lib" for dir in $places; do if test -n "$trf_cv_lib_SSL_LIB_DIR"; then break fi for libsuff in .so ".so.*" .sl .a .dylib; do if test -n "$trf_cv_lib_SSL_LIB_DIR"; then break fi if test -f $dir/libcrypto$libsuff; then trf_cv_lib_SSL_LIB_DIR="$dir" SSL_LIB_DIR="$dir" fi done done fi { echo "$as_me:$LINENO: result: $trf_cv_lib_SSL_LIB_DIR" >&5 echo "${ECHO_T}$trf_cv_lib_SSL_LIB_DIR" >&6; } if test -z "$trf_cv_lib_SSL_LIB_DIR" ; then { echo "$as_me:$LINENO: WARNING: not found; use --with-ssl-lib-dir=path" >&5 echo "$as_me: WARNING: not found; use --with-ssl-lib-dir=path" >&2;} SSL_LIB_DIR="\".\"" else SSL_LIB_DIR="`${CYGPATH} $trf_cv_lib_SSL_LIB_DIR`" fi { echo "$as_me:$LINENO: checking for directory with bzlib.h" >&5 echo $ECHO_N "checking for directory with bzlib.h... $ECHO_C" >&6; } if test "${trf_cv_path_BZ2_INCLUDE_DIR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else trf_cv_path_BZ2_INCLUDE_DIR="" places="$BZ2_INCLUDE_DIR \ $TCL_INCLUDE_DIR \ $prefix/include \ /usr/local/include \ /usr/include" for dir in $places; do if test -r $dir/bzlib.h ; then trf_cv_path_BZ2_INCLUDE_DIR=$dir break fi done fi { echo "$as_me:$LINENO: result: $trf_cv_path_BZ2_INCLUDE_DIR" >&5 echo "${ECHO_T}$trf_cv_path_BZ2_INCLUDE_DIR" >&6; } if test -z "$trf_cv_path_BZ2_INCLUDE_DIR" ; then { echo "$as_me:$LINENO: WARNING: not found; falling back to compat/ headers; use --with-bz2=DIR or --with-bz2-include-dir=DIR" >&5 echo "$as_me: WARNING: not found; falling back to compat/ headers; use --with-bz2=DIR or --with-bz2-include-dir=DIR" >&2;} BZ2_INCLUDE_DIR="\".\"" else BZ2_INCLUDE_DIR="\"`${CYGPATH} $trf_cv_path_BZ2_INCLUDE_DIR`\"" eval cat >>confdefs.h <<_ACEOF #define HAVE_BZ2_H 1 _ACEOF fi { echo "$as_me:$LINENO: checking for bz2 compressor library" >&5 echo $ECHO_N "checking for bz2 compressor library... $ECHO_C" >&6; } if test "${trf_cv_lib_BZ2_LIB_DIR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else trf_cv_lib_BZ2_LIB_DIR="" places="$BZ2_LIB_DIR \ $TCL_LIB_DIR \ $exec_prefix/lib \ $prefix/lib \ /usr/local/bz2/lib \ /usr/local/lib \ /usr/lib \ /lib" for dir in $places; do if test -n "$trf_cv_lib_BZ2_LIB_DIR"; then break fi for libsuff in .so ".so.*" .sl .a .dylib; do if test -n "$trf_cv_lib_BZ2_LIB_DIR"; then break fi if test -f $dir/libbz2$libsuff; then trf_cv_lib_BZ2_LIB_DIR="$dir" BZ2_LIB_DIR="$dir" fi done done fi { echo "$as_me:$LINENO: result: $trf_cv_lib_BZ2_LIB_DIR" >&5 echo "${ECHO_T}$trf_cv_lib_BZ2_LIB_DIR" >&6; } if test -z "$trf_cv_lib_BZ2_LIB_DIR" ; then { echo "$as_me:$LINENO: WARNING: not found; use --with-bz2-lib-dir=path" >&5 echo "$as_me: WARNING: not found; use --with-bz2-lib-dir=path" >&2;} BZ2_LIB_DIR=. else TRF_TESTS="$TRF_TESTS hasBz" BZ2_LIB_DIR="`${CYGPATH} $trf_cv_lib_BZ2_LIB_DIR`" fi if test "x$ZLIB_STATIC" = "xyes" then eval cat >>confdefs.h <<_ACEOF #define ZLIB_STATIC_BUILD 1 _ACEOF fi if test "x$BZLIB_STATIC" = "xyes" then eval cat >>confdefs.h <<_ACEOF #define BZLIB_STATIC_BUILD 1 _ACEOF fi if test "x$MD5_STATIC" = "xyes" then eval cat >>confdefs.h <<_ACEOF #define MD5_STATIC_BUILD 1 _ACEOF fi if test "x$trf_debug" = "xyes" then eval cat >>confdefs.h <<_ACEOF #define TRF_DEBUG 1 _ACEOF fi if test "x$stream_debug" = "xyes" then eval cat >>confdefs.h <<_ACEOF #define TRF_STREAM_DEBUG 1 _ACEOF fi for ac_header in dlfcn.h stdlib.h features.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done #-------------------------------------------------------------------- # MD5 handling... # Cases: # (1) libcrypt not present => compile, use that name. # (2) libcrypt present, contains Md5 => nothing to do # (3) libcrypt present, no Md5 => compile, name = libmd5crypt #-------------------------------------------------------------------- MD5_LIB_FILE="" if test \( $HAS_LIBCRYPT -eq 0 \) then # (1) ## MD5_LIB_FILE=libcrypt$TCL_SHLIB_SUFFIX ## TRF_DEFS="$TRF_DEFS -DCRYPT_LIB_NAME=\\\"NONE\\\"" eval cat >>confdefs.h <<_ACEOF #define MD5_STATIC_BUILD 1 _ACEOF vars="md5-crypt/crypt-entry.c md5-crypt/md5-crypt.c md5-crypt/md5.c compat/stpncpy.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done elif test "`uname -s`" != "Darwin"; then # (2,3) if test \( $HAS_LIBCRYPT_MD5 -eq 0 \) then # (3) ## MD5_LIB_FILE=libmd5crypt$TCL_SHLIB_SUFFIX ## TRF_DEFS="$TRF_DEFS -DCRYPT_LIB_NAME=\\\"NONE\\\"" # Sun Solaris is special, we may not use -lcrypt ! # Verified for: SunOS 5.5.1 (Solaris 2.5) # SunOS 5.6 (Solaris 2.6) ## case "`uname -s`" in ## SunOS*) ;; ## *) LIBS="-lcrypt $LIBS" ## SHLIB_LD_LIBS="-lcrypt $SHLIB_LD_LIBS" ## ;; ## esac eval cat >>confdefs.h <<_ACEOF #define MD5_STATIC_BUILD 1 _ACEOF vars="md5-crypt/crypt-entry.c md5-crypt/md5-crypt.c md5-crypt/md5.c compat/stpncpy.c" for i in $vars; do case $i in \$*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ ; then { { echo "$as_me:$LINENO: error: could not find source file '$i'" >&5 echo "$as_me: error: could not find source file '$i'" >&2;} { (exit 1); exit 1; }; } fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done fi fi #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- ac_config_files="$ac_config_files Makefile test.setup" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS="" : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Trf $as_me 2.1.4, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ Trf config.status 2.1.4 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "test.setup") CONFIG_FILES="$CONFIG_FILES test.setup" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim CYGPATH!$CYGPATH$ac_delim EXEEXT!$EXEEXT$ac_delim PKG_LIB_FILE!$PKG_LIB_FILE$ac_delim PKG_STUB_LIB_FILE!$PKG_STUB_LIB_FILE$ac_delim PKG_STUB_SOURCES!$PKG_STUB_SOURCES$ac_delim PKG_STUB_OBJECTS!$PKG_STUB_OBJECTS$ac_delim PKG_TCL_SOURCES!$PKG_TCL_SOURCES$ac_delim PKG_HEADERS!$PKG_HEADERS$ac_delim PKG_INCLUDES!$PKG_INCLUDES$ac_delim PKG_LIBS!$PKG_LIBS$ac_delim PKG_CFLAGS!$PKG_CFLAGS$ac_delim TCL_VERSION!$TCL_VERSION$ac_delim TCL_BIN_DIR!$TCL_BIN_DIR$ac_delim TCL_SRC_DIR!$TCL_SRC_DIR$ac_delim TCL_LIB_FILE!$TCL_LIB_FILE$ac_delim TCL_LIB_FLAG!$TCL_LIB_FLAG$ac_delim TCL_LIB_SPEC!$TCL_LIB_SPEC$ac_delim TCL_STUB_LIB_FILE!$TCL_STUB_LIB_FILE$ac_delim TCL_STUB_LIB_FLAG!$TCL_STUB_LIB_FLAG$ac_delim TCL_STUB_LIB_SPEC!$TCL_STUB_LIB_SPEC$ac_delim TCL_LIBS!$TCL_LIBS$ac_delim TCL_DEFS!$TCL_DEFS$ac_delim TCL_EXTRA_CFLAGS!$TCL_EXTRA_CFLAGS$ac_delim TCL_LD_FLAGS!$TCL_LD_FLAGS$ac_delim TCL_SHLIB_LD_LIBS!$TCL_SHLIB_LD_LIBS$ac_delim zlibtcl_VERSION!$zlibtcl_VERSION$ac_delim zlibtcl_BIN_DIR!$zlibtcl_BIN_DIR$ac_delim zlibtcl_SRC_DIR!$zlibtcl_SRC_DIR$ac_delim zlibtcl_LIB_FILE!$zlibtcl_LIB_FILE$ac_delim zlibtcl_LIB_SPEC!$zlibtcl_LIB_SPEC$ac_delim zlibtcl_STUB_LIB_FILE!$zlibtcl_STUB_LIB_FILE$ac_delim zlibtcl_STUB_LIB_SPEC!$zlibtcl_STUB_LIB_SPEC$ac_delim zlibtcl_STUB_LIB_PATH!$zlibtcl_STUB_LIB_PATH$ac_delim zlibtcl_SRC_PATH!$zlibtcl_SRC_PATH$ac_delim zlibtcl_BUILD_PATH!$zlibtcl_BUILD_PATH$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim OBJEXT!$OBJEXT$ac_delim CPP!$CPP$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim SET_MAKE!$SET_MAKE$ac_delim RANLIB!$RANLIB$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim MATH_LIBS!$MATH_LIBS$ac_delim PKG_SOURCES!$PKG_SOURCES$ac_delim PKG_OBJECTS!$PKG_OBJECTS$ac_delim SHLIB_SUFFIX!$SHLIB_SUFFIX$ac_delim TCL_INCLUDES!$TCL_INCLUDES$ac_delim TCL_TOP_DIR_NATIVE!$TCL_TOP_DIR_NATIVE$ac_delim CLEANFILES!$CLEANFILES$ac_delim TCL_THREADS!$TCL_THREADS$ac_delim SHARED_BUILD!$SHARED_BUILD$ac_delim AR!$AR$ac_delim CELIB_DIR!$CELIB_DIR$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF LIBOBJS!$LIBOBJS$ac_delim DL_LIBS!$DL_LIBS$ac_delim CFLAGS_DEBUG!$CFLAGS_DEBUG$ac_delim CFLAGS_OPTIMIZE!$CFLAGS_OPTIMIZE$ac_delim CFLAGS_WARNING!$CFLAGS_WARNING$ac_delim STLIB_LD!$STLIB_LD$ac_delim SHLIB_LD!$SHLIB_LD$ac_delim SHLIB_LD_LIBS!$SHLIB_LD_LIBS$ac_delim SHLIB_CFLAGS!$SHLIB_CFLAGS$ac_delim LD_LIBRARY_PATH_VAR!$LD_LIBRARY_PATH_VAR$ac_delim CFLAGS_DEFAULT!$CFLAGS_DEFAULT$ac_delim LDFLAGS_DEFAULT!$LDFLAGS_DEFAULT$ac_delim TCL_DBGX!$TCL_DBGX$ac_delim MAKE_LIB!$MAKE_LIB$ac_delim MAKE_SHARED_LIB!$MAKE_SHARED_LIB$ac_delim MAKE_STATIC_LIB!$MAKE_STATIC_LIB$ac_delim MAKE_STUB_LIB!$MAKE_STUB_LIB$ac_delim RANLIB_STUB!$RANLIB_STUB$ac_delim TCLSH_PROG!$TCLSH_PROG$ac_delim ZLIB_INCLUDE_DIR!$ZLIB_INCLUDE_DIR$ac_delim ZLIB_LIB_DIR!$ZLIB_LIB_DIR$ac_delim SSL_INCLUDE_DIR!$SSL_INCLUDE_DIR$ac_delim SSL_LIB_DIR!$SSL_LIB_DIR$ac_delim BZ2_INCLUDE_DIR!$BZ2_INCLUDE_DIR$ac_delim BZ2_LIB_DIR!$BZ2_LIB_DIR$ac_delim TRF_TESTS!$TRF_TESTS$ac_delim MD5_LIB_FILE!$MD5_LIB_FILE$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 28; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi #-------------------------------------------------------------------- trf2.1.4/patches/0000755000175000017500000000000011216344734013206 5ustar sergeisergeitrf2.1.4/patches/v8.1/0000755000175000017500000000000011216344734013702 5ustar sergeisergeitrf2.1.4/patches/v8.1/tclStubs.c0000644000175000017500000017132511216344362015657 0ustar sergeisergei/* * 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.1 1999/05/07 18:51:00 aku 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); } /* Slot 345 */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp * interp; Tcl_ChannelType * typePtr; ClientData instanceData; int mask; Tcl_Channel prevChan; { return (tclStubsPtr->tcl_ReplaceChannel)(interp, typePtr, instanceData, mask, prevChan); } /* Slot 346 */ void Tcl_UndoReplaceChannel(interp, chan) Tcl_Interp * interp; Tcl_Channel chan; { (tclStubsPtr->tcl_UndoReplaceChannel)(interp, chan); } /* !END!: Do not edit above this line. */ trf2.1.4/patches/v8.1/standard.patch0000644000175000017500000004300711216344362016524 0ustar sergeisergei*** ./tcl.decls.orig Fri May 7 20:30:02 1999 --- ./tcl.decls Fri May 7 20:33:35 1999 *************** *** 967,977 **** 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 { --- 967,996 ---- void Tcl_InitMemory(Tcl_Interp *interp) } + # Andreas Kupries , 03/21/1999 + # "Trf-Patch for filtering channels" + # + # C-Level API for (un)stacking of channels. This allows the introduction + # of filtering channels with relatively little changes to the core. + # This patch was created in cooperation with Jan Nijtmans + # and is therefore part of his plus-patches too. + # + # It would have been possible to place the following definitions according + # to the alphabetical order used elsewhere in this file, but I decided + # against that to ease the maintenance of the patch across new tcl versions + # (patch usually has no problems to integrate the patch file for the last + # version into the new one). + + declare 281 generic { + Tcl_Channel Tcl_StackChannel(Tcl_Interp *interp, \ + Tcl_ChannelType *typePtr, ClientData instanceData, \ + int mask, Tcl_Channel prevChan) + } + declare 282 generic { + void Tcl_UnstackChannel(Tcl_Interp *interp, Tcl_Channel chan) + } + # Reserved for future use (8.0.x vs. 8.1) # declare 283 generic { # } # declare 284 generic { *** ./tclDecls.h.orig Fri May 7 20:30:02 1999 --- ./tclDecls.h Fri May 7 20:33:35 1999 *************** *** 875,882 **** 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 */ --- 875,888 ---- int * patchLevel, int * type)); /* 280 */ EXTERN void Tcl_InitMemory _ANSI_ARGS_((Tcl_Interp * interp)); ! /* 281 */ ! EXTERN Tcl_Channel Tcl_StackChannel _ANSI_ARGS_((Tcl_Interp * interp, ! Tcl_ChannelType * typePtr, ! ClientData instanceData, int mask, ! Tcl_Channel prevChan)); ! /* 282 */ ! EXTERN void Tcl_UnstackChannel _ANSI_ARGS_(( ! Tcl_Interp * interp, Tcl_Channel chan)); /* Slot 283 is reserved */ /* Slot 284 is reserved */ /* Slot 285 is reserved */ *************** *** 1439,1446 **** 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; --- 1445,1452 ---- 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 */ ! Tcl_Channel (*tcl_StackChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 281 */ ! void (*tcl_UnstackChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 282 */ void *reserved283; void *reserved284; void *reserved285; *************** *** 2670,2677 **** #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 */ --- 2676,2689 ---- #define Tcl_InitMemory \ (tclStubsPtr->tcl_InitMemory) /* 280 */ #endif ! #ifndef Tcl_StackChannel ! #define Tcl_StackChannel \ ! (tclStubsPtr->tcl_StackChannel) /* 281 */ ! #endif ! #ifndef Tcl_UnstackChannel ! #define Tcl_UnstackChannel \ ! (tclStubsPtr->tcl_UnstackChannel) /* 282 */ ! #endif /* Slot 283 is reserved */ /* Slot 284 is reserved */ /* Slot 285 is reserved */ *** ./tclIO.c.orig Fri May 7 20:30:02 1999 --- ./tclIO.c Fri May 7 20:33:35 1999 *************** *** 202,207 **** --- 202,229 ---- int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ + + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * The single change to the internal datastructures of the core. Every + * channel now maintains a reference to the channel he is stacked upon. + * This reference is NULL for normal channels. Only the two exported + * procedures (Tcl_StackChannel and Tcl_UnstackChannel, see at the + * end of 'tcl.h') use this field in a non-trivial way. + * + * Of the existing procedures the only following are affected by this + * change: + * + * - Tcl_RegisterChannel + * - Tcl_CreateChannel + * - CloseChannel + * + * The why is explained at the changed locations. + */ + + struct Channel* supercedes; /* Refers to channel this one was stacked upon */ + } Channel; /* *************** *** 1038,1044 **** if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! panic("Tcl_RegisterChannel: duplicate channel names"); } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } --- 1060,1080 ---- if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! ! /* Andreas Kupries , 12/13/1998 ! * "Trf-Patch for filtering channels" ! * ! * This is the change to 'Tcl_RegisterChannel'. ! * ! * Explanation: ! * The moment a channel is stacked upon another he ! * takes the identity of the channel he supercedes, ! * i.e. he gets the *same* name. Because of this we ! * cannot check for duplicate names anymore, they ! * have to be allowed now. ! */ ! ! /* panic("Tcl_RegisterChannel: duplicate channel names"); */ } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } *************** *** 1297,1302 **** --- 1333,1352 ---- chanPtr->timer = NULL; chanPtr->csPtr = NULL; + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * This is the change to 'Tcl_CreateChannel'. + * + * Explanation: + * It is of course necessary to initialize the new field + * in the Channel structure. The chosen value indicates + * that the created channel is a normal one, and not + * stacked upon another. + */ + + chanPtr->supercedes = (Channel*) NULL; + chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) *************** *** 1330,1335 **** --- 1380,1622 ---- return (Tcl_Channel) chanPtr; } + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * The following two procedures are the new, exported ones. They + * - create a channel stacked upon an existing one and + * - pop a stacked channel off, thus revealing the superceded one. + * + * Please read the following completely. + */ + + /* + *---------------------------------------------------------------------- + * + * Tcl_StackChannel -- + * + * Replaces an entry in the hash table for a Tcl_Channel + * record. The replacement is a new channel with same name, + * it supercedes the replaced channel. Input and output of + * the superceded channel is now going through the newly + * created channel and allows the arbitrary filtering/manipulation + * of the dataflow. + * + * Results: + * Returns the new Tcl_Channel. + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + + Tcl_Channel + Tcl_StackChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_ChannelType *typePtr; /* The channel type record for the new + * channel. */ + ClientData instanceData; /* Instance specific data for the new + * channel. */ + int mask; /* TCL_READABLE & TCL_WRITABLE to indicate + * if the channel is readable, writable. */ + Tcl_Channel prevChan; /* The channel structure to replace */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr, *pt, *prevPt; + + /* + * Find the given channel in the list of all channels, compute enough + * information to allow easy removal after the conditions are met. + */ + + prevPt = (Channel*) NULL; + pt = (Channel*) tsdPtr->firstChanPtr; + + while (pt != (Channel *) prevChan) { + prevPt = pt; + pt = pt->nextChanPtr; + } + + /* + * 'pt == prevChan' now + */ + + if (!pt) { + return (Tcl_Channel) NULL; + } + + /* + * Here we check if the given "mask" matches the "flags" + * of the already existing channel. + * + * | - | R | W | RW | + * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) + * - | | | | | + * R | | + | | + | The superceding channel is allowed to + * W | | | + | + | restrict the capabilities of the + * RW| | + | + | + | superceded one ! + * --+---+---+---+----+ + */ + + if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { + return (Tcl_Channel) NULL; + } + + + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); + chanPtr->flags = mask; + + /* + * Set the channel up initially in no Input translation mode and + * no Output translation mode. + */ + + chanPtr->inputTranslation = TCL_TRANSLATE_LF; + chanPtr->outputTranslation = TCL_TRANSLATE_LF; + chanPtr->inEofChar = 0; + chanPtr->outEofChar = 0; + + chanPtr->unreportedError = 0; + chanPtr->instanceData = instanceData; + chanPtr->typePtr = typePtr; + chanPtr->refCount = 0; + chanPtr->closeCbPtr = (CloseCallback *) NULL; + chanPtr->curOutPtr = (ChannelBuffer *) NULL; + chanPtr->outQueueHead = (ChannelBuffer *) NULL; + chanPtr->outQueueTail = (ChannelBuffer *) NULL; + chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; + chanPtr->inQueueHead = (ChannelBuffer *) NULL; + 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; + + /* 06/12/1998: New for Tcl 8.1 + * + * Take over the encoding from the superceded channel, so that it will be + * executed in the future despite the replacement, and at the proper time + * (*after* / *before* our transformation, depending on the direction of + * the dataflow). + * + * *Important* + * The I/O functionality of the filtering channel has to use 'Tcl_Read' to + * get at the underlying information. This will circumvent the de/encoder + * stage [*] in the superceded channel and removes the need to trouble + * ourselves with 'ByteArray's too. + * + * [*] I'm talking about the conversion between UNICODE and other + * representations, like ASCII. + */ + + chanPtr->encoding=Tcl_GetEncoding(interp,Tcl_GetEncodingName(pt->encoding)); + chanPtr->inputEncodingState = pt->inputEncodingState; + chanPtr->inputEncodingFlags = pt->inputEncodingFlags; + chanPtr->outputEncodingState = pt->outputEncodingState; + chanPtr->outputEncodingFlags = pt->outputEncodingFlags; + + chanPtr->outputStage = NULL; + + if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { + chanPtr->outputStage = (char *) + ckalloc((unsigned) (chanPtr->bufSize + 2)); + } + + chanPtr->supercedes = (Channel*) prevChan; + + chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); + strcpy (chanPtr->channelName, pt->channelName); + + if (prevPt) { + prevPt->nextChanPtr = chanPtr; + } else { + tsdPtr->firstChanPtr = chanPtr; + } + + chanPtr->nextChanPtr = pt->nextChanPtr; + + Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); + + /* + * The superceded channel is effectively unregistered + */ + + /*chanPtr->supercedes->refCount --;*/ + + return (Tcl_Channel) chanPtr; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_UnstackChannel -- + * + * Unstacks an entry in the hash table for a Tcl_Channel + * record. This is the reverse to 'Tcl_StackChannel'. + * The old, superceded channel is uncovered and re-registered + * in the appropriate datastructures. + * + * Results: + * Returns the old Tcl_Channel, i.e. the one which was stacked over. + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + + void + Tcl_UnstackChannel (interp, chan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_Channel chan; /* The channel to unstack */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel* chanPtr = (Channel*) chan; + + if (chanPtr->supercedes != (Channel*) NULL) { + Tcl_HashTable *hTblPtr; /* Hash table of channels. */ + Tcl_HashEntry *hPtr; /* Search variable. */ + int new; /* Is the hash entry new or does it exist? */ + + /* + * Insert the channel we were stacked upon back into + * the list of open channels. Place it back into the hashtable too. + * Correct 'refCount', as this actually unregisters 'chan'. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + + hTblPtr = GetChannelTable (interp); + hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); + + Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); + chanPtr->refCount --; + + /* + * The superceded channel is effectively registered again + */ + + /*chanPtr->supercedes->refCount ++;*/ + } + + /* + * Disconnect the channels, then do a regular close upon the + * stacked one, the filtering channel. This may cause flushing + * of data into the superceded channel (if the filtering channel + * ('chan') remembered its parent in itself). + */ + + chanPtr->supercedes = NULL; + + if (chanPtr->refCount == 0) { + Tcl_Close (interp, chan); + } + } + /* *---------------------------------------------------------------------- * *************** *** 2003,2008 **** --- 2290,2330 ---- if (errorCode != 0) { Tcl_SetErrno(errorCode); } + } + + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * This is the change to 'CloseChannel'. + * + * Explanation + * Closing a filtering channel closes the one it + * superceded too. This basically ripples through + * the whole chain of filters until it reaches + * the underlying normal channel. + * + * This is done by reintegrating the superceded + * channel into the (thread) global list of open + * channels and then invoking a regular close. + * There is no need to handle the complexities of + * this process by ourselves. + * + * *Note* + * This has to be done after the call to the + * 'closeProc' of the filtering channel to allow + * that one the flushing of internal buffers into + * the underlying channel. + */ + + if (chanPtr->supercedes != (Channel*) NULL) { + /* Insert the channel we were stacked upon back into + * the list of open channels, then do a regular close. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + chanPtr->supercedes->refCount --; /* is deregistered */ + Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* *** ./tclStubInit.c.orig Fri May 7 20:30:02 1999 --- ./tclStubInit.c Fri May 7 20:33:35 1999 *************** *** 593,600 **** Tcl_PanicVA, /* 278 */ Tcl_GetVersion, /* 279 */ Tcl_InitMemory, /* 280 */ ! NULL, /* 281 */ ! NULL, /* 282 */ NULL, /* 283 */ NULL, /* 284 */ NULL, /* 285 */ --- 593,600 ---- Tcl_PanicVA, /* 278 */ Tcl_GetVersion, /* 279 */ Tcl_InitMemory, /* 280 */ ! Tcl_StackChannel, /* 281 */ ! Tcl_UnstackChannel, /* 282 */ NULL, /* 283 */ NULL, /* 284 */ NULL, /* 285 */ *** ./tclStubs.c.orig Fri May 7 20:30:02 1999 --- ./tclStubs.c Fri May 7 20:33:35 1999 *************** *** 3263,3267 **** --- 3263,3288 ---- (tclStubsPtr->tcl_ServiceModeHook)(mode); } + /* Slot 345 */ + Tcl_Channel + Tcl_StackChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp * interp; + Tcl_ChannelType * typePtr; + ClientData instanceData; + int mask; + Tcl_Channel prevChan; + { + return (tclStubsPtr->tcl_StackChannel)(interp, typePtr, instanceData, mask, prevChan); + } + + /* Slot 346 */ + void + Tcl_UnstackChannel(interp, chan) + Tcl_Interp * interp; + Tcl_Channel chan; + { + (tclStubsPtr->tcl_UnstackChannel)(interp, chan); + } + /* !END!: Do not edit above this line. */ trf2.1.4/patches/v8.1/tcl.decls0000644000175000017500000011314311216344362015500 0ustar sergeisergei# 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.1 1999/05/07 18:50:58 aku 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) } # Andreas Kupries , 03/21/1999 # "Trf-Patch for filtering channels" # # C-Level API for (un)stacking of channels. This allows the introduction # of filtering channels with relatively little changes to the core. # This patch was created in cooperation with Jan Nijtmans # and is therefore part of his plus-patches too. # # It would have been possible to place the following definitions according # to the alphabetical order used elsewhere in this file, but I decided # against that to ease the maintenance of the patch across new tcl versions # (patch usually has no problems to integrate the patch file for the last # version into the new one). declare 281 generic { Tcl_Channel Tcl_ReplaceChannel(Tcl_Interp *interp, \ Tcl_ChannelType *typePtr, ClientData instanceData, \ int mask, Tcl_Channel prevChan) } declare 282 generic { void Tcl_UndoReplaceChannel(Tcl_Interp *interp, Tcl_Channel chan) } # Reserved for future use (8.0.x vs. 8.1) # 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) } declare 367 generic { int Tcl_Access(CONST char *path, int mode) } declare 368 generic { int Tcl_Stat(CONST char *path, struct stat *bufPtr) } ############################################################################## # 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) } trf2.1.4/patches/v8.1/tclIO.c0000644000175000017500000072642711216344362015077 0ustar sergeisergei/* * 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 1999/05/07 18:50:59 aku 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. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) # define EWOULDBLOCK EAGAIN #endif #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) error one of EWOULDBLOCK or EAGAIN must be defined #endif /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this * structure. */ typedef struct CopyState { struct Channel *readPtr; /* Pointer to input channel. */ struct Channel *writePtr; /* Pointer to output channel. */ int readFlags; /* Original read channel flags. */ int writeFlags; /* Original write channel flags. */ int toRead; /* Number of bytes to copy, or -1. */ int total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ 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) /* * Structure to record a close callback. One such record exists for * each close callback registered for a channel. */ typedef struct CloseCallback { Tcl_CloseProc *proc; /* The procedure to call. */ ClientData clientData; /* Arbitrary one-word data to pass * to the callback. */ struct CloseCallback *nextPtr; /* For chaining close callbacks. */ } CloseCallback; /* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to * invoke the saved script in the interpreter designed in this record. */ 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; /* * struct Channel: * * One of these structures is allocated for each open channel. It contains data * specific to the channel but which belongs to the generic part of the Tcl * channel mechanism, and it points at an instance specific (and type * specific) * instance data, and at a channel type structure. */ 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. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ struct ChannelHandler *chPtr;/* List of channel handlers registered * for this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ struct Channel *nextChanPtr;/* Next in list of channels currently open. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for * event handlers ("fileevent") on this * channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * The single change to the internal datastructures of the core. Every * channel now maintains a reference to the channel he is stacked upon. * This reference is NULL for normal channels. Only the two exported * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the * end of 'tcl.h') use this field in a non-trivial way. * * Of the existing procedures the only following are affected by this * change: * * - Tcl_RegisterChannel * - Tcl_CreateChannel * - CloseChannel * * The why is explained at the changed locations. */ struct Channel* supercedes; /* Refers to channel this one was stacked upon */ } Channel; /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in * nonblocking mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the * curOutPtr field in the * channel structure) should be * output as soon as possible even * though it may not be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the * queued output buffers has been * scheduled. */ #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No * further Tcl-level IO on the * channel is allowed. */ #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. * This bit is cleared before every * input operation. */ #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because * we saw the input eofChar. This bit * prevents clearing of the EOF bit * before every input operation. */ #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. */ typedef struct ChannelHandler { Channel *chanPtr; /* The channel structure for this channel. */ int mask; /* Mask of desired events. */ Tcl_ChannelProc *proc; /* Procedure to call in the type of * Tcl_CreateChannelHandler. */ ClientData clientData; /* Argument to pass to procedure. */ struct ChannelHandler *nextPtr; /* Next one in list of registered handlers. */ } ChannelHandler; /* * This structure keeps track of the current ChannelHandler being invoked in * the current invocation of ChannelHandlerEventProc. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. * The nextPtr field is used to chain together all recursive invocations, so * that Tcl_DeleteChannelHandler can find all the recursively nested * invocations of ChannelHandlerEventProc and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. */ typedef struct NextChannelHandler { 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 * for stdin/stdout/stderr in new interpreters. * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ 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 * closed. * * Results: * None. * * Side effects: * Causes the callback to be called in the future when the channel * will be closed. * *---------------------------------------------------------------------- */ void Tcl_CreateCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to create the * close callback. */ Tcl_CloseProc *proc; /* The callback routine to call when the * channel will be closed. */ ClientData clientData; /* Arbitrary data to pass to the * close callback. */ { Channel *chanPtr; CloseCallback *cbPtr; chanPtr = (Channel *) chan; cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; cbPtr->nextPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr; } /* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * * Removes a callback that would have been called on closing * the channel. If there is no matching callback then this * function has no effect. * * Results: * None. * * Side effects: * The callback will not be called in the future when the channel * is eventually closed. * *---------------------------------------------------------------------- */ void Tcl_DeleteCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to cancel the * close callback. */ Tcl_CloseProc *proc; /* The procedure for the callback to * remove. */ ClientData clientData; /* The callback data for the callback * to remove. */ { Channel *chanPtr; CloseCallback *cbPtr, *cbPrevPtr; chanPtr = (Channel *) chan; for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL; cbPtr != (CloseCallback *) NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == (CloseCallback *) NULL) { chanPtr->closeCbPtr = cbPtr->nextPtr; } ckfree((char *) cbPtr); break; } else { cbPrevPtr = cbPtr; } } } /* *---------------------------------------------------------------------- * * GetChannelTable -- * * Gets and potentially initializes the channel table for an * interpreter. If it is initializing the table it also inserts * channels for stdin, stdout and stderr if the interpreter is * trusted. * * Results: * A pointer to the hash table created, for use by the caller. * * Side effects: * Initializes the channel table for an interpreter. May create * channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */ static Tcl_HashTable * GetChannelTable(interp) Tcl_Interp *interp; { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); (void) Tcl_SetAssocData(interp, "tclIO", (Tcl_InterpDeleteProc *) DeleteChannelTable, (ClientData) hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels * for stdin, stdout and stderr (possibly creating them in the * process). */ if (Tcl_IsSafe(interp) == 0) { stdinChan = Tcl_GetStdChannel(TCL_STDIN); if (stdinChan != NULL) { Tcl_RegisterChannel(interp, stdinChan); } stdoutChan = Tcl_GetStdChannel(TCL_STDOUT); if (stdoutChan != NULL) { Tcl_RegisterChannel(interp, stdoutChan); } stderrChan = Tcl_GetStdChannel(TCL_STDERR); if (stderrChan != NULL) { Tcl_RegisterChannel(interp, stderrChan); } } } return hTblPtr; } /* *---------------------------------------------------------------------- * * DeleteChannelTable -- * * Deletes the channel table for an interpreter, closing any open * channels whose refcount reaches zero. This procedure is invoked * when an interpreter is deleted, via the AssocData cleanup * mechanism. * * Results: * None. * * Side effects: * Deletes the hash table of channels. May close channels. May flush * output on closed channels. Removes any channeEvent handlers that were * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable(clientData, interp) ClientData clientData; /* The per-interpreter data structure. */ Tcl_Interp *interp; /* The interpreter being deleted. */ { Tcl_HashTable *hTblPtr; /* The hash table. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* Channel being deleted. */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* Variables to loop over all channel events * registered, to delete the ones that refer * to the interpreter being deleted. */ /* * Delete all the registered channels - this will close channels whose * refcount reaches zero. */ hTblPtr = (Tcl_HashTable *) clientData; for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); /* * Remove any fileevents registered in this interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } /* * Cannot call Tcl_UnregisterChannel because that procedure calls * Tcl_GetAssocData to get the channel table, which might already * be inaccessible from the interpreter structure. Instead, we * emulate the behavior of Tcl_UnregisterChannel directly here. */ Tcl_DeleteHashEntry(hPtr); chanPtr->refCount--; if (chanPtr->refCount <= 0) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } } Tcl_DeleteHashTable(hTblPtr); ckfree((char *) hTblPtr); } /* *---------------------------------------------------------------------- * * CheckForStdChannelsBeingClosed -- * * Perform special handling for standard channels being closed. When * given a standard channel, if the refcount is now 1, it means that * the last reference to the standard channel is being explicitly * closed. Now bump the refcount artificially down to 0, to ensure the * normal handling of channels being closed will occur. Also reset the * static pointer to the channel to NULL, to avoid dangling references. * * Results: * None. * * Side effects: * Manipulates the refcount on standard channels. May smash the global * static pointer to a standard channel. * *---------------------------------------------------------------------- */ 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; } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_RegisterChannel'. * * Explanation: * The moment a channel is stacked upon another he * takes the identity of the channel he supercedes, * i.e. he gets the *same* name. Because of this we * cannot check for duplicate names anymore, they * have to be allowed now. */ /* 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. * If the interpreter given as argument is NULL, it only decrements the * reference count. * * Results: * A standard Tcl result. * * Side effects: * Deletes the hash entry for a channel associated with an interpreter. * *---------------------------------------------------------------------- */ int Tcl_UnregisterChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which channel is defined. */ Tcl_Channel chan; /* Channel to delete. */ { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The real IO channel. */ chanPtr = (Channel *) chan; if (interp != (Tcl_Interp *) NULL) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } hPtr = Tcl_FindHashEntry(hTblPtr, chanPtr->channelName); if (hPtr == (Tcl_HashEntry *) NULL) { return TCL_OK; } if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) { return TCL_OK; } Tcl_DeleteHashEntry(hPtr); /* * Remove channel handlers that refer to this interpreter, so that they * will not be present if the actual close is delayed and more events * happen on the channel. This may occur if the channel is shared * between several interpreters, or if the channel has async * flushing active. */ CleanupChannelHandlers(interp, chanPtr); } chanPtr->refCount--; /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); /* * If the refCount reached zero, close the actual channel. */ if (chanPtr->refCount <= 0) { /* * Ensure that if there is another buffer, it gets flushed * whether or not we are doing a background flush. */ if ((chanPtr->curOutPtr != NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; } chanPtr->flags |= CHANNEL_CLOSED; if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { if (Tcl_Close(interp, chan) != TCL_OK) { return TCL_ERROR; } } } 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. */ int *modePtr; /* Where to store the mode in which the * channel was opened? Will contain an ORed * combination of TCL_READABLE and * TCL_WRITABLE, if non-NULL. */ { Channel *chanPtr; /* The actual channel. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ char *name; /* Translated name. */ /* * Substitute "stdin", etc. Note that even though we immediately * find the channel using Tcl_GetStdChannel, we still need to look * it up in the specified interpreter to ensure that it is present * in the channel table. Otherwise, safe interpreters would always * have access to the standard channels. */ name = chanName; if ((chanName[0] == 's') && (chanName[1] == 't')) { chanPtr = NULL; if (strcmp(chanName, "stdin") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDIN); } else if (strcmp(chanName, "stdout") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDOUT); } else if (strcmp(chanName, "stderr") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDERR); } if (chanPtr != NULL) { name = chanPtr->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == (Tcl_HashEntry *) NULL) { Tcl_AppendResult(interp, "can not find channel named \"", chanName, "\"", (char *) NULL); return NULL; } chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (modePtr != NULL) { *modePtr = (chanPtr->flags & (TCL_READABLE|TCL_WRITABLE)); } return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_CreateChannel -- * * Creates a new entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Creates a new Tcl_Channel instance and inserts it into the * hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_CreateChannel(typePtr, chanName, instanceData, mask) 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. */ chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_CreateChannel'. * * Explanation: * It is of course necessary to initialize the new field * in the Channel structure. The chosen value indicates * that the created channel is a normal one, and not * stacked upon another. */ chanPtr->supercedes = (Channel*) 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; } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * The following two procedures are the new, exported ones. They * - create a channel stacked upon an existing one and * - pop a stacked channel off, thus revealing the superceded one. * * Please read the following completely. */ /* *---------------------------------------------------------------------- * * Tcl_ReplaceChannel -- * * Replaces an entry in the hash table for a Tcl_Channel * record. The replacement is a new channel with same name, * it supercedes the replaced channel. Input and output of * the superceded channel is now going through the newly * created channel and allows the arbitrary filtering/manipulation * of the dataflow. * * Results: * Returns the new Tcl_Channel. * * Side effects: * See above. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_ChannelType *typePtr; /* The channel type record for the new * channel. */ ClientData instanceData; /* Instance specific data for the new * channel. */ int mask; /* TCL_READABLE & TCL_WRITABLE to indicate * if the channel is readable, writable. */ Tcl_Channel prevChan; /* The channel structure to replace */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel *chanPtr, *pt, *prevPt; /* * Find the given channel in the list of all channels, compute enough * information to allow easy removal after the conditions are met. */ prevPt = (Channel*) NULL; pt = (Channel*) tsdPtr->firstChanPtr; while (pt != (Channel *) prevChan) { prevPt = pt; pt = pt->nextChanPtr; } /* * 'pt == prevChan' now */ if (!pt) { return (Tcl_Channel) NULL; } /* * Here we check if the given "mask" matches the "flags" * of the already existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to * W | | | + | + | restrict the capabilities of the * RW| | + | + | + | superceded one ! * --+---+---+---+----+ */ if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { return (Tcl_Channel) NULL; } chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); chanPtr->flags = mask; /* * Set the channel up initially in no Input translation mode and * no Output translation mode. */ chanPtr->inputTranslation = TCL_TRANSLATE_LF; chanPtr->outputTranslation = TCL_TRANSLATE_LF; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* 06/12/1998: New for Tcl 8.1 * * Take over the encoding from the superceded channel, so that it will be * executed in the future despite the replacement, and at the proper time * (*after* / *before* our transformation, depending on the direction of * the dataflow). * * *Important* * The I/O functionality of the filtering channel has to use 'Tcl_Read' to * get at the underlying information. This will circumvent the de/encoder * stage [*] in the superceded channel and removes the need to trouble * ourselves with 'ByteArray's too. * * [*] I'm talking about the conversion between UNICODE and other * representations, like ASCII. */ chanPtr->encoding = pt->encoding; chanPtr->inputEncodingState = pt->inputEncodingState; chanPtr->inputEncodingFlags = pt->inputEncodingFlags; chanPtr->outputEncodingState = pt->outputEncodingState; chanPtr->outputEncodingFlags = pt->outputEncodingFlags; chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) ckalloc((unsigned) (chanPtr->bufSize + 2)); } chanPtr->supercedes = (Channel*) prevChan; chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); strcpy (chanPtr->channelName, pt->channelName); if (prevPt) { prevPt->nextChanPtr = chanPtr; } else { tsdPtr->firstChanPtr = chanPtr; } chanPtr->nextChanPtr = pt->nextChanPtr; Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); /* * The superceded channel is effectively unregistered */ /*chanPtr->supercedes->refCount --;*/ return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_UndoReplaceChannel -- * * Unstacks an entry in the hash table for a Tcl_Channel * record. This is the reverse to 'Tcl_ReplaceChannel'. * The old, superceded channel is uncovered and re-registered * in the appropriate datastructures. * * Results: * Returns the old Tcl_Channel, i.e. the one which was stacked over. * * Side effects: * See above. * *---------------------------------------------------------------------- */ void Tcl_UndoReplaceChannel (interp, chan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_Channel chan; /* The channel to unstack */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel* chanPtr = (Channel*) chan; if (chanPtr->supercedes != (Channel*) NULL) { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ int new; /* Is the hash entry new or does it exist? */ /* * Insert the channel we were stacked upon back into * the list of open channels. Place it back into the hashtable too. * Correct 'refCount', as this actually unregisters 'chan'. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; hTblPtr = GetChannelTable (interp); hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); chanPtr->refCount --; /* * The superceded channel is effectively registered again */ /*chanPtr->supercedes->refCount ++;*/ } /* * Disconnect the channels, then do a regular close upon the * stacked one, the filtering channel. This may cause flushing * of data into the superceded channel (if the filtering channel * ('chan') remembered its parent in itself). */ chanPtr->supercedes = NULL; if (chanPtr->refCount == 0) { Tcl_Close (interp, chan); } } /* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * * Computes a mask indicating whether the channel is open for * reading and writing. * * Results: * An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelMode(chan) Tcl_Channel chan; /* The channel for which the mode is * being computed. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE)); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * * Returns the string identifying the channel name. * * Results: * The string containing the channel name. This memory is * owned by the generic layer and should not be modified by * the caller. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Tcl_GetChannelName(chan) Tcl_Channel chan; /* The channel for which to return the name. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->channelName; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * * Given a channel structure, returns the channel type structure. * * Results: * Returns a pointer to the channel type structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ChannelType * Tcl_GetChannelType(chan) Tcl_Channel chan; /* The channel to return type for. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->typePtr; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * * Returns an OS handle associated with a channel. * * Results: * Returns TCL_OK and places the handle in handlePtr, or returns * TCL_ERROR on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelHandle(chan, direction, handlePtr) Tcl_Channel chan; /* The channel to get file from. */ int direction; /* TCL_WRITABLE or TCL_READABLE. */ ClientData *handlePtr; /* Where to store handle */ { Channel *chanPtr; /* The actual channel. */ ClientData handle; int result; chanPtr = (Channel *) chan; result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData, direction, &handle); if (handlePtr) { *handlePtr = handle; } return result; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * * Returns the client data associated with a channel. * * Results: * The client data. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_GetChannelInstanceData(chan) 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 * that two input buffers are saved (one in the input queue and * another in the saveInBufPtr field) and that curOutPtr is set * to a buffer. Only if these conditions are met is the buffer * freed to the OS. * * Results: * None. * * Side effects: * May free a buffer to the OS. * *---------------------------------------------------------------------- */ static void RecycleBuffer(chanPtr, bufPtr, mustDiscard) Channel *chanPtr; /* Channel for which to recycle buffers. */ ChannelBuffer *bufPtr; /* The buffer to recycle. */ int mustDiscard; /* If nonzero, free the buffer to the * OS, always. */ { /* * Do we have to free the buffer to the OS? */ if (mustDiscard) { ckfree((char *) bufPtr); return; } /* * Only save buffers for the input queue if the channel is readable. */ if (chanPtr->flags & TCL_READABLE) { if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) { chanPtr->inQueueHead = bufPtr; chanPtr->inQueueTail = bufPtr; goto keepit; } if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) { chanPtr->saveInBufPtr = bufPtr; goto keepit; } } /* * Only save buffers for the output queue if the channel is writable. */ if (chanPtr->flags & TCL_WRITABLE) { if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) { chanPtr->curOutPtr = bufPtr; goto keepit; } } /* * 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 -- * * Discards all output queued in the output queue of a channel. * * Results: * None. * * Side effects: * Recycles buffers. * *---------------------------------------------------------------------- */ static void DiscardOutputQueued(chanPtr) Channel *chanPtr; /* The channel for which to discard output. */ { ChannelBuffer *bufPtr; while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { bufPtr = chanPtr->outQueueHead; chanPtr->outQueueHead = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, 0); } chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; } /* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * * This function checks is a given channel is Dead. * (A channel that has been closed but not yet deallocated.) * * Results: * True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: * None * *---------------------------------------------------------------------- */ static int CheckForDeadChannel(interp, chanPtr) Tcl_Interp *interp; /* For error reporting (can be NULL) */ Channel *chanPtr; /* The channel to check. */ { if (chanPtr->flags & CHANNEL_DEAD) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, "unable to access channel: invalid channel", (char *) NULL); } return 1; } return 0; } /* *---------------------------------------------------------------------- * * FlushChannel -- * * This function flushes as much of the queued output as is possible * now. If calledFromAsyncFlush is nonzero, it is being called in an * event handler to flush channel output asynchronously. * * Results: * 0 if successful, else the error code that was returned by the * channel type operation. * * Side effects: * May produce output on a channel. May block indefinitely if the * channel is synchronous. May schedule an async flush on the channel. * May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */ static int FlushChannel(interp, chanPtr, calledFromAsyncFlush) Tcl_Interp *interp; /* For error reporting during close. */ Channel *chanPtr; /* The channel to flush on. */ int calledFromAsyncFlush; /* If nonzero then we are being * called from an asynchronous * flush callback. */ { 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. */ if (CheckForDeadChannel(interp,chanPtr)) return -1; /* * Loop over the queued buffers and attempt to flush as * much as possible of the queued output to the channel. */ while (1) { /* * 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 { chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr; } chanPtr->outQueueTail = chanPtr->curOutPtr; chanPtr->curOutPtr = (ChannelBuffer *) NULL; } bufPtr = chanPtr->outQueueHead; /* * If we are not being called from an async flush and an async * flush is active, we just return without producing any output. */ if ((!calledFromAsyncFlush) && (chanPtr->flags & BG_FLUSH_SCHEDULED)) { return 0; } /* * If the output queue is still empty, break out of the while loop. */ if (bufPtr == (ChannelBuffer *) NULL) { break; /* Out of the "while (1)". */ } /* * 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. */ if (written < 0) { /* * If the last attempt to write was interrupted, simply retry. */ if (errorCode == EINTR) { errorCode = 0; continue; } /* * If the channel is non-blocking and we would have blocked, * start a background flushing handler and break out of the loop. */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { if (chanPtr->flags & CHANNEL_NONBLOCKING) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { chanPtr->flags |= BG_FLUSH_SCHEDULED; UpdateInterest(chanPtr); } errorCode = 0; break; } else { panic("Blocking channel driver did not block on output"); } } /* * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { if (chanPtr->unreportedError == 0) { chanPtr->unreportedError = errorCode; } } else { Tcl_SetErrno(errorCode); if (interp != NULL) { Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } } /* * 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. */ if ((chanPtr->flags & CHANNEL_CLOSED) && (chanPtr->refCount <= 0) && (chanPtr->outQueueHead == (ChannelBuffer *) NULL) && ((chanPtr->curOutPtr == (ChannelBuffer *) NULL) || (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->nextRemoved))) { return CloseChannel(interp, chanPtr, errorCode); } return errorCode; } /* *---------------------------------------------------------------------- * * CloseChannel -- * * Utility procedure to close a channel and free its associated * resources. * * Results: * 0 on success or a POSIX error code if the operation failed. * * Side effects: * May close the actual channel; may free memory. * *---------------------------------------------------------------------- */ static int CloseChannel(interp, chanPtr, errorCode) Tcl_Interp *interp; /* For error reporting. */ Channel *chanPtr; /* The channel to close. */ 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. */ DiscardInputQueued(chanPtr, 1); /* * Discard a leftover buffer in the current output buffer field. */ if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { ckfree((char *) chanPtr->curOutPtr); chanPtr->curOutPtr = (ChannelBuffer *) NULL; } /* * The caller guarantees that there are no more buffers * queued for output. */ if (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { panic("TclFlush, closed channel: queued output left"); } /* * If the EOF character is set in the channel, append that to the * output device. */ if ((chanPtr->outEofChar != 0) && (chanPtr->flags & TCL_WRITABLE)) { int dummy; char c; c = (char) chanPtr->outEofChar; (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy); } /* * Remove TCL_READABLE and TCL_WRITABLE from chanPtr->flags, so * that close callbacks can not do input or output (assuming they * squirreled the channel away in their clientData). This also * prevents infinite loops if the callback calls any C API that * could call FlushChannel. */ 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. */ if (chanPtr->unreportedError != 0) { errorCode = chanPtr->unreportedError; } if (errorCode == 0) { errorCode = result; if (errorCode != 0) { Tcl_SetErrno(errorCode); } } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'CloseChannel'. * * Explanation * Closing a filtering channel closes the one it * superceded too. This basically ripples through * the whole chain of filters until it reaches * the underlying normal channel. * * This is done by reintegrating the superceded * channel into the (thread) global list of open * channels and then invoking a regular close. * There is no need to handle the complexities of * this process by ourselves. * * *Note* * This has to be done after the call to the * 'closeProc' of the filtering channel to allow * that one the flushing of internal buffers into * the underlying channel. */ if (chanPtr->supercedes != (Channel*) NULL) { /* Insert the channel we were stacked upon back into * the list of open channels, then do a regular close. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; chanPtr->supercedes->refCount --; /* is deregistered */ Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* * Cancel any outstanding timer. */ Tcl_DeleteTimerHandler(chanPtr->timer); /* * Mark the channel as deleted by clearing the type structure. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC); return errorCode; } /* *---------------------------------------------------------------------- * * Tcl_Close -- * * Closes a channel. * * Results: * A standard Tcl result. * * Side effects: * Closes the channel if this is the last reference. * * NOTE: * Tcl_Close removes the channel as far as the user is concerned. * However, it may continue to exist for a while longer if it has * a background flush scheduled. The device itself is eventually * closed and the channel record removed, in CloseChannel, above. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_Close(interp, chan) Tcl_Interp *interp; /* Interpreter for errors. */ Tcl_Channel chan; /* The channel being closed. Must * not be referenced in any * interpreter. */ { 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; } /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); chanPtr = (Channel *) chan; if (chanPtr->refCount > 0) { panic("called Tcl_Close on channel with refCount > 0"); } /* * 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; } } /* * Remove all the channel handler records attached to the channel * itself. */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chNext) { chNext = chPtr->nextPtr; ckfree((char *) chPtr); } chanPtr->chPtr = (ChannelHandler *) NULL; /* * Cancel any pending copy operation. */ StopCopy(chanPtr->csPtr); /* * Must set the interest mask now to 0, otherwise infinite loops * will occur if Tcl_DoOneEvent is called before the channel is * finally deleted in FlushChannel. This can happen if the channel * has a background flush active. */ chanPtr->interestMask = 0; /* * 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. */ while (chanPtr->closeCbPtr != (CloseCallback *) NULL) { cbPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr->nextPtr; (cbPtr->proc) (cbPtr->clientData); ckfree((char *) cbPtr); } /* * 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 -- * * Flushes output data on a channel. * * Results: * A standard Tcl result. * * Side effects: * May flush output queued on this channel. * *---------------------------------------------------------------------- */ int 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; } return TCL_OK; } /* *---------------------------------------------------------------------- * * DiscardInputQueued -- * * Discards any input read from the channel but not yet consumed * by Tcl reading commands. * * Results: * None. * * Side effects: * May discard input from the channel. If discardLastBuffer is zero, * leaves one buffer in place for back-filling. * *---------------------------------------------------------------------- */ static void DiscardInputQueued(chanPtr, discardSavedBuffers) Channel *chanPtr; /* Channel on which to discard * the queued input. */ int discardSavedBuffers; /* If non-zero, discard all buffers including * last one. */ { ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ bufPtr = chanPtr->inQueueHead; chanPtr->inQueueHead = (ChannelBuffer *) NULL; chanPtr->inQueueTail = (ChannelBuffer *) NULL; for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) { nxtPtr = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, discardSavedBuffers); } /* * If discardSavedBuffers is nonzero, must also discard any previously * saved buffer in the saveInBufPtr field. */ if (discardSavedBuffers) { if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) { 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 -- * * Implements seeking on Tcl Channels. This is a public function * so that other C facilities may be implemented on top of it. * * Results: * The new access point or -1 on error. If error, use Tcl_GetErrno() * to retrieve the POSIX error code for the error that occurred. * * Side effects: * May flush output on the channel. May discard queued input. * *---------------------------------------------------------------------- */ int Tcl_Seek(chan, offset, mode) Tcl_Channel chan; /* The channel on which to seek. */ int offset; /* Offset to seek to. */ int mode; /* Relative to which location to seek? */ { Channel *chanPtr; /* The real IO channel. */ ChannelBuffer *bufPtr; int inputBuffered, outputBuffered; 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 * registered in an interpreter. */ if (CheckForDeadChannel(NULL,chanPtr)) return -1; /* * Disallow seek on channels whose type does not have a seek procedure * defined. This means that the channel does not support seeking. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * If we are seeking relative to the current position, compute the * corrected offset taking into account the amount of unread input. */ if (mode == SEEK_CUR) { offset -= inputBuffered; } /* * Discard any queued input - this input should not be read after * the seek. */ DiscardInputQueued(chanPtr, 0); /* * Reset EOF and BLOCKED flags. We invalidate them by moving the * access point. Also clear CR related flags. */ chanPtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR)); /* * If the channel is in asynchronous output mode, switch it back * to synchronous mode and cancel any async flush that may be * scheduled. After the flush, the channel will be put back into * asynchronous output mode. */ wasAsync = 0; if (chanPtr->flags & CHANNEL_NONBLOCKING) { wasAsync = 1; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_BLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } chanPtr->flags &= (~(CHANNEL_NONBLOCKING)); if (chanPtr->flags & BG_FLUSH_SCHEDULED) { chanPtr->flags &= (~(BG_FLUSH_SCHEDULED)); } } /* * If the flush fails we cannot recover the original position. In * that case the seek is not attempted because we do not know where * the access position is - instead we return the error. FlushChannel * has already called Tcl_SetErrno() to report the error upwards. * If the flush succeeds we do the seek also. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { curPos = -1; } else { /* * Now seek to the new position in the channel as requested by the * caller. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) offset, mode, &result); if (curPos == -1) { Tcl_SetErrno(result); } } /* * Restore to nonblocking mode if that was the previous behavior. * * NOTE: Even if there was an async flush active we do not restore * it now because we already flushed all the queued output, above. */ if (wasAsync) { chanPtr->flags |= CHANNEL_NONBLOCKING; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_NONBLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } } return curPos; } /* *---------------------------------------------------------------------- * * Tcl_Tell -- * * Returns the position of the next character to be read/written on * this channel. * * Results: * A nonnegative integer on success, -1 on failure. If failed, * use Tcl_GetErrno() to retrieve the POSIX error code for the * error that occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Tell(chan) Tcl_Channel chan; /* The channel to return pos for. */ { 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. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * Get the current position in the device and compute the position * where the next character will be read or written. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) 0, SEEK_CUR, &result); if (curPos == -1) { Tcl_SetErrno(result); 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. * * Results: * 1 or 0, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Eof(chan) Tcl_Channel chan; /* Does this channel have EOF? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_STICKY_EOF) || ((chanPtr->flags & CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * * Results: * 0 or 1, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBlocked(chan) Tcl_Channel chan; /* Is this channel blocked? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return (chanPtr->flags & CHANNEL_BLOCKED) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBuffered -- * * Returns the number of bytes of input currently buffered in the * internal buffer of a channel. * * Results: * The number of input bytes buffered, or zero if the channel is not * open for reading. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBuffered(chan) Tcl_Channel chan; /* The channel to query. */ { Channel *chanPtr; int bytesBuffered; ChannelBuffer *bufPtr; chanPtr = (Channel *) chan; for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } return bytesBuffered; } /* *---------------------------------------------------------------------- * * Tcl_SetChannelBufferSize -- * * Sets the size of buffers to allocate to store input or output * in the channel. The size must be between 10 bytes and 1 MByte. * * Results: * None. * * Side effects: * Sets the size of buffers subsequently allocated for this channel. * *---------------------------------------------------------------------- */ void Tcl_SetChannelBufferSize(chan, sz) Tcl_Channel chan; /* The channel whose buffer size * to set. */ int sz; /* The size to set. */ { Channel *chanPtr; /* * If the buffer size is smaller than 10 bytes or larger than one MByte, * do not accept the requested size and leave the current buffer size. */ if (sz < 10) { return; } 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 -- * * Retrieves the size of buffers to allocate for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelBufferSize(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->bufSize; } /* *---------------------------------------------------------------------- * * Tcl_BadChannelOption -- * * This procedure generates a "bad option" error message in an * (optional) interpreter. It is used by channel drivers when * a invalid Set/Get option is requested. Its purpose is to concatenate * the generic options list to the specific ones and factorize * the generic options error message string. * * Results: * TCL_ERROR. * * Side effects: * An error message is generated in interp's result object to * indicate that a command was invoked with the a bad option * The message has the form * bad option "blah": should be one of * <...generic options...>+<...specific options...> * "blah" is the optionName argument and "" * is a space separated list of specific option words. * The function takes good care of inserting minus signs before * each option, commas after, and an "or" before the last option. * *---------------------------------------------------------------------- */ int Tcl_BadChannelOption(interp, optionName, optionList) Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/ char *optionName; /* 'bad option' name */ char *optionList; /* Specific options list to append * to the standard generic options. * can be NULL for generic options * only. */ { if (interp) { CONST char *genericopt = "blocking buffering buffersize eofchar translation"; char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, (char *) genericopt, -1); if (optionList && (*optionList)) { Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad option \"", optionName, "\": should be one of ", (char *) NULL); argc--; for (i = 0; i < argc; i++) { Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL); } Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL); Tcl_DStringFree(&ds); ckfree((char *) argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelOption -- * * 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: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelOption(interp, chan, optionName, dsPtr) Tcl_Interp *interp; /* For error reporting - can be NULL. */ Tcl_Channel chan; /* Channel on which to get option. */ char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */ { size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; int flags; /* * If we are in the middle of a background copy, use the saved flags. */ if (chanPtr->csPtr) { if (chanPtr == chanPtr->csPtr->readPtr) { flags = chanPtr->csPtr->readFlags; } else { flags = chanPtr->csPtr->writeFlags; } } else { flags = chanPtr->flags; } /* * Disallow options 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(interp,chanPtr)) return TCL_ERROR; /* * If the optionName is NULL it means that we want a list of all * options and values. */ if (optionName == (char *) NULL) { len = 0; } else { len = strlen(optionName); } if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blocking"); } Tcl_DStringAppendElement(dsPtr, (flags & CHANNEL_NONBLOCKING) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffering", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffering"); } if (flags & CHANNEL_LINEBUFFERED) { Tcl_DStringAppendElement(dsPtr, "line"); } else if (flags & CHANNEL_UNBUFFERED) { Tcl_DStringAppendElement(dsPtr, "none"); } else { Tcl_DStringAppendElement(dsPtr, "full"); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffersize", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffersize"); } 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); } if (flags & TCL_READABLE) { if (chanPtr->inEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->inEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (flags & TCL_WRITABLE) { if (chanPtr->outEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->outEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 1) && (optionName[1] == 't') && (strncmp(optionName, "-translation", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-translation"); } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringStartSublist(dsPtr); } if (flags & TCL_READABLE) { if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (flags & TCL_WRITABLE) { if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) { /* * let the driver specific handle additional options * and result code and message. */ return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData, interp, optionName, dsPtr); } else { /* * no driver specific options case. */ if (len == 0) { 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? */ char *newValue; /* New value for option. */ { int newMode; /* New (numeric) mode to sert. */ Channel *chanPtr; /* The real IO channel. */ size_t len; /* Length of optionName string. */ int argc; char **argv; chanPtr = (Channel *) chan; /* * If the channel is in the middle of a background copy, fail. */ if (chanPtr->csPtr) { if (interp) { Tcl_AppendResult(interp, "unable to set channel options: background copy in progress", (char *) NULL); } return TCL_ERROR; } /* * Disallow options 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 TCL_ERROR; len = strlen(optionName); if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0)) { if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) { return TCL_ERROR; } 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)) { chanPtr->flags &= (~(CHANNEL_UNBUFFERED)); chanPtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { chanPtr->flags &= (~(CHANNEL_LINEBUFFERED)); chanPtr->flags |= CHANNEL_UNBUFFERED; } else { 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; } else if (argc == 1) { if (chanPtr->flags & TCL_WRITABLE) { chanPtr->outEofChar = (int) argv[0][0]; } if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } } else if (argc != 2) { if (interp) { Tcl_AppendResult(interp, "bad value for -eofchar: should be a list of one or", " two elements", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } else { if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } 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; } if (argc == 1) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: must be a one or two", " element list", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } 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) { newMode = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered * 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) { /* * This is a hack to get TCP sockets to produce output * in CRLF mode if they are being set into AUTO mode. * A better solution for achieving this effect will be * coded later. */ if (strcmp(chanPtr->typePtr->typeName, "tcp") == 0) { 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) { chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } 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 -- * * Removes channel handlers that refer to the supplied interpreter, * so that if the actual channel is not closed now, these handlers * will not run on subsequent events on the channel. This would be * erroneous, because the interpreter no longer has a reference to * this channel. * * Results: * None. * * Side effects: * Removes channel handlers. * *---------------------------------------------------------------------- */ static void CleanupChannelHandlers(interp, chanPtr) Tcl_Interp *interp; Channel *chanPtr; { EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* * Remove fileevent records on this channel that refer to the * given interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } } /* *---------------------------------------------------------------------- * * Tcl_NotifyChannel -- * * This procedure is called by a channel driver when a driver * detects an event on a channel. This procedure is responsible * for actually handling the event by invoking any channel * handler callbacks. * * Results: * None. * * Side effects: * Whatever the channel handler callback procedure does. * *---------------------------------------------------------------------- */ void Tcl_NotifyChannel(channel, mask) 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. */ if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; (*(chPtr->proc))(chPtr->clientData, mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; } } /* * 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 -- * * Arrange for the notifier to call us back at appropriate times * based on the current state of the channel. * * Results: * None. * * Side effects: * May schedule a timer or driver handler. * *---------------------------------------------------------------------- */ static void UpdateInterest(chanPtr) Channel *chanPtr; /* Channel to update. */ { int mask = chanPtr->interestMask; /* * If there are flushed buffers waiting to be written, then * we need to watch for the channel to become writable. */ 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); } } } (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask); } /* *---------------------------------------------------------------------- * * ChannelTimerProc -- * * Timer handler scheduled by UpdateInterest to monitor the * channel buffers until they are empty. * * Results: * None. * * Side effects: * May invoke channel handlers. * *---------------------------------------------------------------------- */ 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. */ chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc, (ClientData) chanPtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); } else { chanPtr->timer = NULL; UpdateInterest(chanPtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * * Arrange for a given procedure to be invoked whenever the * channel indicated by the chanPtr arg becomes readable or * writable. * * Results: * None. * * Side effects: * From now on, whenever the I/O channel given by chanPtr becomes * ready in the way indicated by mask, proc will be invoked. * See the manual entry for details on the calling sequence * to proc. If there is already an event handler for chan, proc * and clientData, then the mask will be updated. * *---------------------------------------------------------------------- */ void Tcl_CreateChannelHandler(chan, mask, proc, clientData) Tcl_Channel chan; /* The channel to create the handler for. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions under which * proc should be called. Use 0 to * disable a registered handler. */ Tcl_ChannelProc *proc; /* Procedure to call for each * selected event. */ ClientData clientData; /* Arbitrary data to pass to proc. */ { ChannelHandler *chPtr; Channel *chanPtr; chanPtr = (Channel *) chan; /* * Check whether this channel handler is not already registered. If * it is not, create a new record, else reuse existing record (smash * current values). */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) && (chPtr->clientData == clientData)) { break; } } if (chPtr == (ChannelHandler *) NULL) { chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler)); chPtr->mask = 0; chPtr->proc = proc; chPtr->clientData = clientData; chPtr->chanPtr = chanPtr; chPtr->nextPtr = chanPtr->chPtr; chanPtr->chPtr = chPtr; } /* * The remainder of the initialization below is done regardless of * whether or not this is a new record or a modification of an old * one. */ chPtr->mask = mask; /* * Recompute the interest mask for the channel - this call may actually * be disabling an existing handler. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * Tcl_DeleteChannelHandler -- * * Cancel a previously arranged callback arrangement for an IO * channel. * * Results: * None. * * Side effects: * If a callback was previously registered for this chan, proc and * clientData , it is removed and the callback will no longer be called * when the channel becomes ready for IO. * *---------------------------------------------------------------------- */ void Tcl_DeleteChannelHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to remove the * callback. */ 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. */ for (prevChPtr = (ChannelHandler *) NULL, chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData) && (chPtr->proc == proc)) { break; } prevChPtr = chPtr; } /* * If not found, return without doing anything. */ if (chPtr == (ChannelHandler *) NULL) { return; } /* * 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; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * DeleteScriptRecord -- * * Delete a script record for this combination of channel, interp * and mask. * * Results: * None. * * Side effects: * Deletes a script record and cancels a channel event handler. * *---------------------------------------------------------------------- */ static void DeleteScriptRecord(interp, chanPtr, mask) Tcl_Interp *interp; /* Interpreter in which script was to be * executed. */ Channel *chanPtr; /* The channel for which to delete the * script record (if any). */ int mask; /* Events in mask must exactly match mask * of script to delete. */ { EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = chanPtr->scriptRecordPtr, prevEsPtr = (EventScriptRecord *) NULL; esPtr != (EventScriptRecord *) NULL; prevEsPtr = esPtr, esPtr = esPtr->nextPtr) { if ((esPtr->interp == interp) && (esPtr->mask == mask)) { if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { prevEsPtr->nextPtr = esPtr->nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) esPtr); Tcl_DecrRefCount(esPtr->scriptPtr); ckfree((char *) esPtr); break; } } } /* *---------------------------------------------------------------------- * * CreateScriptRecord -- * * Creates a record to store a script to be executed when a specific * event fires on a specific channel. * * Results: * None. * * 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 -- * * Invokes a script scheduled by "fileevent" for when the channel * becomes ready for IO. This function is invoked by the channel * handler which was created by the Tcl "fileevent" command. * * Results: * None. * * Side effects: * Whatever the script does. * *---------------------------------------------------------------------- */ static void 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. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundError(interp); } 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; } /* *---------------------------------------------------------------------- * * TclTestChannelCmd -- * * Implements the Tcl "testchannel" debugging command and its * subcommands. This is part of the testing environment but must be * in this file instead of tclTest.c because it needs access to the * fields of struct Channel. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int TclTestChannelCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Interpreter for result. */ int argc; /* Count of additional args. */ char **argv; /* Additional arg strings. */ { char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ 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]); Tcl_AppendElement(interp, chanPtr->typePtr->typeName); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_NONBLOCKING) { Tcl_AppendElement(interp, "nonblocking"); } else { Tcl_AppendElement(interp, "blocking"); } if (chanPtr->flags & CHANNEL_LINEBUFFERED) { Tcl_AppendElement(interp, "line"); } else if (chanPtr->flags & CHANNEL_UNBUFFERED) { Tcl_AppendElement(interp, "none"); } else { Tcl_AppendElement(interp, "full"); } if (chanPtr->flags & BG_FLUSH_SCHEDULED) { Tcl_AppendElement(interp, "async_flush"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_EOF) { Tcl_AppendElement(interp, "eof"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_BLOCKED) { Tcl_AppendElement(interp, "blocked"); } else { Tcl_AppendElement(interp, "unblocked"); } if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "saw_cr"); } else { Tcl_AppendElement(interp, ""); } } else if (chanPtr->inputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "queued_cr"); } else { Tcl_AppendElement(interp, ""); } } if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); } for (IOQueued = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved; } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved; } for (bufPtr = chanPtr->outQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved); } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr)); Tcl_AppendElement(interp, buf); TclFormatInt(buf, chanPtr->refCount); Tcl_AppendElement(interp, buf); return TCL_OK; } if ((cmdName[0] == 'i') && (strncmp(cmdName, "inputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; } if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } return TCL_OK; } if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "outputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - 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) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (chanPtr->flags & INPUT_SAW_CR) ? "1" : "0", (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } 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", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ", "info, open, readable, or writable", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclTestChannelEventCmd -- * * This procedure implements the "testchannelevent" command. It is * used to test the Tcl channel event mechanism. It is present in * this file instead of tclTest.c because it needs access to the * internal structure of the channel. * * Results: * A standard Tcl result. * * Side effects: * Creates, deletes and returns channel event handlers. * *---------------------------------------------------------------------- */ /* ARGSUSED */ 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], " channelName cmd ?arg1? ?arg2?\"", (char *) NULL); return TCL_ERROR; } chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL); if (chanPtr == (Channel *) NULL) { return TCL_ERROR; } cmd = argv[2]; len = strlen(cmd); if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName add eventSpec script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[3], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[3], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[3], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr = (EventScriptRecord *) ckalloc((unsigned) 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; } if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) { if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { for (prevEsPtr = chanPtr->scriptRecordPtr; (prevEsPtr != (EventScriptRecord *) NULL) && (prevEsPtr->nextPtr != esPtr); prevEsPtr = prevEsPtr->nextPtr) { /* Empty loop body. */ } 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)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index event\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[4], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[4], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[4], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[4], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr->mask = mask; 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 -- * * This routine copies data from one channel to another, either * synchronously or asynchronously. If a command script is * supplied, the operation runs in the background. The script * is invoked when the copy completes. Otherwise the function * waits until the copy is completed before returning. * * Results: * A standard Tcl result. * * Side effects: * May schedule a background copy operation that causes both * channels to be marked busy. * *---------------------------------------------------------------------- */ int TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Channel inChan; /* Channel to read from. */ Tcl_Channel outChan; /* Channel to write to. */ int toRead; /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */ { Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; if (inPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); return TCL_ERROR; } if (outPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); return TCL_ERROR; } readFlags = inPtr->flags; writeFlags = outPtr->flags; /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. * If there is an error, restore the old blocking mode. */ if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(interp, inPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) { return TCL_ERROR; } } if (inPtr != outPtr) { if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(NULL, outPtr, nonBlocking ? TCL_MODE_BLOCKING : TCL_MODE_NONBLOCKING) != TCL_OK) { if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING) ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); return TCL_ERROR; } } } } /* * Make sure the output side is unbuffered. */ outPtr->flags = (outPtr->flags & ~(CHANNEL_LINEBUFFERED)) | CHANNEL_UNBUFFERED; /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inPtr->bufSize); csPtr->bufSize = inPtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; inPtr->csPtr = csPtr; outPtr->csPtr = csPtr; /* * Start copying data between the channels. */ return CopyData(csPtr, 0); } /* *---------------------------------------------------------------------- * * CopyData -- * * This function implements the lowest level of the copying * mechanism for TclCopyChannel. * * Results: * Returns TCL_OK on success, else TCL_ERROR. * * Side effects: * Moves data between channels, may create channel handlers. * *---------------------------------------------------------------------- */ static int CopyData(csPtr, mask) CopyState *csPtr; /* State of copy operation. */ int mask; /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL; Tcl_Channel inChan, outChan; int result = TCL_OK; int size; int total; inChan = (Tcl_Channel)csPtr->readPtr; outChan = (Tcl_Channel)csPtr->writePtr; interp = csPtr->interp; cmdPtr = csPtr->cmdPtr; /* * Copy the data the slow way, using the translation mechanism. */ while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ if (csPtr->readPtr->unreportedError != 0) { Tcl_SetErrno(csPtr->readPtr->unreportedError); csPtr->readPtr->unreportedError = 0; goto readError; } if (csPtr->writePtr->unreportedError != 0) { Tcl_SetErrno(csPtr->writePtr->unreportedError); csPtr->writePtr->unreportedError = 0; goto writeError; } /* * Read up to bufSize bytes. */ if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { size = csPtr->bufSize; } else { size = csPtr->toRead; } size = DoRead(csPtr->readPtr, csPtr->buffer, size); if (size < 0) { readError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error reading \"", Tcl_GetChannelName(inChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } else if (size == 0) { /* * We had an underflow on the read side. If we are at EOF, * then the copying is done, otherwise set up a channel * handler to detect when the channel becomes readable again. */ if (Tcl_Eof(inChan)) { break; } else if (!(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Now write the buffer out. */ size = DoWrite(csPtr->writePtr, csPtr->buffer, size); if (size < 0) { writeError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error writing \"", Tcl_GetChannelName(outChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } /* * Check to see if the write is happening in the background. If so, * stop copying and wait for the channel to become writable again. */ if (csPtr->writePtr->flags & BG_FLUSH_SCHEDULED) { if (!(mask & TCL_WRITABLE)) { if (mask & TCL_READABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Update the current byte count if we care. */ if (csPtr->toRead != -1) { csPtr->toRead -= size; } csPtr->total += size; /* * For background copies, we only do one buffer per invocation so * we don't starve the rest of the system. */ if (cmdPtr) { /* * The first time we enter this code, there won't be a * channel handler established yet, so do it here. */ if (mask == 0) { Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } } /* * Make the callback or return the number of bytes transferred. * The local total is used because StopCopy frees csPtr. */ total = csPtr->total; if (cmdPtr) { /* * Get a private copy of the command so we can mutate it * by adding arguments. Note that StopCopy frees our saved * reference to the original command obj. */ cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); 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 * the background copy operation. It is just a trivial wrapper * around the CopyData routine. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void CopyEventProc(clientData, mask) ClientData clientData; int mask; { (void) CopyData((CopyState *)clientData, mask); } /* *---------------------------------------------------------------------- * * StopCopy -- * * This routine halts a copy that is in progress. * * Results: * None. * * Side effects: * Removes any pending channel handlers and restores the blocking * and buffering modes of the channels. The CopyState is freed. * *---------------------------------------------------------------------- */ static void StopCopy(csPtr) CopyState *csPtr; /* State for bg copy to stop . */ { int nonBlocking; if (!csPtr) { return; } /* * Restore the old blocking mode and output buffering mode. */ nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING); if (nonBlocking != (csPtr->readPtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->readPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } if (csPtr->writePtr != csPtr->writePtr) { if (nonBlocking != (csPtr->writePtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->writePtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } } csPtr->writePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); csPtr->writePtr->flags |= csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc, (ClientData)csPtr); if (csPtr->readPtr != csPtr->writePtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr, CopyEventProc, (ClientData)csPtr); } 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; } trf2.1.4/patches/v8.1/tclStubInit.c0000644000175000017500000004776611216344362016333 0ustar sergeisergei/* * 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.1 1999/05/07 18:50:59 aku 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. */ TclIntStubs tclIntStubs = { TCL_STUB_MAGIC, NULL, TclAccess, /* 0 */ TclAccessDeleteProc, /* 1 */ TclAccessInsertProc, /* 2 */ TclAllocateFreeObjects, /* 3 */ NULL, /* 4 */ TclCleanupChildren, /* 5 */ TclCleanupCommand, /* 6 */ TclCopyAndCollapse, /* 7 */ TclCopyChannel, /* 8 */ TclCreatePipeline, /* 9 */ TclCreateProc, /* 10 */ TclDeleteCompiledLocalVars, /* 11 */ TclDeleteVars, /* 12 */ TclDoGlob, /* 13 */ TclDumpMemoryInfo, /* 14 */ NULL, /* 15 */ TclExprFloatError, /* 16 */ TclFileAttrsCmd, /* 17 */ TclFileCopyCmd, /* 18 */ TclFileDeleteCmd, /* 19 */ TclFileMakeDirsCmd, /* 20 */ TclFileRenameCmd, /* 21 */ TclFindElement, /* 22 */ TclFindProc, /* 23 */ TclFormatInt, /* 24 */ TclFreePackageInfo, /* 25 */ NULL, /* 26 */ TclGetDate, /* 27 */ TclpGetDefaultStdChannel, /* 28 */ TclGetElementOfIndexedArray, /* 29 */ NULL, /* 30 */ TclGetExtension, /* 31 */ TclGetFrame, /* 32 */ TclGetInterpProc, /* 33 */ TclGetIntForIndex, /* 34 */ TclGetIndexedScalar, /* 35 */ TclGetLong, /* 36 */ TclGetLoadedPackages, /* 37 */ TclGetNamespaceForQualName, /* 38 */ TclGetObjInterpProc, /* 39 */ TclGetOpenMode, /* 40 */ TclGetOriginalCommand, /* 41 */ TclpGetUserHome, /* 42 */ TclGlobalInvoke, /* 43 */ TclGuessPackageName, /* 44 */ TclHideUnsafeCommands, /* 45 */ TclInExit, /* 46 */ TclIncrElementOfIndexedArray, /* 47 */ TclIncrIndexedScalar, /* 48 */ TclIncrVar2, /* 49 */ TclInitCompiledLocals, /* 50 */ TclInterpInit, /* 51 */ TclInvoke, /* 52 */ TclInvokeObjectCommand, /* 53 */ TclInvokeStringCommand, /* 54 */ TclIsProc, /* 55 */ NULL, /* 56 */ NULL, /* 57 */ TclLookupVar, /* 58 */ TclpMatchFiles, /* 59 */ TclNeedSpace, /* 60 */ TclNewProcBodyObj, /* 61 */ TclObjCommandComplete, /* 62 */ TclObjInterpProc, /* 63 */ TclObjInvoke, /* 64 */ TclObjInvokeGlobal, /* 65 */ TclOpenFileChannelDeleteProc, /* 66 */ TclOpenFileChannelInsertProc, /* 67 */ TclpAccess, /* 68 */ TclpAlloc, /* 69 */ TclpCopyFile, /* 70 */ TclpCopyDirectory, /* 71 */ TclpCreateDirectory, /* 72 */ TclpDeleteFile, /* 73 */ TclpFree, /* 74 */ TclpGetClicks, /* 75 */ TclpGetSeconds, /* 76 */ TclpGetTime, /* 77 */ TclpGetTimeZone, /* 78 */ TclpListVolumes, /* 79 */ TclpOpenFileChannel, /* 80 */ TclpRealloc, /* 81 */ TclpRemoveDirectory, /* 82 */ TclpRenameFile, /* 83 */ NULL, /* 84 */ NULL, /* 85 */ NULL, /* 86 */ NULL, /* 87 */ TclPrecTraceProc, /* 88 */ TclPreventAliasLoop, /* 89 */ NULL, /* 90 */ TclProcCleanupProc, /* 91 */ TclProcCompileProc, /* 92 */ TclProcDeleteProc, /* 93 */ TclProcInterpProc, /* 94 */ TclpStat, /* 95 */ TclRenameCommand, /* 96 */ TclResetShadowedCmdRefs, /* 97 */ TclServiceIdle, /* 98 */ TclSetElementOfIndexedArray, /* 99 */ TclSetIndexedScalar, /* 100 */ TclSetPreInitScript, /* 101 */ TclSetupEnv, /* 102 */ TclSockGetPort, /* 103 */ TclSockMinimumBuffers, /* 104 */ TclStat, /* 105 */ TclStatDeleteProc, /* 106 */ TclStatInsertProc, /* 107 */ TclTeardownNamespace, /* 108 */ TclUpdateReturnInfo, /* 109 */ NULL, /* 110 */ Tcl_AddInterpResolvers, /* 111 */ Tcl_AppendExportList, /* 112 */ Tcl_CreateNamespace, /* 113 */ Tcl_DeleteNamespace, /* 114 */ Tcl_Export, /* 115 */ Tcl_FindCommand, /* 116 */ Tcl_FindNamespace, /* 117 */ Tcl_GetInterpResolvers, /* 118 */ Tcl_GetNamespaceResolvers, /* 119 */ Tcl_FindNamespaceVar, /* 120 */ Tcl_ForgetImport, /* 121 */ Tcl_GetCommandFromObj, /* 122 */ Tcl_GetCommandFullName, /* 123 */ Tcl_GetCurrentNamespace, /* 124 */ Tcl_GetGlobalNamespace, /* 125 */ Tcl_GetVariableFullName, /* 126 */ Tcl_Import, /* 127 */ Tcl_PopCallFrame, /* 128 */ Tcl_PushCallFrame, /* 129 */ Tcl_RemoveInterpResolvers, /* 130 */ Tcl_SetNamespaceResolvers, /* 131 */ TclpHasSockets, /* 132 */ TclpGetDate, /* 133 */ TclpStrftime, /* 134 */ TclpCheckStackSpace, /* 135 */ NULL, /* 136 */ TclpChdir, /* 137 */ TclGetEnv, /* 138 */ TclpLoadFile, /* 139 */ TclLooksLikeInt, /* 140 */ TclpGetCwd, /* 141 */ }; TclIntPlatStubs tclIntPlatStubs = { TCL_STUB_MAGIC, NULL, #if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */ TclGetAndDetachPids, /* 0 */ TclpCloseFile, /* 1 */ TclpCreateCommandChannel, /* 2 */ TclpCreatePipe, /* 3 */ TclpCreateProcess, /* 4 */ NULL, /* 5 */ TclpMakeFile, /* 6 */ TclpOpenFile, /* 7 */ TclUnixWaitForFile, /* 8 */ TclpCreateTempFile, /* 9 */ #endif /* UNIX */ #ifdef __WIN32__ TclWinConvertError, /* 0 */ TclWinConvertWSAError, /* 1 */ TclWinGetServByName, /* 2 */ TclWinGetSockOpt, /* 3 */ TclWinGetTclInstance, /* 4 */ NULL, /* 5 */ TclWinNToHS, /* 6 */ TclWinSetSockOpt, /* 7 */ TclpGetPid, /* 8 */ TclWinGetPlatformId, /* 9 */ TclWinSynchSpawn, /* 10 */ TclGetAndDetachPids, /* 11 */ TclpCloseFile, /* 12 */ TclpCreateCommandChannel, /* 13 */ TclpCreatePipe, /* 14 */ TclpCreateProcess, /* 15 */ NULL, /* 16 */ NULL, /* 17 */ TclpMakeFile, /* 18 */ TclpOpenFile, /* 19 */ TclWinAddProcess, /* 20 */ TclpAsyncMark, /* 21 */ TclpCreateTempFile, /* 22 */ TclpGetTZName, /* 23 */ TclWinNoBackslash, /* 24 */ #endif /* __WIN32__ */ #ifdef MAC_TCL TclpSysAlloc, /* 0 */ TclpSysFree, /* 1 */ TclpSysRealloc, /* 2 */ TclpExit, /* 3 */ FSpGetDefaultDir, /* 4 */ FSpSetDefaultDir, /* 5 */ FSpFindFolder, /* 6 */ GetGlobalMouse, /* 7 */ FSpGetDirectoryID, /* 8 */ FSpOpenResFileCompat, /* 9 */ FSpCreateResFileCompat, /* 10 */ FSpLocationFromPath, /* 11 */ FSpPathFromLocation, /* 12 */ TclMacExitHandler, /* 13 */ TclMacInitExitToShell, /* 14 */ TclMacInstallExitToShellPatch, /* 15 */ TclMacOSErrorToPosixError, /* 16 */ TclMacRemoveTimer, /* 17 */ TclMacStartTimer, /* 18 */ TclMacTimerExpired, /* 19 */ TclMacRegisterResourceFork, /* 20 */ TclMacUnRegisterResourceFork, /* 21 */ TclMacCreateEnv, /* 22 */ TclMacFOpenHack, /* 23 */ NULL, /* 24 */ TclMacChmod, /* 25 */ #endif /* MAC_TCL */ }; TclPlatStubs tclPlatStubs = { TCL_STUB_MAGIC, NULL, #ifdef __WIN32__ Tcl_WinUtfToTChar, /* 0 */ Tcl_WinTCharToUtf, /* 1 */ #endif /* __WIN32__ */ #ifdef MAC_TCL Tcl_MacSetEventProc, /* 0 */ Tcl_MacConvertTextResource, /* 1 */ Tcl_MacEvalResource, /* 2 */ Tcl_MacFindResource, /* 3 */ Tcl_GetOSTypeFromObj, /* 4 */ Tcl_SetOSTypeObj, /* 5 */ Tcl_NewOSTypeObj, /* 6 */ strncasecmp, /* 7 */ strcasecmp, /* 8 */ #endif /* MAC_TCL */ }; static TclStubHooks tclStubHooks = { &tclPlatStubs, &tclIntStubs, &tclIntPlatStubs }; TclStubs tclStubs = { TCL_STUB_MAGIC, &tclStubHooks, Tcl_PkgProvideEx, /* 0 */ Tcl_PkgRequireEx, /* 1 */ Tcl_Panic, /* 2 */ 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 */ Tcl_ReplaceChannel, /* 281 */ Tcl_UndoReplaceChannel, /* 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 */ Tcl_Access, /* 367 */ Tcl_Stat, /* 368 */ }; /* !END!: Do not edit above this line. */ trf2.1.4/patches/v8.1/tclDecls.h0000644000175000017500000033560711216344362015623 0ustar sergeisergei/* * 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.1 1999/05/07 18:50:58 aku 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)); /* 281 */ EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 282 */ EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Channel chan)); /* 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)); /* 367 */ EXTERN int Tcl_Access _ANSI_ARGS_((CONST char * path, int mode)); /* 368 */ EXTERN int Tcl_Stat _ANSI_ARGS_((CONST char * path, struct stat * bufPtr)); 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 */ Tcl_Channel (*tcl_ReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 281 */ void (*tcl_UndoReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 282 */ 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 */ int (*tcl_Access) _ANSI_ARGS_((CONST char * path, int mode)); /* 367 */ int (*tcl_Stat) _ANSI_ARGS_((CONST char * path, struct stat * bufPtr)); /* 368 */ } TclStubs; #ifdef __cplusplus extern "C" { #endif extern TclStubs *tclStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) /* * Inline function declarations: */ #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 #ifndef Tcl_ReplaceChannel #define Tcl_ReplaceChannel \ (tclStubsPtr->tcl_ReplaceChannel) /* 281 */ #endif #ifndef Tcl_UndoReplaceChannel #define Tcl_UndoReplaceChannel \ (tclStubsPtr->tcl_UndoReplaceChannel) /* 282 */ #endif /* 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 #ifndef Tcl_Access #define Tcl_Access \ (tclStubsPtr->tcl_Access) /* 367 */ #endif #ifndef Tcl_Stat #define Tcl_Stat \ (tclStubsPtr->tcl_Stat) /* 368 */ #endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLDECLS */ trf2.1.4/patches/v8.0/0000755000175000017500000000000011216344734013701 5ustar sergeisergeitrf2.1.4/patches/v8.0/standard.patch0000644000175000017500000002135511216344361016524 0ustar sergeisergei*** tcl.h.orig Mon Aug 18 21:10:22 1997 --- tcl.h Mon Aug 18 21:10:39 1997 *************** *** 1484,1488 **** --- 1484,1498 ---- EXTERN void Tcl_WrongNumArgs _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], char *message)); + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf. + */ + EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_ChannelType* typePtr, ClientData instanceData, + int mask, Tcl_Channel prevChan)); + + EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_Channel chan)); + #endif /* RESOURCE_INCLUDED */ #endif /* _TCL */ *** tclIO.c.orig Mon Aug 18 21:10:22 1997 --- tclIO.c Mon Aug 18 21:10:39 1997 *************** *** 169,174 **** --- 169,181 ---- int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ + + + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf. + */ + struct Channel* supercedes; /* Refers to channel this one was stacked upon */ + } Channel; /* *************** *** 1066,1072 **** if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! panic("Tcl_RegisterChannel: duplicate channel names"); } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } --- 1073,1082 ---- if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! /* Andreas Kupries , 05/31/1997. ! * Support of Tcl-Trf. ! */ ! /* panic("Tcl_RegisterChannel: duplicate channel names"); */ } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } *************** *** 1217,1222 **** --- 1227,1237 ---- chanPtr->timer = NULL; chanPtr->csPtr = NULL; + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf. + */ + chanPtr->supercedes = (Channel*) 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 *************** *** 1249,1254 **** --- 1264,1449 ---- return (Tcl_Channel) chanPtr; } + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf. + */ + /* + *---------------------------------------------------------------------- + * + * Tcl_ReplaceChannel -- + * + * Replaces an entry in the hash table for a Tcl_Channel + * record. + * + * Results: + * Returns the new Tcl_Channel. + * + * Side effects: + * Replaces a Tcl_Channel instance into the hash table. + * + *---------------------------------------------------------------------- + */ + + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp* interp; /* the interpreter we are working in */ + Tcl_ChannelType *typePtr; /* The channel type record. */ + ClientData instanceData; /* Instance specific data. */ + int mask; /* TCL_READABLE & TCL_WRITABLE to indicate + * if the channel is readable, writable. */ + Tcl_Channel prevChan; /* The channel structure that should + * be replaced. */ + { + Channel *chanPtr, *pt, *prevPt; + + /* + * Replace the channel into the list of all channels; + */ + + prevPt = (Channel*) NULL; + pt = (Channel*) firstChanPtr; + + while (pt != (Channel *) prevChan) { + prevPt = pt; + pt = pt->nextChanPtr; + } + + if (!pt) { + return (Tcl_Channel) NULL; + } + + /* + * Here we check if the "mask" matches the "flags" + * of the already existing channel. + * + * | - | R | W | RW | + * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) + * - | | | | | + * R | | + | | + | The superceding channel is allowed to + * W | | | + | + | restrict the capabilities of the + * RW| | + | + | + | superceded one ! + * --+---+---+---+----+ + */ + + if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { + return (Tcl_Channel) NULL; + } + + + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); + chanPtr->flags = mask; + + /* + * Set the channel up initially in no Input translation mode and + * no Output translation mode. + */ + + chanPtr->inputTranslation = TCL_TRANSLATE_LF; + chanPtr->outputTranslation = TCL_TRANSLATE_LF; + chanPtr->inEofChar = 0; + chanPtr->outEofChar = 0; + + chanPtr->unreportedError = 0; + chanPtr->instanceData = instanceData; + chanPtr->typePtr = typePtr; + chanPtr->refCount = 0; + chanPtr->closeCbPtr = (CloseCallback *) NULL; + chanPtr->curOutPtr = (ChannelBuffer *) NULL; + chanPtr->outQueueHead = (ChannelBuffer *) NULL; + chanPtr->outQueueTail = (ChannelBuffer *) NULL; + chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; + chanPtr->inQueueHead = (ChannelBuffer *) NULL; + 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->supercedes = (Channel*) prevChan; + + chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); + strcpy (chanPtr->channelName, pt->channelName); + + if (prevPt) { + prevPt->nextChanPtr = chanPtr; + } else { + firstChanPtr = chanPtr; + } + + chanPtr->nextChanPtr = pt->nextChanPtr; + + + Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); + + /* The superceded channel is effectively unregistered */ + /*chanPtr->supercedes->refCount --;*/ + + return (Tcl_Channel) chanPtr; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_UndoReplaceChannel -- + * + * Unstacks an entry in the hash table for a Tcl_Channel + * record. + * + * Results: + * Returns the old Tcl_Channel, i.e. the one which was stacked over. + * + * Side effects: + * Replaces a Tcl_Channel instance into the hash table. + * + *---------------------------------------------------------------------- + */ + + void + Tcl_UndoReplaceChannel (interp, chan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_Channel chan; /* The channel to unstack */ + { + Channel* chanPtr = (Channel*) chan; + + if (chanPtr->supercedes != (Channel*) NULL) { + Tcl_HashTable *hTblPtr; /* Hash table of channels. */ + Tcl_HashEntry *hPtr; /* Search variable. */ + int new; /* Is the hash entry new or does it exist? */ + + /* + * Insert the channel we were stacked upon back into + * the list of open channels. Place it back into the hashtable too. + * Correct 'refCount', as this actually unregisters 'chan'. + */ + + chanPtr->supercedes->nextChanPtr = firstChanPtr; + firstChanPtr = chanPtr->supercedes; + + hTblPtr = GetChannelTable (interp); + hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); + + Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); + chanPtr->refCount --; + + /* The superceded channel is effectively registered again */ + /*chanPtr->supercedes->refCount ++;*/ + } + + /* + * Disconnect the channels, then do a regular close upon the + * stacked one. This may cause flushing of data into the + * superceded channel (if 'chan' remembered its parent in itself). + */ + + chanPtr->supercedes = NULL; + + if (chanPtr->refCount == 0) { + Tcl_Close (interp, chan); + } + } + /* *---------------------------------------------------------------------- * *************** *** 1862,1867 **** --- 2057,2081 ---- if (errorCode != 0) { Tcl_SetErrno(errorCode); } + } + + /* -- CloseChannel -- + * Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf. + * + * Handle stacking of channels. Must be done after 'closeProc' + * to allow for flushing of data into the underlying channel. + */ + + if (chanPtr->supercedes != (Channel*) NULL) { + /* Insert the channel we were stacked upon back into + * the list of open channels, then do a regular close. + */ + + chanPtr->supercedes->nextChanPtr = firstChanPtr; + firstChanPtr = chanPtr->supercedes; + chanPtr->supercedes->refCount --; /* is deregistered */ + Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* trf2.1.4/patches/v8.0/byteorder.patch0000644000175000017500000001431011216344361016714 0ustar sergeisergei*** tcl.h.orig Mon Aug 18 21:11:15 1997 --- tcl.h Mon Aug 18 21:11:22 1997 *************** *** 918,923 **** --- 918,935 ---- } Tcl_EolTranslation; /* + * Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + * + * Enum for different byteorders. + */ + + typedef enum Tcl_ByteOrder { + TCL_BIGENDIAN, /* Multibyte words are stored with MSB first */ + TCL_SMALLENDIAN /* Multibyte words are stored with MSB last */ + } Tcl_ByteOrder; + + /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. *************** *** 1201,1206 **** --- 1213,1224 ---- char *chanName, int *modePtr)); EXTERN int Tcl_GetChannelBufferSize _ANSI_ARGS_(( Tcl_Channel chan)); + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + EXTERN Tcl_ByteOrder Tcl_GetChannelByteorder _ANSI_ARGS_(( + Tcl_Channel chan)); + EXTERN Tcl_ByteOrder Tcl_GetHostByteorder _ANSI_ARGS_((void)); EXTERN int Tcl_GetChannelHandle _ANSI_ARGS_((Tcl_Channel chan, int direction, ClientData *handlePtr)); EXTERN ClientData Tcl_GetChannelInstanceData _ANSI_ARGS_(( *** tclIO.c.orig Mon Aug 18 21:11:15 1997 --- tclIO.c Mon Aug 18 21:11:22 1997 *************** *** 127,132 **** --- 127,136 ---- * code, is dynamically allocated. */ int flags; /* ORed combination of the flags defined * below. */ + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + Tcl_ByteOrder byteOrder; /* byteorder associated to this channel */ Tcl_EolTranslation inputTranslation; /* What translation to apply for end of line * sequences on input? */ *************** *** 1194,1199 **** --- 1198,1207 ---- * indicator (e.g. ^Z) and does not append an EOF indicator to files. */ + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + chanPtr->byteOrder = Tcl_GetHostByteorder (); chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; *************** *** 3912,3918 **** { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize eofchar translation"; char **argv; int argc, i; Tcl_DString ds; --- 3920,3926 ---- { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; *************** *** 3945,3950 **** --- 3953,4013 ---- /* *---------------------------------------------------------------------- * + * Tcl_GetChannelByteorder -- + * + * Retrieves the byteorder set for this channel. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + Tcl_ByteOrder + Tcl_GetChannelByteorder(chan) + Tcl_Channel chan; /* The channel for which to find the + * buffer size. */ + { + Channel *chanPtr; + + chanPtr = (Channel *) chan; + return chanPtr->byteOrder; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_GetHostByteorder -- + * + * Retrieves the byteorder of the machine we are running on. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + Tcl_ByteOrder + Tcl_GetHostByteorder() + { + union { + char c[sizeof(short)]; + short s; + } order; + + order.s = 1; + return (order.c[0] == 1) ? TCL_SMALLENDIAN : TCL_BIGENDIAN; + } + + /* + *---------------------------------------------------------------------- + * * Tcl_GetChannelOption -- * * Gets a mode associated with an IO channel. If the optionName arg *************** *** 4046,4051 **** --- 4109,4128 ---- return TCL_OK; } } + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0))) { + if (len == 0) { + Tcl_DStringAppendElement(dsPtr, "-byteorder"); + } + Tcl_DStringAppendElement(dsPtr, + (chanPtr->byteOrder == TCL_BIGENDIAN) ? "bigendian" : "smallendian"); + if (len > 0) { + return TCL_OK; + } + } if ((len == 0) || ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-eofchar", len) == 0))) { *************** *** 4246,4251 **** --- 4323,4358 ---- chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; } return TCL_OK; + } + + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + if ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0)) { + int nv_len = strlen (newValue); + + if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { + chanPtr->byteOrder = TCL_BIGENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_BIGENDIAN; + return TCL_OK; + } + + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, + "bad value for -byteorder: ", + "must be one of smallendian, littleendian, bigendian or network", + (char *) NULL); + } + return TCL_ERROR; } if ((len > 1) && (optionName[1] == 'e') && trf2.1.4/patches/v8.0/tclIO.c0000644000175000017500000057620711216344361015074 0ustar sergeisergei/* * 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.268 97/07/28 14:20:36 */ #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. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) # define EWOULDBLOCK EAGAIN #endif #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) error one of EWOULDBLOCK or EAGAIN must be defined #endif /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this * structure. */ typedef struct CopyState { struct Channel *readPtr; /* Pointer to input channel. */ struct Channel *writePtr; /* Pointer to output channel. */ int readFlags; /* Original read channel flags. */ int writeFlags; /* Original write channel flags. */ int toRead; /* Number of bytes to copy, or -1. */ int total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ 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) /* * Structure to record a close callback. One such record exists for * each close callback registered for a channel. */ typedef struct CloseCallback { Tcl_CloseProc *proc; /* The procedure to call. */ ClientData clientData; /* Arbitrary one-word data to pass * to the callback. */ struct CloseCallback *nextPtr; /* For chaining close callbacks. */ } CloseCallback; /* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to * invoke the saved script in the interpreter designed in this record. */ 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; /* * struct Channel: * * One of these structures is allocated for each open channel. It contains data * specific to the channel but which belongs to the generic part of the Tcl * channel mechanism, and it points at an instance specific (and type * specific) * instance data, and at a channel type structure. */ 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. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ Tcl_ByteOrder byteOrder; /* byteorder associated to this channel */ 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. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ struct ChannelHandler *chPtr;/* List of channel handlers registered * for this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ struct Channel *nextChanPtr;/* Next in list of channels currently open. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for * event handlers ("fileevent") on this * channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf. */ struct Channel* supercedes; /* Refers to channel this one was stacked upon */ } Channel; /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in * nonblocking mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the * curOutPtr field in the * channel structure) should be * output as soon as possible even * though it may not be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the * queued output buffers has been * scheduled. */ #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No * further Tcl-level IO on the * channel is allowed. */ #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. * This bit is cleared before every * input operation. */ #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because * we saw the input eofChar. This bit * prevents clearing of the EOF bit * before every input operation. */ #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. */ typedef struct ChannelHandler { Channel *chanPtr; /* The channel structure for this channel. */ int mask; /* Mask of desired events. */ Tcl_ChannelProc *proc; /* Procedure to call in the type of * Tcl_CreateChannelHandler. */ ClientData clientData; /* Argument to pass to procedure. */ struct ChannelHandler *nextPtr; /* Next one in list of registered handlers. */ } ChannelHandler; /* * This structure keeps track of the current ChannelHandler being invoked in * the current invocation of ChannelHandlerEventProc. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. * The nextPtr field is used to chain together all recursive invocations, so * that Tcl_DeleteChannelHandler can find all the recursively nested * invocations of ChannelHandlerEventProc and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. */ typedef struct NextChannelHandler { 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 * for stdin/stdout/stderr in new interpreters. * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ 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 * closed. * * Results: * None. * * Side effects: * Causes the callback to be called in the future when the channel * will be closed. * *---------------------------------------------------------------------- */ void Tcl_CreateCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to create the * close callback. */ Tcl_CloseProc *proc; /* The callback routine to call when the * channel will be closed. */ ClientData clientData; /* Arbitrary data to pass to the * close callback. */ { Channel *chanPtr; CloseCallback *cbPtr; chanPtr = (Channel *) chan; cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; cbPtr->nextPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr; } /* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * * Removes a callback that would have been called on closing * the channel. If there is no matching callback then this * function has no effect. * * Results: * None. * * Side effects: * The callback will not be called in the future when the channel * is eventually closed. * *---------------------------------------------------------------------- */ void Tcl_DeleteCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to cancel the * close callback. */ Tcl_CloseProc *proc; /* The procedure for the callback to * remove. */ ClientData clientData; /* The callback data for the callback * to remove. */ { Channel *chanPtr; CloseCallback *cbPtr, *cbPrevPtr; chanPtr = (Channel *) chan; for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL; cbPtr != (CloseCallback *) NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == (CloseCallback *) NULL) { chanPtr->closeCbPtr = cbPtr->nextPtr; } 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 * interpreter. If it is initializing the table it also inserts * channels for stdin, stdout and stderr if the interpreter is * trusted. * * Results: * A pointer to the hash table created, for use by the caller. * * Side effects: * Initializes the channel table for an interpreter. May create * channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */ static Tcl_HashTable * GetChannelTable(interp) Tcl_Interp *interp; { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); (void) Tcl_SetAssocData(interp, "tclIO", (Tcl_InterpDeleteProc *) DeleteChannelTable, (ClientData) hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels * for stdin, stdout and stderr (possibly creating them in the * process). */ if (Tcl_IsSafe(interp) == 0) { stdinChan = Tcl_GetStdChannel(TCL_STDIN); if (stdinChan != NULL) { Tcl_RegisterChannel(interp, stdinChan); } stdoutChan = Tcl_GetStdChannel(TCL_STDOUT); if (stdoutChan != NULL) { Tcl_RegisterChannel(interp, stdoutChan); } stderrChan = Tcl_GetStdChannel(TCL_STDERR); if (stderrChan != NULL) { Tcl_RegisterChannel(interp, stderrChan); } } } return hTblPtr; } /* *---------------------------------------------------------------------- * * DeleteChannelTable -- * * Deletes the channel table for an interpreter, closing any open * channels whose refcount reaches zero. This procedure is invoked * when an interpreter is deleted, via the AssocData cleanup * mechanism. * * Results: * None. * * Side effects: * Deletes the hash table of channels. May close channels. May flush * output on closed channels. Removes any channeEvent handlers that were * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable(clientData, interp) ClientData clientData; /* The per-interpreter data structure. */ Tcl_Interp *interp; /* The interpreter being deleted. */ { Tcl_HashTable *hTblPtr; /* The hash table. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* Channel being deleted. */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* Variables to loop over all channel events * registered, to delete the ones that refer * to the interpreter being deleted. */ /* * Delete all the registered channels - this will close channels whose * refcount reaches zero. */ hTblPtr = (Tcl_HashTable *) clientData; for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); /* * Remove any fileevents registered in this interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); ckfree(sPtr->script); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } /* * Cannot call Tcl_UnregisterChannel because that procedure calls * Tcl_GetAssocData to get the channel table, which might already * be inaccessible from the interpreter structure. Instead, we * emulate the behavior of Tcl_UnregisterChannel directly here. */ Tcl_DeleteHashEntry(hPtr); chanPtr->refCount--; if (chanPtr->refCount <= 0) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } } Tcl_DeleteHashTable(hTblPtr); ckfree((char *) hTblPtr); } /* *---------------------------------------------------------------------- * * CheckForStdChannelsBeingClosed -- * * Perform special handling for standard channels being closed. When * given a standard channel, if the refcount is now 1, it means that * the last reference to the standard channel is being explicitly * closed. Now bump the refcount artificially down to 0, to ensure the * normal handling of channels being closed will occur. Also reset the * static pointer to the channel to NULL, to avoid dangling references. * * Results: * None. * * Side effects: * Manipulates the refcount on standard channels. May smash the global * static pointer to a standard channel. * *---------------------------------------------------------------------- */ 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. * If the interpreter given as argument is NULL, it only decrements the * reference count. * * Results: * A standard Tcl result. * * Side effects: * Deletes the hash entry for a channel associated with an interpreter. * *---------------------------------------------------------------------- */ int Tcl_UnregisterChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which channel is defined. */ Tcl_Channel chan; /* Channel to delete. */ { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The real IO channel. */ chanPtr = (Channel *) chan; if (interp != (Tcl_Interp *) NULL) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } hPtr = Tcl_FindHashEntry(hTblPtr, chanPtr->channelName); if (hPtr == (Tcl_HashEntry *) NULL) { return TCL_OK; } if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) { return TCL_OK; } Tcl_DeleteHashEntry(hPtr); /* * Remove channel handlers that refer to this interpreter, so that they * will not be present if the actual close is delayed and more events * happen on the channel. This may occur if the channel is shared * between several interpreters, or if the channel has async * flushing active. */ CleanupChannelHandlers(interp, chanPtr); } chanPtr->refCount--; /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); /* * If the refCount reached zero, close the actual channel. */ if (chanPtr->refCount <= 0) { /* * Ensure that if there is another buffer, it gets flushed * whether or not we are doing a background flush. */ if ((chanPtr->curOutPtr != NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; } chanPtr->flags |= CHANNEL_CLOSED; if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { if (Tcl_Close(interp, chan) != TCL_OK) { return TCL_ERROR; } } } 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; } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf. */ /* 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. */ int *modePtr; /* Where to store the mode in which the * channel was opened? Will contain an ORed * combination of TCL_READABLE and * TCL_WRITABLE, if non-NULL. */ { Channel *chanPtr; /* The actual channel. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ char *name; /* Translated name. */ /* * Substitute "stdin", etc. Note that even though we immediately * find the channel using Tcl_GetStdChannel, we still need to look * it up in the specified interpreter to ensure that it is present * in the channel table. Otherwise, safe interpreters would always * have access to the standard channels. */ name = chanName; if ((chanName[0] == 's') && (chanName[1] == 't')) { chanPtr = NULL; if (strcmp(chanName, "stdin") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDIN); } else if (strcmp(chanName, "stdout") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDOUT); } else if (strcmp(chanName, "stderr") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDERR); } if (chanPtr != NULL) { name = chanPtr->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == (Tcl_HashEntry *) NULL) { Tcl_AppendResult(interp, "can not find channel named \"", chanName, "\"", (char *) NULL); return NULL; } chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (modePtr != NULL) { *modePtr = (chanPtr->flags & (TCL_READABLE|TCL_WRITABLE)); } return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_CreateChannel -- * * Creates a new entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Creates a new Tcl_Channel instance and inserts it into the * hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_CreateChannel(typePtr, chanName, instanceData, mask) 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. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ chanPtr->byteOrder = Tcl_GetHostByteorder (); chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf. */ chanPtr->supercedes = (Channel*) 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; } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf. */ /* *---------------------------------------------------------------------- * * Tcl_ReplaceChannel -- * * Replaces an entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Replaces a Tcl_Channel instance into the hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp* interp; /* the interpreter we are working in */ Tcl_ChannelType *typePtr; /* The channel type record. */ ClientData instanceData; /* Instance specific data. */ int mask; /* TCL_READABLE & TCL_WRITABLE to indicate * if the channel is readable, writable. */ Tcl_Channel prevChan; /* The channel structure that should * be replaced. */ { Channel *chanPtr, *pt, *prevPt; /* * Replace the channel into the list of all channels; */ prevPt = (Channel*) NULL; pt = (Channel*) firstChanPtr; while (pt != (Channel *) prevChan) { prevPt = pt; pt = pt->nextChanPtr; } if (!pt) { return (Tcl_Channel) NULL; } /* * Here we check if the "mask" matches the "flags" * of the already existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to * W | | | + | + | restrict the capabilities of the * RW| | + | + | + | superceded one ! * --+---+---+---+----+ */ if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { return (Tcl_Channel) NULL; } chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); chanPtr->flags = mask; /* * Set the channel up initially in no Input translation mode and * no Output translation mode. */ chanPtr->inputTranslation = TCL_TRANSLATE_LF; chanPtr->outputTranslation = TCL_TRANSLATE_LF; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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->supercedes = (Channel*) prevChan; chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); strcpy (chanPtr->channelName, pt->channelName); if (prevPt) { prevPt->nextChanPtr = chanPtr; } else { firstChanPtr = chanPtr; } chanPtr->nextChanPtr = pt->nextChanPtr; Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); /* The superceded channel is effectively unregistered */ /*chanPtr->supercedes->refCount --;*/ return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_UndoReplaceChannel -- * * Unstacks an entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the old Tcl_Channel, i.e. the one which was stacked over. * * Side effects: * Replaces a Tcl_Channel instance into the hash table. * *---------------------------------------------------------------------- */ void Tcl_UndoReplaceChannel (interp, chan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_Channel chan; /* The channel to unstack */ { Channel* chanPtr = (Channel*) chan; if (chanPtr->supercedes != (Channel*) NULL) { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ int new; /* Is the hash entry new or does it exist? */ /* * Insert the channel we were stacked upon back into * the list of open channels. Place it back into the hashtable too. * Correct 'refCount', as this actually unregisters 'chan'. */ chanPtr->supercedes->nextChanPtr = firstChanPtr; firstChanPtr = chanPtr->supercedes; hTblPtr = GetChannelTable (interp); hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); chanPtr->refCount --; /* The superceded channel is effectively registered again */ /*chanPtr->supercedes->refCount ++;*/ } /* * Disconnect the channels, then do a regular close upon the * stacked one. This may cause flushing of data into the * superceded channel (if 'chan' remembered its parent in itself). */ chanPtr->supercedes = NULL; if (chanPtr->refCount == 0) { Tcl_Close (interp, chan); } } /* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * * Computes a mask indicating whether the channel is open for * reading and writing. * * Results: * An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelMode(chan) Tcl_Channel chan; /* The channel for which the mode is * being computed. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE)); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * * Returns the string identifying the channel name. * * Results: * The string containing the channel name. This memory is * owned by the generic layer and should not be modified by * the caller. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Tcl_GetChannelName(chan) Tcl_Channel chan; /* The channel for which to return the name. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->channelName; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * * Given a channel structure, returns the channel type structure. * * Results: * Returns a pointer to the channel type structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ChannelType * Tcl_GetChannelType(chan) Tcl_Channel chan; /* The channel to return type for. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->typePtr; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * * Returns an OS handle associated with a channel. * * Results: * Returns TCL_OK and places the handle in handlePtr, or returns * TCL_ERROR on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelHandle(chan, direction, handlePtr) Tcl_Channel chan; /* The channel to get file from. */ int direction; /* TCL_WRITABLE or TCL_READABLE. */ ClientData *handlePtr; /* Where to store handle */ { Channel *chanPtr; /* The actual channel. */ ClientData handle; int result; chanPtr = (Channel *) chan; result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData, direction, &handle); if (handlePtr) { *handlePtr = handle; } return result; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * * Returns the client data associated with a channel. * * Results: * The client data. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_GetChannelInstanceData(chan) 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 * that two input buffers are saved (one in the input queue and * another in the saveInBufPtr field) and that curOutPtr is set * to a buffer. Only if these conditions are met is the buffer * freed to the OS. * * Results: * None. * * Side effects: * May free a buffer to the OS. * *---------------------------------------------------------------------- */ static void RecycleBuffer(chanPtr, bufPtr, mustDiscard) Channel *chanPtr; /* Channel for which to recycle buffers. */ ChannelBuffer *bufPtr; /* The buffer to recycle. */ int mustDiscard; /* If nonzero, free the buffer to the * OS, always. */ { /* * Do we have to free the buffer to the OS? */ if (mustDiscard) { ckfree((char *) bufPtr); return; } /* * Only save buffers for the input queue if the channel is readable. */ if (chanPtr->flags & TCL_READABLE) { if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) { chanPtr->inQueueHead = bufPtr; chanPtr->inQueueTail = bufPtr; goto keepit; } if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) { chanPtr->saveInBufPtr = bufPtr; goto keepit; } } /* * Only save buffers for the output queue if the channel is writable. */ if (chanPtr->flags & TCL_WRITABLE) { if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) { chanPtr->curOutPtr = bufPtr; goto keepit; } } /* * 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 -- * * Discards all output queued in the output queue of a channel. * * Results: * None. * * Side effects: * Recycles buffers. * *---------------------------------------------------------------------- */ static void DiscardOutputQueued(chanPtr) Channel *chanPtr; /* The channel for which to discard output. */ { ChannelBuffer *bufPtr; while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { bufPtr = chanPtr->outQueueHead; chanPtr->outQueueHead = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, 0); } chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; } /* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * * This function checks is a given channel is Dead. * (A channel that has been closed but not yet deallocated.) * * Results: * True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: * None * *---------------------------------------------------------------------- */ static int CheckForDeadChannel(interp, chanPtr) Tcl_Interp *interp; /* For error reporting (can be NULL) */ Channel *chanPtr; /* The channel to check. */ { if (chanPtr->flags & CHANNEL_DEAD) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, "unable to access channel: invalid channel", (char *) NULL); } return 1; } return 0; } /* *---------------------------------------------------------------------- * * FlushChannel -- * * This function flushes as much of the queued output as is possible * now. If calledFromAsyncFlush is nonzero, it is being called in an * event handler to flush channel output asynchronously. * * Results: * 0 if successful, else the error code that was returned by the * channel type operation. * * Side effects: * May produce output on a channel. May block indefinitely if the * channel is synchronous. May schedule an async flush on the channel. * May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */ static int FlushChannel(interp, chanPtr, calledFromAsyncFlush) Tcl_Interp *interp; /* For error reporting during close. */ Channel *chanPtr; /* The channel to flush on. */ int calledFromAsyncFlush; /* If nonzero then we are being * called from an asynchronous * flush callback. */ { 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. */ if (CheckForDeadChannel(interp,chanPtr)) return -1; /* * Loop over the queued buffers and attempt to flush as * much as possible of the queued output to the channel. */ while (1) { /* * 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 { chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr; } chanPtr->outQueueTail = chanPtr->curOutPtr; chanPtr->curOutPtr = (ChannelBuffer *) NULL; } bufPtr = chanPtr->outQueueHead; /* * If we are not being called from an async flush and an async * flush is active, we just return without producing any output. */ if ((!calledFromAsyncFlush) && (chanPtr->flags & BG_FLUSH_SCHEDULED)) { return 0; } /* * If the output queue is still empty, break out of the while loop. */ if (bufPtr == (ChannelBuffer *) NULL) { break; /* Out of the "while (1)". */ } /* * 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. */ if (written < 0) { /* * If the last attempt to write was interrupted, simply retry. */ if (errorCode == EINTR) { errorCode = 0; continue; } /* * If the channel is non-blocking and we would have blocked, * start a background flushing handler and break out of the loop. */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { if (chanPtr->flags & CHANNEL_NONBLOCKING) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { chanPtr->flags |= BG_FLUSH_SCHEDULED; UpdateInterest(chanPtr); } errorCode = 0; break; } else { panic("Blocking channel driver did not block on output"); } } /* * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { if (chanPtr->unreportedError == 0) { chanPtr->unreportedError = errorCode; } } else { Tcl_SetErrno(errorCode); if (interp != NULL) { Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } } /* * 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. */ if ((chanPtr->flags & CHANNEL_CLOSED) && (chanPtr->refCount <= 0) && (chanPtr->outQueueHead == (ChannelBuffer *) NULL) && ((chanPtr->curOutPtr == (ChannelBuffer *) NULL) || (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->nextRemoved))) { return CloseChannel(interp, chanPtr, errorCode); } return errorCode; } /* *---------------------------------------------------------------------- * * CloseChannel -- * * Utility procedure to close a channel and free its associated * resources. * * Results: * 0 on success or a POSIX error code if the operation failed. * * Side effects: * May close the actual channel; may free memory. * *---------------------------------------------------------------------- */ static int CloseChannel(interp, chanPtr, errorCode) Tcl_Interp *interp; /* For error reporting. */ Channel *chanPtr; /* The channel to close. */ 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. */ DiscardInputQueued(chanPtr, 1); /* * Discard a leftover buffer in the current output buffer field. */ if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { ckfree((char *) chanPtr->curOutPtr); chanPtr->curOutPtr = (ChannelBuffer *) NULL; } /* * The caller guarantees that there are no more buffers * queued for output. */ if (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { panic("TclFlush, closed channel: queued output left"); } /* * If the EOF character is set in the channel, append that to the * output device. */ if ((chanPtr->outEofChar != 0) && (chanPtr->flags & TCL_WRITABLE)) { int dummy; char c; c = (char) chanPtr->outEofChar; (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy); } /* * Remove TCL_READABLE and TCL_WRITABLE from chanPtr->flags, so * that close callbacks can not do input or output (assuming they * squirreled the channel away in their clientData). This also * prevents infinite loops if the callback calls any C API that * could call FlushChannel. */ 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. */ if (chanPtr->unreportedError != 0) { errorCode = chanPtr->unreportedError; } if (errorCode == 0) { errorCode = result; if (errorCode != 0) { Tcl_SetErrno(errorCode); } } /* -- CloseChannel -- * Andreas Kupries , 05/31/1997. * Support of Tcl-Trf. * * Handle stacking of channels. Must be done after 'closeProc' * to allow for flushing of data into the underlying channel. */ if (chanPtr->supercedes != (Channel*) NULL) { /* Insert the channel we were stacked upon back into * the list of open channels, then do a regular close. */ chanPtr->supercedes->nextChanPtr = firstChanPtr; firstChanPtr = chanPtr->supercedes; chanPtr->supercedes->refCount --; /* is deregistered */ Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* * Cancel any outstanding timer. */ Tcl_DeleteTimerHandler(chanPtr->timer); /* * Mark the channel as deleted by clearing the type structure. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC); return errorCode; } /* *---------------------------------------------------------------------- * * Tcl_Close -- * * Closes a channel. * * Results: * A standard Tcl result. * * Side effects: * Closes the channel if this is the last reference. * * NOTE: * Tcl_Close removes the channel as far as the user is concerned. * However, it may continue to exist for a while longer if it has * a background flush scheduled. The device itself is eventually * closed and the channel record removed, in CloseChannel, above. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_Close(interp, chan) Tcl_Interp *interp; /* Interpreter for errors. */ Tcl_Channel chan; /* The channel being closed. Must * not be referenced in any * interpreter. */ { 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; } /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); chanPtr = (Channel *) chan; if (chanPtr->refCount > 0) { panic("called Tcl_Close on channel with refCount > 0"); } /* * 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; } } /* * Remove all the channel handler records attached to the channel * itself. */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chNext) { chNext = chPtr->nextPtr; ckfree((char *) chPtr); } chanPtr->chPtr = (ChannelHandler *) NULL; /* * Cancel any pending copy operation. */ StopCopy(chanPtr->csPtr); /* * Must set the interest mask now to 0, otherwise infinite loops * will occur if Tcl_DoOneEvent is called before the channel is * finally deleted in FlushChannel. This can happen if the channel * has a background flush active. */ chanPtr->interestMask = 0; /* * 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. */ while (chanPtr->closeCbPtr != (CloseCallback *) NULL) { cbPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr->nextPtr; (cbPtr->proc) (cbPtr->clientData); ckfree((char *) cbPtr); } /* * 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 -- * * Flushes output data on a channel. * * Results: * A standard Tcl result. * * Side effects: * May flush output queued on this channel. * *---------------------------------------------------------------------- */ int 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; } return TCL_OK; } /* *---------------------------------------------------------------------- * * DiscardInputQueued -- * * Discards any input read from the channel but not yet consumed * by Tcl reading commands. * * Results: * None. * * Side effects: * May discard input from the channel. If discardLastBuffer is zero, * leaves one buffer in place for back-filling. * *---------------------------------------------------------------------- */ static void DiscardInputQueued(chanPtr, discardSavedBuffers) Channel *chanPtr; /* Channel on which to discard * the queued input. */ int discardSavedBuffers; /* If non-zero, discard all buffers including * last one. */ { ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ bufPtr = chanPtr->inQueueHead; chanPtr->inQueueHead = (ChannelBuffer *) NULL; chanPtr->inQueueTail = (ChannelBuffer *) NULL; for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) { nxtPtr = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, discardSavedBuffers); } /* * If discardSavedBuffers is nonzero, must also discard any previously * saved buffer in the saveInBufPtr field. */ if (discardSavedBuffers) { if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) { 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 -- * * Implements seeking on Tcl Channels. This is a public function * so that other C facilities may be implemented on top of it. * * Results: * The new access point or -1 on error. If error, use Tcl_GetErrno() * to retrieve the POSIX error code for the error that occurred. * * Side effects: * May flush output on the channel. May discard queued input. * *---------------------------------------------------------------------- */ int Tcl_Seek(chan, offset, mode) Tcl_Channel chan; /* The channel on which to seek. */ int offset; /* Offset to seek to. */ int mode; /* Relative to which location to seek? */ { Channel *chanPtr; /* The real IO channel. */ ChannelBuffer *bufPtr; int inputBuffered, outputBuffered; 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 * registered in an interpreter. */ if (CheckForDeadChannel(NULL,chanPtr)) return -1; /* * Disallow seek on channels whose type does not have a seek procedure * defined. This means that the channel does not support seeking. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * If we are seeking relative to the current position, compute the * corrected offset taking into account the amount of unread input. */ if (mode == SEEK_CUR) { offset -= inputBuffered; } /* * Discard any queued input - this input should not be read after * the seek. */ DiscardInputQueued(chanPtr, 0); /* * Reset EOF and BLOCKED flags. We invalidate them by moving the * access point. Also clear CR related flags. */ chanPtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR)); /* * If the channel is in asynchronous output mode, switch it back * to synchronous mode and cancel any async flush that may be * scheduled. After the flush, the channel will be put back into * asynchronous output mode. */ wasAsync = 0; if (chanPtr->flags & CHANNEL_NONBLOCKING) { wasAsync = 1; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_BLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } chanPtr->flags &= (~(CHANNEL_NONBLOCKING)); if (chanPtr->flags & BG_FLUSH_SCHEDULED) { chanPtr->flags &= (~(BG_FLUSH_SCHEDULED)); } } /* * If the flush fails we cannot recover the original position. In * that case the seek is not attempted because we do not know where * the access position is - instead we return the error. FlushChannel * has already called Tcl_SetErrno() to report the error upwards. * If the flush succeeds we do the seek also. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { curPos = -1; } else { /* * Now seek to the new position in the channel as requested by the * caller. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) offset, mode, &result); if (curPos == -1) { Tcl_SetErrno(result); } } /* * Restore to nonblocking mode if that was the previous behavior. * * NOTE: Even if there was an async flush active we do not restore * it now because we already flushed all the queued output, above. */ if (wasAsync) { chanPtr->flags |= CHANNEL_NONBLOCKING; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_NONBLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } } return curPos; } /* *---------------------------------------------------------------------- * * Tcl_Tell -- * * Returns the position of the next character to be read/written on * this channel. * * Results: * A nonnegative integer on success, -1 on failure. If failed, * use Tcl_GetErrno() to retrieve the POSIX error code for the * error that occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Tell(chan) Tcl_Channel chan; /* The channel to return pos for. */ { 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. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * Get the current position in the device and compute the position * where the next character will be read or written. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) 0, SEEK_CUR, &result); if (curPos == -1) { Tcl_SetErrno(result); return -1; } if (inputBuffered != 0) { return (curPos - inputBuffered); } return (curPos + outputBuffered); } /* *---------------------------------------------------------------------- * * Tcl_Eof -- * * Returns 1 if the channel is at EOF, 0 otherwise. * * Results: * 1 or 0, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Eof(chan) Tcl_Channel chan; /* Does this channel have EOF? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_STICKY_EOF) || ((chanPtr->flags & CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * * Results: * 0 or 1, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBlocked(chan) Tcl_Channel chan; /* Is this channel blocked? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return (chanPtr->flags & CHANNEL_BLOCKED) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBuffered -- * * Returns the number of bytes of input currently buffered in the * internal buffer of a channel. * * Results: * The number of input bytes buffered, or zero if the channel is not * open for reading. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBuffered(chan) Tcl_Channel chan; /* The channel to query. */ { Channel *chanPtr; int bytesBuffered; ChannelBuffer *bufPtr; chanPtr = (Channel *) chan; for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } return bytesBuffered; } /* *---------------------------------------------------------------------- * * Tcl_SetChannelBufferSize -- * * Sets the size of buffers to allocate to store input or output * in the channel. The size must be between 10 bytes and 1 MByte. * * Results: * None. * * Side effects: * Sets the size of buffers subsequently allocated for this channel. * *---------------------------------------------------------------------- */ void Tcl_SetChannelBufferSize(chan, sz) Tcl_Channel chan; /* The channel whose buffer size * to set. */ int sz; /* The size to set. */ { Channel *chanPtr; /* * If the buffer size is smaller than 10 bytes or larger than one MByte, * do not accept the requested size and leave the current buffer size. */ if (sz < 10) { return; } if (sz > (1024 * 1024)) { return; } chanPtr = (Channel *) chan; chanPtr->bufSize = sz; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelBufferSize -- * * Retrieves the size of buffers to allocate for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelBufferSize(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->bufSize; } /* *---------------------------------------------------------------------- * * Tcl_BadChannelOption -- * * This procedure generates a "bad option" error message in an * (optional) interpreter. It is used by channel drivers when * a invalid Set/Get option is requested. Its purpose is to concatenate * the generic options list to the specific ones and factorize * the generic options error message string. * * Results: * TCL_ERROR. * * Side effects: * An error message is generated in interp's result object to * indicate that a command was invoked with the a bad option * The message has the form * bad option "blah": should be one of * <...generic options...>+<...specific options...> * "blah" is the optionName argument and "" * is a space separated list of specific option words. * The function takes good care of inserting minus signs before * each option, commas after, and an "or" before the last option. * *---------------------------------------------------------------------- */ int Tcl_BadChannelOption(interp, optionName, optionList) Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/ char *optionName; /* 'bad option' name */ char *optionList; /* Specific options list to append * to the standard generic options. * can be NULL for generic options * only. */ { if (interp) { CONST char *genericopt = "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, (char *) genericopt, -1); if (optionList && (*optionList)) { Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad option \"", optionName, "\": should be one of ", (char *) NULL); argc--; for (i = 0; i < argc; i++) { Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL); } Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL); Tcl_DStringFree(&ds); ckfree((char *) argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelByteorder -- * * Retrieves the byteorder set for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ByteOrder Tcl_GetChannelByteorder(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->byteOrder; } /* *---------------------------------------------------------------------- * * Tcl_GetHostByteorder -- * * Retrieves the byteorder of the machine we are running on. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ByteOrder Tcl_GetHostByteorder() { union { char c[sizeof(short)]; short s; } order; order.s = 1; return (order.c[0] == 1) ? TCL_SMALLENDIAN : TCL_BIGENDIAN; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelOption -- * * 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: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelOption(interp, chan, optionName, dsPtr) Tcl_Interp *interp; /* For error reporting - can be NULL. */ Tcl_Channel chan; /* Channel on which to get option. */ char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */ { size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; int flags; /* * If we are in the middle of a background copy, use the saved flags. */ if (chanPtr->csPtr) { if (chanPtr == chanPtr->csPtr->readPtr) { flags = chanPtr->csPtr->readFlags; } else { flags = chanPtr->csPtr->writeFlags; } } else { flags = chanPtr->flags; } /* * Disallow options 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(interp,chanPtr)) return TCL_ERROR; /* * If the optionName is NULL it means that we want a list of all * options and values. */ if (optionName == (char *) NULL) { len = 0; } else { len = strlen(optionName); } if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blocking"); } Tcl_DStringAppendElement(dsPtr, (flags & CHANNEL_NONBLOCKING) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffering", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffering"); } if (flags & CHANNEL_LINEBUFFERED) { Tcl_DStringAppendElement(dsPtr, "line"); } else if (flags & CHANNEL_UNBUFFERED) { Tcl_DStringAppendElement(dsPtr, "none"); } else { Tcl_DStringAppendElement(dsPtr, "full"); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffersize", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffersize"); } TclFormatInt(optionVal, chanPtr->bufSize); Tcl_DStringAppendElement(dsPtr, optionVal); if (len > 0) { return TCL_OK; } } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-byteorder"); } Tcl_DStringAppendElement(dsPtr, (chanPtr->byteOrder == TCL_BIGENDIAN) ? "bigendian" : "smallendian"); 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); } if (flags & TCL_READABLE) { if (chanPtr->inEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->inEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (flags & TCL_WRITABLE) { if (chanPtr->outEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->outEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 1) && (optionName[1] == 't') && (strncmp(optionName, "-translation", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-translation"); } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringStartSublist(dsPtr); } if (flags & TCL_READABLE) { if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (flags & TCL_WRITABLE) { if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) { /* * let the driver specific handle additional options * and result code and message. */ return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData, interp, optionName, dsPtr); } else { /* * no driver specific options case. */ if (len == 0) { 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? */ char *newValue; /* New value for option. */ { int newMode; /* New (numeric) mode to sert. */ Channel *chanPtr; /* The real IO channel. */ size_t len; /* Length of optionName string. */ int argc; char **argv; chanPtr = (Channel *) chan; /* * If the channel is in the middle of a background copy, fail. */ if (chanPtr->csPtr) { if (interp) { Tcl_AppendResult(interp, "unable to set channel options: background copy in progress", (char *) NULL); } return TCL_ERROR; } /* * Disallow options 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 TCL_ERROR; len = strlen(optionName); if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0)) { if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) { return TCL_ERROR; } 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)) { chanPtr->flags &= (~(CHANNEL_UNBUFFERED)); chanPtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { chanPtr->flags &= (~(CHANNEL_LINEBUFFERED)); chanPtr->flags |= CHANNEL_UNBUFFERED; } else { 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; } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0)) { int nv_len = strlen (newValue); if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { chanPtr->byteOrder = TCL_BIGENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_BIGENDIAN; return TCL_OK; } if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "bad value for -byteorder: ", "must be one of smallendian, littleendian, bigendian or network", (char *) NULL); } return TCL_ERROR; } 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; } else if (argc == 1) { if (chanPtr->flags & TCL_WRITABLE) { chanPtr->outEofChar = (int) argv[0][0]; } if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } } else if (argc != 2) { if (interp) { Tcl_AppendResult(interp, "bad value for -eofchar: should be a list of one or", " two elements", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } else { if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } 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; } if (argc == 1) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: must be a one or two", " element list", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } 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) { newMode = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered * 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(argv[0], "auto") == 0) { /* * This is a hack to get TCP sockets to produce output * in CRLF mode if they are being set into AUTO mode. * A better solution for achieving this effect will be * coded later. */ if (strcmp(chanPtr->typePtr->typeName, "tcp") == 0) { 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) { chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } 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 -- * * Removes channel handlers that refer to the supplied interpreter, * so that if the actual channel is not closed now, these handlers * will not run on subsequent events on the channel. This would be * erroneous, because the interpreter no longer has a reference to * this channel. * * Results: * None. * * Side effects: * Removes channel handlers. * *---------------------------------------------------------------------- */ static void CleanupChannelHandlers(interp, chanPtr) Tcl_Interp *interp; Channel *chanPtr; { EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* * Remove fileevent records on this channel that refer to the * given interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); ckfree(sPtr->script); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } } /* *---------------------------------------------------------------------- * * Tcl_NotifyChannel -- * * This procedure is called by a channel driver when a driver * detects an event on a channel. This procedure is responsible * for actually handling the event by invoking any channel * handler callbacks. * * Results: * None. * * Side effects: * Whatever the channel handler callback procedure does. * *---------------------------------------------------------------------- */ void Tcl_NotifyChannel(channel, mask) 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. */ if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; (*(chPtr->proc))(chPtr->clientData, mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; } } /* * 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 -- * * Arrange for the notifier to call us back at appropriate times * based on the current state of the channel. * * Results: * None. * * Side effects: * May schedule a timer or driver handler. * *---------------------------------------------------------------------- */ static void UpdateInterest(chanPtr) Channel *chanPtr; /* Channel to update. */ { int mask = chanPtr->interestMask; /* * If there are flushed buffers waiting to be written, then * we need to watch for the channel to become writable. */ 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); } } } (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask); } /* *---------------------------------------------------------------------- * * ChannelTimerProc -- * * Timer handler scheduled by UpdateInterest to monitor the * channel buffers until they are empty. * * Results: * None. * * Side effects: * May invoke channel handlers. * *---------------------------------------------------------------------- */ static void ChannelTimerProc(clientData) ClientData clientData; { Channel *chanPtr = (Channel *) clientData; if (!(chanPtr->flags & CHANNEL_GETS_BLOCKED) && (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. */ chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc, (ClientData) chanPtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); } else { chanPtr->timer = NULL; UpdateInterest(chanPtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * * Arrange for a given procedure to be invoked whenever the * channel indicated by the chanPtr arg becomes readable or * writable. * * Results: * None. * * Side effects: * From now on, whenever the I/O channel given by chanPtr becomes * ready in the way indicated by mask, proc will be invoked. * See the manual entry for details on the calling sequence * to proc. If there is already an event handler for chan, proc * and clientData, then the mask will be updated. * *---------------------------------------------------------------------- */ void Tcl_CreateChannelHandler(chan, mask, proc, clientData) Tcl_Channel chan; /* The channel to create the handler for. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions under which * proc should be called. Use 0 to * disable a registered handler. */ Tcl_ChannelProc *proc; /* Procedure to call for each * selected event. */ ClientData clientData; /* Arbitrary data to pass to proc. */ { ChannelHandler *chPtr; Channel *chanPtr; chanPtr = (Channel *) chan; /* * Check whether this channel handler is not already registered. If * it is not, create a new record, else reuse existing record (smash * current values). */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) && (chPtr->clientData == clientData)) { break; } } if (chPtr == (ChannelHandler *) NULL) { chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler)); chPtr->mask = 0; chPtr->proc = proc; chPtr->clientData = clientData; chPtr->chanPtr = chanPtr; chPtr->nextPtr = chanPtr->chPtr; chanPtr->chPtr = chPtr; } /* * The remainder of the initialization below is done regardless of * whether or not this is a new record or a modification of an old * one. */ chPtr->mask = mask; /* * Recompute the interest mask for the channel - this call may actually * be disabling an existing handler. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * Tcl_DeleteChannelHandler -- * * Cancel a previously arranged callback arrangement for an IO * channel. * * Results: * None. * * Side effects: * If a callback was previously registered for this chan, proc and * clientData , it is removed and the callback will no longer be called * when the channel becomes ready for IO. * *---------------------------------------------------------------------- */ void Tcl_DeleteChannelHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to remove the * callback. */ 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. */ for (prevChPtr = (ChannelHandler *) NULL, chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData) && (chPtr->proc == proc)) { break; } prevChPtr = chPtr; } /* * If not found, return without doing anything. */ if (chPtr == (ChannelHandler *) NULL) { return; } /* * 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; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * DeleteScriptRecord -- * * Delete a script record for this combination of channel, interp * and mask. * * Results: * None. * * Side effects: * Deletes a script record and cancels a channel event handler. * *---------------------------------------------------------------------- */ static void DeleteScriptRecord(interp, chanPtr, mask) Tcl_Interp *interp; /* Interpreter in which script was to be * executed. */ Channel *chanPtr; /* The channel for which to delete the * script record (if any). */ int mask; /* Events in mask must exactly match mask * of script to delete. */ { EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = chanPtr->scriptRecordPtr, prevEsPtr = (EventScriptRecord *) NULL; esPtr != (EventScriptRecord *) NULL; prevEsPtr = esPtr, esPtr = esPtr->nextPtr) { if ((esPtr->interp == interp) && (esPtr->mask == mask)) { if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { prevEsPtr->nextPtr = esPtr->nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) esPtr); ckfree(esPtr->script); ckfree((char *) esPtr); break; } } } /* *---------------------------------------------------------------------- * * CreateScriptRecord -- * * Creates a record to store a script to be executed when a specific * event fires on a specific channel. * * Results: * None. * * 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 -- * * Invokes a script scheduled by "fileevent" for when the channel * becomes ready for IO. This function is invoked by the channel * handler which was created by the Tcl "fileevent" command. * * Results: * None. * * Side effects: * Whatever the script does. * *---------------------------------------------------------------------- */ static void 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. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundError(interp); } 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; } /* *---------------------------------------------------------------------- * * TclTestChannelCmd -- * * Implements the Tcl "testchannel" debugging command and its * subcommands. This is part of the testing environment but must be * in this file instead of tclTest.c because it needs access to the * fields of struct Channel. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int TclTestChannelCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Interpreter for result. */ int argc; /* Count of additional args. */ char **argv; /* Additional arg strings. */ { char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ 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]); Tcl_AppendElement(interp, chanPtr->typePtr->typeName); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_NONBLOCKING) { Tcl_AppendElement(interp, "nonblocking"); } else { Tcl_AppendElement(interp, "blocking"); } if (chanPtr->flags & CHANNEL_LINEBUFFERED) { Tcl_AppendElement(interp, "line"); } else if (chanPtr->flags & CHANNEL_UNBUFFERED) { Tcl_AppendElement(interp, "none"); } else { Tcl_AppendElement(interp, "full"); } if (chanPtr->flags & BG_FLUSH_SCHEDULED) { Tcl_AppendElement(interp, "async_flush"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_EOF) { Tcl_AppendElement(interp, "eof"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_BLOCKED) { Tcl_AppendElement(interp, "blocked"); } else { Tcl_AppendElement(interp, "unblocked"); } if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "saw_cr"); } else { Tcl_AppendElement(interp, ""); } } else if (chanPtr->inputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "queued_cr"); } else { Tcl_AppendElement(interp, ""); } } if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); } for (IOQueued = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved; } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved; } for (bufPtr = chanPtr->outQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved); } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr)); Tcl_AppendElement(interp, buf); TclFormatInt(buf, chanPtr->refCount); Tcl_AppendElement(interp, buf); return TCL_OK; } if ((cmdName[0] == 'i') && (strncmp(cmdName, "inputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; } if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } return TCL_OK; } if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "outputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - 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) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (chanPtr->flags & INPUT_SAW_CR) ? "1" : "0", (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } 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", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ", "info, open, readable, or writable", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclTestChannelEventCmd -- * * This procedure implements the "testchannelevent" command. It is * used to test the Tcl channel event mechanism. It is present in * this file instead of tclTest.c because it needs access to the * internal structure of the channel. * * Results: * A standard Tcl result. * * Side effects: * Creates, deletes and returns channel event handlers. * *---------------------------------------------------------------------- */ /* ARGSUSED */ 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], " channelName cmd ?arg1? ?arg2?\"", (char *) NULL); return TCL_ERROR; } chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL); if (chanPtr == (Channel *) NULL) { return TCL_ERROR; } cmd = argv[2]; len = strlen(cmd); if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName add eventSpec script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[3], "writable") == 0) { mask = TCL_WRITABLE; } else { Tcl_AppendResult(interp, "bad event name \"", argv[3], "\": must be readable or writable", (char *) NULL); return TCL_ERROR; } esPtr = (EventScriptRecord *) ckalloc((unsigned) 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; } if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) { if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { for (prevEsPtr = chanPtr->scriptRecordPtr; (prevEsPtr != (EventScriptRecord *) NULL) && (prevEsPtr->nextPtr != esPtr); prevEsPtr = prevEsPtr->nextPtr) { /* Empty loop body. */ } 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) { Tcl_AppendElement(interp, esPtr->mask == TCL_READABLE ? "readable" : "writable"); 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; } Tcl_AppendResult(interp, "bad command ", cmd, ", must be one of ", "add, delete, list, or removeall", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclCopyChannel -- * * This routine copies data from one channel to another, either * synchronously or asynchronously. If a command script is * supplied, the operation runs in the background. The script * is invoked when the copy completes. Otherwise the function * waits until the copy is completed before returning. * * Results: * A standard Tcl result. * * Side effects: * May schedule a background copy operation that causes both * channels to be marked busy. * *---------------------------------------------------------------------- */ int TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Channel inChan; /* Channel to read from. */ Tcl_Channel outChan; /* Channel to write to. */ int toRead; /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */ { Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; if (inPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); return TCL_ERROR; } if (outPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); return TCL_ERROR; } readFlags = inPtr->flags; writeFlags = outPtr->flags; /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. * If there is an error, restore the old blocking mode. */ if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(interp, inPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) { return TCL_ERROR; } } if (inPtr != outPtr) { if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(NULL, outPtr, nonBlocking ? TCL_MODE_BLOCKING : TCL_MODE_NONBLOCKING) != TCL_OK) { if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING) ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); return TCL_ERROR; } } } } /* * Make sure the output side is unbuffered. */ outPtr->flags = (outPtr->flags & ~(CHANNEL_LINEBUFFERED)) | CHANNEL_UNBUFFERED; /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inPtr->bufSize); csPtr->bufSize = inPtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; inPtr->csPtr = csPtr; outPtr->csPtr = csPtr; /* * Start copying data between the channels. */ return CopyData(csPtr, 0); } /* *---------------------------------------------------------------------- * * CopyData -- * * This function implements the lowest level of the copying * mechanism for TclCopyChannel. * * Results: * Returns TCL_OK on success, else TCL_ERROR. * * Side effects: * Moves data between channels, may create channel handlers. * *---------------------------------------------------------------------- */ static int CopyData(csPtr, mask) CopyState *csPtr; /* State of copy operation. */ int mask; /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL; Tcl_Channel inChan, outChan; int result = TCL_OK; int size; int total; inChan = (Tcl_Channel)csPtr->readPtr; outChan = (Tcl_Channel)csPtr->writePtr; interp = csPtr->interp; cmdPtr = csPtr->cmdPtr; /* * Copy the data the slow way, using the translation mechanism. */ while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ if (csPtr->readPtr->unreportedError != 0) { Tcl_SetErrno(csPtr->readPtr->unreportedError); csPtr->readPtr->unreportedError = 0; goto readError; } if (csPtr->writePtr->unreportedError != 0) { Tcl_SetErrno(csPtr->writePtr->unreportedError); csPtr->writePtr->unreportedError = 0; goto writeError; } /* * Read up to bufSize bytes. */ if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { size = csPtr->bufSize; } else { size = csPtr->toRead; } size = DoRead(csPtr->readPtr, csPtr->buffer, size); if (size < 0) { readError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error reading \"", Tcl_GetChannelName(inChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } else if (size == 0) { /* * We had an underflow on the read side. If we are at EOF, * then the copying is done, otherwise set up a channel * handler to detect when the channel becomes readable again. */ if (Tcl_Eof(inChan)) { break; } else if (!(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Now write the buffer out. */ size = DoWrite(csPtr->writePtr, csPtr->buffer, size); if (size < 0) { writeError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error writing \"", Tcl_GetChannelName(outChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } /* * Check to see if the write is happening in the background. If so, * stop copying and wait for the channel to become writable again. */ if (csPtr->writePtr->flags & BG_FLUSH_SCHEDULED) { if (!(mask & TCL_WRITABLE)) { if (mask & TCL_READABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Update the current byte count if we care. */ if (csPtr->toRead != -1) { csPtr->toRead -= size; } csPtr->total += size; /* * For background copies, we only do one buffer per invocation so * we don't starve the rest of the system. */ if (cmdPtr) { /* * The first time we enter this code, there won't be a * channel handler established yet, so do it here. */ if (mask == 0) { Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } } /* * Make the callback or return the number of bytes transferred. * The local total is used because StopCopy frees csPtr. */ total = csPtr->total; if (cmdPtr) { /* * Get a private copy of the command so we can mutate it * by adding arguments. Note that StopCopy frees our saved * reference to the original command obj. */ cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); StopCopy(csPtr); Tcl_Preserve((ClientData) interp); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(total)); if (errObj) { Tcl_ListObjAppendElement(interp, cmdPtr, errObj); } if (Tcl_EvalObj(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 * the background copy operation. It is just a trivial wrapper * around the CopyData routine. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void CopyEventProc(clientData, mask) ClientData clientData; int mask; { (void) CopyData((CopyState *)clientData, mask); } /* *---------------------------------------------------------------------- * * StopCopy -- * * This routine halts a copy that is in progress. * * Results: * None. * * Side effects: * Removes any pending channel handlers and restores the blocking * and buffering modes of the channels. The CopyState is freed. * *---------------------------------------------------------------------- */ static void StopCopy(csPtr) CopyState *csPtr; /* State for bg copy to stop . */ { int nonBlocking; if (!csPtr) { return; } /* * Restore the old blocking mode and output buffering mode. */ nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING); if (nonBlocking != (csPtr->readPtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->readPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } if (csPtr->writePtr != csPtr->writePtr) { if (nonBlocking != (csPtr->writePtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->writePtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } } csPtr->writePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); csPtr->writePtr->flags |= csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc, (ClientData)csPtr); if (csPtr->readPtr != csPtr->writePtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr, CopyEventProc, (ClientData)csPtr); } Tcl_DecrRefCount(csPtr->cmdPtr); } csPtr->readPtr->csPtr = NULL; csPtr->writePtr->csPtr = NULL; ckfree((char*) csPtr); } trf2.1.4/patches/v8.0/tcl.h0000644000175000017500000016513511216344361014643 0ustar sergeisergei/* * 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.324 97/08/07 10:26:49 */ #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 0 #define TCL_VERSION "8.0" #define TCL_PATCH_LEVEL "8.0" /* * The following definitions set up the proper options for Windows * compilers. We use this method because there is no autoconf equivalent. */ #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) # define __WIN32__ # endif #endif #ifdef __WIN32__ # ifndef STRICT # define STRICT # endif # ifndef USE_PROTOTYPE # define USE_PROTOTYPE 1 # 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. */ #ifndef RESOURCE_INCLUDED #ifndef BUFSIZ #include #endif /* * Definitions that allow Tcl functions with variable numbers of * arguments to be used with either varargs.h or stdarg.h. TCL_VARARGS * is used in procedure prototypes. TCL_VARARGS_DEF is used to declare * 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. */ #ifndef __WIN32__ #ifndef VOID # ifdef __STDC__ # define VOID void # else # define VOID char # endif #endif #else /* __WIN32__ */ /* * The following code is copied from winnt.h */ #ifndef VOID #define VOID void typedef char CHAR; typedef short SHORT; typedef long LONG; #endif #endif /* __WIN32__ */ /* * Miscellaneous declarations. */ #ifndef NULL #define NULL 0 #endif #ifndef _CLIENTDATA # if defined(__STDC__) || defined(__cplusplus) typedef void *ClientData; # else typedef int *ClientData; # endif /* __STDC__ */ #define _CLIENTDATA #endif /* * Data structures defined opaquely in this module. The definitions below * just provide dummy types. A few fields are made visible in Tcl_Interp * structures, namely those used for returning a string result from * commands. Direct access to the result field is discouraged in Tcl 8.0. * The interpreter result is either an object or a string, and the two * values are kept consistent unless some C code sets interp->result * directly. Programmers should use either the procedure Tcl_GetObjResult() * or Tcl_GetStringResult() to read the interpreter's result. See the * SetResult man page for details. * * Note: any change to the Tcl_Interp definition below must be mirrored * in the "real" definition in tclInt.h. * * Note: Tcl_ObjCmdProc procedures do not directly set result and freeProc. * Instead, they set a Tcl_Obj member in the "real" structure that can be * accessed with Tcl_GetObjResult() and Tcl_SetObjResult(). */ typedef struct Tcl_Interp { char *result; /* If the last command returned a string * result, this points to it. */ void (*freeProc) _ANSI_ARGS_((char *blockPtr)); /* Zero means the string result is * statically allocated. TCL_DYNAMIC means * it was allocated with ckalloc and should * be freed with ckfree. Other values give * the address of procedure to invoke to * free the result. Tcl_Eval must free it * before executing next command. */ int errorLine; /* When TCL_ERROR is returned, this gives * 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 * procedures Tcl_GetObjResult() or Tcl_GetStringResult() to read the * interpreter's result. See the SetResult man page for details. Besides * this result, the command procedure returns an integer code, which is * one of the following: * * TCL_OK Command completed normally; the interpreter's * result contains the command's result. * TCL_ERROR The command couldn't be completed successfully; * the interpreter's result describes what went wrong. * TCL_RETURN The command requests that the current procedure * return; the interpreter's result contains the * procedure's return value. * TCL_BREAK The command requests that the innermost loop * be exited; the interpreter's result is meaningless. * TCL_CONTINUE Go on to the next iteration of the current loop; * the interpreter's result is meaningless. */ #define TCL_OK 0 #define TCL_ERROR 1 #define TCL_RETURN 2 #define TCL_BREAK 3 #define TCL_CONTINUE 4 #define TCL_RESULT_SIZE 200 /* * Argument descriptors for math function callbacks in expressions: */ typedef enum {TCL_INT, TCL_DOUBLE, TCL_EITHER} Tcl_ValueType; typedef struct Tcl_Value { Tcl_ValueType type; /* Indicates intValue or doubleValue is * valid, or both. */ long intValue; /* Integer value. */ double doubleValue; /* Double-precision floating value. */ } Tcl_Value; /* * Forward declaration of Tcl_Obj to prevent an error when the forward * reference to Tcl_Obj is encountered in the procedure types declared * below. */ struct Tcl_Obj; /* * Procedure types defined by Tcl: */ typedef int (Tcl_AppInitProc) _ANSI_ARGS_((Tcl_Interp *interp)); typedef int (Tcl_AsyncProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int code)); typedef void (Tcl_ChannelProc) _ANSI_ARGS_((ClientData clientData, int mask)); typedef void (Tcl_CloseProc) _ANSI_ARGS_((ClientData data)); typedef void (Tcl_CmdDeleteProc) _ANSI_ARGS_((ClientData clientData)); 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, Tcl_Interp *interp, char *part1, char *part2, int flags)); /* * The following structure represents a type of object, which is a * particular internal representation for an object plus a set of * procedures that provide standard operations on objects of that type. */ typedef struct Tcl_ObjType { char *name; /* Name of the type, e.g. "int". */ Tcl_FreeInternalRepProc *freeIntRepProc; /* Called to free any storage for the type's * internal rep. NULL if the internal rep * does not need freeing. */ Tcl_DupInternalRepProc *dupIntRepProc; /* Called to create a new object as a copy * of an existing object. */ Tcl_UpdateStringProc *updateStringProc; /* Called to update the string rep from the * type's internal representation. */ Tcl_SetFromAnyProc *setFromAnyProc; /* Called to convert the object's internal * rep to this type. Frees the internal rep * of the old type. Returns TCL_ERROR on * failure. */ } Tcl_ObjType; /* * One of the following structures exists for each object in the Tcl * system. An object stores a value as either a string, some internal * representation, or both. */ typedef struct Tcl_Obj { int refCount; /* When 0 the object will be freed. */ char *bytes; /* This points to the first byte of the * object's string representation. The array * 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: */ long longValue; /* - an long integer value */ double doubleValue; /* - a double-precision floating value */ VOID *otherValuePtr; /* - another, type-specific value */ struct { /* - internal rep as two pointers */ VOID *ptr1; VOID *ptr2; } twoPtrValue; } internalRep; } Tcl_Obj; /* * Macros to increment and decrement a Tcl_Obj's reference count, and to * test whether an object is shared (i.e. has reference count > 1). * Note: clients should use Tcl_DecrRefCount() when they are finished using * an object, and should never call TclFreeObj() directly. TclFreeObj() is * only defined and made public in tcl.h to support Tcl_DecrRefCount's macro * definition. Note also that Tcl_DecrRefCount() refers to the parameter * "obj" twice. This means that you should avoid calling it with an * expression that is expensive to compute or has side effects. */ EXTERN void Tcl_IncrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN void Tcl_DecrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN int Tcl_IsShared _ANSI_ARGS_((Tcl_Obj *objPtr)); #ifdef TCL_MEM_DEBUG # define Tcl_IncrRefCount(objPtr) \ Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_DecrRefCount(objPtr) \ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_IsShared(objPtr) \ Tcl_DbIsShared(objPtr, __FILE__, __LINE__) #else # define Tcl_IncrRefCount(objPtr) \ ++(objPtr)->refCount # define Tcl_DecrRefCount(objPtr) \ 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). */ typedef struct Tcl_Namespace { char *name; /* The namespace's name within its parent * namespace. This contains no ::'s. The * name of the global namespace is "" * although "::" is an synonym. */ char *fullName; /* The namespace's fully qualified name. * This starts with ::. */ ClientData clientData; /* Arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc* deleteProc; /* Procedure invoked when deleting the * namespace to, e.g., free clientData. */ struct Tcl_Namespace* parentPtr; /* Points to the namespace that contains * this one. NULL if this is the global * namespace. */ } Tcl_Namespace; /* * The following structure represents a call frame, or activation record. * A call frame defines a naming context for a procedure call: its local * scope (for local variables) and its namespace scope (used for non-local * variables; often 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 command's code should execute. The * Tcl_CallFrame structures exist only while procedures or namespace * eval/inscope's are being executed, and provide a Tcl call stack. * * A call frame is initialized and pushed using Tcl_PushCallFrame and * popped using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be * provided by the Tcl_PushCallFrame caller, and callers typically allocate * them on the C call stack for efficiency. For this reason, Tcl_CallFrame * is defined as a structure and not as an opaque token. However, most * Tcl_CallFrame fields are hidden since applications should not access * them directly; others are declared as "dummyX". * * WARNING!! The structure definition must be kept consistent with the * CallFrame structure in tclInt.h. If you change one, change the other. */ typedef struct Tcl_CallFrame { Tcl_Namespace *nsPtr; int dummy1; int dummy2; char *dummy3; char *dummy4; char *dummy5; int dummy6; char *dummy7; char *dummy8; int dummy9; char* dummy10; } Tcl_CallFrame; /* * Information about commands that is returned by Tcl_GetCommandInfo and * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based * command procedure while proc is a traditional Tcl argc/argv * string-based procedure. Tcl_CreateObjCommand and Tcl_CreateCommand * ensure that both objProc and proc are non-NULL and can be called to * execute the command. However, it may be faster to call one instead of * the other. The member isNativeObjectProc is set to 1 if an * object-based procedure was registered by Tcl_CreateObjCommand, and to * 0 if a string-based procedure was registered by Tcl_CreateCommand. * The other procedure is typically set to a compatibility wrapper that * does string-to-object or object-to-string argument conversions then * calls the other procedure. */ typedef struct Tcl_CmdInfo { int isNativeObjectProc; /* 1 if objProc was registered by a call to * Tcl_CreateObjCommand; 0 otherwise. * Tcl_SetCmdInfo does not modify this * field. */ Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ ClientData objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based procedure. */ ClientData clientData; /* ClientData for string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure to call when command is * deleted. */ ClientData deleteData; /* Value to pass to deleteProc (usually * the same as clientData). */ Tcl_Namespace *namespacePtr; /* Points to the namespace that contains * this command. Note that Tcl_SetCmdInfo * will not change a command's namespace; * use Tcl_RenameCommand to do that. */ } Tcl_CmdInfo; /* * The structure defined below is used to hold dynamic strings. The only * field that clients should use is the string field, and they should * never modify it. */ #define TCL_DSTRING_STATIC_SIZE 200 typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ int length; /* Number of non-NULL characters in the * string. */ int spaceAvl; /* Total number of bytes available for the * string and its terminating NULL char. */ char staticSpace[TCL_DSTRING_STATIC_SIZE]; /* Space to use in common case where string * is small. */ } Tcl_DString; #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) #define TCL_STATIC ((Tcl_FreeProc *) 0) #define TCL_DYNAMIC ((Tcl_FreeProc *) 3) /* * Flag values passed to variable-related procedures. */ #define TCL_GLOBAL_ONLY 1 #define TCL_NAMESPACE_ONLY 2 #define TCL_APPEND_VALUE 4 #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 struct Tcl_HashTable; #endif /* * Structure definition for an entry in a hash table. No-one outside * Tcl should access any of these fields directly; use the macros * defined below. */ typedef struct Tcl_HashEntry { struct Tcl_HashEntry *nextPtr; /* Pointer to next entry in this * hash bucket, or NULL for end of * chain. */ struct Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */ struct Tcl_HashEntry **bucketPtr; /* Pointer to bucket that points to * first entry in this entry's chain: * used for deleting the entry. */ ClientData clientData; /* Application stores something here * with Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ int words[1]; /* Multiple integer words for key. * The actual size will be as large * as necessary for this table's * keys. */ char string[4]; /* String for key. The actual size * will be as large as needed to hold * the key. */ } key; /* MUST BE LAST FIELD IN RECORD!! */ } Tcl_HashEntry; /* * Structure definition for a hash table. Must be in tcl.h so clients * can allocate space for these structures, but clients should never * access any fields in this structure. */ #define TCL_SMALL_HASH_TABLE 4 typedef struct Tcl_HashTable { Tcl_HashEntry **buckets; /* Pointer to bucket array. Each * element points to first entry in * bucket's hash chain, or NULL. */ Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables * (to avoid mallocs and frees). */ int numBuckets; /* Total number of buckets allocated * at **bucketPtr. */ int numEntries; /* Total number of entries present * in table. */ int rebuildSize; /* Enlarge table when numEntries gets * to be this large. */ int downShift; /* Shift count used in hashing * function. Designed to use high- * order bits of randomized keys. */ int mask; /* Mask value used in hashing * function. */ int keyType; /* Type of keys used in this table. * It's either TCL_STRING_KEYS, * TCL_ONE_WORD_KEYS, or an integer * giving the number of ints that * is the size of the key. */ Tcl_HashEntry *(*findProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key)); Tcl_HashEntry *(*createProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key, int *newPtr)); } Tcl_HashTable; /* * Structure definition for information used to keep track of searches * through hash tables: */ typedef struct Tcl_HashSearch { Tcl_HashTable *tablePtr; /* Table being searched. */ int nextIndex; /* Index of next bucket to be * enumerated after present one. */ Tcl_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the * the current bucket. */ } Tcl_HashSearch; /* * Acceptable key types for hash tables: */ #define TCL_STRING_KEYS 0 #define TCL_ONE_WORD_KEYS 1 /* * Macros for clients to use to access fields of hash entries: */ #define Tcl_GetHashValue(h) ((h)->clientData) #define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value)) #define Tcl_GetHashKey(tablePtr, h) \ ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS) ? (h)->key.oneWordValue \ : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create procedures * for hash tables: */ #define Tcl_FindHashEntry(tablePtr, key) \ (*((tablePtr)->findProc))(tablePtr, key) #define Tcl_CreateHashEntry(tablePtr, key, newPtr) \ (*((tablePtr)->createProc))(tablePtr, key, newPtr) /* * Flag values to pass to Tcl_DoOneEvent to disable searches * for some kinds of events: */ #define TCL_DONT_WAIT (1<<1) #define TCL_WINDOW_EVENTS (1<<2) #define TCL_FILE_EVENTS (1<<3) #define TCL_TIMER_EVENTS (1<<4) #define TCL_IDLE_EVENTS (1<<5) /* WAS 0x10 ???? */ #define TCL_ALL_EVENTS (~TCL_DONT_WAIT) /* * The following structure defines a generic event for the Tcl event * system. These are the things that are queued in calls to Tcl_QueueEvent * and serviced later by Tcl_DoOneEvent. There can be many different * kinds of events with different fields, corresponding to window events, * timer events, etc. The structure for a particular event consists of * a Tcl_Event header followed by additional information specific to that * event. */ struct Tcl_Event { Tcl_EventProc *proc; /* Procedure to call to service this event. */ struct Tcl_Event *nextPtr; /* Next in list of pending events, or NULL. */ }; /* * Positions to pass to Tcl_QueueEvent: */ typedef enum { TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK } Tcl_QueuePosition; /* * Values to pass to Tcl_SetServiceMode to specify the behavior of notifier * event routines. */ #define TCL_SERVICE_NONE 0 #define TCL_SERVICE_ALL 1 /* * The following structure keeps is used to hold a time value, either as * an absolute time (the number of seconds from the epoch) or as an * elapsed time. On Unix systems the epoch is Midnight Jan 1, 1970 GMT. * On Macintosh systems the epoch is Midnight Jan 1, 1904 GMT. */ typedef struct Tcl_Time { long sec; /* Seconds. */ long usec; /* Microseconds. */ } Tcl_Time; /* * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler * to indicate what sorts of events are of interest: */ #define TCL_READABLE (1<<1) #define TCL_WRITABLE (1<<2) #define TCL_EXCEPTION (1<<3) /* * Flag values to pass to Tcl_OpenCommandChannel to indicate the * disposition of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, * are also used in Tcl_GetStdChannel. */ #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. */ TCL_TRANSLATE_LF, /* Eol == \n. */ TCL_TRANSLATE_CRLF /* Eol == \r\n. */ } Tcl_EolTranslation; /* * Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). * * Enum for different byteorders. */ typedef enum Tcl_ByteOrder { TCL_BIGENDIAN, /* Multibyte words are stored with MSB first */ TCL_SMALLENDIAN /* Multibyte words are stored with MSB last */ } Tcl_ByteOrder; /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. * It collects together in one place all the functions that are * part of the specific channel type. */ 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. */ #define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */ #define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking * mode. */ /* * Enum for different types of file paths. */ 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)); /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ EXTERN Tcl_ByteOrder Tcl_GetChannelByteorder _ANSI_ARGS_(( Tcl_Channel chan)); EXTERN Tcl_ByteOrder Tcl_GetHostByteorder _ANSI_ARGS_((void)); 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)); /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf. */ EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_ChannelType* typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_Channel chan)); #endif /* RESOURCE_INCLUDED */ #endif /* _TCL */ trf2.1.4/patches/v8.0.5/0000755000175000017500000000000011216344734014044 5ustar sergeisergeitrf2.1.4/patches/v8.0.5/standard.patch0000644000175000017500000002700711216344361016667 0ustar sergeisergei*** tcl.h.orig Wed Feb 3 03:58:25 1999 --- tcl.h Sun Mar 14 19:03:07 1999 *************** *** 1572,1577 **** --- 1572,1599 ---- EXTERN int Tcl_AppInit _ANSI_ARGS_((Tcl_Interp *interp)); + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * C-Level API for (un)stacking of channels. This allows the introduction + * of filtering channels with relatively little changes to the core. + * This patch was created in cooperation with Jan Nijtmans + * and is therefore part of his plus-patches too. + * + * It would have been possible to place the following definitions according + * to the alphabetical order used elsewhere in this file, but I decided + * against that to ease the maintenance of the patch across new tcl versions + * (patch usually has no problems to integrate the patch file for the last + * version into the new one). + */ + + EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_ChannelType* typePtr, ClientData instanceData, + int mask, Tcl_Channel prevChan)); + + EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_Channel chan)); + #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS *** tclIO.c.orig Fri Oct 30 01:38:38 1998 --- tclIO.c Sun Mar 14 19:03:08 1999 *************** *** 170,175 **** --- 170,197 ---- int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ + + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * The single change to the internal datastructures of the core. Every + * channel now maintains a reference to the channel he is stacked upon. + * This reference is NULL for normal channels. Only the two exported + * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the + * end of 'tcl.h') use this field in a non-trivial way. + * + * Of the existing procedures the only following are affected by this + * change: + * + * - Tcl_RegisterChannel + * - Tcl_CreateChannel + * - CloseChannel + * + * The why is explained at the changed locations. + */ + struct Channel* supercedes; /* Refers to channel this one was stacked upon */ + } Channel; /* *************** *** 1067,1073 **** if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! panic("Tcl_RegisterChannel: duplicate channel names"); } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } --- 1089,1108 ---- if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! /* Andreas Kupries , 05/31/1997. ! * "Trf-Patch for filtering channels" ! * ! * This is the change to 'Tcl_RegisterChannel'. ! * ! * Explanation: ! * The moment a channel is stacked upon another he ! * takes the identity of the channel he supercedes, ! * i.e. he gets the *same* name. Because of this we ! * cannot check for duplicate names anymore, they ! * have to be allowed now. ! */ ! ! /* panic("Tcl_RegisterChannel: duplicate channel names"); */ } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } *************** *** 1218,1223 **** --- 1253,1272 ---- chanPtr->timer = NULL; chanPtr->csPtr = NULL; + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * This is the change to 'Tcl_CreateChannel'. + * + * Explanation: + * It is of course necessary to initialize the new field + * in the Channel structure. The chosen value indicates + * that the created channel is a normal one, and not + * stacked upon another. + */ + + chanPtr->supercedes = (Channel*) 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 *************** *** 1250,1255 **** --- 1299,1490 ---- return (Tcl_Channel) chanPtr; } + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * The following two procedures are the new, exported ones. They + * - create a channel stacked upon an existing one and + * - pop a stacked channel off, thus revealing the superceded one. + * + * Please read the following completely. + */ + /* + *---------------------------------------------------------------------- + * + * Tcl_ReplaceChannel -- + * + * Replaces an entry in the hash table for a Tcl_Channel + * record. + * + * Results: + * Returns the new Tcl_Channel. + * + * Side effects: + * Replaces a Tcl_Channel instance into the hash table. + * + *---------------------------------------------------------------------- + */ + + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp* interp; /* the interpreter we are working in */ + Tcl_ChannelType *typePtr; /* The channel type record. */ + ClientData instanceData; /* Instance specific data. */ + int mask; /* TCL_READABLE & TCL_WRITABLE to indicate + * if the channel is readable, writable. */ + Tcl_Channel prevChan; /* The channel structure that should + * be replaced. */ + { + Channel *chanPtr, *pt, *prevPt; + + /* + * Replace the channel into the list of all channels; + */ + + prevPt = (Channel*) NULL; + pt = (Channel*) firstChanPtr; + + while (pt != (Channel *) prevChan) { + prevPt = pt; + pt = pt->nextChanPtr; + } + + if (!pt) { + return (Tcl_Channel) NULL; + } + + /* + * Here we check if the "mask" matches the "flags" + * of the already existing channel. + * + * | - | R | W | RW | + * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) + * - | | | | | + * R | | + | | + | The superceding channel is allowed to + * W | | | + | + | restrict the capabilities of the + * RW| | + | + | + | superceded one ! + * --+---+---+---+----+ + */ + + if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { + return (Tcl_Channel) NULL; + } + + + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); + chanPtr->flags = mask; + + /* + * Set the channel up initially in no Input translation mode and + * no Output translation mode. + */ + + chanPtr->inputTranslation = TCL_TRANSLATE_LF; + chanPtr->outputTranslation = TCL_TRANSLATE_LF; + chanPtr->inEofChar = 0; + chanPtr->outEofChar = 0; + + chanPtr->unreportedError = 0; + chanPtr->instanceData = instanceData; + chanPtr->typePtr = typePtr; + chanPtr->refCount = 0; + chanPtr->closeCbPtr = (CloseCallback *) NULL; + chanPtr->curOutPtr = (ChannelBuffer *) NULL; + chanPtr->outQueueHead = (ChannelBuffer *) NULL; + chanPtr->outQueueTail = (ChannelBuffer *) NULL; + chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; + chanPtr->inQueueHead = (ChannelBuffer *) NULL; + 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->supercedes = (Channel*) prevChan; + + chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); + strcpy (chanPtr->channelName, pt->channelName); + + if (prevPt) { + prevPt->nextChanPtr = chanPtr; + } else { + firstChanPtr = chanPtr; + } + + chanPtr->nextChanPtr = pt->nextChanPtr; + + + Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); + + /* The superceded channel is effectively unregistered */ + /*chanPtr->supercedes->refCount --;*/ + + return (Tcl_Channel) chanPtr; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_UndoReplaceChannel -- + * + * Unstacks an entry in the hash table for a Tcl_Channel + * record. + * + * Results: + * Returns the old Tcl_Channel, i.e. the one which was stacked over. + * + * Side effects: + * Replaces a Tcl_Channel instance into the hash table. + * + *---------------------------------------------------------------------- + */ + + void + Tcl_UndoReplaceChannel (interp, chan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_Channel chan; /* The channel to unstack */ + { + Channel* chanPtr = (Channel*) chan; + + if (chanPtr->supercedes != (Channel*) NULL) { + Tcl_HashTable *hTblPtr; /* Hash table of channels. */ + Tcl_HashEntry *hPtr; /* Search variable. */ + int new; /* Is the hash entry new or does it exist? */ + + /* + * Insert the channel we were stacked upon back into + * the list of open channels. Place it back into the hashtable too. + * Correct 'refCount', as this actually unregisters 'chan'. + */ + + chanPtr->supercedes->nextChanPtr = firstChanPtr; + firstChanPtr = chanPtr->supercedes; + + hTblPtr = GetChannelTable (interp); + hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); + + Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); + chanPtr->refCount --; + + /* The superceded channel is effectively registered again */ + /*chanPtr->supercedes->refCount ++;*/ + } + + /* + * Disconnect the channels, then do a regular close upon the + * stacked one. This may cause flushing of data into the + * superceded channel (if 'chan' remembered its parent in itself). + */ + + chanPtr->supercedes = NULL; + + if (chanPtr->refCount == 0) { + Tcl_Close (interp, chan); + } + } + /* *---------------------------------------------------------------------- * *************** *** 1863,1868 **** --- 2098,2138 ---- if (errorCode != 0) { Tcl_SetErrno(errorCode); } + } + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * This is the change to 'CloseChannel'. + * + * Explanation + * Closing a filtering channel closes the one it + * superceded too. This basically ripples through + * the whole chain of filters until it reaches + * the underlying normal channel. + * + * This is done by reintegrating the superceded + * channel into the (thread) global list of open + * channels and then invoking a regular close. + * There is no need to handle the complexities of + * this process by ourselves. + * + * *Note* + * This has to be done after the call to the + * 'closeProc' of the filtering channel to allow + * that one the flushing of internal buffers into + * the underlying channel. + */ + + if (chanPtr->supercedes != (Channel*) NULL) { + /* Insert the channel we were stacked upon back into + * the list of open channels, then do a regular close. + */ + + chanPtr->supercedes->nextChanPtr = firstChanPtr; + firstChanPtr = chanPtr->supercedes; + chanPtr->supercedes->refCount --; /* is deregistered */ + Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* trf2.1.4/patches/v8.0.5/byteorder.patch0000644000175000017500000001431211216344361017061 0ustar sergeisergei*** tcl.h.orig Sun Mar 14 19:04:51 1999 --- tcl.h Sun Mar 14 19:05:01 1999 *************** *** 999,1004 **** --- 999,1016 ---- } Tcl_EolTranslation; /* + * Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + * + * Enum for different byteorders. + */ + + typedef enum Tcl_ByteOrder { + TCL_BIGENDIAN, /* Multibyte words are stored with MSB first */ + TCL_SMALLENDIAN /* Multibyte words are stored with MSB last */ + } Tcl_ByteOrder; + + /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. *************** *** 1282,1287 **** --- 1294,1305 ---- char *chanName, int *modePtr)); EXTERN int Tcl_GetChannelBufferSize _ANSI_ARGS_(( Tcl_Channel chan)); + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + EXTERN Tcl_ByteOrder Tcl_GetChannelByteorder _ANSI_ARGS_(( + Tcl_Channel chan)); + EXTERN Tcl_ByteOrder Tcl_GetHostByteorder _ANSI_ARGS_((void)); EXTERN int Tcl_GetChannelHandle _ANSI_ARGS_((Tcl_Channel chan, int direction, ClientData *handlePtr)); EXTERN ClientData Tcl_GetChannelInstanceData _ANSI_ARGS_(( *** tclIO.c.orig Sun Mar 14 19:04:51 1999 --- tclIO.c Sun Mar 14 19:05:01 1999 *************** *** 128,133 **** --- 128,137 ---- * code, is dynamically allocated. */ int flags; /* ORed combination of the flags defined * below. */ + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + Tcl_ByteOrder byteOrder; /* byteorder associated to this channel */ Tcl_EolTranslation inputTranslation; /* What translation to apply for end of line * sequences on input? */ *************** *** 1195,1200 **** --- 1199,1208 ---- * indicator (e.g. ^Z) and does not append an EOF indicator to files. */ + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + chanPtr->byteOrder = Tcl_GetHostByteorder (); chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; *************** *** 3947,3953 **** { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize eofchar translation"; char **argv; int argc, i; Tcl_DString ds; --- 3955,3961 ---- { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; *************** *** 3980,3985 **** --- 3988,4048 ---- /* *---------------------------------------------------------------------- * + * Tcl_GetChannelByteorder -- + * + * Retrieves the byteorder set for this channel. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + Tcl_ByteOrder + Tcl_GetChannelByteorder(chan) + Tcl_Channel chan; /* The channel for which to find the + * buffer size. */ + { + Channel *chanPtr; + + chanPtr = (Channel *) chan; + return chanPtr->byteOrder; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_GetHostByteorder -- + * + * Retrieves the byteorder of the machine we are running on. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + Tcl_ByteOrder + Tcl_GetHostByteorder() + { + union { + char c[sizeof(short)]; + short s; + } order; + + order.s = 1; + return (order.c[0] == 1) ? TCL_SMALLENDIAN : TCL_BIGENDIAN; + } + + /* + *---------------------------------------------------------------------- + * * Tcl_GetChannelOption -- * * Gets a mode associated with an IO channel. If the optionName arg *************** *** 4081,4086 **** --- 4144,4163 ---- return TCL_OK; } } + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0))) { + if (len == 0) { + Tcl_DStringAppendElement(dsPtr, "-byteorder"); + } + Tcl_DStringAppendElement(dsPtr, + (chanPtr->byteOrder == TCL_BIGENDIAN) ? "bigendian" : "smallendian"); + if (len > 0) { + return TCL_OK; + } + } if ((len == 0) || ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-eofchar", len) == 0))) { *************** *** 4281,4286 **** --- 4358,4393 ---- chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; } return TCL_OK; + } + + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + if ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0)) { + int nv_len = strlen (newValue); + + if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { + chanPtr->byteOrder = TCL_BIGENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_BIGENDIAN; + return TCL_OK; + } + + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, + "bad value for -byteorder: ", + "must be one of smallendian, littleendian, bigendian or network", + (char *) NULL); + } + return TCL_ERROR; } if ((len > 1) && (optionName[1] == 'e') && trf2.1.4/patches/v8.0.5/tclIO.c0000644000175000017500000060732311216344361015231 0ustar sergeisergei/* * 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.2 1999/04/18 13:27:02 aku 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. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) # define EWOULDBLOCK EAGAIN #endif #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) error one of EWOULDBLOCK or EAGAIN must be defined #endif /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this * structure. */ typedef struct CopyState { struct Channel *readPtr; /* Pointer to input channel. */ struct Channel *writePtr; /* Pointer to output channel. */ int readFlags; /* Original read channel flags. */ int writeFlags; /* Original write channel flags. */ int toRead; /* Number of bytes to copy, or -1. */ int total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ 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) /* * Structure to record a close callback. One such record exists for * each close callback registered for a channel. */ typedef struct CloseCallback { Tcl_CloseProc *proc; /* The procedure to call. */ ClientData clientData; /* Arbitrary one-word data to pass * to the callback. */ struct CloseCallback *nextPtr; /* For chaining close callbacks. */ } CloseCallback; /* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to * invoke the saved script in the interpreter designed in this record. */ 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; /* * struct Channel: * * One of these structures is allocated for each open channel. It contains data * specific to the channel but which belongs to the generic part of the Tcl * channel mechanism, and it points at an instance specific (and type * specific) * instance data, and at a channel type structure. */ 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. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ Tcl_ByteOrder byteOrder; /* byteorder associated to this channel */ 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. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ struct ChannelHandler *chPtr;/* List of channel handlers registered * for this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ struct Channel *nextChanPtr;/* Next in list of channels currently open. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for * event handlers ("fileevent") on this * channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * The single change to the internal datastructures of the core. Every * channel now maintains a reference to the channel he is stacked upon. * This reference is NULL for normal channels. Only the two exported * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the * end of 'tcl.h') use this field in a non-trivial way. * * Of the existing procedures the only following are affected by this * change: * * - Tcl_RegisterChannel * - Tcl_CreateChannel * - CloseChannel * * The why is explained at the changed locations. */ struct Channel* supercedes; /* Refers to channel this one was stacked upon */ } Channel; /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in * nonblocking mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the * curOutPtr field in the * channel structure) should be * output as soon as possible even * though it may not be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the * queued output buffers has been * scheduled. */ #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No * further Tcl-level IO on the * channel is allowed. */ #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. * This bit is cleared before every * input operation. */ #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because * we saw the input eofChar. This bit * prevents clearing of the EOF bit * before every input operation. */ #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. */ typedef struct ChannelHandler { Channel *chanPtr; /* The channel structure for this channel. */ int mask; /* Mask of desired events. */ Tcl_ChannelProc *proc; /* Procedure to call in the type of * Tcl_CreateChannelHandler. */ ClientData clientData; /* Argument to pass to procedure. */ struct ChannelHandler *nextPtr; /* Next one in list of registered handlers. */ } ChannelHandler; /* * This structure keeps track of the current ChannelHandler being invoked in * the current invocation of ChannelHandlerEventProc. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. * The nextPtr field is used to chain together all recursive invocations, so * that Tcl_DeleteChannelHandler can find all the recursively nested * invocations of ChannelHandlerEventProc and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. */ typedef struct NextChannelHandler { 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 * for stdin/stdout/stderr in new interpreters. * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ 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 * closed. * * Results: * None. * * Side effects: * Causes the callback to be called in the future when the channel * will be closed. * *---------------------------------------------------------------------- */ void Tcl_CreateCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to create the * close callback. */ Tcl_CloseProc *proc; /* The callback routine to call when the * channel will be closed. */ ClientData clientData; /* Arbitrary data to pass to the * close callback. */ { Channel *chanPtr; CloseCallback *cbPtr; chanPtr = (Channel *) chan; cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; cbPtr->nextPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr; } /* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * * Removes a callback that would have been called on closing * the channel. If there is no matching callback then this * function has no effect. * * Results: * None. * * Side effects: * The callback will not be called in the future when the channel * is eventually closed. * *---------------------------------------------------------------------- */ void Tcl_DeleteCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to cancel the * close callback. */ Tcl_CloseProc *proc; /* The procedure for the callback to * remove. */ ClientData clientData; /* The callback data for the callback * to remove. */ { Channel *chanPtr; CloseCallback *cbPtr, *cbPrevPtr; chanPtr = (Channel *) chan; for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL; cbPtr != (CloseCallback *) NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == (CloseCallback *) NULL) { chanPtr->closeCbPtr = cbPtr->nextPtr; } 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 * interpreter. If it is initializing the table it also inserts * channels for stdin, stdout and stderr if the interpreter is * trusted. * * Results: * A pointer to the hash table created, for use by the caller. * * Side effects: * Initializes the channel table for an interpreter. May create * channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */ static Tcl_HashTable * GetChannelTable(interp) Tcl_Interp *interp; { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); (void) Tcl_SetAssocData(interp, "tclIO", (Tcl_InterpDeleteProc *) DeleteChannelTable, (ClientData) hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels * for stdin, stdout and stderr (possibly creating them in the * process). */ if (Tcl_IsSafe(interp) == 0) { stdinChan = Tcl_GetStdChannel(TCL_STDIN); if (stdinChan != NULL) { Tcl_RegisterChannel(interp, stdinChan); } stdoutChan = Tcl_GetStdChannel(TCL_STDOUT); if (stdoutChan != NULL) { Tcl_RegisterChannel(interp, stdoutChan); } stderrChan = Tcl_GetStdChannel(TCL_STDERR); if (stderrChan != NULL) { Tcl_RegisterChannel(interp, stderrChan); } } } return hTblPtr; } /* *---------------------------------------------------------------------- * * DeleteChannelTable -- * * Deletes the channel table for an interpreter, closing any open * channels whose refcount reaches zero. This procedure is invoked * when an interpreter is deleted, via the AssocData cleanup * mechanism. * * Results: * None. * * Side effects: * Deletes the hash table of channels. May close channels. May flush * output on closed channels. Removes any channeEvent handlers that were * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable(clientData, interp) ClientData clientData; /* The per-interpreter data structure. */ Tcl_Interp *interp; /* The interpreter being deleted. */ { Tcl_HashTable *hTblPtr; /* The hash table. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* Channel being deleted. */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* Variables to loop over all channel events * registered, to delete the ones that refer * to the interpreter being deleted. */ /* * Delete all the registered channels - this will close channels whose * refcount reaches zero. */ hTblPtr = (Tcl_HashTable *) clientData; for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); /* * Remove any fileevents registered in this interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); ckfree(sPtr->script); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } /* * Cannot call Tcl_UnregisterChannel because that procedure calls * Tcl_GetAssocData to get the channel table, which might already * be inaccessible from the interpreter structure. Instead, we * emulate the behavior of Tcl_UnregisterChannel directly here. */ Tcl_DeleteHashEntry(hPtr); chanPtr->refCount--; if (chanPtr->refCount <= 0) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } } Tcl_DeleteHashTable(hTblPtr); ckfree((char *) hTblPtr); } /* *---------------------------------------------------------------------- * * CheckForStdChannelsBeingClosed -- * * Perform special handling for standard channels being closed. When * given a standard channel, if the refcount is now 1, it means that * the last reference to the standard channel is being explicitly * closed. Now bump the refcount artificially down to 0, to ensure the * normal handling of channels being closed will occur. Also reset the * static pointer to the channel to NULL, to avoid dangling references. * * Results: * None. * * Side effects: * Manipulates the refcount on standard channels. May smash the global * static pointer to a standard channel. * *---------------------------------------------------------------------- */ 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. * If the interpreter given as argument is NULL, it only decrements the * reference count. * * Results: * A standard Tcl result. * * Side effects: * Deletes the hash entry for a channel associated with an interpreter. * *---------------------------------------------------------------------- */ int Tcl_UnregisterChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which channel is defined. */ Tcl_Channel chan; /* Channel to delete. */ { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The real IO channel. */ chanPtr = (Channel *) chan; if (interp != (Tcl_Interp *) NULL) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } hPtr = Tcl_FindHashEntry(hTblPtr, chanPtr->channelName); if (hPtr == (Tcl_HashEntry *) NULL) { return TCL_OK; } if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) { return TCL_OK; } Tcl_DeleteHashEntry(hPtr); /* * Remove channel handlers that refer to this interpreter, so that they * will not be present if the actual close is delayed and more events * happen on the channel. This may occur if the channel is shared * between several interpreters, or if the channel has async * flushing active. */ CleanupChannelHandlers(interp, chanPtr); } chanPtr->refCount--; /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); /* * If the refCount reached zero, close the actual channel. */ if (chanPtr->refCount <= 0) { /* * Ensure that if there is another buffer, it gets flushed * whether or not we are doing a background flush. */ if ((chanPtr->curOutPtr != NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; } chanPtr->flags |= CHANNEL_CLOSED; if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { if (Tcl_Close(interp, chan) != TCL_OK) { return TCL_ERROR; } } } 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; } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_RegisterChannel'. * * Explanation: * The moment a channel is stacked upon another he * takes the identity of the channel he supercedes, * i.e. he gets the *same* name. Because of this we * cannot check for duplicate names anymore, they * have to be allowed now. */ /* 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. */ int *modePtr; /* Where to store the mode in which the * channel was opened? Will contain an ORed * combination of TCL_READABLE and * TCL_WRITABLE, if non-NULL. */ { Channel *chanPtr; /* The actual channel. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ char *name; /* Translated name. */ /* * Substitute "stdin", etc. Note that even though we immediately * find the channel using Tcl_GetStdChannel, we still need to look * it up in the specified interpreter to ensure that it is present * in the channel table. Otherwise, safe interpreters would always * have access to the standard channels. */ name = chanName; if ((chanName[0] == 's') && (chanName[1] == 't')) { chanPtr = NULL; if (strcmp(chanName, "stdin") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDIN); } else if (strcmp(chanName, "stdout") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDOUT); } else if (strcmp(chanName, "stderr") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDERR); } if (chanPtr != NULL) { name = chanPtr->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == (Tcl_HashEntry *) NULL) { Tcl_AppendResult(interp, "can not find channel named \"", chanName, "\"", (char *) NULL); return NULL; } chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (modePtr != NULL) { *modePtr = (chanPtr->flags & (TCL_READABLE|TCL_WRITABLE)); } return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_CreateChannel -- * * Creates a new entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Creates a new Tcl_Channel instance and inserts it into the * hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_CreateChannel(typePtr, chanName, instanceData, mask) 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. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ chanPtr->byteOrder = Tcl_GetHostByteorder (); chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_CreateChannel'. * * Explanation: * It is of course necessary to initialize the new field * in the Channel structure. The chosen value indicates * that the created channel is a normal one, and not * stacked upon another. */ chanPtr->supercedes = (Channel*) 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; } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * The following two procedures are the new, exported ones. They * - create a channel stacked upon an existing one and * - pop a stacked channel off, thus revealing the superceded one. * * Please read the following completely. */ /* *---------------------------------------------------------------------- * * Tcl_ReplaceChannel -- * * Replaces an entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Replaces a Tcl_Channel instance into the hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp* interp; /* the interpreter we are working in */ Tcl_ChannelType *typePtr; /* The channel type record. */ ClientData instanceData; /* Instance specific data. */ int mask; /* TCL_READABLE & TCL_WRITABLE to indicate * if the channel is readable, writable. */ Tcl_Channel prevChan; /* The channel structure that should * be replaced. */ { Channel *chanPtr, *pt, *prevPt; /* * Replace the channel into the list of all channels; */ prevPt = (Channel*) NULL; pt = (Channel*) firstChanPtr; while (pt != (Channel *) prevChan) { prevPt = pt; pt = pt->nextChanPtr; } if (!pt) { return (Tcl_Channel) NULL; } /* * Here we check if the "mask" matches the "flags" * of the already existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to * W | | | + | + | restrict the capabilities of the * RW| | + | + | + | superceded one ! * --+---+---+---+----+ */ if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { return (Tcl_Channel) NULL; } chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); chanPtr->flags = mask; /* * Set the channel up initially in no Input translation mode and * no Output translation mode. */ chanPtr->inputTranslation = TCL_TRANSLATE_LF; chanPtr->outputTranslation = TCL_TRANSLATE_LF; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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->supercedes = (Channel*) prevChan; chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); strcpy (chanPtr->channelName, pt->channelName); if (prevPt) { prevPt->nextChanPtr = chanPtr; } else { firstChanPtr = chanPtr; } chanPtr->nextChanPtr = pt->nextChanPtr; Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); /* The superceded channel is effectively unregistered */ /*chanPtr->supercedes->refCount --;*/ return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_UndoReplaceChannel -- * * Unstacks an entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the old Tcl_Channel, i.e. the one which was stacked over. * * Side effects: * Replaces a Tcl_Channel instance into the hash table. * *---------------------------------------------------------------------- */ void Tcl_UndoReplaceChannel (interp, chan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_Channel chan; /* The channel to unstack */ { Channel* chanPtr = (Channel*) chan; if (chanPtr->supercedes != (Channel*) NULL) { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ int new; /* Is the hash entry new or does it exist? */ /* * Insert the channel we were stacked upon back into * the list of open channels. Place it back into the hashtable too. * Correct 'refCount', as this actually unregisters 'chan'. */ chanPtr->supercedes->nextChanPtr = firstChanPtr; firstChanPtr = chanPtr->supercedes; hTblPtr = GetChannelTable (interp); hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); chanPtr->refCount --; /* The superceded channel is effectively registered again */ /*chanPtr->supercedes->refCount ++;*/ } /* * Disconnect the channels, then do a regular close upon the * stacked one. This may cause flushing of data into the * superceded channel (if 'chan' remembered its parent in itself). */ chanPtr->supercedes = NULL; if (chanPtr->refCount == 0) { Tcl_Close (interp, chan); } } /* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * * Computes a mask indicating whether the channel is open for * reading and writing. * * Results: * An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelMode(chan) Tcl_Channel chan; /* The channel for which the mode is * being computed. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE)); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * * Returns the string identifying the channel name. * * Results: * The string containing the channel name. This memory is * owned by the generic layer and should not be modified by * the caller. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Tcl_GetChannelName(chan) Tcl_Channel chan; /* The channel for which to return the name. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->channelName; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * * Given a channel structure, returns the channel type structure. * * Results: * Returns a pointer to the channel type structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ChannelType * Tcl_GetChannelType(chan) Tcl_Channel chan; /* The channel to return type for. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->typePtr; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * * Returns an OS handle associated with a channel. * * Results: * Returns TCL_OK and places the handle in handlePtr, or returns * TCL_ERROR on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelHandle(chan, direction, handlePtr) Tcl_Channel chan; /* The channel to get file from. */ int direction; /* TCL_WRITABLE or TCL_READABLE. */ ClientData *handlePtr; /* Where to store handle */ { Channel *chanPtr; /* The actual channel. */ ClientData handle; int result; chanPtr = (Channel *) chan; result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData, direction, &handle); if (handlePtr) { *handlePtr = handle; } return result; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * * Returns the client data associated with a channel. * * Results: * The client data. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_GetChannelInstanceData(chan) 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 * that two input buffers are saved (one in the input queue and * another in the saveInBufPtr field) and that curOutPtr is set * to a buffer. Only if these conditions are met is the buffer * freed to the OS. * * Results: * None. * * Side effects: * May free a buffer to the OS. * *---------------------------------------------------------------------- */ static void RecycleBuffer(chanPtr, bufPtr, mustDiscard) Channel *chanPtr; /* Channel for which to recycle buffers. */ ChannelBuffer *bufPtr; /* The buffer to recycle. */ int mustDiscard; /* If nonzero, free the buffer to the * OS, always. */ { /* * Do we have to free the buffer to the OS? */ if (mustDiscard) { ckfree((char *) bufPtr); return; } /* * Only save buffers for the input queue if the channel is readable. */ if (chanPtr->flags & TCL_READABLE) { if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) { chanPtr->inQueueHead = bufPtr; chanPtr->inQueueTail = bufPtr; goto keepit; } if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) { chanPtr->saveInBufPtr = bufPtr; goto keepit; } } /* * Only save buffers for the output queue if the channel is writable. */ if (chanPtr->flags & TCL_WRITABLE) { if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) { chanPtr->curOutPtr = bufPtr; goto keepit; } } /* * 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 -- * * Discards all output queued in the output queue of a channel. * * Results: * None. * * Side effects: * Recycles buffers. * *---------------------------------------------------------------------- */ static void DiscardOutputQueued(chanPtr) Channel *chanPtr; /* The channel for which to discard output. */ { ChannelBuffer *bufPtr; while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { bufPtr = chanPtr->outQueueHead; chanPtr->outQueueHead = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, 0); } chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; } /* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * * This function checks is a given channel is Dead. * (A channel that has been closed but not yet deallocated.) * * Results: * True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: * None * *---------------------------------------------------------------------- */ static int CheckForDeadChannel(interp, chanPtr) Tcl_Interp *interp; /* For error reporting (can be NULL) */ Channel *chanPtr; /* The channel to check. */ { if (chanPtr->flags & CHANNEL_DEAD) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, "unable to access channel: invalid channel", (char *) NULL); } return 1; } return 0; } /* *---------------------------------------------------------------------- * * FlushChannel -- * * This function flushes as much of the queued output as is possible * now. If calledFromAsyncFlush is nonzero, it is being called in an * event handler to flush channel output asynchronously. * * Results: * 0 if successful, else the error code that was returned by the * channel type operation. * * Side effects: * May produce output on a channel. May block indefinitely if the * channel is synchronous. May schedule an async flush on the channel. * May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */ static int FlushChannel(interp, chanPtr, calledFromAsyncFlush) Tcl_Interp *interp; /* For error reporting during close. */ Channel *chanPtr; /* The channel to flush on. */ int calledFromAsyncFlush; /* If nonzero then we are being * called from an asynchronous * flush callback. */ { 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. */ if (CheckForDeadChannel(interp,chanPtr)) return -1; /* * Loop over the queued buffers and attempt to flush as * much as possible of the queued output to the channel. */ while (1) { /* * 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 { chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr; } chanPtr->outQueueTail = chanPtr->curOutPtr; chanPtr->curOutPtr = (ChannelBuffer *) NULL; } bufPtr = chanPtr->outQueueHead; /* * If we are not being called from an async flush and an async * flush is active, we just return without producing any output. */ if ((!calledFromAsyncFlush) && (chanPtr->flags & BG_FLUSH_SCHEDULED)) { return 0; } /* * If the output queue is still empty, break out of the while loop. */ if (bufPtr == (ChannelBuffer *) NULL) { break; /* Out of the "while (1)". */ } /* * 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. */ if (written < 0) { /* * If the last attempt to write was interrupted, simply retry. */ if (errorCode == EINTR) { errorCode = 0; continue; } /* * If the channel is non-blocking and we would have blocked, * start a background flushing handler and break out of the loop. */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { if (chanPtr->flags & CHANNEL_NONBLOCKING) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { chanPtr->flags |= BG_FLUSH_SCHEDULED; UpdateInterest(chanPtr); } errorCode = 0; break; } else { panic("Blocking channel driver did not block on output"); } } /* * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { if (chanPtr->unreportedError == 0) { chanPtr->unreportedError = errorCode; } } else { Tcl_SetErrno(errorCode); if (interp != NULL) { Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } } /* * 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. */ if ((chanPtr->flags & CHANNEL_CLOSED) && (chanPtr->refCount <= 0) && (chanPtr->outQueueHead == (ChannelBuffer *) NULL) && ((chanPtr->curOutPtr == (ChannelBuffer *) NULL) || (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->nextRemoved))) { return CloseChannel(interp, chanPtr, errorCode); } return errorCode; } /* *---------------------------------------------------------------------- * * CloseChannel -- * * Utility procedure to close a channel and free its associated * resources. * * Results: * 0 on success or a POSIX error code if the operation failed. * * Side effects: * May close the actual channel; may free memory. * *---------------------------------------------------------------------- */ static int CloseChannel(interp, chanPtr, errorCode) Tcl_Interp *interp; /* For error reporting. */ Channel *chanPtr; /* The channel to close. */ 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. */ DiscardInputQueued(chanPtr, 1); /* * Discard a leftover buffer in the current output buffer field. */ if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { ckfree((char *) chanPtr->curOutPtr); chanPtr->curOutPtr = (ChannelBuffer *) NULL; } /* * The caller guarantees that there are no more buffers * queued for output. */ if (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { panic("TclFlush, closed channel: queued output left"); } /* * If the EOF character is set in the channel, append that to the * output device. */ if ((chanPtr->outEofChar != 0) && (chanPtr->flags & TCL_WRITABLE)) { int dummy; char c; c = (char) chanPtr->outEofChar; (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy); } /* * Remove TCL_READABLE and TCL_WRITABLE from chanPtr->flags, so * that close callbacks can not do input or output (assuming they * squirreled the channel away in their clientData). This also * prevents infinite loops if the callback calls any C API that * could call FlushChannel. */ 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. */ if (chanPtr->unreportedError != 0) { errorCode = chanPtr->unreportedError; } if (errorCode == 0) { errorCode = result; if (errorCode != 0) { Tcl_SetErrno(errorCode); } } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * This is the change to 'CloseChannel'. * * Explanation * Closing a filtering channel closes the one it * superceded too. This basically ripples through * the whole chain of filters until it reaches * the underlying normal channel. * * This is done by reintegrating the superceded * channel into the (thread) global list of open * channels and then invoking a regular close. * There is no need to handle the complexities of * this process by ourselves. * * *Note* * This has to be done after the call to the * 'closeProc' of the filtering channel to allow * that one the flushing of internal buffers into * the underlying channel. */ if (chanPtr->supercedes != (Channel*) NULL) { /* Insert the channel we were stacked upon back into * the list of open channels, then do a regular close. */ chanPtr->supercedes->nextChanPtr = firstChanPtr; firstChanPtr = chanPtr->supercedes; chanPtr->supercedes->refCount --; /* is deregistered */ Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* * Cancel any outstanding timer. */ Tcl_DeleteTimerHandler(chanPtr->timer); /* * Mark the channel as deleted by clearing the type structure. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC); return errorCode; } /* *---------------------------------------------------------------------- * * Tcl_Close -- * * Closes a channel. * * Results: * A standard Tcl result. * * Side effects: * Closes the channel if this is the last reference. * * NOTE: * Tcl_Close removes the channel as far as the user is concerned. * However, it may continue to exist for a while longer if it has * a background flush scheduled. The device itself is eventually * closed and the channel record removed, in CloseChannel, above. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_Close(interp, chan) Tcl_Interp *interp; /* Interpreter for errors. */ Tcl_Channel chan; /* The channel being closed. Must * not be referenced in any * interpreter. */ { 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; } /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); chanPtr = (Channel *) chan; if (chanPtr->refCount > 0) { panic("called Tcl_Close on channel with refCount > 0"); } /* * 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; } } /* * Remove all the channel handler records attached to the channel * itself. */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chNext) { chNext = chPtr->nextPtr; ckfree((char *) chPtr); } chanPtr->chPtr = (ChannelHandler *) NULL; /* * Cancel any pending copy operation. */ StopCopy(chanPtr->csPtr); /* * Must set the interest mask now to 0, otherwise infinite loops * will occur if Tcl_DoOneEvent is called before the channel is * finally deleted in FlushChannel. This can happen if the channel * has a background flush active. */ chanPtr->interestMask = 0; /* * 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. */ while (chanPtr->closeCbPtr != (CloseCallback *) NULL) { cbPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr->nextPtr; (cbPtr->proc) (cbPtr->clientData); ckfree((char *) cbPtr); } /* * 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 -- * * Flushes output data on a channel. * * Results: * A standard Tcl result. * * Side effects: * May flush output queued on this channel. * *---------------------------------------------------------------------- */ int 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; } return TCL_OK; } /* *---------------------------------------------------------------------- * * DiscardInputQueued -- * * Discards any input read from the channel but not yet consumed * by Tcl reading commands. * * Results: * None. * * Side effects: * May discard input from the channel. If discardLastBuffer is zero, * leaves one buffer in place for back-filling. * *---------------------------------------------------------------------- */ static void DiscardInputQueued(chanPtr, discardSavedBuffers) Channel *chanPtr; /* Channel on which to discard * the queued input. */ int discardSavedBuffers; /* If non-zero, discard all buffers including * last one. */ { ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ bufPtr = chanPtr->inQueueHead; chanPtr->inQueueHead = (ChannelBuffer *) NULL; chanPtr->inQueueTail = (ChannelBuffer *) NULL; for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) { nxtPtr = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, discardSavedBuffers); } /* * If discardSavedBuffers is nonzero, must also discard any previously * saved buffer in the saveInBufPtr field. */ if (discardSavedBuffers) { if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) { 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) { 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; } /* *---------------------------------------------------------------------- * * 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) { copiedTotal = -1; goto done; } 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); done: /* * Update the notifier state so we don't block while there is still * data in the buffers. */ UpdateInterest(chanPtr); 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) { copiedTotal = -1; goto done; } (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); done: /* * Update the notifier state so we don't block while there is still * data in the buffers. */ UpdateInterest(chanPtr); 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; } /* * Update the notifier state so we don't block while there is still * data in the buffers. */ UpdateInterest(chanPtr); return len; } /* *---------------------------------------------------------------------- * * Tcl_Seek -- * * Implements seeking on Tcl Channels. This is a public function * so that other C facilities may be implemented on top of it. * * Results: * The new access point or -1 on error. If error, use Tcl_GetErrno() * to retrieve the POSIX error code for the error that occurred. * * Side effects: * May flush output on the channel. May discard queued input. * *---------------------------------------------------------------------- */ int Tcl_Seek(chan, offset, mode) Tcl_Channel chan; /* The channel on which to seek. */ int offset; /* Offset to seek to. */ int mode; /* Relative to which location to seek? */ { Channel *chanPtr; /* The real IO channel. */ ChannelBuffer *bufPtr; int inputBuffered, outputBuffered; 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 * registered in an interpreter. */ if (CheckForDeadChannel(NULL,chanPtr)) return -1; /* * Disallow seek on channels whose type does not have a seek procedure * defined. This means that the channel does not support seeking. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * If we are seeking relative to the current position, compute the * corrected offset taking into account the amount of unread input. */ if (mode == SEEK_CUR) { offset -= inputBuffered; } /* * Discard any queued input - this input should not be read after * the seek. */ DiscardInputQueued(chanPtr, 0); /* * Reset EOF and BLOCKED flags. We invalidate them by moving the * access point. Also clear CR related flags. */ chanPtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR)); /* * If the channel is in asynchronous output mode, switch it back * to synchronous mode and cancel any async flush that may be * scheduled. After the flush, the channel will be put back into * asynchronous output mode. */ wasAsync = 0; if (chanPtr->flags & CHANNEL_NONBLOCKING) { wasAsync = 1; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_BLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } chanPtr->flags &= (~(CHANNEL_NONBLOCKING)); if (chanPtr->flags & BG_FLUSH_SCHEDULED) { chanPtr->flags &= (~(BG_FLUSH_SCHEDULED)); } } /* * If the flush fails we cannot recover the original position. In * that case the seek is not attempted because we do not know where * the access position is - instead we return the error. FlushChannel * has already called Tcl_SetErrno() to report the error upwards. * If the flush succeeds we do the seek also. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { curPos = -1; } else { /* * Now seek to the new position in the channel as requested by the * caller. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) offset, mode, &result); if (curPos == -1) { Tcl_SetErrno(result); } } /* * Restore to nonblocking mode if that was the previous behavior. * * NOTE: Even if there was an async flush active we do not restore * it now because we already flushed all the queued output, above. */ if (wasAsync) { chanPtr->flags |= CHANNEL_NONBLOCKING; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_NONBLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } } return curPos; } /* *---------------------------------------------------------------------- * * Tcl_Tell -- * * Returns the position of the next character to be read/written on * this channel. * * Results: * A nonnegative integer on success, -1 on failure. If failed, * use Tcl_GetErrno() to retrieve the POSIX error code for the * error that occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Tell(chan) Tcl_Channel chan; /* The channel to return pos for. */ { 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. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * Get the current position in the device and compute the position * where the next character will be read or written. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) 0, SEEK_CUR, &result); if (curPos == -1) { Tcl_SetErrno(result); return -1; } if (inputBuffered != 0) { return (curPos - inputBuffered); } return (curPos + outputBuffered); } /* *---------------------------------------------------------------------- * * Tcl_Eof -- * * Returns 1 if the channel is at EOF, 0 otherwise. * * Results: * 1 or 0, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Eof(chan) Tcl_Channel chan; /* Does this channel have EOF? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_STICKY_EOF) || ((chanPtr->flags & CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * * Results: * 0 or 1, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBlocked(chan) Tcl_Channel chan; /* Is this channel blocked? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return (chanPtr->flags & CHANNEL_BLOCKED) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBuffered -- * * Returns the number of bytes of input currently buffered in the * internal buffer of a channel. * * Results: * The number of input bytes buffered, or zero if the channel is not * open for reading. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBuffered(chan) Tcl_Channel chan; /* The channel to query. */ { Channel *chanPtr; int bytesBuffered; ChannelBuffer *bufPtr; chanPtr = (Channel *) chan; for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } return bytesBuffered; } /* *---------------------------------------------------------------------- * * Tcl_SetChannelBufferSize -- * * Sets the size of buffers to allocate to store input or output * in the channel. The size must be between 10 bytes and 1 MByte. * * Results: * None. * * Side effects: * Sets the size of buffers subsequently allocated for this channel. * *---------------------------------------------------------------------- */ void Tcl_SetChannelBufferSize(chan, sz) Tcl_Channel chan; /* The channel whose buffer size * to set. */ int sz; /* The size to set. */ { Channel *chanPtr; /* * If the buffer size is smaller than 10 bytes or larger than one MByte, * do not accept the requested size and leave the current buffer size. */ if (sz < 10) { return; } if (sz > (1024 * 1024)) { return; } chanPtr = (Channel *) chan; chanPtr->bufSize = sz; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelBufferSize -- * * Retrieves the size of buffers to allocate for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelBufferSize(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->bufSize; } /* *---------------------------------------------------------------------- * * Tcl_BadChannelOption -- * * This procedure generates a "bad option" error message in an * (optional) interpreter. It is used by channel drivers when * a invalid Set/Get option is requested. Its purpose is to concatenate * the generic options list to the specific ones and factorize * the generic options error message string. * * Results: * TCL_ERROR. * * Side effects: * An error message is generated in interp's result object to * indicate that a command was invoked with the a bad option * The message has the form * bad option "blah": should be one of * <...generic options...>+<...specific options...> * "blah" is the optionName argument and "" * is a space separated list of specific option words. * The function takes good care of inserting minus signs before * each option, commas after, and an "or" before the last option. * *---------------------------------------------------------------------- */ int Tcl_BadChannelOption(interp, optionName, optionList) Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/ char *optionName; /* 'bad option' name */ char *optionList; /* Specific options list to append * to the standard generic options. * can be NULL for generic options * only. */ { if (interp) { CONST char *genericopt = "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, (char *) genericopt, -1); if (optionList && (*optionList)) { Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad option \"", optionName, "\": should be one of ", (char *) NULL); argc--; for (i = 0; i < argc; i++) { Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL); } Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL); Tcl_DStringFree(&ds); ckfree((char *) argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelByteorder -- * * Retrieves the byteorder set for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ByteOrder Tcl_GetChannelByteorder(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->byteOrder; } /* *---------------------------------------------------------------------- * * Tcl_GetHostByteorder -- * * Retrieves the byteorder of the machine we are running on. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ByteOrder Tcl_GetHostByteorder() { union { char c[sizeof(short)]; short s; } order; order.s = 1; return (order.c[0] == 1) ? TCL_SMALLENDIAN : TCL_BIGENDIAN; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelOption -- * * 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: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelOption(interp, chan, optionName, dsPtr) Tcl_Interp *interp; /* For error reporting - can be NULL. */ Tcl_Channel chan; /* Channel on which to get option. */ char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */ { size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; int flags; /* * If we are in the middle of a background copy, use the saved flags. */ if (chanPtr->csPtr) { if (chanPtr == chanPtr->csPtr->readPtr) { flags = chanPtr->csPtr->readFlags; } else { flags = chanPtr->csPtr->writeFlags; } } else { flags = chanPtr->flags; } /* * Disallow options 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(interp,chanPtr)) return TCL_ERROR; /* * If the optionName is NULL it means that we want a list of all * options and values. */ if (optionName == (char *) NULL) { len = 0; } else { len = strlen(optionName); } if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blocking"); } Tcl_DStringAppendElement(dsPtr, (flags & CHANNEL_NONBLOCKING) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffering", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffering"); } if (flags & CHANNEL_LINEBUFFERED) { Tcl_DStringAppendElement(dsPtr, "line"); } else if (flags & CHANNEL_UNBUFFERED) { Tcl_DStringAppendElement(dsPtr, "none"); } else { Tcl_DStringAppendElement(dsPtr, "full"); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffersize", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffersize"); } TclFormatInt(optionVal, chanPtr->bufSize); Tcl_DStringAppendElement(dsPtr, optionVal); if (len > 0) { return TCL_OK; } } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-byteorder"); } Tcl_DStringAppendElement(dsPtr, (chanPtr->byteOrder == TCL_BIGENDIAN) ? "bigendian" : "smallendian"); 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); } if (flags & TCL_READABLE) { if (chanPtr->inEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->inEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (flags & TCL_WRITABLE) { if (chanPtr->outEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->outEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 1) && (optionName[1] == 't') && (strncmp(optionName, "-translation", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-translation"); } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringStartSublist(dsPtr); } if (flags & TCL_READABLE) { if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (flags & TCL_WRITABLE) { if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) { /* * let the driver specific handle additional options * and result code and message. */ return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData, interp, optionName, dsPtr); } else { /* * no driver specific options case. */ if (len == 0) { 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? */ char *newValue; /* New value for option. */ { int newMode; /* New (numeric) mode to sert. */ Channel *chanPtr; /* The real IO channel. */ size_t len; /* Length of optionName string. */ int argc; char **argv; chanPtr = (Channel *) chan; /* * If the channel is in the middle of a background copy, fail. */ if (chanPtr->csPtr) { if (interp) { Tcl_AppendResult(interp, "unable to set channel options: background copy in progress", (char *) NULL); } return TCL_ERROR; } /* * Disallow options 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 TCL_ERROR; len = strlen(optionName); if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0)) { if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) { return TCL_ERROR; } 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)) { chanPtr->flags &= (~(CHANNEL_UNBUFFERED)); chanPtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { chanPtr->flags &= (~(CHANNEL_LINEBUFFERED)); chanPtr->flags |= CHANNEL_UNBUFFERED; } else { 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; } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0)) { int nv_len = strlen (newValue); if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { chanPtr->byteOrder = TCL_BIGENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_BIGENDIAN; return TCL_OK; } if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "bad value for -byteorder: ", "must be one of smallendian, littleendian, bigendian or network", (char *) NULL); } return TCL_ERROR; } 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; } else if (argc == 1) { if (chanPtr->flags & TCL_WRITABLE) { chanPtr->outEofChar = (int) argv[0][0]; } if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } } else if (argc != 2) { if (interp) { Tcl_AppendResult(interp, "bad value for -eofchar: should be a list of one or", " two elements", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } else { if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } 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; } if (argc == 1) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: must be a one or two", " element list", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } 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) { newMode = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered * 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) { /* * This is a hack to get TCP sockets to produce output * in CRLF mode if they are being set into AUTO mode. * A better solution for achieving this effect will be * coded later. */ if (strcmp(chanPtr->typePtr->typeName, "tcp") == 0) { 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) { chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } 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 -- * * Removes channel handlers that refer to the supplied interpreter, * so that if the actual channel is not closed now, these handlers * will not run on subsequent events on the channel. This would be * erroneous, because the interpreter no longer has a reference to * this channel. * * Results: * None. * * Side effects: * Removes channel handlers. * *---------------------------------------------------------------------- */ static void CleanupChannelHandlers(interp, chanPtr) Tcl_Interp *interp; Channel *chanPtr; { EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* * Remove fileevent records on this channel that refer to the * given interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); ckfree(sPtr->script); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } } /* *---------------------------------------------------------------------- * * Tcl_NotifyChannel -- * * This procedure is called by a channel driver when a driver * detects an event on a channel. This procedure is responsible * for actually handling the event by invoking any channel * handler callbacks. * * Results: * None. * * Side effects: * Whatever the channel handler callback procedure does. * *---------------------------------------------------------------------- */ void Tcl_NotifyChannel(channel, mask) 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; /* * 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 = 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. */ if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; (*(chPtr->proc))(chPtr->clientData, mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; } } /* * Update the notifier interest, since it may have changed after * invoking event handlers. */ if (chanPtr->typePtr != NULL) { UpdateInterest(chanPtr); } Tcl_Release((ClientData) channel); nestedHandlerPtr = nh.nestedHandlerPtr; } /* *---------------------------------------------------------------------- * * UpdateInterest -- * * Arrange for the notifier to call us back at appropriate times * based on the current state of the channel. * * Results: * None. * * Side effects: * May schedule a timer or driver handler. * *---------------------------------------------------------------------- */ static void UpdateInterest(chanPtr) Channel *chanPtr; /* Channel to update. */ { int mask = chanPtr->interestMask; /* * If there are flushed buffers waiting to be written, then * we need to watch for the channel to become writable. */ 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); } } } (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask); } /* *---------------------------------------------------------------------- * * ChannelTimerProc -- * * Timer handler scheduled by UpdateInterest to monitor the * channel buffers until they are empty. * * Results: * None. * * Side effects: * May invoke channel handlers. * *---------------------------------------------------------------------- */ 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. */ chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc, (ClientData) chanPtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); } else { chanPtr->timer = NULL; UpdateInterest(chanPtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * * Arrange for a given procedure to be invoked whenever the * channel indicated by the chanPtr arg becomes readable or * writable. * * Results: * None. * * Side effects: * From now on, whenever the I/O channel given by chanPtr becomes * ready in the way indicated by mask, proc will be invoked. * See the manual entry for details on the calling sequence * to proc. If there is already an event handler for chan, proc * and clientData, then the mask will be updated. * *---------------------------------------------------------------------- */ void Tcl_CreateChannelHandler(chan, mask, proc, clientData) Tcl_Channel chan; /* The channel to create the handler for. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions under which * proc should be called. Use 0 to * disable a registered handler. */ Tcl_ChannelProc *proc; /* Procedure to call for each * selected event. */ ClientData clientData; /* Arbitrary data to pass to proc. */ { ChannelHandler *chPtr; Channel *chanPtr; chanPtr = (Channel *) chan; /* * Check whether this channel handler is not already registered. If * it is not, create a new record, else reuse existing record (smash * current values). */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) && (chPtr->clientData == clientData)) { break; } } if (chPtr == (ChannelHandler *) NULL) { chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler)); chPtr->mask = 0; chPtr->proc = proc; chPtr->clientData = clientData; chPtr->chanPtr = chanPtr; chPtr->nextPtr = chanPtr->chPtr; chanPtr->chPtr = chPtr; } /* * The remainder of the initialization below is done regardless of * whether or not this is a new record or a modification of an old * one. */ chPtr->mask = mask; /* * Recompute the interest mask for the channel - this call may actually * be disabling an existing handler. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * Tcl_DeleteChannelHandler -- * * Cancel a previously arranged callback arrangement for an IO * channel. * * Results: * None. * * Side effects: * If a callback was previously registered for this chan, proc and * clientData , it is removed and the callback will no longer be called * when the channel becomes ready for IO. * *---------------------------------------------------------------------- */ void Tcl_DeleteChannelHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to remove the * callback. */ 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. */ for (prevChPtr = (ChannelHandler *) NULL, chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData) && (chPtr->proc == proc)) { break; } prevChPtr = chPtr; } /* * If not found, return without doing anything. */ if (chPtr == (ChannelHandler *) NULL) { return; } /* * 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; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * DeleteScriptRecord -- * * Delete a script record for this combination of channel, interp * and mask. * * Results: * None. * * Side effects: * Deletes a script record and cancels a channel event handler. * *---------------------------------------------------------------------- */ static void DeleteScriptRecord(interp, chanPtr, mask) Tcl_Interp *interp; /* Interpreter in which script was to be * executed. */ Channel *chanPtr; /* The channel for which to delete the * script record (if any). */ int mask; /* Events in mask must exactly match mask * of script to delete. */ { EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = chanPtr->scriptRecordPtr, prevEsPtr = (EventScriptRecord *) NULL; esPtr != (EventScriptRecord *) NULL; prevEsPtr = esPtr, esPtr = esPtr->nextPtr) { if ((esPtr->interp == interp) && (esPtr->mask == mask)) { if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { prevEsPtr->nextPtr = esPtr->nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) esPtr); ckfree(esPtr->script); ckfree((char *) esPtr); break; } } } /* *---------------------------------------------------------------------- * * CreateScriptRecord -- * * Creates a record to store a script to be executed when a specific * event fires on a specific channel. * * Results: * None. * * 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 -- * * Invokes a script scheduled by "fileevent" for when the channel * becomes ready for IO. This function is invoked by the channel * handler which was created by the Tcl "fileevent" command. * * Results: * None. * * Side effects: * Whatever the script does. * *---------------------------------------------------------------------- */ static void 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. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundError(interp); } 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; } /* *---------------------------------------------------------------------- * * TclTestChannelCmd -- * * Implements the Tcl "testchannel" debugging command and its * subcommands. This is part of the testing environment but must be * in this file instead of tclTest.c because it needs access to the * fields of struct Channel. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int TclTestChannelCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Interpreter for result. */ int argc; /* Count of additional args. */ char **argv; /* Additional arg strings. */ { char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ 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]); Tcl_AppendElement(interp, chanPtr->typePtr->typeName); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_NONBLOCKING) { Tcl_AppendElement(interp, "nonblocking"); } else { Tcl_AppendElement(interp, "blocking"); } if (chanPtr->flags & CHANNEL_LINEBUFFERED) { Tcl_AppendElement(interp, "line"); } else if (chanPtr->flags & CHANNEL_UNBUFFERED) { Tcl_AppendElement(interp, "none"); } else { Tcl_AppendElement(interp, "full"); } if (chanPtr->flags & BG_FLUSH_SCHEDULED) { Tcl_AppendElement(interp, "async_flush"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_EOF) { Tcl_AppendElement(interp, "eof"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_BLOCKED) { Tcl_AppendElement(interp, "blocked"); } else { Tcl_AppendElement(interp, "unblocked"); } if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "saw_cr"); } else { Tcl_AppendElement(interp, ""); } } else if (chanPtr->inputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "queued_cr"); } else { Tcl_AppendElement(interp, ""); } } if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); } for (IOQueued = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved; } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved; } for (bufPtr = chanPtr->outQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved); } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr)); Tcl_AppendElement(interp, buf); TclFormatInt(buf, chanPtr->refCount); Tcl_AppendElement(interp, buf); return TCL_OK; } if ((cmdName[0] == 'i') && (strncmp(cmdName, "inputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; } if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } return TCL_OK; } if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "outputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - 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) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (chanPtr->flags & INPUT_SAW_CR) ? "1" : "0", (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } 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", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ", "info, open, readable, or writable", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclTestChannelEventCmd -- * * This procedure implements the "testchannelevent" command. It is * used to test the Tcl channel event mechanism. It is present in * this file instead of tclTest.c because it needs access to the * internal structure of the channel. * * Results: * A standard Tcl result. * * Side effects: * Creates, deletes and returns channel event handlers. * *---------------------------------------------------------------------- */ /* ARGSUSED */ 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], " channelName cmd ?arg1? ?arg2?\"", (char *) NULL); return TCL_ERROR; } chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL); if (chanPtr == (Channel *) NULL) { return TCL_ERROR; } cmd = argv[2]; len = strlen(cmd); if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName add eventSpec script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[3], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[3], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[3], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr = (EventScriptRecord *) ckalloc((unsigned) 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; } if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) { if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { for (prevEsPtr = chanPtr->scriptRecordPtr; (prevEsPtr != (EventScriptRecord *) NULL) && (prevEsPtr->nextPtr != esPtr); prevEsPtr = prevEsPtr->nextPtr) { /* Empty loop body. */ } 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)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index event\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[4], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[4], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[4], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[4], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr->mask = mask; 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 -- * * This routine copies data from one channel to another, either * synchronously or asynchronously. If a command script is * supplied, the operation runs in the background. The script * is invoked when the copy completes. Otherwise the function * waits until the copy is completed before returning. * * Results: * A standard Tcl result. * * Side effects: * May schedule a background copy operation that causes both * channels to be marked busy. * *---------------------------------------------------------------------- */ int TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Channel inChan; /* Channel to read from. */ Tcl_Channel outChan; /* Channel to write to. */ int toRead; /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */ { Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; if (inPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); return TCL_ERROR; } if (outPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); return TCL_ERROR; } readFlags = inPtr->flags; writeFlags = outPtr->flags; /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. * If there is an error, restore the old blocking mode. */ if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(interp, inPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) { return TCL_ERROR; } } if (inPtr != outPtr) { if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(NULL, outPtr, nonBlocking ? TCL_MODE_BLOCKING : TCL_MODE_NONBLOCKING) != TCL_OK) { if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING) ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); return TCL_ERROR; } } } } /* * Make sure the output side is unbuffered. */ outPtr->flags = (outPtr->flags & ~(CHANNEL_LINEBUFFERED)) | CHANNEL_UNBUFFERED; /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inPtr->bufSize); csPtr->bufSize = inPtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; inPtr->csPtr = csPtr; outPtr->csPtr = csPtr; /* * Start copying data between the channels. */ return CopyData(csPtr, 0); } /* *---------------------------------------------------------------------- * * CopyData -- * * This function implements the lowest level of the copying * mechanism for TclCopyChannel. * * Results: * Returns TCL_OK on success, else TCL_ERROR. * * Side effects: * Moves data between channels, may create channel handlers. * *---------------------------------------------------------------------- */ static int CopyData(csPtr, mask) CopyState *csPtr; /* State of copy operation. */ int mask; /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL; Tcl_Channel inChan, outChan; int result = TCL_OK; int size; int total; inChan = (Tcl_Channel)csPtr->readPtr; outChan = (Tcl_Channel)csPtr->writePtr; interp = csPtr->interp; cmdPtr = csPtr->cmdPtr; /* * Copy the data the slow way, using the translation mechanism. */ while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ if (csPtr->readPtr->unreportedError != 0) { Tcl_SetErrno(csPtr->readPtr->unreportedError); csPtr->readPtr->unreportedError = 0; goto readError; } if (csPtr->writePtr->unreportedError != 0) { Tcl_SetErrno(csPtr->writePtr->unreportedError); csPtr->writePtr->unreportedError = 0; goto writeError; } /* * Read up to bufSize bytes. */ if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { size = csPtr->bufSize; } else { size = csPtr->toRead; } size = DoRead(csPtr->readPtr, csPtr->buffer, size); if (size < 0) { readError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error reading \"", Tcl_GetChannelName(inChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } else if (size == 0) { /* * We had an underflow on the read side. If we are at EOF, * then the copying is done, otherwise set up a channel * handler to detect when the channel becomes readable again. */ if (Tcl_Eof(inChan)) { break; } else if (!(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Now write the buffer out. */ size = DoWrite(csPtr->writePtr, csPtr->buffer, size); if (size < 0) { writeError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error writing \"", Tcl_GetChannelName(outChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } /* * Check to see if the write is happening in the background. If so, * stop copying and wait for the channel to become writable again. */ if (csPtr->writePtr->flags & BG_FLUSH_SCHEDULED) { if (!(mask & TCL_WRITABLE)) { if (mask & TCL_READABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Update the current byte count if we care. */ if (csPtr->toRead != -1) { csPtr->toRead -= size; } csPtr->total += size; /* * For background copies, we only do one buffer per invocation so * we don't starve the rest of the system. */ if (cmdPtr) { /* * The first time we enter this code, there won't be a * channel handler established yet, so do it here. */ if (mask == 0) { Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } } /* * Make the callback or return the number of bytes transferred. * The local total is used because StopCopy frees csPtr. */ total = csPtr->total; if (cmdPtr) { /* * Get a private copy of the command so we can mutate it * by adding arguments. Note that StopCopy frees our saved * reference to the original command obj. */ cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); 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 * the background copy operation. It is just a trivial wrapper * around the CopyData routine. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void CopyEventProc(clientData, mask) ClientData clientData; int mask; { (void) CopyData((CopyState *)clientData, mask); } /* *---------------------------------------------------------------------- * * StopCopy -- * * This routine halts a copy that is in progress. * * Results: * None. * * Side effects: * Removes any pending channel handlers and restores the blocking * and buffering modes of the channels. The CopyState is freed. * *---------------------------------------------------------------------- */ static void StopCopy(csPtr) CopyState *csPtr; /* State for bg copy to stop . */ { int nonBlocking; if (!csPtr) { return; } /* * Restore the old blocking mode and output buffering mode. */ nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING); if (nonBlocking != (csPtr->readPtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->readPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } if (csPtr->writePtr != csPtr->writePtr) { if (nonBlocking != (csPtr->writePtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->writePtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } } csPtr->writePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); csPtr->writePtr->flags |= csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc, (ClientData)csPtr); if (csPtr->readPtr != csPtr->writePtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr, CopyEventProc, (ClientData)csPtr); } Tcl_DecrRefCount(csPtr->cmdPtr); } csPtr->readPtr->csPtr = NULL; csPtr->writePtr->csPtr = NULL; ckfree((char*) csPtr); } trf2.1.4/patches/v8.0.5/tcl.h0000644000175000017500000017327011216344361015005 0ustar sergeisergei/* * 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. * 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. * * RCS: @(#) $Id: tcl.h,v 1.1 1999/03/14 18:44:03 aku Exp $ */ #ifndef _TCL #define _TCL /* * When version numbers change here, must also go into the following files * and update the version numbers: * * README * 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/README * win/README.binary * mac/README * * 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 5 #define TCL_VERSION "8.0" #define TCL_PATCH_LEVEL "8.0.5" /* * The following definitions set up the proper options for Windows * compilers. We use this method because there is no autoconf equivalent. */ #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) # define __WIN32__ # endif #endif #ifdef __WIN32__ # ifndef STRICT # define STRICT # endif # ifndef USE_PROTOTYPE # define USE_PROTOTYPE 1 # 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 #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 /* * 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. */ #ifndef RESOURCE_INCLUDED #ifndef BUFSIZ #include #endif /* * Definitions that allow Tcl functions with variable numbers of * arguments to be used with either varargs.h or stdarg.h. TCL_VARARGS * is used in procedure prototypes. TCL_VARARGS_DEF is used to declare * 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 /* * 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. * The support follows the convention 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. See BUILD_tcl in this * file for an example of how the macro is to be used. */ #ifdef __WIN32__ # ifdef STATIC_BUILD # define DLLIMPORT # define DLLEXPORT # else # if defined(_MSC_VER) || (defined(__GNUC__) && defined(__declspec)) # define DLLIMPORT __declspec(dllimport) # define DLLEXPORT __declspec(dllexport) # else # define DLLIMPORT # define DLLEXPORT # endif # endif #else # define DLLIMPORT # define DLLEXPORT #endif #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_tcl # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #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" 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. */ #ifndef __WIN32__ #ifndef VOID # ifdef __STDC__ # define VOID void # else # define VOID char # endif #endif #else /* __WIN32__ */ /* * The following code is copied from winnt.h */ #ifndef VOID #define VOID void typedef char CHAR; typedef short SHORT; typedef long LONG; #endif #endif /* __WIN32__ */ /* * Miscellaneous declarations. */ #ifndef NULL #define NULL 0 #endif #ifndef _CLIENTDATA # if defined(__STDC__) || defined(__cplusplus) typedef void *ClientData; # else typedef int *ClientData; # endif /* __STDC__ */ #define _CLIENTDATA #endif /* * Data structures defined opaquely in this module. The definitions below * just provide dummy types. A few fields are made visible in Tcl_Interp * structures, namely those used for returning a string result from * commands. Direct access to the result field is discouraged in Tcl 8.0. * The interpreter result is either an object or a string, and the two * values are kept consistent unless some C code sets interp->result * directly. Programmers should use either the procedure Tcl_GetObjResult() * or Tcl_GetStringResult() to read the interpreter's result. See the * SetResult man page for details. * * Note: any change to the Tcl_Interp definition below must be mirrored * in the "real" definition in tclInt.h. * * Note: Tcl_ObjCmdProc procedures do not directly set result and freeProc. * Instead, they set a Tcl_Obj member in the "real" structure that can be * accessed with Tcl_GetObjResult() and Tcl_SetObjResult(). */ typedef struct Tcl_Interp { char *result; /* If the last command returned a string * result, this points to it. */ void (*freeProc) _ANSI_ARGS_((char *blockPtr)); /* Zero means the string result is * statically allocated. TCL_DYNAMIC means * it was allocated with ckalloc and should * be freed with ckfree. Other values give * the address of procedure to invoke to * free the result. Tcl_Eval must free it * before executing next command. */ int errorLine; /* When TCL_ERROR is returned, this gives * 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 * procedures Tcl_GetObjResult() or Tcl_GetStringResult() to read the * interpreter's result. See the SetResult man page for details. Besides * this result, the command procedure returns an integer code, which is * one of the following: * * TCL_OK Command completed normally; the interpreter's * result contains the command's result. * TCL_ERROR The command couldn't be completed successfully; * the interpreter's result describes what went wrong. * TCL_RETURN The command requests that the current procedure * return; the interpreter's result contains the * procedure's return value. * TCL_BREAK The command requests that the innermost loop * be exited; the interpreter's result is meaningless. * TCL_CONTINUE Go on to the next iteration of the current loop; * the interpreter's result is meaningless. */ #define TCL_OK 0 #define TCL_ERROR 1 #define TCL_RETURN 2 #define TCL_BREAK 3 #define TCL_CONTINUE 4 #define TCL_RESULT_SIZE 200 /* * Argument descriptors for math function callbacks in expressions: */ typedef enum {TCL_INT, TCL_DOUBLE, TCL_EITHER} Tcl_ValueType; typedef struct Tcl_Value { Tcl_ValueType type; /* Indicates intValue or doubleValue is * valid, or both. */ long intValue; /* Integer value. */ double doubleValue; /* Double-precision floating value. */ } Tcl_Value; /* * Forward declaration of Tcl_Obj to prevent an error when the forward * reference to Tcl_Obj is encountered in the procedure types declared * below. */ struct Tcl_Obj; /* * Procedure types defined by Tcl: */ typedef int (Tcl_AppInitProc) _ANSI_ARGS_((Tcl_Interp *interp)); typedef int (Tcl_AsyncProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int code)); typedef void (Tcl_ChannelProc) _ANSI_ARGS_((ClientData clientData, int mask)); typedef void (Tcl_CloseProc) _ANSI_ARGS_((ClientData data)); typedef void (Tcl_CmdDeleteProc) _ANSI_ARGS_((ClientData clientData)); 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, Tcl_Interp *interp, char *part1, char *part2, int flags)); /* * The following structure represents a type of object, which is a * particular internal representation for an object plus a set of * procedures that provide standard operations on objects of that type. */ typedef struct Tcl_ObjType { char *name; /* Name of the type, e.g. "int". */ Tcl_FreeInternalRepProc *freeIntRepProc; /* Called to free any storage for the type's * internal rep. NULL if the internal rep * does not need freeing. */ Tcl_DupInternalRepProc *dupIntRepProc; /* Called to create a new object as a copy * of an existing object. */ Tcl_UpdateStringProc *updateStringProc; /* Called to update the string rep from the * type's internal representation. */ Tcl_SetFromAnyProc *setFromAnyProc; /* Called to convert the object's internal * rep to this type. Frees the internal rep * of the old type. Returns TCL_ERROR on * failure. */ } Tcl_ObjType; /* * One of the following structures exists for each object in the Tcl * system. An object stores a value as either a string, some internal * representation, or both. */ typedef struct Tcl_Obj { int refCount; /* When 0 the object will be freed. */ char *bytes; /* This points to the first byte of the * object's string representation. The array * 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: */ long longValue; /* - an long integer value */ double doubleValue; /* - a double-precision floating value */ VOID *otherValuePtr; /* - another, type-specific value */ struct { /* - internal rep as two pointers */ VOID *ptr1; VOID *ptr2; } twoPtrValue; } internalRep; } Tcl_Obj; /* * Macros to increment and decrement a Tcl_Obj's reference count, and to * test whether an object is shared (i.e. has reference count > 1). * Note: clients should use Tcl_DecrRefCount() when they are finished using * an object, and should never call TclFreeObj() directly. TclFreeObj() is * only defined and made public in tcl.h to support Tcl_DecrRefCount's macro * definition. Note also that Tcl_DecrRefCount() refers to the parameter * "obj" twice. This means that you should avoid calling it with an * expression that is expensive to compute or has side effects. */ EXTERN void Tcl_IncrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN void Tcl_DecrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN int Tcl_IsShared _ANSI_ARGS_((Tcl_Obj *objPtr)); #ifdef TCL_MEM_DEBUG # define Tcl_IncrRefCount(objPtr) \ Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_DecrRefCount(objPtr) \ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_IsShared(objPtr) \ Tcl_DbIsShared(objPtr, __FILE__, __LINE__) #else # define Tcl_IncrRefCount(objPtr) \ ++(objPtr)->refCount # define Tcl_DecrRefCount(objPtr) \ 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). */ typedef struct Tcl_Namespace { char *name; /* The namespace's name within its parent * namespace. This contains no ::'s. The * name of the global namespace is "" * although "::" is an synonym. */ char *fullName; /* The namespace's fully qualified name. * This starts with ::. */ ClientData clientData; /* Arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc* deleteProc; /* Procedure invoked when deleting the * namespace to, e.g., free clientData. */ struct Tcl_Namespace* parentPtr; /* Points to the namespace that contains * this one. NULL if this is the global * namespace. */ } Tcl_Namespace; /* * The following structure represents a call frame, or activation record. * A call frame defines a naming context for a procedure call: its local * scope (for local variables) and its namespace scope (used for non-local * variables; often 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 command's code should execute. The * Tcl_CallFrame structures exist only while procedures or namespace * eval/inscope's are being executed, and provide a Tcl call stack. * * A call frame is initialized and pushed using Tcl_PushCallFrame and * popped using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be * provided by the Tcl_PushCallFrame caller, and callers typically allocate * them on the C call stack for efficiency. For this reason, Tcl_CallFrame * is defined as a structure and not as an opaque token. However, most * Tcl_CallFrame fields are hidden since applications should not access * them directly; others are declared as "dummyX". * * WARNING!! The structure definition must be kept consistent with the * CallFrame structure in tclInt.h. If you change one, change the other. */ typedef struct Tcl_CallFrame { Tcl_Namespace *nsPtr; int dummy1; int dummy2; char *dummy3; char *dummy4; char *dummy5; int dummy6; char *dummy7; char *dummy8; int dummy9; char* dummy10; } Tcl_CallFrame; /* * Information about commands that is returned by Tcl_GetCommandInfo and * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based * command procedure while proc is a traditional Tcl argc/argv * string-based procedure. Tcl_CreateObjCommand and Tcl_CreateCommand * ensure that both objProc and proc are non-NULL and can be called to * execute the command. However, it may be faster to call one instead of * the other. The member isNativeObjectProc is set to 1 if an * object-based procedure was registered by Tcl_CreateObjCommand, and to * 0 if a string-based procedure was registered by Tcl_CreateCommand. * The other procedure is typically set to a compatibility wrapper that * does string-to-object or object-to-string argument conversions then * calls the other procedure. */ typedef struct Tcl_CmdInfo { int isNativeObjectProc; /* 1 if objProc was registered by a call to * Tcl_CreateObjCommand; 0 otherwise. * Tcl_SetCmdInfo does not modify this * field. */ Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ ClientData objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based procedure. */ ClientData clientData; /* ClientData for string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure to call when command is * deleted. */ ClientData deleteData; /* Value to pass to deleteProc (usually * the same as clientData). */ Tcl_Namespace *namespacePtr; /* Points to the namespace that contains * this command. Note that Tcl_SetCmdInfo * will not change a command's namespace; * use Tcl_RenameCommand to do that. */ } Tcl_CmdInfo; /* * The structure defined below is used to hold dynamic strings. The only * field that clients should use is the string field, and they should * never modify it. */ #define TCL_DSTRING_STATIC_SIZE 200 typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ int length; /* Number of non-NULL characters in the * string. */ int spaceAvl; /* Total number of bytes available for the * string and its terminating NULL char. */ char staticSpace[TCL_DSTRING_STATIC_SIZE]; /* Space to use in common case where string * is small. */ } Tcl_DString; #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) #define TCL_STATIC ((Tcl_FreeProc *) 0) #define TCL_DYNAMIC ((Tcl_FreeProc *) 3) /* * Flag values passed to variable-related procedures. */ #define TCL_GLOBAL_ONLY 1 #define TCL_NAMESPACE_ONLY 2 #define TCL_APPEND_VALUE 4 #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 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_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 struct Tcl_HashTable; #endif /* * Structure definition for an entry in a hash table. No-one outside * Tcl should access any of these fields directly; use the macros * defined below. */ typedef struct Tcl_HashEntry { struct Tcl_HashEntry *nextPtr; /* Pointer to next entry in this * hash bucket, or NULL for end of * chain. */ struct Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */ struct Tcl_HashEntry **bucketPtr; /* Pointer to bucket that points to * first entry in this entry's chain: * used for deleting the entry. */ ClientData clientData; /* Application stores something here * with Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ int words[1]; /* Multiple integer words for key. * The actual size will be as large * as necessary for this table's * keys. */ char string[4]; /* String for key. The actual size * will be as large as needed to hold * the key. */ } key; /* MUST BE LAST FIELD IN RECORD!! */ } Tcl_HashEntry; /* * Structure definition for a hash table. Must be in tcl.h so clients * can allocate space for these structures, but clients should never * access any fields in this structure. */ #define TCL_SMALL_HASH_TABLE 4 typedef struct Tcl_HashTable { Tcl_HashEntry **buckets; /* Pointer to bucket array. Each * element points to first entry in * bucket's hash chain, or NULL. */ Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables * (to avoid mallocs and frees). */ int numBuckets; /* Total number of buckets allocated * at **bucketPtr. */ int numEntries; /* Total number of entries present * in table. */ int rebuildSize; /* Enlarge table when numEntries gets * to be this large. */ int downShift; /* Shift count used in hashing * function. Designed to use high- * order bits of randomized keys. */ int mask; /* Mask value used in hashing * function. */ int keyType; /* Type of keys used in this table. * It's either TCL_STRING_KEYS, * TCL_ONE_WORD_KEYS, or an integer * giving the number of ints that * is the size of the key. */ Tcl_HashEntry *(*findProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key)); Tcl_HashEntry *(*createProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key, int *newPtr)); } Tcl_HashTable; /* * Structure definition for information used to keep track of searches * through hash tables: */ typedef struct Tcl_HashSearch { Tcl_HashTable *tablePtr; /* Table being searched. */ int nextIndex; /* Index of next bucket to be * enumerated after present one. */ Tcl_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the * the current bucket. */ } Tcl_HashSearch; /* * Acceptable key types for hash tables: */ #define TCL_STRING_KEYS 0 #define TCL_ONE_WORD_KEYS 1 /* * Macros for clients to use to access fields of hash entries: */ #define Tcl_GetHashValue(h) ((h)->clientData) #define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value)) #define Tcl_GetHashKey(tablePtr, h) \ ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS) ? (h)->key.oneWordValue \ : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create procedures * for hash tables: */ #define Tcl_FindHashEntry(tablePtr, key) \ (*((tablePtr)->findProc))(tablePtr, key) #define Tcl_CreateHashEntry(tablePtr, key, newPtr) \ (*((tablePtr)->createProc))(tablePtr, key, newPtr) /* * Flag values to pass to Tcl_DoOneEvent to disable searches * for some kinds of events: */ #define TCL_DONT_WAIT (1<<1) #define TCL_WINDOW_EVENTS (1<<2) #define TCL_FILE_EVENTS (1<<3) #define TCL_TIMER_EVENTS (1<<4) #define TCL_IDLE_EVENTS (1<<5) /* WAS 0x10 ???? */ #define TCL_ALL_EVENTS (~TCL_DONT_WAIT) /* * The following structure defines a generic event for the Tcl event * system. These are the things that are queued in calls to Tcl_QueueEvent * and serviced later by Tcl_DoOneEvent. There can be many different * kinds of events with different fields, corresponding to window events, * timer events, etc. The structure for a particular event consists of * a Tcl_Event header followed by additional information specific to that * event. */ struct Tcl_Event { Tcl_EventProc *proc; /* Procedure to call to service this event. */ struct Tcl_Event *nextPtr; /* Next in list of pending events, or NULL. */ }; /* * Positions to pass to Tcl_QueueEvent: */ typedef enum { TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK } Tcl_QueuePosition; /* * Values to pass to Tcl_SetServiceMode to specify the behavior of notifier * event routines. */ #define TCL_SERVICE_NONE 0 #define TCL_SERVICE_ALL 1 /* * The following structure keeps is used to hold a time value, either as * an absolute time (the number of seconds from the epoch) or as an * elapsed time. On Unix systems the epoch is Midnight Jan 1, 1970 GMT. * On Macintosh systems the epoch is Midnight Jan 1, 1904 GMT. */ typedef struct Tcl_Time { long sec; /* Seconds. */ long usec; /* Microseconds. */ } Tcl_Time; /* * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler * to indicate what sorts of events are of interest: */ #define TCL_READABLE (1<<1) #define TCL_WRITABLE (1<<2) #define TCL_EXCEPTION (1<<3) /* * Flag values to pass to Tcl_OpenCommandChannel to indicate the * disposition of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, * are also used in Tcl_GetStdChannel. */ #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. */ TCL_TRANSLATE_LF, /* Eol == \n. */ TCL_TRANSLATE_CRLF /* Eol == \r\n. */ } Tcl_EolTranslation; /* * Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). * * Enum for different byteorders. */ typedef enum Tcl_ByteOrder { TCL_BIGENDIAN, /* Multibyte words are stored with MSB first */ TCL_SMALLENDIAN /* Multibyte words are stored with MSB last */ } Tcl_ByteOrder; /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. * It collects together in one place all the functions that are * part of the specific channel type. */ 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. */ VOID *reserved; /* reserved for future expansion */ } 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. */ #define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */ #define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking * mode. */ /* * Enum for different types of file paths. */ 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 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)); /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ EXTERN Tcl_ByteOrder Tcl_GetChannelByteorder _ANSI_ARGS_(( Tcl_Channel chan)); EXTERN Tcl_ByteOrder Tcl_GetHostByteorder _ANSI_ARGS_((void)); 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 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 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 CONST char * Tcl_GetNameOfExecutable _ANSI_ARGS_((void)); 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_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_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)); #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS /* * 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 */ EXTERN int Tcl_AppInit _ANSI_ARGS_((Tcl_Interp *interp)); /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * C-Level API for (un)stacking of channels. This allows the introduction * of filtering channels with relatively little changes to the core. * This patch was created in cooperation with Jan Nijtmans * and is therefore part of his plus-patches too. * * It would have been possible to place the following definitions according * to the alphabetical order used elsewhere in this file, but I decided * against that to ease the maintenance of the patch across new tcl versions * (patch usually has no problems to integrate the patch file for the last * version into the new one). */ EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_ChannelType* typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_Channel chan)); #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TCL */ trf2.1.4/patches/v8.1b1/0000755000175000017500000000000011216344734014125 5ustar sergeisergeitrf2.1.4/patches/v8.1b1/standard.patch0000644000175000017500000003302711216344361016747 0ustar sergeisergei*** tcl.h.orig Fri Dec 4 04:02:25 1998 --- tcl.h Sun Dec 13 11:59:31 1998 *************** *** 1856,1861 **** --- 1856,1886 ---- EXTERN void Tcl_WrongNumArgs _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], char *message)); + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * C-Level API for (un)stacking of channels. This allows the introduction + * of filtering channels with relatively little changes to the core. + * This patch was created in cooperation with Jan Nijtmans + * and is therefore part of his plus-patches too. + * + * It would have been possible to place the following definitions according + * to the alphabetical order used elsewhere in this file, but I decided + * against that to ease the maintenance of the patch across new tcl versions + * (patch usually has no problems to integrate the patch file for the last + * version into the new one). + */ + + EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_ChannelType* typePtr, + ClientData instanceData, + int mask, + Tcl_Channel prevChan)); + + EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_Channel chan)); + + #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS *** tclIO.c.orig Fri Dec 4 04:02:25 1998 --- tclIO.c Sun Dec 13 13:39:29 1998 *************** *** 202,207 **** --- 202,229 ---- int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ + + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * The single change to the internal datastructures of the core. Every + * channel now maintains a reference to the channel he is stacked upon. + * This reference is NULL for normal channels. Only the two exported + * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the + * end of 'tcl.h') use this field in a non-trivial way. + * + * Of the existing procedures the only following are affected by this + * change: + * + * - Tcl_RegisterChannel + * - Tcl_CreateChannel + * - CloseChannel + * + * The why is explained at the changed locations. + */ + + struct Channel* supercedes; /* Refers to channel this one was stacked upon */ + } Channel; /* *************** *** 1038,1044 **** if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! panic("Tcl_RegisterChannel: duplicate channel names"); } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } --- 1060,1080 ---- if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! ! /* Andreas Kupries , 12/13/1998 ! * "Trf-Patch for filtering channels" ! * ! * This is the change to 'Tcl_RegisterChannel'. ! * ! * Explanation: ! * The moment a channel is stacked upon another he ! * takes the identity of the channel he supercedes, ! * i.e. he gets the *same* name. Because of this we ! * cannot check for duplicate names anymore, they ! * have to be allowed now. ! */ ! ! /* panic("Tcl_RegisterChannel: duplicate channel names"); */ } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } *************** *** 1297,1302 **** --- 1333,1352 ---- chanPtr->timer = NULL; chanPtr->csPtr = NULL; + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * This is the change to 'Tcl_CreateChannel'. + * + * Explanation: + * It is of course necessary to initialize the new field + * in the Channel structure. The chosen value indicates + * that the created channel is a normal one, and not + * stacked upon another. + */ + + chanPtr->supercedes = (Channel*) NULL; + chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) *************** *** 1330,1335 **** --- 1380,1622 ---- return (Tcl_Channel) chanPtr; } + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * The following two procedures are the new, exported ones. They + * - create a channel stacked upon an existing one and + * - pop a stacked channel off, thus revealing the superceded one. + * + * Please read the following completely. + */ + + /* + *---------------------------------------------------------------------- + * + * Tcl_ReplaceChannel -- + * + * Replaces an entry in the hash table for a Tcl_Channel + * record. The replacement is a new channel with same name, + * it supercedes the replaced channel. Input and output of + * the superceded channel is now going through the newly + * created channel and allows the arbitrary filtering/manipulation + * of the dataflow. + * + * Results: + * Returns the new Tcl_Channel. + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_ChannelType *typePtr; /* The channel type record for the new + * channel. */ + ClientData instanceData; /* Instance specific data for the new + * channel. */ + int mask; /* TCL_READABLE & TCL_WRITABLE to indicate + * if the channel is readable, writable. */ + Tcl_Channel prevChan; /* The channel structure to replace */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr, *pt, *prevPt; + + /* + * Find the given channel in the list of all channels, compute enough + * information to allow easy removal after the conditions are met. + */ + + prevPt = (Channel*) NULL; + pt = (Channel*) tsdPtr->firstChanPtr; + + while (pt != (Channel *) prevChan) { + prevPt = pt; + pt = pt->nextChanPtr; + } + + /* + * 'pt == prevChan' now + */ + + if (!pt) { + return (Tcl_Channel) NULL; + } + + /* + * Here we check if the given "mask" matches the "flags" + * of the already existing channel. + * + * | - | R | W | RW | + * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) + * - | | | | | + * R | | + | | + | The superceding channel is allowed to + * W | | | + | + | restrict the capabilities of the + * RW| | + | + | + | superceded one ! + * --+---+---+---+----+ + */ + + if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { + return (Tcl_Channel) NULL; + } + + + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); + chanPtr->flags = mask; + + /* + * Set the channel up initially in no Input translation mode and + * no Output translation mode. + */ + + chanPtr->inputTranslation = TCL_TRANSLATE_LF; + chanPtr->outputTranslation = TCL_TRANSLATE_LF; + chanPtr->inEofChar = 0; + chanPtr->outEofChar = 0; + + chanPtr->unreportedError = 0; + chanPtr->instanceData = instanceData; + chanPtr->typePtr = typePtr; + chanPtr->refCount = 0; + chanPtr->closeCbPtr = (CloseCallback *) NULL; + chanPtr->curOutPtr = (ChannelBuffer *) NULL; + chanPtr->outQueueHead = (ChannelBuffer *) NULL; + chanPtr->outQueueTail = (ChannelBuffer *) NULL; + chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; + chanPtr->inQueueHead = (ChannelBuffer *) NULL; + 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; + + /* 06/12/1998: New for Tcl 8.1 + * + * Take over the encoding from the superceded channel, so that it will be + * executed in the future despite the replacement, and at the proper time + * (*after* / *before* our transformation, depending on the direction of + * the dataflow). + * + * *Important* + * The I/O functionality of the filtering channel has to use 'Tcl_Read' to + * get at the underlying information. This will circumvent the de/encoder + * stage [*] in the superceded channel and removes the need to trouble + * ourselves with 'ByteArray's too. + * + * [*] I'm talking about the conversion between UNICODE and other + * representations, like ASCII. + */ + + chanPtr->encoding=Tcl_GetEncoding(interp,Tcl_GetEncodingName(pt->encoding)); + chanPtr->inputEncodingState = pt->inputEncodingState; + chanPtr->inputEncodingFlags = pt->inputEncodingFlags; + chanPtr->outputEncodingState = pt->outputEncodingState; + chanPtr->outputEncodingFlags = pt->outputEncodingFlags; + + chanPtr->outputStage = NULL; + + if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { + chanPtr->outputStage = (char *) + ckalloc((unsigned) (chanPtr->bufSize + 2)); + } + + chanPtr->supercedes = (Channel*) prevChan; + + chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); + strcpy (chanPtr->channelName, pt->channelName); + + if (prevPt) { + prevPt->nextChanPtr = chanPtr; + } else { + tsdPtr->firstChanPtr = chanPtr; + } + + chanPtr->nextChanPtr = pt->nextChanPtr; + + Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); + + /* + * The superceded channel is effectively unregistered + */ + + /*chanPtr->supercedes->refCount --;*/ + + return (Tcl_Channel) chanPtr; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_UndoReplaceChannel -- + * + * Unstacks an entry in the hash table for a Tcl_Channel + * record. This is the reverse to 'Tcl_ReplaceChannel'. + * The old, superceded channel is uncovered and re-registered + * in the appropriate datastructures. + * + * Results: + * Returns the old Tcl_Channel, i.e. the one which was stacked over. + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + + void + Tcl_UndoReplaceChannel (interp, chan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_Channel chan; /* The channel to unstack */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel* chanPtr = (Channel*) chan; + + if (chanPtr->supercedes != (Channel*) NULL) { + Tcl_HashTable *hTblPtr; /* Hash table of channels. */ + Tcl_HashEntry *hPtr; /* Search variable. */ + int new; /* Is the hash entry new or does it exist? */ + + /* + * Insert the channel we were stacked upon back into + * the list of open channels. Place it back into the hashtable too. + * Correct 'refCount', as this actually unregisters 'chan'. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + + hTblPtr = GetChannelTable (interp); + hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); + + Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); + chanPtr->refCount --; + + /* + * The superceded channel is effectively registered again + */ + + /*chanPtr->supercedes->refCount ++;*/ + } + + /* + * Disconnect the channels, then do a regular close upon the + * stacked one, the filtering channel. This may cause flushing + * of data into the superceded channel (if the filtering channel + * ('chan') remembered its parent in itself). + */ + + chanPtr->supercedes = NULL; + + if (chanPtr->refCount == 0) { + Tcl_Close (interp, chan); + } + } + /* *---------------------------------------------------------------------- * *************** *** 2003,2008 **** --- 2290,2330 ---- if (errorCode != 0) { Tcl_SetErrno(errorCode); } + } + + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * This is the change to 'CloseChannel'. + * + * Explanation + * Closing a filtering channel closes the one it + * superceded too. This basically ripples through + * the whole chain of filters until it reaches + * the underlying normal channel. + * + * This is done by reintegrating the superceded + * channel into the (thread) global list of open + * channels and then invoking a regular close. + * There is no need to handle the complexities of + * this process by ourselves. + * + * *Note* + * This has to be done after the call to the + * 'closeProc' of the filtering channel to allow + * that one the flushing of internal buffers into + * the underlying channel. + */ + + if (chanPtr->supercedes != (Channel*) NULL) { + /* Insert the channel we were stacked upon back into + * the list of open channels, then do a regular close. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + chanPtr->supercedes->refCount --; /* is deregistered */ + Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* trf2.1.4/patches/v8.1b1/README0000644000175000017500000000012111216344361014773 0ustar sergeisergeiThe byteorder patch for 8.1b1 was written by Jan Nijtmans . trf2.1.4/patches/v8.1b1/byteorder.patch0000644000175000017500000001276311216344361017152 0ustar sergeisergei*** tcl.h.orig Fri Dec 4 04:02:25 1998 --- tcl.h Tue Dec 15 00:32:08 1998 *************** *** 1495,1500 **** --- 1495,1507 ---- char *chanName, int *modePtr)); EXTERN int Tcl_GetChannelBufferSize _ANSI_ARGS_(( Tcl_Channel chan)); + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + */ + EXTERN int Tcl_GetChannelByteorder _ANSI_ARGS_(( + Tcl_Channel chan)); + EXTERN int Tcl_GetChannelHandle _ANSI_ARGS_((Tcl_Channel chan, int direction, ClientData *handlePtr)); EXTERN ClientData Tcl_GetChannelInstanceData _ANSI_ARGS_(( *** tclIO.c.orig Fri Dec 4 04:02:25 1998 --- tclIO.c Tue Dec 15 00:52:07 1998 *************** *** 261,266 **** --- 261,270 ---- * When set, file events will not be * delivered for buffered data until * the state of the channel changes. */ + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + */ + #define CHANNEL_IS_SMALLENDIAN (1<<16) /* Multibyte words are stored with MSB last */ /* * For each channel handler registered in a call to Tcl_CreateChannelHandler, *************** *** 1241,1246 **** --- 1245,1264 ---- CONST char *name; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + * Location: Tcl_CreateChannel. + */ + union { + char c[sizeof(short)]; + short s; + } order; + + order.s = 1; + if (order.c[0] == 1) { + mask |= CHANNEL_IS_SMALLENDIAN; + } + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); if (chanName != (char *) NULL) { *************** *** 4924,4930 **** { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize eofchar translation"; char **argv; int argc, i; Tcl_DString ds; --- 4942,4948 ---- { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; *************** *** 4954,4959 **** --- 4972,5009 ---- return TCL_ERROR; } + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + * Exported functionality. + */ + + /* + *---------------------------------------------------------------------- + * + * Tcl_GetChannelByteorder -- + * + * Retrieves the byteorder set for this channel. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + int + Tcl_GetChannelByteorder(chan) + Tcl_Channel chan; /* The channel for which to find the + * buffer size. */ + { + Channel *chanPtr; + + chanPtr = (Channel *) chan; + return ((chanPtr->flags & CHANNEL_IS_SMALLENDIAN) != 0); + } + /* *---------------------------------------------------------------------- * *************** *** 5074,5079 **** --- 5124,5148 ---- return TCL_OK; } } + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + * Location: Tcl_GetChannelOption + */ + + if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0))) { + if (len == 0) { + Tcl_DStringAppendElement(dsPtr, "-byteorder"); + } + Tcl_DStringAppendElement(dsPtr, + (chanPtr->flags & CHANNEL_IS_SMALLENDIAN) ? + "smallendian" : "bigendian"); + if (len > 0) { + return TCL_OK; + } + } + if ((len == 0) || ((len > 2) && (optionName[1] == 'e') && (strncmp(optionName, "-eofchar", len) == 0))) { *************** *** 5269,5274 **** --- 5338,5378 ---- if ((chanPtr->bufSize < 10) || (chanPtr->bufSize > (1024 * 1024))) { chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; } + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + * Location: Tcl_SetChannelOption. + */ + + } else if ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0)) { + int nv_len = strlen (newValue); + + if ((nv_len > 0) && + (strncmp (newValue, "smallendian", nv_len) == 0)) { + chanPtr->flags |= CHANNEL_IS_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "littleendian", nv_len) == 0)) { + chanPtr->flags |= CHANNEL_IS_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "network", nv_len) == 0)) { + chanPtr->flags &= ~CHANNEL_IS_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "bigendian", nv_len) == 0)) { + chanPtr->flags &= ~CHANNEL_IS_SMALLENDIAN; + return TCL_OK; + } + + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, + "bad value for -byteorder: ", + "must be one of smallendian, littleendian, bigendian or network", + (char *) NULL); + } + return TCL_ERROR; } else if ((len > 2) && (optionName[1] == 'e') && (strncmp(optionName, "-encoding", len) == 0)) { Tcl_Encoding encoding; trf2.1.4/patches/v8.1b1/tclIO.c0000644000175000017500000073427711216344361015323 0ustar sergeisergei/* * 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.3 1999/04/18 13:27:07 aku 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. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) # define EWOULDBLOCK EAGAIN #endif #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) error one of EWOULDBLOCK or EAGAIN must be defined #endif /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this * structure. */ typedef struct CopyState { struct Channel *readPtr; /* Pointer to input channel. */ struct Channel *writePtr; /* Pointer to output channel. */ int readFlags; /* Original read channel flags. */ int writeFlags; /* Original write channel flags. */ int toRead; /* Number of bytes to copy, or -1. */ int total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ 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) /* * Structure to record a close callback. One such record exists for * each close callback registered for a channel. */ typedef struct CloseCallback { Tcl_CloseProc *proc; /* The procedure to call. */ ClientData clientData; /* Arbitrary one-word data to pass * to the callback. */ struct CloseCallback *nextPtr; /* For chaining close callbacks. */ } CloseCallback; /* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to * invoke the saved script in the interpreter designed in this record. */ 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; /* * struct Channel: * * One of these structures is allocated for each open channel. It contains data * specific to the channel but which belongs to the generic part of the Tcl * channel mechanism, and it points at an instance specific (and type * specific) * instance data, and at a channel type structure. */ 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. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ struct ChannelHandler *chPtr;/* List of channel handlers registered * for this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ struct Channel *nextChanPtr;/* Next in list of channels currently open. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for * event handlers ("fileevent") on this * channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * The single change to the internal datastructures of the core. Every * channel now maintains a reference to the channel he is stacked upon. * This reference is NULL for normal channels. Only the two exported * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the * end of 'tcl.h') use this field in a non-trivial way. * * Of the existing procedures the only following are affected by this * change: * * - Tcl_RegisterChannel * - Tcl_CreateChannel * - CloseChannel * * The why is explained at the changed locations. */ struct Channel* supercedes; /* Refers to channel this one was stacked upon */ } Channel; /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in * nonblocking mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the * curOutPtr field in the * channel structure) should be * output as soon as possible even * though it may not be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the * queued output buffers has been * scheduled. */ #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No * further Tcl-level IO on the * channel is allowed. */ #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. * This bit is cleared before every * input operation. */ #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because * we saw the input eofChar. This bit * prevents clearing of the EOF bit * before every input operation. */ #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. */ /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" */ #define CHANNEL_IS_SMALLENDIAN (1<<16) /* Multibyte words are stored with MSB last */ /* * 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. */ typedef struct ChannelHandler { Channel *chanPtr; /* The channel structure for this channel. */ int mask; /* Mask of desired events. */ Tcl_ChannelProc *proc; /* Procedure to call in the type of * Tcl_CreateChannelHandler. */ ClientData clientData; /* Argument to pass to procedure. */ struct ChannelHandler *nextPtr; /* Next one in list of registered handlers. */ } ChannelHandler; /* * This structure keeps track of the current ChannelHandler being invoked in * the current invocation of ChannelHandlerEventProc. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. * The nextPtr field is used to chain together all recursive invocations, so * that Tcl_DeleteChannelHandler can find all the recursively nested * invocations of ChannelHandlerEventProc and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. */ typedef struct NextChannelHandler { 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 * for stdin/stdout/stderr in new interpreters. * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ 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 * closed. * * Results: * None. * * Side effects: * Causes the callback to be called in the future when the channel * will be closed. * *---------------------------------------------------------------------- */ void Tcl_CreateCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to create the * close callback. */ Tcl_CloseProc *proc; /* The callback routine to call when the * channel will be closed. */ ClientData clientData; /* Arbitrary data to pass to the * close callback. */ { Channel *chanPtr; CloseCallback *cbPtr; chanPtr = (Channel *) chan; cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; cbPtr->nextPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr; } /* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * * Removes a callback that would have been called on closing * the channel. If there is no matching callback then this * function has no effect. * * Results: * None. * * Side effects: * The callback will not be called in the future when the channel * is eventually closed. * *---------------------------------------------------------------------- */ void Tcl_DeleteCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to cancel the * close callback. */ Tcl_CloseProc *proc; /* The procedure for the callback to * remove. */ ClientData clientData; /* The callback data for the callback * to remove. */ { Channel *chanPtr; CloseCallback *cbPtr, *cbPrevPtr; chanPtr = (Channel *) chan; for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL; cbPtr != (CloseCallback *) NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == (CloseCallback *) NULL) { chanPtr->closeCbPtr = cbPtr->nextPtr; } ckfree((char *) cbPtr); break; } else { cbPrevPtr = cbPtr; } } } /* *---------------------------------------------------------------------- * * GetChannelTable -- * * Gets and potentially initializes the channel table for an * interpreter. If it is initializing the table it also inserts * channels for stdin, stdout and stderr if the interpreter is * trusted. * * Results: * A pointer to the hash table created, for use by the caller. * * Side effects: * Initializes the channel table for an interpreter. May create * channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */ static Tcl_HashTable * GetChannelTable(interp) Tcl_Interp *interp; { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); (void) Tcl_SetAssocData(interp, "tclIO", (Tcl_InterpDeleteProc *) DeleteChannelTable, (ClientData) hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels * for stdin, stdout and stderr (possibly creating them in the * process). */ if (Tcl_IsSafe(interp) == 0) { stdinChan = Tcl_GetStdChannel(TCL_STDIN); if (stdinChan != NULL) { Tcl_RegisterChannel(interp, stdinChan); } stdoutChan = Tcl_GetStdChannel(TCL_STDOUT); if (stdoutChan != NULL) { Tcl_RegisterChannel(interp, stdoutChan); } stderrChan = Tcl_GetStdChannel(TCL_STDERR); if (stderrChan != NULL) { Tcl_RegisterChannel(interp, stderrChan); } } } return hTblPtr; } /* *---------------------------------------------------------------------- * * DeleteChannelTable -- * * Deletes the channel table for an interpreter, closing any open * channels whose refcount reaches zero. This procedure is invoked * when an interpreter is deleted, via the AssocData cleanup * mechanism. * * Results: * None. * * Side effects: * Deletes the hash table of channels. May close channels. May flush * output on closed channels. Removes any channeEvent handlers that were * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable(clientData, interp) ClientData clientData; /* The per-interpreter data structure. */ Tcl_Interp *interp; /* The interpreter being deleted. */ { Tcl_HashTable *hTblPtr; /* The hash table. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* Channel being deleted. */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* Variables to loop over all channel events * registered, to delete the ones that refer * to the interpreter being deleted. */ /* * Delete all the registered channels - this will close channels whose * refcount reaches zero. */ hTblPtr = (Tcl_HashTable *) clientData; for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); /* * Remove any fileevents registered in this interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } /* * Cannot call Tcl_UnregisterChannel because that procedure calls * Tcl_GetAssocData to get the channel table, which might already * be inaccessible from the interpreter structure. Instead, we * emulate the behavior of Tcl_UnregisterChannel directly here. */ Tcl_DeleteHashEntry(hPtr); chanPtr->refCount--; if (chanPtr->refCount <= 0) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } } Tcl_DeleteHashTable(hTblPtr); ckfree((char *) hTblPtr); } /* *---------------------------------------------------------------------- * * CheckForStdChannelsBeingClosed -- * * Perform special handling for standard channels being closed. When * given a standard channel, if the refcount is now 1, it means that * the last reference to the standard channel is being explicitly * closed. Now bump the refcount artificially down to 0, to ensure the * normal handling of channels being closed will occur. Also reset the * static pointer to the channel to NULL, to avoid dangling references. * * Results: * None. * * Side effects: * Manipulates the refcount on standard channels. May smash the global * static pointer to a standard channel. * *---------------------------------------------------------------------- */ 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; } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_RegisterChannel'. * * Explanation: * The moment a channel is stacked upon another he * takes the identity of the channel he supercedes, * i.e. he gets the *same* name. Because of this we * cannot check for duplicate names anymore, they * have to be allowed now. */ /* 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. * If the interpreter given as argument is NULL, it only decrements the * reference count. * * Results: * A standard Tcl result. * * Side effects: * Deletes the hash entry for a channel associated with an interpreter. * *---------------------------------------------------------------------- */ int Tcl_UnregisterChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which channel is defined. */ Tcl_Channel chan; /* Channel to delete. */ { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The real IO channel. */ chanPtr = (Channel *) chan; if (interp != (Tcl_Interp *) NULL) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } hPtr = Tcl_FindHashEntry(hTblPtr, chanPtr->channelName); if (hPtr == (Tcl_HashEntry *) NULL) { return TCL_OK; } if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) { return TCL_OK; } Tcl_DeleteHashEntry(hPtr); /* * Remove channel handlers that refer to this interpreter, so that they * will not be present if the actual close is delayed and more events * happen on the channel. This may occur if the channel is shared * between several interpreters, or if the channel has async * flushing active. */ CleanupChannelHandlers(interp, chanPtr); } chanPtr->refCount--; /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); /* * If the refCount reached zero, close the actual channel. */ if (chanPtr->refCount <= 0) { /* * Ensure that if there is another buffer, it gets flushed * whether or not we are doing a background flush. */ if ((chanPtr->curOutPtr != NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; } chanPtr->flags |= CHANNEL_CLOSED; if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { if (Tcl_Close(interp, chan) != TCL_OK) { return TCL_ERROR; } } } 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. */ int *modePtr; /* Where to store the mode in which the * channel was opened? Will contain an ORed * combination of TCL_READABLE and * TCL_WRITABLE, if non-NULL. */ { Channel *chanPtr; /* The actual channel. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ char *name; /* Translated name. */ /* * Substitute "stdin", etc. Note that even though we immediately * find the channel using Tcl_GetStdChannel, we still need to look * it up in the specified interpreter to ensure that it is present * in the channel table. Otherwise, safe interpreters would always * have access to the standard channels. */ name = chanName; if ((chanName[0] == 's') && (chanName[1] == 't')) { chanPtr = NULL; if (strcmp(chanName, "stdin") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDIN); } else if (strcmp(chanName, "stdout") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDOUT); } else if (strcmp(chanName, "stderr") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDERR); } if (chanPtr != NULL) { name = chanPtr->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == (Tcl_HashEntry *) NULL) { Tcl_AppendResult(interp, "can not find channel named \"", chanName, "\"", (char *) NULL); return NULL; } chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (modePtr != NULL) { *modePtr = (chanPtr->flags & (TCL_READABLE|TCL_WRITABLE)); } return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_CreateChannel -- * * Creates a new entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Creates a new Tcl_Channel instance and inserts it into the * hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_CreateChannel(typePtr, chanName, instanceData, mask) 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); /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" * Location: Tcl_CreateChannel. */ union { char c[sizeof(short)]; short s; } order; order.s = 1; if (order.c[0] == 1) { mask |= CHANNEL_IS_SMALLENDIAN; } 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. */ chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_CreateChannel'. * * Explanation: * It is of course necessary to initialize the new field * in the Channel structure. The chosen value indicates * that the created channel is a normal one, and not * stacked upon another. */ chanPtr->supercedes = (Channel*) 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; } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * The following two procedures are the new, exported ones. They * - create a channel stacked upon an existing one and * - pop a stacked channel off, thus revealing the superceded one. * * Please read the following completely. */ /* *---------------------------------------------------------------------- * * Tcl_ReplaceChannel -- * * Replaces an entry in the hash table for a Tcl_Channel * record. The replacement is a new channel with same name, * it supercedes the replaced channel. Input and output of * the superceded channel is now going through the newly * created channel and allows the arbitrary filtering/manipulation * of the dataflow. * * Results: * Returns the new Tcl_Channel. * * Side effects: * See above. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_ChannelType *typePtr; /* The channel type record for the new * channel. */ ClientData instanceData; /* Instance specific data for the new * channel. */ int mask; /* TCL_READABLE & TCL_WRITABLE to indicate * if the channel is readable, writable. */ Tcl_Channel prevChan; /* The channel structure to replace */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel *chanPtr, *pt, *prevPt; /* * Find the given channel in the list of all channels, compute enough * information to allow easy removal after the conditions are met. */ prevPt = (Channel*) NULL; pt = (Channel*) tsdPtr->firstChanPtr; while (pt != (Channel *) prevChan) { prevPt = pt; pt = pt->nextChanPtr; } /* * 'pt == prevChan' now */ if (!pt) { return (Tcl_Channel) NULL; } /* * Here we check if the given "mask" matches the "flags" * of the already existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to * W | | | + | + | restrict the capabilities of the * RW| | + | + | + | superceded one ! * --+---+---+---+----+ */ if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { return (Tcl_Channel) NULL; } chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); chanPtr->flags = mask; /* * Set the channel up initially in no Input translation mode and * no Output translation mode. */ chanPtr->inputTranslation = TCL_TRANSLATE_LF; chanPtr->outputTranslation = TCL_TRANSLATE_LF; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* 06/12/1998: New for Tcl 8.1 * * Take over the encoding from the superceded channel, so that it will be * executed in the future despite the replacement, and at the proper time * (*after* / *before* our transformation, depending on the direction of * the dataflow). * * *Important* * The I/O functionality of the filtering channel has to use 'Tcl_Read' to * get at the underlying information. This will circumvent the de/encoder * stage [*] in the superceded channel and removes the need to trouble * ourselves with 'ByteArray's too. * * [*] I'm talking about the conversion between UNICODE and other * representations, like ASCII. */ chanPtr->encoding = pt->encoding; chanPtr->inputEncodingState = pt->inputEncodingState; chanPtr->inputEncodingFlags = pt->inputEncodingFlags; chanPtr->outputEncodingState = pt->outputEncodingState; chanPtr->outputEncodingFlags = pt->outputEncodingFlags; chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) ckalloc((unsigned) (chanPtr->bufSize + 2)); } chanPtr->supercedes = (Channel*) prevChan; chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); strcpy (chanPtr->channelName, pt->channelName); if (prevPt) { prevPt->nextChanPtr = chanPtr; } else { tsdPtr->firstChanPtr = chanPtr; } chanPtr->nextChanPtr = pt->nextChanPtr; Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); /* * The superceded channel is effectively unregistered */ /*chanPtr->supercedes->refCount --;*/ return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_UndoReplaceChannel -- * * Unstacks an entry in the hash table for a Tcl_Channel * record. This is the reverse to 'Tcl_ReplaceChannel'. * The old, superceded channel is uncovered and re-registered * in the appropriate datastructures. * * Results: * Returns the old Tcl_Channel, i.e. the one which was stacked over. * * Side effects: * See above. * *---------------------------------------------------------------------- */ void Tcl_UndoReplaceChannel (interp, chan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_Channel chan; /* The channel to unstack */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel* chanPtr = (Channel*) chan; if (chanPtr->supercedes != (Channel*) NULL) { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ int new; /* Is the hash entry new or does it exist? */ /* * Insert the channel we were stacked upon back into * the list of open channels. Place it back into the hashtable too. * Correct 'refCount', as this actually unregisters 'chan'. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; hTblPtr = GetChannelTable (interp); hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); chanPtr->refCount --; /* * The superceded channel is effectively registered again */ /*chanPtr->supercedes->refCount ++;*/ } /* * Disconnect the channels, then do a regular close upon the * stacked one, the filtering channel. This may cause flushing * of data into the superceded channel (if the filtering channel * ('chan') remembered its parent in itself). */ chanPtr->supercedes = NULL; if (chanPtr->refCount == 0) { Tcl_Close (interp, chan); } } /* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * * Computes a mask indicating whether the channel is open for * reading and writing. * * Results: * An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelMode(chan) Tcl_Channel chan; /* The channel for which the mode is * being computed. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE)); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * * Returns the string identifying the channel name. * * Results: * The string containing the channel name. This memory is * owned by the generic layer and should not be modified by * the caller. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Tcl_GetChannelName(chan) Tcl_Channel chan; /* The channel for which to return the name. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->channelName; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * * Given a channel structure, returns the channel type structure. * * Results: * Returns a pointer to the channel type structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ChannelType * Tcl_GetChannelType(chan) Tcl_Channel chan; /* The channel to return type for. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->typePtr; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * * Returns an OS handle associated with a channel. * * Results: * Returns TCL_OK and places the handle in handlePtr, or returns * TCL_ERROR on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelHandle(chan, direction, handlePtr) Tcl_Channel chan; /* The channel to get file from. */ int direction; /* TCL_WRITABLE or TCL_READABLE. */ ClientData *handlePtr; /* Where to store handle */ { Channel *chanPtr; /* The actual channel. */ ClientData handle; int result; chanPtr = (Channel *) chan; result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData, direction, &handle); if (handlePtr) { *handlePtr = handle; } return result; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * * Returns the client data associated with a channel. * * Results: * The client data. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_GetChannelInstanceData(chan) 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 * that two input buffers are saved (one in the input queue and * another in the saveInBufPtr field) and that curOutPtr is set * to a buffer. Only if these conditions are met is the buffer * freed to the OS. * * Results: * None. * * Side effects: * May free a buffer to the OS. * *---------------------------------------------------------------------- */ static void RecycleBuffer(chanPtr, bufPtr, mustDiscard) Channel *chanPtr; /* Channel for which to recycle buffers. */ ChannelBuffer *bufPtr; /* The buffer to recycle. */ int mustDiscard; /* If nonzero, free the buffer to the * OS, always. */ { /* * Do we have to free the buffer to the OS? */ if (mustDiscard) { ckfree((char *) bufPtr); return; } /* * Only save buffers for the input queue if the channel is readable. */ if (chanPtr->flags & TCL_READABLE) { if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) { chanPtr->inQueueHead = bufPtr; chanPtr->inQueueTail = bufPtr; goto keepit; } if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) { chanPtr->saveInBufPtr = bufPtr; goto keepit; } } /* * Only save buffers for the output queue if the channel is writable. */ if (chanPtr->flags & TCL_WRITABLE) { if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) { chanPtr->curOutPtr = bufPtr; goto keepit; } } /* * 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 -- * * Discards all output queued in the output queue of a channel. * * Results: * None. * * Side effects: * Recycles buffers. * *---------------------------------------------------------------------- */ static void DiscardOutputQueued(chanPtr) Channel *chanPtr; /* The channel for which to discard output. */ { ChannelBuffer *bufPtr; while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { bufPtr = chanPtr->outQueueHead; chanPtr->outQueueHead = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, 0); } chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; } /* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * * This function checks is a given channel is Dead. * (A channel that has been closed but not yet deallocated.) * * Results: * True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: * None * *---------------------------------------------------------------------- */ static int CheckForDeadChannel(interp, chanPtr) Tcl_Interp *interp; /* For error reporting (can be NULL) */ Channel *chanPtr; /* The channel to check. */ { if (chanPtr->flags & CHANNEL_DEAD) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, "unable to access channel: invalid channel", (char *) NULL); } return 1; } return 0; } /* *---------------------------------------------------------------------- * * FlushChannel -- * * This function flushes as much of the queued output as is possible * now. If calledFromAsyncFlush is nonzero, it is being called in an * event handler to flush channel output asynchronously. * * Results: * 0 if successful, else the error code that was returned by the * channel type operation. * * Side effects: * May produce output on a channel. May block indefinitely if the * channel is synchronous. May schedule an async flush on the channel. * May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */ static int FlushChannel(interp, chanPtr, calledFromAsyncFlush) Tcl_Interp *interp; /* For error reporting during close. */ Channel *chanPtr; /* The channel to flush on. */ int calledFromAsyncFlush; /* If nonzero then we are being * called from an asynchronous * flush callback. */ { 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. */ if (CheckForDeadChannel(interp,chanPtr)) return -1; /* * Loop over the queued buffers and attempt to flush as * much as possible of the queued output to the channel. */ while (1) { /* * 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 { chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr; } chanPtr->outQueueTail = chanPtr->curOutPtr; chanPtr->curOutPtr = (ChannelBuffer *) NULL; } bufPtr = chanPtr->outQueueHead; /* * If we are not being called from an async flush and an async * flush is active, we just return without producing any output. */ if ((!calledFromAsyncFlush) && (chanPtr->flags & BG_FLUSH_SCHEDULED)) { return 0; } /* * If the output queue is still empty, break out of the while loop. */ if (bufPtr == (ChannelBuffer *) NULL) { break; /* Out of the "while (1)". */ } /* * 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. */ if (written < 0) { /* * If the last attempt to write was interrupted, simply retry. */ if (errorCode == EINTR) { errorCode = 0; continue; } /* * If the channel is non-blocking and we would have blocked, * start a background flushing handler and break out of the loop. */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { if (chanPtr->flags & CHANNEL_NONBLOCKING) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { chanPtr->flags |= BG_FLUSH_SCHEDULED; UpdateInterest(chanPtr); } errorCode = 0; break; } else { panic("Blocking channel driver did not block on output"); } } /* * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { if (chanPtr->unreportedError == 0) { chanPtr->unreportedError = errorCode; } } else { Tcl_SetErrno(errorCode); if (interp != NULL) { Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } } /* * 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. */ if ((chanPtr->flags & CHANNEL_CLOSED) && (chanPtr->refCount <= 0) && (chanPtr->outQueueHead == (ChannelBuffer *) NULL) && ((chanPtr->curOutPtr == (ChannelBuffer *) NULL) || (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->nextRemoved))) { return CloseChannel(interp, chanPtr, errorCode); } return errorCode; } /* *---------------------------------------------------------------------- * * CloseChannel -- * * Utility procedure to close a channel and free its associated * resources. * * Results: * 0 on success or a POSIX error code if the operation failed. * * Side effects: * May close the actual channel; may free memory. * *---------------------------------------------------------------------- */ static int CloseChannel(interp, chanPtr, errorCode) Tcl_Interp *interp; /* For error reporting. */ Channel *chanPtr; /* The channel to close. */ 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. */ DiscardInputQueued(chanPtr, 1); /* * Discard a leftover buffer in the current output buffer field. */ if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { ckfree((char *) chanPtr->curOutPtr); chanPtr->curOutPtr = (ChannelBuffer *) NULL; } /* * The caller guarantees that there are no more buffers * queued for output. */ if (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { panic("TclFlush, closed channel: queued output left"); } /* * If the EOF character is set in the channel, append that to the * output device. */ if ((chanPtr->outEofChar != 0) && (chanPtr->flags & TCL_WRITABLE)) { int dummy; char c; c = (char) chanPtr->outEofChar; (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy); } /* * Remove TCL_READABLE and TCL_WRITABLE from chanPtr->flags, so * that close callbacks can not do input or output (assuming they * squirreled the channel away in their clientData). This also * prevents infinite loops if the callback calls any C API that * could call FlushChannel. */ 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. */ if (chanPtr->unreportedError != 0) { errorCode = chanPtr->unreportedError; } if (errorCode == 0) { errorCode = result; if (errorCode != 0) { Tcl_SetErrno(errorCode); } } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'CloseChannel'. * * Explanation * Closing a filtering channel closes the one it * superceded too. This basically ripples through * the whole chain of filters until it reaches * the underlying normal channel. * * This is done by reintegrating the superceded * channel into the (thread) global list of open * channels and then invoking a regular close. * There is no need to handle the complexities of * this process by ourselves. * * *Note* * This has to be done after the call to the * 'closeProc' of the filtering channel to allow * that one the flushing of internal buffers into * the underlying channel. */ if (chanPtr->supercedes != (Channel*) NULL) { /* Insert the channel we were stacked upon back into * the list of open channels, then do a regular close. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; chanPtr->supercedes->refCount --; /* is deregistered */ Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* * Cancel any outstanding timer. */ Tcl_DeleteTimerHandler(chanPtr->timer); /* * Mark the channel as deleted by clearing the type structure. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC); return errorCode; } /* *---------------------------------------------------------------------- * * Tcl_Close -- * * Closes a channel. * * Results: * A standard Tcl result. * * Side effects: * Closes the channel if this is the last reference. * * NOTE: * Tcl_Close removes the channel as far as the user is concerned. * However, it may continue to exist for a while longer if it has * a background flush scheduled. The device itself is eventually * closed and the channel record removed, in CloseChannel, above. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_Close(interp, chan) Tcl_Interp *interp; /* Interpreter for errors. */ Tcl_Channel chan; /* The channel being closed. Must * not be referenced in any * interpreter. */ { 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; } /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); chanPtr = (Channel *) chan; if (chanPtr->refCount > 0) { panic("called Tcl_Close on channel with refCount > 0"); } /* * 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; } } /* * Remove all the channel handler records attached to the channel * itself. */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chNext) { chNext = chPtr->nextPtr; ckfree((char *) chPtr); } chanPtr->chPtr = (ChannelHandler *) NULL; /* * Cancel any pending copy operation. */ StopCopy(chanPtr->csPtr); /* * Must set the interest mask now to 0, otherwise infinite loops * will occur if Tcl_DoOneEvent is called before the channel is * finally deleted in FlushChannel. This can happen if the channel * has a background flush active. */ chanPtr->interestMask = 0; /* * 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. */ while (chanPtr->closeCbPtr != (CloseCallback *) NULL) { cbPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr->nextPtr; (cbPtr->proc) (cbPtr->clientData); ckfree((char *) cbPtr); } /* * 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 -- * * Flushes output data on a channel. * * Results: * A standard Tcl result. * * Side effects: * May flush output queued on this channel. * *---------------------------------------------------------------------- */ int 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; } return TCL_OK; } /* *---------------------------------------------------------------------- * * DiscardInputQueued -- * * Discards any input read from the channel but not yet consumed * by Tcl reading commands. * * Results: * None. * * Side effects: * May discard input from the channel. If discardLastBuffer is zero, * leaves one buffer in place for back-filling. * *---------------------------------------------------------------------- */ static void DiscardInputQueued(chanPtr, discardSavedBuffers) Channel *chanPtr; /* Channel on which to discard * the queued input. */ int discardSavedBuffers; /* If non-zero, discard all buffers including * last one. */ { ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ bufPtr = chanPtr->inQueueHead; chanPtr->inQueueHead = (ChannelBuffer *) NULL; chanPtr->inQueueTail = (ChannelBuffer *) NULL; for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) { nxtPtr = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, discardSavedBuffers); } /* * If discardSavedBuffers is nonzero, must also discard any previously * saved buffer in the saveInBufPtr field. */ if (discardSavedBuffers) { if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) { 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 -- * * Implements seeking on Tcl Channels. This is a public function * so that other C facilities may be implemented on top of it. * * Results: * The new access point or -1 on error. If error, use Tcl_GetErrno() * to retrieve the POSIX error code for the error that occurred. * * Side effects: * May flush output on the channel. May discard queued input. * *---------------------------------------------------------------------- */ int Tcl_Seek(chan, offset, mode) Tcl_Channel chan; /* The channel on which to seek. */ int offset; /* Offset to seek to. */ int mode; /* Relative to which location to seek? */ { Channel *chanPtr; /* The real IO channel. */ ChannelBuffer *bufPtr; int inputBuffered, outputBuffered; 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 * registered in an interpreter. */ if (CheckForDeadChannel(NULL,chanPtr)) return -1; /* * Disallow seek on channels whose type does not have a seek procedure * defined. This means that the channel does not support seeking. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * If we are seeking relative to the current position, compute the * corrected offset taking into account the amount of unread input. */ if (mode == SEEK_CUR) { offset -= inputBuffered; } /* * Discard any queued input - this input should not be read after * the seek. */ DiscardInputQueued(chanPtr, 0); /* * Reset EOF and BLOCKED flags. We invalidate them by moving the * access point. Also clear CR related flags. */ chanPtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR)); /* * If the channel is in asynchronous output mode, switch it back * to synchronous mode and cancel any async flush that may be * scheduled. After the flush, the channel will be put back into * asynchronous output mode. */ wasAsync = 0; if (chanPtr->flags & CHANNEL_NONBLOCKING) { wasAsync = 1; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_BLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } chanPtr->flags &= (~(CHANNEL_NONBLOCKING)); if (chanPtr->flags & BG_FLUSH_SCHEDULED) { chanPtr->flags &= (~(BG_FLUSH_SCHEDULED)); } } /* * If the flush fails we cannot recover the original position. In * that case the seek is not attempted because we do not know where * the access position is - instead we return the error. FlushChannel * has already called Tcl_SetErrno() to report the error upwards. * If the flush succeeds we do the seek also. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { curPos = -1; } else { /* * Now seek to the new position in the channel as requested by the * caller. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) offset, mode, &result); if (curPos == -1) { Tcl_SetErrno(result); } } /* * Restore to nonblocking mode if that was the previous behavior. * * NOTE: Even if there was an async flush active we do not restore * it now because we already flushed all the queued output, above. */ if (wasAsync) { chanPtr->flags |= CHANNEL_NONBLOCKING; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_NONBLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } } return curPos; } /* *---------------------------------------------------------------------- * * Tcl_Tell -- * * Returns the position of the next character to be read/written on * this channel. * * Results: * A nonnegative integer on success, -1 on failure. If failed, * use Tcl_GetErrno() to retrieve the POSIX error code for the * error that occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Tell(chan) Tcl_Channel chan; /* The channel to return pos for. */ { 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. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * Get the current position in the device and compute the position * where the next character will be read or written. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) 0, SEEK_CUR, &result); if (curPos == -1) { Tcl_SetErrno(result); 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. * * Results: * 1 or 0, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Eof(chan) Tcl_Channel chan; /* Does this channel have EOF? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_STICKY_EOF) || ((chanPtr->flags & CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * * Results: * 0 or 1, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBlocked(chan) Tcl_Channel chan; /* Is this channel blocked? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return (chanPtr->flags & CHANNEL_BLOCKED) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBuffered -- * * Returns the number of bytes of input currently buffered in the * internal buffer of a channel. * * Results: * The number of input bytes buffered, or zero if the channel is not * open for reading. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBuffered(chan) Tcl_Channel chan; /* The channel to query. */ { Channel *chanPtr; int bytesBuffered; ChannelBuffer *bufPtr; chanPtr = (Channel *) chan; for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } return bytesBuffered; } /* *---------------------------------------------------------------------- * * Tcl_SetChannelBufferSize -- * * Sets the size of buffers to allocate to store input or output * in the channel. The size must be between 10 bytes and 1 MByte. * * Results: * None. * * Side effects: * Sets the size of buffers subsequently allocated for this channel. * *---------------------------------------------------------------------- */ void Tcl_SetChannelBufferSize(chan, sz) Tcl_Channel chan; /* The channel whose buffer size * to set. */ int sz; /* The size to set. */ { Channel *chanPtr; /* * If the buffer size is smaller than 10 bytes or larger than one MByte, * do not accept the requested size and leave the current buffer size. */ if (sz < 10) { return; } 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 -- * * Retrieves the size of buffers to allocate for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelBufferSize(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->bufSize; } /* *---------------------------------------------------------------------- * * Tcl_BadChannelOption -- * * This procedure generates a "bad option" error message in an * (optional) interpreter. It is used by channel drivers when * a invalid Set/Get option is requested. Its purpose is to concatenate * the generic options list to the specific ones and factorize * the generic options error message string. * * Results: * TCL_ERROR. * * Side effects: * An error message is generated in interp's result object to * indicate that a command was invoked with the a bad option * The message has the form * bad option "blah": should be one of * <...generic options...>+<...specific options...> * "blah" is the optionName argument and "" * is a space separated list of specific option words. * The function takes good care of inserting minus signs before * each option, commas after, and an "or" before the last option. * *---------------------------------------------------------------------- */ int Tcl_BadChannelOption(interp, optionName, optionList) Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/ char *optionName; /* 'bad option' name */ char *optionList; /* Specific options list to append * to the standard generic options. * can be NULL for generic options * only. */ { if (interp) { CONST char *genericopt = "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, (char *) genericopt, -1); if (optionList && (*optionList)) { Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad option \"", optionName, "\": should be one of ", (char *) NULL); argc--; for (i = 0; i < argc; i++) { Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL); } Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL); Tcl_DStringFree(&ds); ckfree((char *) argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" * Exported functionality. */ /* *---------------------------------------------------------------------- * * Tcl_GetChannelByteorder -- * * Retrieves the byteorder set for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelByteorder(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_IS_SMALLENDIAN) != 0); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelOption -- * * 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: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelOption(interp, chan, optionName, dsPtr) Tcl_Interp *interp; /* For error reporting - can be NULL. */ Tcl_Channel chan; /* Channel on which to get option. */ char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */ { size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; int flags; /* * If we are in the middle of a background copy, use the saved flags. */ if (chanPtr->csPtr) { if (chanPtr == chanPtr->csPtr->readPtr) { flags = chanPtr->csPtr->readFlags; } else { flags = chanPtr->csPtr->writeFlags; } } else { flags = chanPtr->flags; } /* * Disallow options 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(interp,chanPtr)) return TCL_ERROR; /* * If the optionName is NULL it means that we want a list of all * options and values. */ if (optionName == (char *) NULL) { len = 0; } else { len = strlen(optionName); } if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blocking"); } Tcl_DStringAppendElement(dsPtr, (flags & CHANNEL_NONBLOCKING) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffering", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffering"); } if (flags & CHANNEL_LINEBUFFERED) { Tcl_DStringAppendElement(dsPtr, "line"); } else if (flags & CHANNEL_UNBUFFERED) { Tcl_DStringAppendElement(dsPtr, "none"); } else { Tcl_DStringAppendElement(dsPtr, "full"); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffersize", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffersize"); } 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; } } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" * Location: Tcl_GetChannelOption */ if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-byteorder"); } Tcl_DStringAppendElement(dsPtr, (chanPtr->flags & CHANNEL_IS_SMALLENDIAN) ? "smallendian" : "bigendian"); 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); } if (flags & TCL_READABLE) { if (chanPtr->inEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->inEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (flags & TCL_WRITABLE) { if (chanPtr->outEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->outEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 1) && (optionName[1] == 't') && (strncmp(optionName, "-translation", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-translation"); } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringStartSublist(dsPtr); } if (flags & TCL_READABLE) { if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (flags & TCL_WRITABLE) { if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) { /* * let the driver specific handle additional options * and result code and message. */ return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData, interp, optionName, dsPtr); } else { /* * no driver specific options case. */ if (len == 0) { 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? */ char *newValue; /* New value for option. */ { int newMode; /* New (numeric) mode to sert. */ Channel *chanPtr; /* The real IO channel. */ size_t len; /* Length of optionName string. */ int argc; char **argv; chanPtr = (Channel *) chan; /* * If the channel is in the middle of a background copy, fail. */ if (chanPtr->csPtr) { if (interp) { Tcl_AppendResult(interp, "unable to set channel options: background copy in progress", (char *) NULL); } return TCL_ERROR; } /* * Disallow options 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 TCL_ERROR; len = strlen(optionName); if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0)) { if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) { return TCL_ERROR; } 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)) { chanPtr->flags &= (~(CHANNEL_UNBUFFERED)); chanPtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { chanPtr->flags &= (~(CHANNEL_LINEBUFFERED)); chanPtr->flags |= CHANNEL_UNBUFFERED; } else { 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; } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" * Location: Tcl_SetChannelOption. */ } else if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0)) { int nv_len = strlen (newValue); if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { chanPtr->flags |= CHANNEL_IS_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { chanPtr->flags |= CHANNEL_IS_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { chanPtr->flags &= ~CHANNEL_IS_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { chanPtr->flags &= ~CHANNEL_IS_SMALLENDIAN; return TCL_OK; } if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "bad value for -byteorder: ", "must be one of smallendian, littleendian, bigendian or network", (char *) NULL); } return TCL_ERROR; } 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; } else if (argc == 1) { if (chanPtr->flags & TCL_WRITABLE) { chanPtr->outEofChar = (int) argv[0][0]; } if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } } else if (argc != 2) { if (interp) { Tcl_AppendResult(interp, "bad value for -eofchar: should be a list of one or", " two elements", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } else { if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } 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; } if (argc == 1) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: must be a one or two", " element list", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } 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) { newMode = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered * 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) { /* * This is a hack to get TCP sockets to produce output * in CRLF mode if they are being set into AUTO mode. * A better solution for achieving this effect will be * coded later. */ if (strcmp(chanPtr->typePtr->typeName, "tcp") == 0) { 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) { chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } 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 -- * * Removes channel handlers that refer to the supplied interpreter, * so that if the actual channel is not closed now, these handlers * will not run on subsequent events on the channel. This would be * erroneous, because the interpreter no longer has a reference to * this channel. * * Results: * None. * * Side effects: * Removes channel handlers. * *---------------------------------------------------------------------- */ static void CleanupChannelHandlers(interp, chanPtr) Tcl_Interp *interp; Channel *chanPtr; { EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* * Remove fileevent records on this channel that refer to the * given interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } } /* *---------------------------------------------------------------------- * * Tcl_NotifyChannel -- * * This procedure is called by a channel driver when a driver * detects an event on a channel. This procedure is responsible * for actually handling the event by invoking any channel * handler callbacks. * * Results: * None. * * Side effects: * Whatever the channel handler callback procedure does. * *---------------------------------------------------------------------- */ void Tcl_NotifyChannel(channel, mask) 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. */ if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; (*(chPtr->proc))(chPtr->clientData, mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; } } /* * 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 -- * * Arrange for the notifier to call us back at appropriate times * based on the current state of the channel. * * Results: * None. * * Side effects: * May schedule a timer or driver handler. * *---------------------------------------------------------------------- */ static void UpdateInterest(chanPtr) Channel *chanPtr; /* Channel to update. */ { int mask = chanPtr->interestMask; /* * If there are flushed buffers waiting to be written, then * we need to watch for the channel to become writable. */ 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); } } } (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask); } /* *---------------------------------------------------------------------- * * ChannelTimerProc -- * * Timer handler scheduled by UpdateInterest to monitor the * channel buffers until they are empty. * * Results: * None. * * Side effects: * May invoke channel handlers. * *---------------------------------------------------------------------- */ 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. */ chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc, (ClientData) chanPtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); } else { chanPtr->timer = NULL; UpdateInterest(chanPtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * * Arrange for a given procedure to be invoked whenever the * channel indicated by the chanPtr arg becomes readable or * writable. * * Results: * None. * * Side effects: * From now on, whenever the I/O channel given by chanPtr becomes * ready in the way indicated by mask, proc will be invoked. * See the manual entry for details on the calling sequence * to proc. If there is already an event handler for chan, proc * and clientData, then the mask will be updated. * *---------------------------------------------------------------------- */ void Tcl_CreateChannelHandler(chan, mask, proc, clientData) Tcl_Channel chan; /* The channel to create the handler for. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions under which * proc should be called. Use 0 to * disable a registered handler. */ Tcl_ChannelProc *proc; /* Procedure to call for each * selected event. */ ClientData clientData; /* Arbitrary data to pass to proc. */ { ChannelHandler *chPtr; Channel *chanPtr; chanPtr = (Channel *) chan; /* * Check whether this channel handler is not already registered. If * it is not, create a new record, else reuse existing record (smash * current values). */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) && (chPtr->clientData == clientData)) { break; } } if (chPtr == (ChannelHandler *) NULL) { chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler)); chPtr->mask = 0; chPtr->proc = proc; chPtr->clientData = clientData; chPtr->chanPtr = chanPtr; chPtr->nextPtr = chanPtr->chPtr; chanPtr->chPtr = chPtr; } /* * The remainder of the initialization below is done regardless of * whether or not this is a new record or a modification of an old * one. */ chPtr->mask = mask; /* * Recompute the interest mask for the channel - this call may actually * be disabling an existing handler. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * Tcl_DeleteChannelHandler -- * * Cancel a previously arranged callback arrangement for an IO * channel. * * Results: * None. * * Side effects: * If a callback was previously registered for this chan, proc and * clientData , it is removed and the callback will no longer be called * when the channel becomes ready for IO. * *---------------------------------------------------------------------- */ void Tcl_DeleteChannelHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to remove the * callback. */ 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. */ for (prevChPtr = (ChannelHandler *) NULL, chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData) && (chPtr->proc == proc)) { break; } prevChPtr = chPtr; } /* * If not found, return without doing anything. */ if (chPtr == (ChannelHandler *) NULL) { return; } /* * 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_DeleteChanelHandler is called inside an event. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * DeleteScriptRecord -- * * Delete a script record for this combination of channel, interp * and mask. * * Results: * None. * * Side effects: * Deletes a script record and cancels a channel event handler. * *---------------------------------------------------------------------- */ static void DeleteScriptRecord(interp, chanPtr, mask) Tcl_Interp *interp; /* Interpreter in which script was to be * executed. */ Channel *chanPtr; /* The channel for which to delete the * script record (if any). */ int mask; /* Events in mask must exactly match mask * of script to delete. */ { EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = chanPtr->scriptRecordPtr, prevEsPtr = (EventScriptRecord *) NULL; esPtr != (EventScriptRecord *) NULL; prevEsPtr = esPtr, esPtr = esPtr->nextPtr) { if ((esPtr->interp == interp) && (esPtr->mask == mask)) { if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { prevEsPtr->nextPtr = esPtr->nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) esPtr); Tcl_DecrRefCount(esPtr->scriptPtr); ckfree((char *) esPtr); break; } } } /* *---------------------------------------------------------------------- * * CreateScriptRecord -- * * Creates a record to store a script to be executed when a specific * event fires on a specific channel. * * Results: * None. * * 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 -- * * Invokes a script scheduled by "fileevent" for when the channel * becomes ready for IO. This function is invoked by the channel * handler which was created by the Tcl "fileevent" command. * * Results: * None. * * Side effects: * Whatever the script does. * *---------------------------------------------------------------------- */ static void 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_EvalObj(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. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundError(interp); } 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; } /* *---------------------------------------------------------------------- * * TclTestChannelCmd -- * * Implements the Tcl "testchannel" debugging command and its * subcommands. This is part of the testing environment but must be * in this file instead of tclTest.c because it needs access to the * fields of struct Channel. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int TclTestChannelCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Interpreter for result. */ int argc; /* Count of additional args. */ char **argv; /* Additional arg strings. */ { char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ 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]); Tcl_AppendElement(interp, chanPtr->typePtr->typeName); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_NONBLOCKING) { Tcl_AppendElement(interp, "nonblocking"); } else { Tcl_AppendElement(interp, "blocking"); } if (chanPtr->flags & CHANNEL_LINEBUFFERED) { Tcl_AppendElement(interp, "line"); } else if (chanPtr->flags & CHANNEL_UNBUFFERED) { Tcl_AppendElement(interp, "none"); } else { Tcl_AppendElement(interp, "full"); } if (chanPtr->flags & BG_FLUSH_SCHEDULED) { Tcl_AppendElement(interp, "async_flush"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_EOF) { Tcl_AppendElement(interp, "eof"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_BLOCKED) { Tcl_AppendElement(interp, "blocked"); } else { Tcl_AppendElement(interp, "unblocked"); } if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "saw_cr"); } else { Tcl_AppendElement(interp, ""); } } else if (chanPtr->inputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "queued_cr"); } else { Tcl_AppendElement(interp, ""); } } if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); } for (IOQueued = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved; } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved; } for (bufPtr = chanPtr->outQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved); } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr)); Tcl_AppendElement(interp, buf); TclFormatInt(buf, chanPtr->refCount); Tcl_AppendElement(interp, buf); return TCL_OK; } if ((cmdName[0] == 'i') && (strncmp(cmdName, "inputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; } if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } return TCL_OK; } if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "outputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - 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) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (chanPtr->flags & INPUT_SAW_CR) ? "1" : "0", (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } 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", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ", "info, open, readable, or writable", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclTestChannelEventCmd -- * * This procedure implements the "testchannelevent" command. It is * used to test the Tcl channel event mechanism. It is present in * this file instead of tclTest.c because it needs access to the * internal structure of the channel. * * Results: * A standard Tcl result. * * Side effects: * Creates, deletes and returns channel event handlers. * *---------------------------------------------------------------------- */ /* ARGSUSED */ 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], " channelName cmd ?arg1? ?arg2?\"", (char *) NULL); return TCL_ERROR; } chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL); if (chanPtr == (Channel *) NULL) { return TCL_ERROR; } cmd = argv[2]; len = strlen(cmd); if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName add eventSpec script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[3], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[3], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[3], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr = (EventScriptRecord *) ckalloc((unsigned) 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; } if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) { if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { for (prevEsPtr = chanPtr->scriptRecordPtr; (prevEsPtr != (EventScriptRecord *) NULL) && (prevEsPtr->nextPtr != esPtr); prevEsPtr = prevEsPtr->nextPtr) { /* Empty loop body. */ } 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)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index event\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[4], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[4], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[4], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[4], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr->mask = mask; 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 -- * * This routine copies data from one channel to another, either * synchronously or asynchronously. If a command script is * supplied, the operation runs in the background. The script * is invoked when the copy completes. Otherwise the function * waits until the copy is completed before returning. * * Results: * A standard Tcl result. * * Side effects: * May schedule a background copy operation that causes both * channels to be marked busy. * *---------------------------------------------------------------------- */ int TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Channel inChan; /* Channel to read from. */ Tcl_Channel outChan; /* Channel to write to. */ int toRead; /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */ { Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; if (inPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); return TCL_ERROR; } if (outPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); return TCL_ERROR; } readFlags = inPtr->flags; writeFlags = outPtr->flags; /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. * If there is an error, restore the old blocking mode. */ if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(interp, inPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) { return TCL_ERROR; } } if (inPtr != outPtr) { if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(NULL, outPtr, nonBlocking ? TCL_MODE_BLOCKING : TCL_MODE_NONBLOCKING) != TCL_OK) { if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING) ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); return TCL_ERROR; } } } } /* * Make sure the output side is unbuffered. */ outPtr->flags = (outPtr->flags & ~(CHANNEL_LINEBUFFERED)) | CHANNEL_UNBUFFERED; /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inPtr->bufSize); csPtr->bufSize = inPtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; inPtr->csPtr = csPtr; outPtr->csPtr = csPtr; /* * Start copying data between the channels. */ return CopyData(csPtr, 0); } /* *---------------------------------------------------------------------- * * CopyData -- * * This function implements the lowest level of the copying * mechanism for TclCopyChannel. * * Results: * Returns TCL_OK on success, else TCL_ERROR. * * Side effects: * Moves data between channels, may create channel handlers. * *---------------------------------------------------------------------- */ static int CopyData(csPtr, mask) CopyState *csPtr; /* State of copy operation. */ int mask; /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL; Tcl_Channel inChan, outChan; int result = TCL_OK; int size; int total; inChan = (Tcl_Channel)csPtr->readPtr; outChan = (Tcl_Channel)csPtr->writePtr; interp = csPtr->interp; cmdPtr = csPtr->cmdPtr; /* * Copy the data the slow way, using the translation mechanism. */ while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ if (csPtr->readPtr->unreportedError != 0) { Tcl_SetErrno(csPtr->readPtr->unreportedError); csPtr->readPtr->unreportedError = 0; goto readError; } if (csPtr->writePtr->unreportedError != 0) { Tcl_SetErrno(csPtr->writePtr->unreportedError); csPtr->writePtr->unreportedError = 0; goto writeError; } /* * Read up to bufSize bytes. */ if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { size = csPtr->bufSize; } else { size = csPtr->toRead; } size = DoRead(csPtr->readPtr, csPtr->buffer, size); if (size < 0) { readError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error reading \"", Tcl_GetChannelName(inChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } else if (size == 0) { /* * We had an underflow on the read side. If we are at EOF, * then the copying is done, otherwise set up a channel * handler to detect when the channel becomes readable again. */ if (Tcl_Eof(inChan)) { break; } else if (!(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Now write the buffer out. */ size = DoWrite(csPtr->writePtr, csPtr->buffer, size); if (size < 0) { writeError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error writing \"", Tcl_GetChannelName(outChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } /* * Check to see if the write is happening in the background. If so, * stop copying and wait for the channel to become writable again. */ if (csPtr->writePtr->flags & BG_FLUSH_SCHEDULED) { if (!(mask & TCL_WRITABLE)) { if (mask & TCL_READABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Update the current byte count if we care. */ if (csPtr->toRead != -1) { csPtr->toRead -= size; } csPtr->total += size; /* * For background copies, we only do one buffer per invocation so * we don't starve the rest of the system. */ if (cmdPtr) { /* * The first time we enter this code, there won't be a * channel handler established yet, so do it here. */ if (mask == 0) { Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } } /* * Make the callback or return the number of bytes transferred. * The local total is used because StopCopy frees csPtr. */ total = csPtr->total; if (cmdPtr) { /* * Get a private copy of the command so we can mutate it * by adding arguments. Note that StopCopy frees our saved * reference to the original command obj. */ cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); StopCopy(csPtr); Tcl_Preserve((ClientData) interp); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(total)); if (errObj) { Tcl_ListObjAppendElement(interp, cmdPtr, errObj); } if (Tcl_EvalObj(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 * the background copy operation. It is just a trivial wrapper * around the CopyData routine. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void CopyEventProc(clientData, mask) ClientData clientData; int mask; { (void) CopyData((CopyState *)clientData, mask); } /* *---------------------------------------------------------------------- * * StopCopy -- * * This routine halts a copy that is in progress. * * Results: * None. * * Side effects: * Removes any pending channel handlers and restores the blocking * and buffering modes of the channels. The CopyState is freed. * *---------------------------------------------------------------------- */ static void StopCopy(csPtr) CopyState *csPtr; /* State for bg copy to stop . */ { int nonBlocking; if (!csPtr) { return; } /* * Restore the old blocking mode and output buffering mode. */ nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING); if (nonBlocking != (csPtr->readPtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->readPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } if (csPtr->writePtr != csPtr->writePtr) { if (nonBlocking != (csPtr->writePtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->writePtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } } csPtr->writePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); csPtr->writePtr->flags |= csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc, (ClientData)csPtr); if (csPtr->readPtr != csPtr->writePtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr, CopyEventProc, (ClientData)csPtr); } 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; } trf2.1.4/patches/v8.1b1/tcl.h0000644000175000017500000022110311216344361015053 0ustar sergeisergei/* * 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 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 1998/12/23 21:16:57 aku Exp $ */ #ifndef _TCL #define _TCL /* * When version numbers change here, must also go into the following files * and update the version numbers: * * README * 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) * README * mac/README * win/README * win/README.binary * unix/README * * 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 1 #define TCL_RELEASE_LEVEL 1 #define TCL_RELEASE_SERIAL 1 #define TCL_VERSION "8.1" #define TCL_PATCH_LEVEL "8.1b1" /* * The following definitions set up the proper options for Windows * compilers. We use this method because there is no autoconf equivalent. */ #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) # define __WIN32__ # endif #endif #ifdef __WIN32__ # ifndef STRICT # define STRICT # endif # ifndef USE_PROTOTYPE # define USE_PROTOTYPE 1 # 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 #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 /* * 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. */ #ifndef RESOURCE_INCLUDED #ifndef BUFSIZ #include #endif /* * Definitions that allow Tcl functions with variable numbers of * arguments to be used with either varargs.h or stdarg.h. TCL_VARARGS * is used in procedure prototypes. TCL_VARARGS_DEF is used to declare * 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 /* * 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. * The support follows the convention 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. See BUILD_tcl in this * file for an example of how the macro is to be used. */ #ifdef __WIN32__ # ifdef STATIC_BUILD # define DLLIMPORT # define DLLEXPORT # else # ifdef _MSC_VER # define DLLIMPORT __declspec(dllimport) # define DLLEXPORT __declspec(dllexport) # else # define DLLIMPORT # define DLLEXPORT # endif # endif #else # define DLLIMPORT # define DLLEXPORT #endif #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_tcl # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #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. */ #ifndef __WIN32__ #ifndef VOID # ifdef __STDC__ # define VOID void # else # define VOID char # endif #endif #else /* __WIN32__ */ /* * The following code is copied from winnt.h */ #ifndef VOID #define VOID void typedef char CHAR; typedef short SHORT; typedef long LONG; #endif #endif /* __WIN32__ */ /* * Miscellaneous declarations. */ #ifndef NULL #define NULL 0 #endif #ifndef _CLIENTDATA # if defined(__STDC__) || defined(__cplusplus) typedef void *ClientData; # else typedef int *ClientData; # endif /* __STDC__ */ #define _CLIENTDATA #endif /* * Data structures defined opaquely in this module. The definitions below * just provide dummy types. A few fields are made visible in Tcl_Interp * structures, namely those used for returning a string result from * commands. Direct access to the result field is discouraged in Tcl 8.0. * The interpreter result is either an object or a string, and the two * values are kept consistent unless some C code sets interp->result * directly. Programmers should use either the procedure Tcl_GetObjResult() * or Tcl_GetStringResult() to read the interpreter's result. See the * SetResult man page for details. * * Note: any change to the Tcl_Interp definition below must be mirrored * in the "real" definition in tclInt.h. * * Note: Tcl_ObjCmdProc procedures do not directly set result and freeProc. * Instead, they set a Tcl_Obj member in the "real" structure that can be * accessed with Tcl_GetObjResult() and Tcl_SetObjResult(). */ typedef struct Tcl_Interp { char *result; /* If the last command returned a string * result, this points to it. */ void (*freeProc) _ANSI_ARGS_((char *blockPtr)); /* Zero means the string result is * statically allocated. TCL_DYNAMIC means * it was allocated with ckalloc and should * be freed with ckfree. Other values give * the address of procedure to invoke to * free the result. Tcl_Eval must free it * before executing next command. */ int errorLine; /* When TCL_ERROR is returned, this gives * 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 * procedures Tcl_GetObjResult() or Tcl_GetStringResult() to read the * interpreter's result. See the SetResult man page for details. Besides * this result, the command procedure returns an integer code, which is * one of the following: * * TCL_OK Command completed normally; the interpreter's * result contains the command's result. * TCL_ERROR The command couldn't be completed successfully; * the interpreter's result describes what went wrong. * TCL_RETURN The command requests that the current procedure * return; the interpreter's result contains the * procedure's return value. * TCL_BREAK The command requests that the innermost loop * be exited; the interpreter's result is meaningless. * TCL_CONTINUE Go on to the next iteration of the current loop; * the interpreter's result is meaningless. */ #define TCL_OK 0 #define TCL_ERROR 1 #define TCL_RETURN 2 #define TCL_BREAK 3 #define TCL_CONTINUE 4 #define TCL_RESULT_SIZE 200 /* * Argument descriptors for math function callbacks in expressions: */ typedef enum {TCL_INT, TCL_DOUBLE, TCL_EITHER} Tcl_ValueType; typedef struct Tcl_Value { Tcl_ValueType type; /* Indicates intValue or doubleValue is * valid, or both. */ long intValue; /* Integer value. */ double doubleValue; /* Double-precision floating value. */ } Tcl_Value; /* * Forward declaration of Tcl_Obj to prevent an error when the forward * reference to Tcl_Obj is encountered in the procedure types declared * below. */ struct Tcl_Obj; /* * Procedure types defined by Tcl: */ typedef int (Tcl_AppInitProc) _ANSI_ARGS_((Tcl_Interp *interp)); typedef int (Tcl_AsyncProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int code)); typedef void (Tcl_ChannelProc) _ANSI_ARGS_((ClientData clientData, int mask)); typedef void (Tcl_CloseProc) _ANSI_ARGS_((ClientData data)); typedef void (Tcl_CmdDeleteProc) _ANSI_ARGS_((ClientData clientData)); 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_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, Tcl_Interp *interp, char *part1, char *part2, int flags)); /* * The following structure represents a type of object, which is a * particular internal representation for an object plus a set of * procedures that provide standard operations on objects of that type. */ typedef struct Tcl_ObjType { char *name; /* Name of the type, e.g. "int". */ Tcl_FreeInternalRepProc *freeIntRepProc; /* Called to free any storage for the type's * internal rep. NULL if the internal rep * does not need freeing. */ Tcl_DupInternalRepProc *dupIntRepProc; /* Called to create a new object as a copy * of an existing object. */ Tcl_UpdateStringProc *updateStringProc; /* Called to update the string rep from the * type's internal representation. */ Tcl_SetFromAnyProc *setFromAnyProc; /* Called to convert the object's internal * rep to this type. Frees the internal rep * of the old type. Returns TCL_ERROR on * failure. */ } Tcl_ObjType; /* * One of the following structures exists for each object in the Tcl * system. An object stores a value as either a string, some internal * representation, or both. */ typedef struct Tcl_Obj { int refCount; /* When 0 the object will be freed. */ char *bytes; /* This points to the first byte of the * object's string representation. The array * 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: */ long longValue; /* - an long integer value */ double doubleValue; /* - a double-precision floating value */ VOID *otherValuePtr; /* - another, type-specific value */ struct { /* - internal rep as two pointers */ VOID *ptr1; VOID *ptr2; } twoPtrValue; } internalRep; } Tcl_Obj; /* * Macros to increment and decrement a Tcl_Obj's reference count, and to * test whether an object is shared (i.e. has reference count > 1). * Note: clients should use Tcl_DecrRefCount() when they are finished using * an object, and should never call TclFreeObj() directly. TclFreeObj() is * only defined and made public in tcl.h to support Tcl_DecrRefCount's macro * definition. Note also that Tcl_DecrRefCount() refers to the parameter * "obj" twice. This means that you should avoid calling it with an * expression that is expensive to compute or has side effects. */ EXTERN void Tcl_IncrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN void Tcl_DecrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN int Tcl_IsShared _ANSI_ARGS_((Tcl_Obj *objPtr)); #ifdef TCL_MEM_DEBUG # define Tcl_IncrRefCount(objPtr) \ Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_DecrRefCount(objPtr) \ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_IsShared(objPtr) \ Tcl_DbIsShared(objPtr, __FILE__, __LINE__) #else # define Tcl_IncrRefCount(objPtr) \ ++(objPtr)->refCount # define Tcl_DecrRefCount(objPtr) \ 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_NewByteArrayObj _ANSI_ARGS_((unsigned char *bytes, int length)); 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_((CONST 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 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). */ typedef struct Tcl_Namespace { char *name; /* The namespace's name within its parent * namespace. This contains no ::'s. The * name of the global namespace is "" * although "::" is an synonym. */ char *fullName; /* The namespace's fully qualified name. * This starts with ::. */ ClientData clientData; /* Arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc* deleteProc; /* Procedure invoked when deleting the * namespace to, e.g., free clientData. */ struct Tcl_Namespace* parentPtr; /* Points to the namespace that contains * this one. NULL if this is the global * namespace. */ } Tcl_Namespace; /* * The following structure represents a call frame, or activation record. * A call frame defines a naming context for a procedure call: its local * scope (for local variables) and its namespace scope (used for non-local * variables; often 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 command's code should execute. The * Tcl_CallFrame structures exist only while procedures or namespace * eval/inscope's are being executed, and provide a Tcl call stack. * * A call frame is initialized and pushed using Tcl_PushCallFrame and * popped using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be * provided by the Tcl_PushCallFrame caller, and callers typically allocate * them on the C call stack for efficiency. For this reason, Tcl_CallFrame * is defined as a structure and not as an opaque token. However, most * Tcl_CallFrame fields are hidden since applications should not access * them directly; others are declared as "dummyX". * * WARNING!! The structure definition must be kept consistent with the * CallFrame structure in tclInt.h. If you change one, change the other. */ typedef struct Tcl_CallFrame { Tcl_Namespace *nsPtr; int dummy1; int dummy2; char *dummy3; char *dummy4; char *dummy5; int dummy6; char *dummy7; char *dummy8; int dummy9; char* dummy10; } Tcl_CallFrame; /* * Information about commands that is returned by Tcl_GetCommandInfo and * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based * command procedure while proc is a traditional Tcl argc/argv * string-based procedure. Tcl_CreateObjCommand and Tcl_CreateCommand * ensure that both objProc and proc are non-NULL and can be called to * execute the command. However, it may be faster to call one instead of * the other. The member isNativeObjectProc is set to 1 if an * object-based procedure was registered by Tcl_CreateObjCommand, and to * 0 if a string-based procedure was registered by Tcl_CreateCommand. * The other procedure is typically set to a compatibility wrapper that * does string-to-object or object-to-string argument conversions then * calls the other procedure. */ typedef struct Tcl_CmdInfo { int isNativeObjectProc; /* 1 if objProc was registered by a call to * Tcl_CreateObjCommand; 0 otherwise. * Tcl_SetCmdInfo does not modify this * field. */ Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ ClientData objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based procedure. */ ClientData clientData; /* ClientData for string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure to call when command is * deleted. */ ClientData deleteData; /* Value to pass to deleteProc (usually * the same as clientData). */ Tcl_Namespace *namespacePtr; /* Points to the namespace that contains * this command. Note that Tcl_SetCmdInfo * will not change a command's namespace; * use Tcl_RenameCommand to do that. */ } Tcl_CmdInfo; /* * The structure defined below is used to hold dynamic strings. The only * field that clients should use is the string field, and they should * never modify it. */ #define TCL_DSTRING_STATIC_SIZE 200 typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ int length; /* Number of non-NULL characters in the * string. */ int spaceAvl; /* Total number of bytes available for the * string and its terminating NULL char. */ char staticSpace[TCL_DSTRING_STATIC_SIZE]; /* Space to use in common case where string * is small. */ } Tcl_DString; #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) #define TCL_STATIC ((Tcl_FreeProc *) 0) #define TCL_DYNAMIC ((Tcl_FreeProc *) 3) /* * Flag values passed to variable-related procedures. */ #define TCL_GLOBAL_ONLY 1 #define TCL_NAMESPACE_ONLY 2 #define TCL_APPEND_VALUE 4 #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 /* * 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)); EXTERN void Tcl_InitMemory _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tcl_DumpActiveMemory _ANSI_ARGS_((char *fileName)); EXTERN void Tcl_ValidateAllMemory _ANSI_ARGS_((char *file, int line)); #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__) #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_InitMemory(x) # 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 struct Tcl_HashTable; #endif /* * Structure definition for an entry in a hash table. No-one outside * Tcl should access any of these fields directly; use the macros * defined below. */ typedef struct Tcl_HashEntry { struct Tcl_HashEntry *nextPtr; /* Pointer to next entry in this * hash bucket, or NULL for end of * chain. */ struct Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */ struct Tcl_HashEntry **bucketPtr; /* Pointer to bucket that points to * first entry in this entry's chain: * used for deleting the entry. */ ClientData clientData; /* Application stores something here * with Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ int words[1]; /* Multiple integer words for key. * The actual size will be as large * as necessary for this table's * keys. */ char string[4]; /* String for key. The actual size * will be as large as needed to hold * the key. */ } key; /* MUST BE LAST FIELD IN RECORD!! */ } Tcl_HashEntry; /* * Structure definition for a hash table. Must be in tcl.h so clients * can allocate space for these structures, but clients should never * access any fields in this structure. */ #define TCL_SMALL_HASH_TABLE 4 typedef struct Tcl_HashTable { Tcl_HashEntry **buckets; /* Pointer to bucket array. Each * element points to first entry in * bucket's hash chain, or NULL. */ Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables * (to avoid mallocs and frees). */ int numBuckets; /* Total number of buckets allocated * at **bucketPtr. */ int numEntries; /* Total number of entries present * in table. */ int rebuildSize; /* Enlarge table when numEntries gets * to be this large. */ int downShift; /* Shift count used in hashing * function. Designed to use high- * order bits of randomized keys. */ int mask; /* Mask value used in hashing * function. */ int keyType; /* Type of keys used in this table. * It's either TCL_STRING_KEYS, * TCL_ONE_WORD_KEYS, or an integer * giving the number of ints that * is the size of the key. */ Tcl_HashEntry *(*findProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key)); Tcl_HashEntry *(*createProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key, int *newPtr)); } Tcl_HashTable; /* * Structure definition for information used to keep track of searches * through hash tables: */ typedef struct Tcl_HashSearch { Tcl_HashTable *tablePtr; /* Table being searched. */ int nextIndex; /* Index of next bucket to be * enumerated after present one. */ Tcl_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the * the current bucket. */ } Tcl_HashSearch; /* * Acceptable key types for hash tables: */ #define TCL_STRING_KEYS 0 #define TCL_ONE_WORD_KEYS 1 /* * Macros for clients to use to access fields of hash entries: */ #define Tcl_GetHashValue(h) ((h)->clientData) #define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value)) #define Tcl_GetHashKey(tablePtr, h) \ ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS) ? (h)->key.oneWordValue \ : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create procedures * for hash tables: */ #define Tcl_FindHashEntry(tablePtr, key) \ (*((tablePtr)->findProc))(tablePtr, key) #define Tcl_CreateHashEntry(tablePtr, key, newPtr) \ (*((tablePtr)->createProc))(tablePtr, key, newPtr) /* * Flag values to pass to Tcl_DoOneEvent to disable searches * for some kinds of events: */ #define TCL_DONT_WAIT (1<<1) #define TCL_WINDOW_EVENTS (1<<2) #define TCL_FILE_EVENTS (1<<3) #define TCL_TIMER_EVENTS (1<<4) #define TCL_IDLE_EVENTS (1<<5) /* WAS 0x10 ???? */ #define TCL_ALL_EVENTS (~TCL_DONT_WAIT) /* * The following structure defines a generic event for the Tcl event * system. These are the things that are queued in calls to Tcl_QueueEvent * and serviced later by Tcl_DoOneEvent. There can be many different * kinds of events with different fields, corresponding to window events, * timer events, etc. The structure for a particular event consists of * a Tcl_Event header followed by additional information specific to that * event. */ struct Tcl_Event { Tcl_EventProc *proc; /* Procedure to call to service this event. */ struct Tcl_Event *nextPtr; /* Next in list of pending events, or NULL. */ }; /* * Positions to pass to Tcl_QueueEvent: */ typedef enum { TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK } Tcl_QueuePosition; /* * Values to pass to Tcl_SetServiceMode to specify the behavior of notifier * event routines. */ #define TCL_SERVICE_NONE 0 #define TCL_SERVICE_ALL 1 /* * The following structure keeps is used to hold a time value, either as * an absolute time (the number of seconds from the epoch) or as an * elapsed time. On Unix systems the epoch is Midnight Jan 1, 1970 GMT. * On Macintosh systems the epoch is Midnight Jan 1, 1904 GMT. */ typedef struct Tcl_Time { long sec; /* Seconds. */ long usec; /* Microseconds. */ } Tcl_Time; /* * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler * to indicate what sorts of events are of interest: */ #define TCL_READABLE (1<<1) #define TCL_WRITABLE (1<<2) #define TCL_EXCEPTION (1<<3) /* * Flag values to pass to Tcl_OpenCommandChannel to indicate the * disposition of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, * are also used in Tcl_GetStdChannel. */ #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)); /* * 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. */ TCL_TRANSLATE_LF, /* Eol == \n. */ TCL_TRANSLATE_CRLF /* Eol == \r\n. */ } Tcl_EolTranslation; /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. * It collects together in one place all the functions that are * part of the specific channel type. */ 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. */ #define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */ #define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking * mode. */ /* * Enum for different types of file paths. */ 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 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; /* * Exported Tcl procedures: */ EXTERN void Tcl_AddErrorInfo _ANSI_ARGS_((Tcl_Interp *interp, CONST char *message)); EXTERN void Tcl_AddObjErrorInfo _ANSI_ARGS_((Tcl_Interp *interp, CONST 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, CONST char *string)); EXTERN void Tcl_AppendResult _ANSI_ARGS_( TCL_VARARGS(Tcl_Interp *,interp)); EXTERN void Tcl_AppendObjToObj _ANSI_ARGS_((Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr)); 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 void Tcl_AlertNotifier _ANSI_ARGS_((ClientData clientData)); 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 Tcl_Encoding Tcl_CreateEncoding _ANSI_ARGS_(( Tcl_EncodingType *typePtr)); 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 void Tcl_CreateThreadExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc, ClientData clientData)); 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_((CONST 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_DeleteThreadExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc, ClientData clientData)); 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_DiscardResult _ANSI_ARGS_(( Tcl_SavedResult *statePtr)); 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_Eval2 _ANSI_ARGS_((Tcl_Interp *interp, char *script, int numBytes, int flags)); EXTERN int Tcl_EvalFile _ANSI_ARGS_((Tcl_Interp *interp, char *fileName)); EXTERN int Tcl_EvalObjv _ANSI_ARGS_ ((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int flags)); EXTERN int Tcl_EvalObj _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)); EXTERN void Tcl_EventuallyFree _ANSI_ARGS_((ClientData clientData, Tcl_FreeProc *freeProc)); EXTERN void Tcl_Exit _ANSI_ARGS_((int status)); EXTERN void Tcl_ExitThread _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 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)); EXTERN char * Tcl_ExternalToUtfDString _ANSI_ARGS_(( Tcl_Encoding encoding, CONST char *src, int srcLen, Tcl_DString *dsPtr)); EXTERN void Tcl_Finalize _ANSI_ARGS_((void)); EXTERN void Tcl_FinalizeThread _ANSI_ARGS_((void)); EXTERN void Tcl_FinalizeNotifier _ANSI_ARGS_(( ClientData clientData)); EXTERN void Tcl_FindExecutable _ANSI_ARGS_((CONST 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 Tcl_FreeEncoding _ANSI_ARGS_((Tcl_Encoding encoding)); 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 unsigned char * Tcl_GetByteArrayFromObj _ANSI_ARGS_(( Tcl_Obj *objPtr, int *lengthPtr)); EXTERN Tcl_Channel Tcl_GetChannel _ANSI_ARGS_((Tcl_Interp *interp, char *chanName, int *modePtr)); EXTERN int Tcl_GetChannelBufferSize _ANSI_ARGS_(( Tcl_Channel chan)); /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" */ EXTERN int Tcl_GetChannelByteorder _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 Tcl_ThreadId Tcl_GetCurrentThread _ANSI_ARGS_((void)); 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 Tcl_Encoding Tcl_GetEncoding _ANSI_ARGS_((Tcl_Interp *interp, CONST char *name)); EXTERN char * Tcl_GetEncodingName _ANSI_ARGS_(( Tcl_Encoding encoding)); EXTERN void Tcl_GetEncodingNames _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN Tcl_Obj * Tcl_GetEncodingPath _ANSI_ARGS_((void)); EXTERN int Tcl_GetErrno _ANSI_ARGS_((void)); 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_GetIndexFromObjStruct _ANSI_ARGS_(( Tcl_Interp *interp, Tcl_Obj *objPtr, char **tablePtr, int offset, 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 CONST char * Tcl_GetNameOfExecutable _ANSI_ARGS_((void)); EXTERN Tcl_Obj * Tcl_GetObjResult _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN Tcl_Obj * Tcl_GetObjVar2 _ANSI_ARGS_((Tcl_Interp *interp, char *part1, char *part2, int flags)); 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_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_GetString _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN char * Tcl_GetStringFromObj _ANSI_ARGS_((Tcl_Obj *objPtr, int *lengthPtr)); EXTERN char * Tcl_GetStringResult _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN VOID * Tcl_GetThreadData _ANSI_ARGS_(( Tcl_ThreadDataKey *keyPtr, int size)); 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 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 ClientData Tcl_InitNotifier _ANSI_ARGS_((void)); 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)); #ifdef TCL_THREADS EXTERN void Tcl_MutexLock _ANSI_ARGS_((Tcl_Mutex *mutexPtr)); EXTERN void Tcl_MutexUnlock _ANSI_ARGS_((Tcl_Mutex *mutexPtr)); EXTERN void Tcl_ConditionNotify _ANSI_ARGS_((Tcl_Condition *condPtr)); EXTERN void Tcl_ConditionWait _ANSI_ARGS_((Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, Tcl_Time *timePtr)); #else #define Tcl_MutexLock(mutexPtr) #define Tcl_MutexUnlock(mutexPtr) #define Tcl_ConditionNotify(condPtr) #define Tcl_ConditionWait(condPtr, mutexPtr, timePtr) #endif /* TCL_THREADS */ EXTERN Tcl_HashEntry * Tcl_NextHashEntry _ANSI_ARGS_(( Tcl_HashSearch *searchPtr)); EXTERN void Tcl_NotifyChannel _ANSI_ARGS_((Tcl_Channel channel, int mask)); EXTERN int Tcl_NumUtfChars _ANSI_ARGS_((CONST char *src, int len)); 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 int Tcl_ReadChars _ANSI_ARGS_((Tcl_Channel channel, Tcl_Obj *objPtr, int charsToRead, int appendFlag)); 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 re, CONST char *string, CONST char *start)); EXTERN int Tcl_RegExpMatch _ANSI_ARGS_((Tcl_Interp *interp, char *string, char *pattern)); EXTERN void Tcl_RegExpRange _ANSI_ARGS_((Tcl_RegExp re, 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_ResetResult _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN void Tcl_RestoreResult _ANSI_ARGS_((Tcl_Interp *interp, Tcl_SavedResult *statePtr)); #define Tcl_Return Tcl_SetResult EXTERN void Tcl_SaveResult _ANSI_ARGS_((Tcl_Interp *interp, Tcl_SavedResult *statePtr)); 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 unsigned char * Tcl_SetByteArrayLength _ANSI_ARGS_((Tcl_Obj *objPtr, int length)); EXTERN void Tcl_SetByteArrayObj _ANSI_ARGS_((Tcl_Obj *objPtr, unsigned char *bytes, int length)); 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 Tcl_Obj * Tcl_SetObjVar2 _ANSI_ARGS_((Tcl_Interp *interp, char *part1, char *part2, Tcl_Obj *newValuePtr, int flags)); 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 int Tcl_SetSystemEncoding _ANSI_ARGS_((Tcl_Interp *interp, CONST char *name)); 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, CONST char *list, int *argcPtr, char ***argvPtr)); EXTERN void Tcl_SplitPath _ANSI_ARGS_((CONST 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_((CONST char *string, CONST char *pattern)); EXTERN int Tcl_Tell _ANSI_ARGS_((Tcl_Channel chan)); EXTERN void Tcl_ThreadAlert _ANSI_ARGS_((Tcl_ThreadId threadId)); EXTERN void Tcl_ThreadQueueEvent _ANSI_ARGS_(( Tcl_ThreadId threadId, Tcl_Event* evPtr, Tcl_QueuePosition position)); #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 Tcl_UniChar Tcl_UniCharAtIndex _ANSI_ARGS_((CONST char *src, int index)); EXTERN Tcl_UniChar Tcl_UniCharToLower _ANSI_ARGS_((int ch)); EXTERN Tcl_UniChar Tcl_UniCharToTitle _ANSI_ARGS_((int ch)); EXTERN Tcl_UniChar Tcl_UniCharToUpper _ANSI_ARGS_((int ch)); EXTERN int Tcl_UniCharToUtf _ANSI_ARGS_((int ch, char *buf)); 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 char * Tcl_UtfAtIndex _ANSI_ARGS_((CONST char *src, int index)); EXTERN int Tcl_UtfCharComplete _ANSI_ARGS_((CONST char *src, int len)); EXTERN int Tcl_UtfBackslash _ANSI_ARGS_((CONST char *src, int *readPtr, char *dst)); EXTERN char * Tcl_UtfFindFirst _ANSI_ARGS_((CONST char *src, int ch)); EXTERN char * Tcl_UtfFindLast _ANSI_ARGS_((CONST char *src, int ch)); EXTERN int Tcl_UtfIsLower _ANSI_ARGS_((CONST char *src)); EXTERN int Tcl_UtfIsUpper _ANSI_ARGS_((CONST char *src)); EXTERN char * Tcl_UtfNext _ANSI_ARGS_((CONST char *src)); EXTERN char * Tcl_UtfPrev _ANSI_ARGS_((CONST char *src, CONST char *start)); 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)); EXTERN char * Tcl_UtfToExternalDString _ANSI_ARGS_(( Tcl_Encoding encoding, CONST char *src, int srcLen, Tcl_DString *dsPtr)); EXTERN int Tcl_UtfToLower _ANSI_ARGS_((char *src)); EXTERN int Tcl_UtfToTitle _ANSI_ARGS_((char *src)); EXTERN int Tcl_UtfToUniChar _ANSI_ARGS_((CONST char *src, Tcl_UniChar *chPtr)); EXTERN int Tcl_UtfToUpper _ANSI_ARGS_((char *src)); 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 *src, int srcLen)); EXTERN int Tcl_WriteChars _ANSI_ARGS_((Tcl_Channel chan, CONST char *src, int srcLen)); EXTERN int Tcl_WriteObj _ANSI_ARGS_((Tcl_Channel chan, Tcl_Obj *objPtr)); EXTERN void Tcl_WrongNumArgs _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], char *message)); /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * C-Level API for (un)stacking of channels. This allows the introduction * of filtering channels with relatively little changes to the core. * This patch was created in cooperation with Jan Nijtmans * and is therefore part of his plus-patches too. * * It would have been possible to place the following definitions according * to the alphabetical order used elsewhere in this file, but I decided * against that to ease the maintenance of the patch across new tcl versions * (patch usually has no problems to integrate the patch file for the last * version into the new one). */ EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_ChannelType* typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_Channel chan)); #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TCL */ trf2.1.4/patches/v8.1b3/0000755000175000017500000000000011216344734014127 5ustar sergeisergeitrf2.1.4/patches/v8.1b3/tclStubs.c0000644000175000017500000017132511216344362016104 0ustar sergeisergei/* * 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.2 1999/04/19 18:29:42 aku 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); } /* Slot 345 */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp * interp; Tcl_ChannelType * typePtr; ClientData instanceData; int mask; Tcl_Channel prevChan; { return (tclStubsPtr->tcl_ReplaceChannel)(interp, typePtr, instanceData, mask, prevChan); } /* Slot 346 */ void Tcl_UndoReplaceChannel(interp, chan) Tcl_Interp * interp; Tcl_Channel chan; { (tclStubsPtr->tcl_UndoReplaceChannel)(interp, chan); } /* !END!: Do not edit above this line. */ trf2.1.4/patches/v8.1b3/standard.patch0000644000175000017500000004312111216344361016745 0ustar sergeisergei*** ./tcl.decls.orig Sat Apr 10 17:50:50 1999 --- ./tcl.decls Mon Apr 19 19:58:16 1999 *************** *** 967,977 **** 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 { --- 967,996 ---- void Tcl_InitMemory(Tcl_Interp *interp) } + # Andreas Kupries , 03/21/1999 + # "Trf-Patch for filtering channels" + # + # C-Level API for (un)stacking of channels. This allows the introduction + # of filtering channels with relatively little changes to the core. + # This patch was created in cooperation with Jan Nijtmans + # and is therefore part of his plus-patches too. + # + # It would have been possible to place the following definitions according + # to the alphabetical order used elsewhere in this file, but I decided + # against that to ease the maintenance of the patch across new tcl versions + # (patch usually has no problems to integrate the patch file for the last + # version into the new one). + + declare 281 generic { + Tcl_Channel Tcl_ReplaceChannel(Tcl_Interp *interp, \ + Tcl_ChannelType *typePtr, ClientData instanceData, \ + int mask, Tcl_Channel prevChan) + } + declare 282 generic { + void Tcl_UndoReplaceChannel(Tcl_Interp *interp, Tcl_Channel chan) + } + # Reserved for future use (8.0.x vs. 8.1) # declare 283 generic { # } # declare 284 generic { *** ./tclDecls.h.orig Sat Apr 10 17:50:50 1999 --- ./tclDecls.h Mon Apr 19 19:58:16 1999 *************** *** 875,882 **** 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 */ --- 875,888 ---- int * patchLevel, int * type)); /* 280 */ EXTERN void Tcl_InitMemory _ANSI_ARGS_((Tcl_Interp * interp)); ! /* 281 */ ! EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_((Tcl_Interp * interp, ! Tcl_ChannelType * typePtr, ! ClientData instanceData, int mask, ! Tcl_Channel prevChan)); ! /* 282 */ ! EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_(( ! Tcl_Interp * interp, Tcl_Channel chan)); /* Slot 283 is reserved */ /* Slot 284 is reserved */ /* Slot 285 is reserved */ *************** *** 1434,1441 **** 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; --- 1440,1447 ---- 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 */ ! Tcl_Channel (*tcl_ReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 281 */ ! void (*tcl_UndoReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 282 */ void *reserved283; void *reserved284; void *reserved285; *************** *** 2657,2664 **** #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 */ --- 2663,2676 ---- #define Tcl_InitMemory \ (tclStubsPtr->tcl_InitMemory) /* 280 */ #endif ! #ifndef Tcl_ReplaceChannel ! #define Tcl_ReplaceChannel \ ! (tclStubsPtr->tcl_ReplaceChannel) /* 281 */ ! #endif ! #ifndef Tcl_UndoReplaceChannel ! #define Tcl_UndoReplaceChannel \ ! (tclStubsPtr->tcl_UndoReplaceChannel) /* 282 */ ! #endif /* Slot 283 is reserved */ /* Slot 284 is reserved */ /* Slot 285 is reserved */ *** ./tclIO.c.orig Sat Apr 10 17:50:52 1999 --- ./tclIO.c Mon Apr 19 19:58:16 1999 *************** *** 202,207 **** --- 202,229 ---- int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ + + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * The single change to the internal datastructures of the core. Every + * channel now maintains a reference to the channel he is stacked upon. + * This reference is NULL for normal channels. Only the two exported + * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the + * end of 'tcl.h') use this field in a non-trivial way. + * + * Of the existing procedures the only following are affected by this + * change: + * + * - Tcl_RegisterChannel + * - Tcl_CreateChannel + * - CloseChannel + * + * The why is explained at the changed locations. + */ + + struct Channel* supercedes; /* Refers to channel this one was stacked upon */ + } Channel; /* *************** *** 1038,1044 **** if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! panic("Tcl_RegisterChannel: duplicate channel names"); } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } --- 1060,1080 ---- if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! ! /* Andreas Kupries , 12/13/1998 ! * "Trf-Patch for filtering channels" ! * ! * This is the change to 'Tcl_RegisterChannel'. ! * ! * Explanation: ! * The moment a channel is stacked upon another he ! * takes the identity of the channel he supercedes, ! * i.e. he gets the *same* name. Because of this we ! * cannot check for duplicate names anymore, they ! * have to be allowed now. ! */ ! ! /* panic("Tcl_RegisterChannel: duplicate channel names"); */ } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } *************** *** 1297,1302 **** --- 1333,1352 ---- chanPtr->timer = NULL; chanPtr->csPtr = NULL; + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * This is the change to 'Tcl_CreateChannel'. + * + * Explanation: + * It is of course necessary to initialize the new field + * in the Channel structure. The chosen value indicates + * that the created channel is a normal one, and not + * stacked upon another. + */ + + chanPtr->supercedes = (Channel*) NULL; + chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) *************** *** 1330,1335 **** --- 1380,1622 ---- return (Tcl_Channel) chanPtr; } + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * The following two procedures are the new, exported ones. They + * - create a channel stacked upon an existing one and + * - pop a stacked channel off, thus revealing the superceded one. + * + * Please read the following completely. + */ + + /* + *---------------------------------------------------------------------- + * + * Tcl_ReplaceChannel -- + * + * Replaces an entry in the hash table for a Tcl_Channel + * record. The replacement is a new channel with same name, + * it supercedes the replaced channel. Input and output of + * the superceded channel is now going through the newly + * created channel and allows the arbitrary filtering/manipulation + * of the dataflow. + * + * Results: + * Returns the new Tcl_Channel. + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_ChannelType *typePtr; /* The channel type record for the new + * channel. */ + ClientData instanceData; /* Instance specific data for the new + * channel. */ + int mask; /* TCL_READABLE & TCL_WRITABLE to indicate + * if the channel is readable, writable. */ + Tcl_Channel prevChan; /* The channel structure to replace */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr, *pt, *prevPt; + + /* + * Find the given channel in the list of all channels, compute enough + * information to allow easy removal after the conditions are met. + */ + + prevPt = (Channel*) NULL; + pt = (Channel*) tsdPtr->firstChanPtr; + + while (pt != (Channel *) prevChan) { + prevPt = pt; + pt = pt->nextChanPtr; + } + + /* + * 'pt == prevChan' now + */ + + if (!pt) { + return (Tcl_Channel) NULL; + } + + /* + * Here we check if the given "mask" matches the "flags" + * of the already existing channel. + * + * | - | R | W | RW | + * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) + * - | | | | | + * R | | + | | + | The superceding channel is allowed to + * W | | | + | + | restrict the capabilities of the + * RW| | + | + | + | superceded one ! + * --+---+---+---+----+ + */ + + if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { + return (Tcl_Channel) NULL; + } + + + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); + chanPtr->flags = mask; + + /* + * Set the channel up initially in no Input translation mode and + * no Output translation mode. + */ + + chanPtr->inputTranslation = TCL_TRANSLATE_LF; + chanPtr->outputTranslation = TCL_TRANSLATE_LF; + chanPtr->inEofChar = 0; + chanPtr->outEofChar = 0; + + chanPtr->unreportedError = 0; + chanPtr->instanceData = instanceData; + chanPtr->typePtr = typePtr; + chanPtr->refCount = 0; + chanPtr->closeCbPtr = (CloseCallback *) NULL; + chanPtr->curOutPtr = (ChannelBuffer *) NULL; + chanPtr->outQueueHead = (ChannelBuffer *) NULL; + chanPtr->outQueueTail = (ChannelBuffer *) NULL; + chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; + chanPtr->inQueueHead = (ChannelBuffer *) NULL; + 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; + + /* 06/12/1998: New for Tcl 8.1 + * + * Take over the encoding from the superceded channel, so that it will be + * executed in the future despite the replacement, and at the proper time + * (*after* / *before* our transformation, depending on the direction of + * the dataflow). + * + * *Important* + * The I/O functionality of the filtering channel has to use 'Tcl_Read' to + * get at the underlying information. This will circumvent the de/encoder + * stage [*] in the superceded channel and removes the need to trouble + * ourselves with 'ByteArray's too. + * + * [*] I'm talking about the conversion between UNICODE and other + * representations, like ASCII. + */ + + chanPtr->encoding=Tcl_GetEncoding(interp,Tcl_GetEncodingName(pt->encoding)); + chanPtr->inputEncodingState = pt->inputEncodingState; + chanPtr->inputEncodingFlags = pt->inputEncodingFlags; + chanPtr->outputEncodingState = pt->outputEncodingState; + chanPtr->outputEncodingFlags = pt->outputEncodingFlags; + + chanPtr->outputStage = NULL; + + if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { + chanPtr->outputStage = (char *) + ckalloc((unsigned) (chanPtr->bufSize + 2)); + } + + chanPtr->supercedes = (Channel*) prevChan; + + chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); + strcpy (chanPtr->channelName, pt->channelName); + + if (prevPt) { + prevPt->nextChanPtr = chanPtr; + } else { + tsdPtr->firstChanPtr = chanPtr; + } + + chanPtr->nextChanPtr = pt->nextChanPtr; + + Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); + + /* + * The superceded channel is effectively unregistered + */ + + /*chanPtr->supercedes->refCount --;*/ + + return (Tcl_Channel) chanPtr; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_UndoReplaceChannel -- + * + * Unstacks an entry in the hash table for a Tcl_Channel + * record. This is the reverse to 'Tcl_ReplaceChannel'. + * The old, superceded channel is uncovered and re-registered + * in the appropriate datastructures. + * + * Results: + * Returns the old Tcl_Channel, i.e. the one which was stacked over. + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + + void + Tcl_UndoReplaceChannel (interp, chan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_Channel chan; /* The channel to unstack */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel* chanPtr = (Channel*) chan; + + if (chanPtr->supercedes != (Channel*) NULL) { + Tcl_HashTable *hTblPtr; /* Hash table of channels. */ + Tcl_HashEntry *hPtr; /* Search variable. */ + int new; /* Is the hash entry new or does it exist? */ + + /* + * Insert the channel we were stacked upon back into + * the list of open channels. Place it back into the hashtable too. + * Correct 'refCount', as this actually unregisters 'chan'. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + + hTblPtr = GetChannelTable (interp); + hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); + + Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); + chanPtr->refCount --; + + /* + * The superceded channel is effectively registered again + */ + + /*chanPtr->supercedes->refCount ++;*/ + } + + /* + * Disconnect the channels, then do a regular close upon the + * stacked one, the filtering channel. This may cause flushing + * of data into the superceded channel (if the filtering channel + * ('chan') remembered its parent in itself). + */ + + chanPtr->supercedes = NULL; + + if (chanPtr->refCount == 0) { + Tcl_Close (interp, chan); + } + } + /* *---------------------------------------------------------------------- * *************** *** 2003,2008 **** --- 2290,2330 ---- if (errorCode != 0) { Tcl_SetErrno(errorCode); } + } + + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * This is the change to 'CloseChannel'. + * + * Explanation + * Closing a filtering channel closes the one it + * superceded too. This basically ripples through + * the whole chain of filters until it reaches + * the underlying normal channel. + * + * This is done by reintegrating the superceded + * channel into the (thread) global list of open + * channels and then invoking a regular close. + * There is no need to handle the complexities of + * this process by ourselves. + * + * *Note* + * This has to be done after the call to the + * 'closeProc' of the filtering channel to allow + * that one the flushing of internal buffers into + * the underlying channel. + */ + + if (chanPtr->supercedes != (Channel*) NULL) { + /* Insert the channel we were stacked upon back into + * the list of open channels, then do a regular close. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + chanPtr->supercedes->refCount --; /* is deregistered */ + Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* *** ./tclStubInit.c.orig Sat Apr 10 17:50:52 1999 --- ./tclStubInit.c Mon Apr 19 19:58:16 1999 *************** *** 350,357 **** Tcl_PanicVA, /* 278 */ Tcl_GetVersion, /* 279 */ Tcl_InitMemory, /* 280 */ ! NULL, /* 281 */ ! NULL, /* 282 */ NULL, /* 283 */ NULL, /* 284 */ NULL, /* 285 */ --- 350,357 ---- Tcl_PanicVA, /* 278 */ Tcl_GetVersion, /* 279 */ Tcl_InitMemory, /* 280 */ ! Tcl_ReplaceChannel, /* 281 */ ! Tcl_UndoReplaceChannel, /* 282 */ NULL, /* 283 */ NULL, /* 284 */ NULL, /* 285 */ *** ./tclStubs.c.orig Sat Apr 10 17:50:52 1999 --- ./tclStubs.c Mon Apr 19 19:58:16 1999 *************** *** 3263,3267 **** --- 3263,3288 ---- (tclStubsPtr->tcl_ServiceModeHook)(mode); } + /* Slot 345 */ + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp * interp; + Tcl_ChannelType * typePtr; + ClientData instanceData; + int mask; + Tcl_Channel prevChan; + { + return (tclStubsPtr->tcl_ReplaceChannel)(interp, typePtr, instanceData, mask, prevChan); + } + + /* Slot 346 */ + void + Tcl_UndoReplaceChannel(interp, chan) + Tcl_Interp * interp; + Tcl_Channel chan; + { + (tclStubsPtr->tcl_UndoReplaceChannel)(interp, chan); + } + /* !END!: Do not edit above this line. */ trf2.1.4/patches/v8.1b3/tcl.decls0000644000175000017500000011271511216344361015730 0ustar sergeisergei# 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.2 1999/04/19 18:29:39 aku 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) } # Andreas Kupries , 03/21/1999 # "Trf-Patch for filtering channels" # # C-Level API for (un)stacking of channels. This allows the introduction # of filtering channels with relatively little changes to the core. # This patch was created in cooperation with Jan Nijtmans # and is therefore part of his plus-patches too. # # It would have been possible to place the following definitions according # to the alphabetical order used elsewhere in this file, but I decided # against that to ease the maintenance of the patch across new tcl versions # (patch usually has no problems to integrate the patch file for the last # version into the new one). declare 281 generic { Tcl_Channel Tcl_ReplaceChannel(Tcl_Interp *interp, \ Tcl_ChannelType *typePtr, ClientData instanceData, \ int mask, Tcl_Channel prevChan) } declare 282 generic { void Tcl_UndoReplaceChannel(Tcl_Interp *interp, Tcl_Channel chan) } # Reserved for future use (8.0.x vs. 8.1) # 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) } trf2.1.4/patches/v8.1b3/tclIO.c0000644000175000017500000072641711216344362015323 0ustar sergeisergei/* * 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.3 1999/04/19 18:29:41 aku 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. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) # define EWOULDBLOCK EAGAIN #endif #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) error one of EWOULDBLOCK or EAGAIN must be defined #endif /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this * structure. */ typedef struct CopyState { struct Channel *readPtr; /* Pointer to input channel. */ struct Channel *writePtr; /* Pointer to output channel. */ int readFlags; /* Original read channel flags. */ int writeFlags; /* Original write channel flags. */ int toRead; /* Number of bytes to copy, or -1. */ int total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ 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) /* * Structure to record a close callback. One such record exists for * each close callback registered for a channel. */ typedef struct CloseCallback { Tcl_CloseProc *proc; /* The procedure to call. */ ClientData clientData; /* Arbitrary one-word data to pass * to the callback. */ struct CloseCallback *nextPtr; /* For chaining close callbacks. */ } CloseCallback; /* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to * invoke the saved script in the interpreter designed in this record. */ 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; /* * struct Channel: * * One of these structures is allocated for each open channel. It contains data * specific to the channel but which belongs to the generic part of the Tcl * channel mechanism, and it points at an instance specific (and type * specific) * instance data, and at a channel type structure. */ 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. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ struct ChannelHandler *chPtr;/* List of channel handlers registered * for this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ struct Channel *nextChanPtr;/* Next in list of channels currently open. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for * event handlers ("fileevent") on this * channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * The single change to the internal datastructures of the core. Every * channel now maintains a reference to the channel he is stacked upon. * This reference is NULL for normal channels. Only the two exported * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the * end of 'tcl.h') use this field in a non-trivial way. * * Of the existing procedures the only following are affected by this * change: * * - Tcl_RegisterChannel * - Tcl_CreateChannel * - CloseChannel * * The why is explained at the changed locations. */ struct Channel* supercedes; /* Refers to channel this one was stacked upon */ } Channel; /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in * nonblocking mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the * curOutPtr field in the * channel structure) should be * output as soon as possible even * though it may not be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the * queued output buffers has been * scheduled. */ #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No * further Tcl-level IO on the * channel is allowed. */ #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. * This bit is cleared before every * input operation. */ #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because * we saw the input eofChar. This bit * prevents clearing of the EOF bit * before every input operation. */ #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. */ typedef struct ChannelHandler { Channel *chanPtr; /* The channel structure for this channel. */ int mask; /* Mask of desired events. */ Tcl_ChannelProc *proc; /* Procedure to call in the type of * Tcl_CreateChannelHandler. */ ClientData clientData; /* Argument to pass to procedure. */ struct ChannelHandler *nextPtr; /* Next one in list of registered handlers. */ } ChannelHandler; /* * This structure keeps track of the current ChannelHandler being invoked in * the current invocation of ChannelHandlerEventProc. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. * The nextPtr field is used to chain together all recursive invocations, so * that Tcl_DeleteChannelHandler can find all the recursively nested * invocations of ChannelHandlerEventProc and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. */ typedef struct NextChannelHandler { 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 * for stdin/stdout/stderr in new interpreters. * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ 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 * closed. * * Results: * None. * * Side effects: * Causes the callback to be called in the future when the channel * will be closed. * *---------------------------------------------------------------------- */ void Tcl_CreateCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to create the * close callback. */ Tcl_CloseProc *proc; /* The callback routine to call when the * channel will be closed. */ ClientData clientData; /* Arbitrary data to pass to the * close callback. */ { Channel *chanPtr; CloseCallback *cbPtr; chanPtr = (Channel *) chan; cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; cbPtr->nextPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr; } /* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * * Removes a callback that would have been called on closing * the channel. If there is no matching callback then this * function has no effect. * * Results: * None. * * Side effects: * The callback will not be called in the future when the channel * is eventually closed. * *---------------------------------------------------------------------- */ void Tcl_DeleteCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to cancel the * close callback. */ Tcl_CloseProc *proc; /* The procedure for the callback to * remove. */ ClientData clientData; /* The callback data for the callback * to remove. */ { Channel *chanPtr; CloseCallback *cbPtr, *cbPrevPtr; chanPtr = (Channel *) chan; for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL; cbPtr != (CloseCallback *) NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == (CloseCallback *) NULL) { chanPtr->closeCbPtr = cbPtr->nextPtr; } ckfree((char *) cbPtr); break; } else { cbPrevPtr = cbPtr; } } } /* *---------------------------------------------------------------------- * * GetChannelTable -- * * Gets and potentially initializes the channel table for an * interpreter. If it is initializing the table it also inserts * channels for stdin, stdout and stderr if the interpreter is * trusted. * * Results: * A pointer to the hash table created, for use by the caller. * * Side effects: * Initializes the channel table for an interpreter. May create * channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */ static Tcl_HashTable * GetChannelTable(interp) Tcl_Interp *interp; { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); (void) Tcl_SetAssocData(interp, "tclIO", (Tcl_InterpDeleteProc *) DeleteChannelTable, (ClientData) hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels * for stdin, stdout and stderr (possibly creating them in the * process). */ if (Tcl_IsSafe(interp) == 0) { stdinChan = Tcl_GetStdChannel(TCL_STDIN); if (stdinChan != NULL) { Tcl_RegisterChannel(interp, stdinChan); } stdoutChan = Tcl_GetStdChannel(TCL_STDOUT); if (stdoutChan != NULL) { Tcl_RegisterChannel(interp, stdoutChan); } stderrChan = Tcl_GetStdChannel(TCL_STDERR); if (stderrChan != NULL) { Tcl_RegisterChannel(interp, stderrChan); } } } return hTblPtr; } /* *---------------------------------------------------------------------- * * DeleteChannelTable -- * * Deletes the channel table for an interpreter, closing any open * channels whose refcount reaches zero. This procedure is invoked * when an interpreter is deleted, via the AssocData cleanup * mechanism. * * Results: * None. * * Side effects: * Deletes the hash table of channels. May close channels. May flush * output on closed channels. Removes any channeEvent handlers that were * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable(clientData, interp) ClientData clientData; /* The per-interpreter data structure. */ Tcl_Interp *interp; /* The interpreter being deleted. */ { Tcl_HashTable *hTblPtr; /* The hash table. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* Channel being deleted. */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* Variables to loop over all channel events * registered, to delete the ones that refer * to the interpreter being deleted. */ /* * Delete all the registered channels - this will close channels whose * refcount reaches zero. */ hTblPtr = (Tcl_HashTable *) clientData; for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); /* * Remove any fileevents registered in this interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } /* * Cannot call Tcl_UnregisterChannel because that procedure calls * Tcl_GetAssocData to get the channel table, which might already * be inaccessible from the interpreter structure. Instead, we * emulate the behavior of Tcl_UnregisterChannel directly here. */ Tcl_DeleteHashEntry(hPtr); chanPtr->refCount--; if (chanPtr->refCount <= 0) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } } Tcl_DeleteHashTable(hTblPtr); ckfree((char *) hTblPtr); } /* *---------------------------------------------------------------------- * * CheckForStdChannelsBeingClosed -- * * Perform special handling for standard channels being closed. When * given a standard channel, if the refcount is now 1, it means that * the last reference to the standard channel is being explicitly * closed. Now bump the refcount artificially down to 0, to ensure the * normal handling of channels being closed will occur. Also reset the * static pointer to the channel to NULL, to avoid dangling references. * * Results: * None. * * Side effects: * Manipulates the refcount on standard channels. May smash the global * static pointer to a standard channel. * *---------------------------------------------------------------------- */ 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; } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_RegisterChannel'. * * Explanation: * The moment a channel is stacked upon another he * takes the identity of the channel he supercedes, * i.e. he gets the *same* name. Because of this we * cannot check for duplicate names anymore, they * have to be allowed now. */ /* 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. * If the interpreter given as argument is NULL, it only decrements the * reference count. * * Results: * A standard Tcl result. * * Side effects: * Deletes the hash entry for a channel associated with an interpreter. * *---------------------------------------------------------------------- */ int Tcl_UnregisterChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which channel is defined. */ Tcl_Channel chan; /* Channel to delete. */ { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The real IO channel. */ chanPtr = (Channel *) chan; if (interp != (Tcl_Interp *) NULL) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } hPtr = Tcl_FindHashEntry(hTblPtr, chanPtr->channelName); if (hPtr == (Tcl_HashEntry *) NULL) { return TCL_OK; } if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) { return TCL_OK; } Tcl_DeleteHashEntry(hPtr); /* * Remove channel handlers that refer to this interpreter, so that they * will not be present if the actual close is delayed and more events * happen on the channel. This may occur if the channel is shared * between several interpreters, or if the channel has async * flushing active. */ CleanupChannelHandlers(interp, chanPtr); } chanPtr->refCount--; /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); /* * If the refCount reached zero, close the actual channel. */ if (chanPtr->refCount <= 0) { /* * Ensure that if there is another buffer, it gets flushed * whether or not we are doing a background flush. */ if ((chanPtr->curOutPtr != NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; } chanPtr->flags |= CHANNEL_CLOSED; if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { if (Tcl_Close(interp, chan) != TCL_OK) { return TCL_ERROR; } } } 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. */ int *modePtr; /* Where to store the mode in which the * channel was opened? Will contain an ORed * combination of TCL_READABLE and * TCL_WRITABLE, if non-NULL. */ { Channel *chanPtr; /* The actual channel. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ char *name; /* Translated name. */ /* * Substitute "stdin", etc. Note that even though we immediately * find the channel using Tcl_GetStdChannel, we still need to look * it up in the specified interpreter to ensure that it is present * in the channel table. Otherwise, safe interpreters would always * have access to the standard channels. */ name = chanName; if ((chanName[0] == 's') && (chanName[1] == 't')) { chanPtr = NULL; if (strcmp(chanName, "stdin") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDIN); } else if (strcmp(chanName, "stdout") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDOUT); } else if (strcmp(chanName, "stderr") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDERR); } if (chanPtr != NULL) { name = chanPtr->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == (Tcl_HashEntry *) NULL) { Tcl_AppendResult(interp, "can not find channel named \"", chanName, "\"", (char *) NULL); return NULL; } chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (modePtr != NULL) { *modePtr = (chanPtr->flags & (TCL_READABLE|TCL_WRITABLE)); } return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_CreateChannel -- * * Creates a new entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Creates a new Tcl_Channel instance and inserts it into the * hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_CreateChannel(typePtr, chanName, instanceData, mask) 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. */ chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_CreateChannel'. * * Explanation: * It is of course necessary to initialize the new field * in the Channel structure. The chosen value indicates * that the created channel is a normal one, and not * stacked upon another. */ chanPtr->supercedes = (Channel*) 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; } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * The following two procedures are the new, exported ones. They * - create a channel stacked upon an existing one and * - pop a stacked channel off, thus revealing the superceded one. * * Please read the following completely. */ /* *---------------------------------------------------------------------- * * Tcl_ReplaceChannel -- * * Replaces an entry in the hash table for a Tcl_Channel * record. The replacement is a new channel with same name, * it supercedes the replaced channel. Input and output of * the superceded channel is now going through the newly * created channel and allows the arbitrary filtering/manipulation * of the dataflow. * * Results: * Returns the new Tcl_Channel. * * Side effects: * See above. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_ChannelType *typePtr; /* The channel type record for the new * channel. */ ClientData instanceData; /* Instance specific data for the new * channel. */ int mask; /* TCL_READABLE & TCL_WRITABLE to indicate * if the channel is readable, writable. */ Tcl_Channel prevChan; /* The channel structure to replace */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel *chanPtr, *pt, *prevPt; /* * Find the given channel in the list of all channels, compute enough * information to allow easy removal after the conditions are met. */ prevPt = (Channel*) NULL; pt = (Channel*) tsdPtr->firstChanPtr; while (pt != (Channel *) prevChan) { prevPt = pt; pt = pt->nextChanPtr; } /* * 'pt == prevChan' now */ if (!pt) { return (Tcl_Channel) NULL; } /* * Here we check if the given "mask" matches the "flags" * of the already existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to * W | | | + | + | restrict the capabilities of the * RW| | + | + | + | superceded one ! * --+---+---+---+----+ */ if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { return (Tcl_Channel) NULL; } chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); chanPtr->flags = mask; /* * Set the channel up initially in no Input translation mode and * no Output translation mode. */ chanPtr->inputTranslation = TCL_TRANSLATE_LF; chanPtr->outputTranslation = TCL_TRANSLATE_LF; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* 06/12/1998: New for Tcl 8.1 * * Take over the encoding from the superceded channel, so that it will be * executed in the future despite the replacement, and at the proper time * (*after* / *before* our transformation, depending on the direction of * the dataflow). * * *Important* * The I/O functionality of the filtering channel has to use 'Tcl_Read' to * get at the underlying information. This will circumvent the de/encoder * stage [*] in the superceded channel and removes the need to trouble * ourselves with 'ByteArray's too. * * [*] I'm talking about the conversion between UNICODE and other * representations, like ASCII. */ chanPtr->encoding = pt->encoding; chanPtr->inputEncodingState = pt->inputEncodingState; chanPtr->inputEncodingFlags = pt->inputEncodingFlags; chanPtr->outputEncodingState = pt->outputEncodingState; chanPtr->outputEncodingFlags = pt->outputEncodingFlags; chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) ckalloc((unsigned) (chanPtr->bufSize + 2)); } chanPtr->supercedes = (Channel*) prevChan; chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); strcpy (chanPtr->channelName, pt->channelName); if (prevPt) { prevPt->nextChanPtr = chanPtr; } else { tsdPtr->firstChanPtr = chanPtr; } chanPtr->nextChanPtr = pt->nextChanPtr; Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); /* * The superceded channel is effectively unregistered */ /*chanPtr->supercedes->refCount --;*/ return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_UndoReplaceChannel -- * * Unstacks an entry in the hash table for a Tcl_Channel * record. This is the reverse to 'Tcl_ReplaceChannel'. * The old, superceded channel is uncovered and re-registered * in the appropriate datastructures. * * Results: * Returns the old Tcl_Channel, i.e. the one which was stacked over. * * Side effects: * See above. * *---------------------------------------------------------------------- */ void Tcl_UndoReplaceChannel (interp, chan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_Channel chan; /* The channel to unstack */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel* chanPtr = (Channel*) chan; if (chanPtr->supercedes != (Channel*) NULL) { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ int new; /* Is the hash entry new or does it exist? */ /* * Insert the channel we were stacked upon back into * the list of open channels. Place it back into the hashtable too. * Correct 'refCount', as this actually unregisters 'chan'. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; hTblPtr = GetChannelTable (interp); hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); chanPtr->refCount --; /* * The superceded channel is effectively registered again */ /*chanPtr->supercedes->refCount ++;*/ } /* * Disconnect the channels, then do a regular close upon the * stacked one, the filtering channel. This may cause flushing * of data into the superceded channel (if the filtering channel * ('chan') remembered its parent in itself). */ chanPtr->supercedes = NULL; if (chanPtr->refCount == 0) { Tcl_Close (interp, chan); } } /* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * * Computes a mask indicating whether the channel is open for * reading and writing. * * Results: * An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelMode(chan) Tcl_Channel chan; /* The channel for which the mode is * being computed. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE)); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * * Returns the string identifying the channel name. * * Results: * The string containing the channel name. This memory is * owned by the generic layer and should not be modified by * the caller. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Tcl_GetChannelName(chan) Tcl_Channel chan; /* The channel for which to return the name. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->channelName; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * * Given a channel structure, returns the channel type structure. * * Results: * Returns a pointer to the channel type structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ChannelType * Tcl_GetChannelType(chan) Tcl_Channel chan; /* The channel to return type for. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->typePtr; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * * Returns an OS handle associated with a channel. * * Results: * Returns TCL_OK and places the handle in handlePtr, or returns * TCL_ERROR on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelHandle(chan, direction, handlePtr) Tcl_Channel chan; /* The channel to get file from. */ int direction; /* TCL_WRITABLE or TCL_READABLE. */ ClientData *handlePtr; /* Where to store handle */ { Channel *chanPtr; /* The actual channel. */ ClientData handle; int result; chanPtr = (Channel *) chan; result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData, direction, &handle); if (handlePtr) { *handlePtr = handle; } return result; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * * Returns the client data associated with a channel. * * Results: * The client data. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_GetChannelInstanceData(chan) 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 * that two input buffers are saved (one in the input queue and * another in the saveInBufPtr field) and that curOutPtr is set * to a buffer. Only if these conditions are met is the buffer * freed to the OS. * * Results: * None. * * Side effects: * May free a buffer to the OS. * *---------------------------------------------------------------------- */ static void RecycleBuffer(chanPtr, bufPtr, mustDiscard) Channel *chanPtr; /* Channel for which to recycle buffers. */ ChannelBuffer *bufPtr; /* The buffer to recycle. */ int mustDiscard; /* If nonzero, free the buffer to the * OS, always. */ { /* * Do we have to free the buffer to the OS? */ if (mustDiscard) { ckfree((char *) bufPtr); return; } /* * Only save buffers for the input queue if the channel is readable. */ if (chanPtr->flags & TCL_READABLE) { if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) { chanPtr->inQueueHead = bufPtr; chanPtr->inQueueTail = bufPtr; goto keepit; } if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) { chanPtr->saveInBufPtr = bufPtr; goto keepit; } } /* * Only save buffers for the output queue if the channel is writable. */ if (chanPtr->flags & TCL_WRITABLE) { if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) { chanPtr->curOutPtr = bufPtr; goto keepit; } } /* * 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 -- * * Discards all output queued in the output queue of a channel. * * Results: * None. * * Side effects: * Recycles buffers. * *---------------------------------------------------------------------- */ static void DiscardOutputQueued(chanPtr) Channel *chanPtr; /* The channel for which to discard output. */ { ChannelBuffer *bufPtr; while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { bufPtr = chanPtr->outQueueHead; chanPtr->outQueueHead = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, 0); } chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; } /* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * * This function checks is a given channel is Dead. * (A channel that has been closed but not yet deallocated.) * * Results: * True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: * None * *---------------------------------------------------------------------- */ static int CheckForDeadChannel(interp, chanPtr) Tcl_Interp *interp; /* For error reporting (can be NULL) */ Channel *chanPtr; /* The channel to check. */ { if (chanPtr->flags & CHANNEL_DEAD) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, "unable to access channel: invalid channel", (char *) NULL); } return 1; } return 0; } /* *---------------------------------------------------------------------- * * FlushChannel -- * * This function flushes as much of the queued output as is possible * now. If calledFromAsyncFlush is nonzero, it is being called in an * event handler to flush channel output asynchronously. * * Results: * 0 if successful, else the error code that was returned by the * channel type operation. * * Side effects: * May produce output on a channel. May block indefinitely if the * channel is synchronous. May schedule an async flush on the channel. * May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */ static int FlushChannel(interp, chanPtr, calledFromAsyncFlush) Tcl_Interp *interp; /* For error reporting during close. */ Channel *chanPtr; /* The channel to flush on. */ int calledFromAsyncFlush; /* If nonzero then we are being * called from an asynchronous * flush callback. */ { 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. */ if (CheckForDeadChannel(interp,chanPtr)) return -1; /* * Loop over the queued buffers and attempt to flush as * much as possible of the queued output to the channel. */ while (1) { /* * 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 { chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr; } chanPtr->outQueueTail = chanPtr->curOutPtr; chanPtr->curOutPtr = (ChannelBuffer *) NULL; } bufPtr = chanPtr->outQueueHead; /* * If we are not being called from an async flush and an async * flush is active, we just return without producing any output. */ if ((!calledFromAsyncFlush) && (chanPtr->flags & BG_FLUSH_SCHEDULED)) { return 0; } /* * If the output queue is still empty, break out of the while loop. */ if (bufPtr == (ChannelBuffer *) NULL) { break; /* Out of the "while (1)". */ } /* * 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. */ if (written < 0) { /* * If the last attempt to write was interrupted, simply retry. */ if (errorCode == EINTR) { errorCode = 0; continue; } /* * If the channel is non-blocking and we would have blocked, * start a background flushing handler and break out of the loop. */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { if (chanPtr->flags & CHANNEL_NONBLOCKING) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { chanPtr->flags |= BG_FLUSH_SCHEDULED; UpdateInterest(chanPtr); } errorCode = 0; break; } else { panic("Blocking channel driver did not block on output"); } } /* * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { if (chanPtr->unreportedError == 0) { chanPtr->unreportedError = errorCode; } } else { Tcl_SetErrno(errorCode); if (interp != NULL) { Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } } /* * 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. */ if ((chanPtr->flags & CHANNEL_CLOSED) && (chanPtr->refCount <= 0) && (chanPtr->outQueueHead == (ChannelBuffer *) NULL) && ((chanPtr->curOutPtr == (ChannelBuffer *) NULL) || (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->nextRemoved))) { return CloseChannel(interp, chanPtr, errorCode); } return errorCode; } /* *---------------------------------------------------------------------- * * CloseChannel -- * * Utility procedure to close a channel and free its associated * resources. * * Results: * 0 on success or a POSIX error code if the operation failed. * * Side effects: * May close the actual channel; may free memory. * *---------------------------------------------------------------------- */ static int CloseChannel(interp, chanPtr, errorCode) Tcl_Interp *interp; /* For error reporting. */ Channel *chanPtr; /* The channel to close. */ 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. */ DiscardInputQueued(chanPtr, 1); /* * Discard a leftover buffer in the current output buffer field. */ if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { ckfree((char *) chanPtr->curOutPtr); chanPtr->curOutPtr = (ChannelBuffer *) NULL; } /* * The caller guarantees that there are no more buffers * queued for output. */ if (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { panic("TclFlush, closed channel: queued output left"); } /* * If the EOF character is set in the channel, append that to the * output device. */ if ((chanPtr->outEofChar != 0) && (chanPtr->flags & TCL_WRITABLE)) { int dummy; char c; c = (char) chanPtr->outEofChar; (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy); } /* * Remove TCL_READABLE and TCL_WRITABLE from chanPtr->flags, so * that close callbacks can not do input or output (assuming they * squirreled the channel away in their clientData). This also * prevents infinite loops if the callback calls any C API that * could call FlushChannel. */ 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. */ if (chanPtr->unreportedError != 0) { errorCode = chanPtr->unreportedError; } if (errorCode == 0) { errorCode = result; if (errorCode != 0) { Tcl_SetErrno(errorCode); } } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'CloseChannel'. * * Explanation * Closing a filtering channel closes the one it * superceded too. This basically ripples through * the whole chain of filters until it reaches * the underlying normal channel. * * This is done by reintegrating the superceded * channel into the (thread) global list of open * channels and then invoking a regular close. * There is no need to handle the complexities of * this process by ourselves. * * *Note* * This has to be done after the call to the * 'closeProc' of the filtering channel to allow * that one the flushing of internal buffers into * the underlying channel. */ if (chanPtr->supercedes != (Channel*) NULL) { /* Insert the channel we were stacked upon back into * the list of open channels, then do a regular close. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; chanPtr->supercedes->refCount --; /* is deregistered */ Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* * Cancel any outstanding timer. */ Tcl_DeleteTimerHandler(chanPtr->timer); /* * Mark the channel as deleted by clearing the type structure. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC); return errorCode; } /* *---------------------------------------------------------------------- * * Tcl_Close -- * * Closes a channel. * * Results: * A standard Tcl result. * * Side effects: * Closes the channel if this is the last reference. * * NOTE: * Tcl_Close removes the channel as far as the user is concerned. * However, it may continue to exist for a while longer if it has * a background flush scheduled. The device itself is eventually * closed and the channel record removed, in CloseChannel, above. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_Close(interp, chan) Tcl_Interp *interp; /* Interpreter for errors. */ Tcl_Channel chan; /* The channel being closed. Must * not be referenced in any * interpreter. */ { 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; } /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); chanPtr = (Channel *) chan; if (chanPtr->refCount > 0) { panic("called Tcl_Close on channel with refCount > 0"); } /* * 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; } } /* * Remove all the channel handler records attached to the channel * itself. */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chNext) { chNext = chPtr->nextPtr; ckfree((char *) chPtr); } chanPtr->chPtr = (ChannelHandler *) NULL; /* * Cancel any pending copy operation. */ StopCopy(chanPtr->csPtr); /* * Must set the interest mask now to 0, otherwise infinite loops * will occur if Tcl_DoOneEvent is called before the channel is * finally deleted in FlushChannel. This can happen if the channel * has a background flush active. */ chanPtr->interestMask = 0; /* * 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. */ while (chanPtr->closeCbPtr != (CloseCallback *) NULL) { cbPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr->nextPtr; (cbPtr->proc) (cbPtr->clientData); ckfree((char *) cbPtr); } /* * 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 -- * * Flushes output data on a channel. * * Results: * A standard Tcl result. * * Side effects: * May flush output queued on this channel. * *---------------------------------------------------------------------- */ int 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; } return TCL_OK; } /* *---------------------------------------------------------------------- * * DiscardInputQueued -- * * Discards any input read from the channel but not yet consumed * by Tcl reading commands. * * Results: * None. * * Side effects: * May discard input from the channel. If discardLastBuffer is zero, * leaves one buffer in place for back-filling. * *---------------------------------------------------------------------- */ static void DiscardInputQueued(chanPtr, discardSavedBuffers) Channel *chanPtr; /* Channel on which to discard * the queued input. */ int discardSavedBuffers; /* If non-zero, discard all buffers including * last one. */ { ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ bufPtr = chanPtr->inQueueHead; chanPtr->inQueueHead = (ChannelBuffer *) NULL; chanPtr->inQueueTail = (ChannelBuffer *) NULL; for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) { nxtPtr = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, discardSavedBuffers); } /* * If discardSavedBuffers is nonzero, must also discard any previously * saved buffer in the saveInBufPtr field. */ if (discardSavedBuffers) { if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) { 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 -- * * Implements seeking on Tcl Channels. This is a public function * so that other C facilities may be implemented on top of it. * * Results: * The new access point or -1 on error. If error, use Tcl_GetErrno() * to retrieve the POSIX error code for the error that occurred. * * Side effects: * May flush output on the channel. May discard queued input. * *---------------------------------------------------------------------- */ int Tcl_Seek(chan, offset, mode) Tcl_Channel chan; /* The channel on which to seek. */ int offset; /* Offset to seek to. */ int mode; /* Relative to which location to seek? */ { Channel *chanPtr; /* The real IO channel. */ ChannelBuffer *bufPtr; int inputBuffered, outputBuffered; 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 * registered in an interpreter. */ if (CheckForDeadChannel(NULL,chanPtr)) return -1; /* * Disallow seek on channels whose type does not have a seek procedure * defined. This means that the channel does not support seeking. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * If we are seeking relative to the current position, compute the * corrected offset taking into account the amount of unread input. */ if (mode == SEEK_CUR) { offset -= inputBuffered; } /* * Discard any queued input - this input should not be read after * the seek. */ DiscardInputQueued(chanPtr, 0); /* * Reset EOF and BLOCKED flags. We invalidate them by moving the * access point. Also clear CR related flags. */ chanPtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR)); /* * If the channel is in asynchronous output mode, switch it back * to synchronous mode and cancel any async flush that may be * scheduled. After the flush, the channel will be put back into * asynchronous output mode. */ wasAsync = 0; if (chanPtr->flags & CHANNEL_NONBLOCKING) { wasAsync = 1; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_BLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } chanPtr->flags &= (~(CHANNEL_NONBLOCKING)); if (chanPtr->flags & BG_FLUSH_SCHEDULED) { chanPtr->flags &= (~(BG_FLUSH_SCHEDULED)); } } /* * If the flush fails we cannot recover the original position. In * that case the seek is not attempted because we do not know where * the access position is - instead we return the error. FlushChannel * has already called Tcl_SetErrno() to report the error upwards. * If the flush succeeds we do the seek also. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { curPos = -1; } else { /* * Now seek to the new position in the channel as requested by the * caller. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) offset, mode, &result); if (curPos == -1) { Tcl_SetErrno(result); } } /* * Restore to nonblocking mode if that was the previous behavior. * * NOTE: Even if there was an async flush active we do not restore * it now because we already flushed all the queued output, above. */ if (wasAsync) { chanPtr->flags |= CHANNEL_NONBLOCKING; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_NONBLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } } return curPos; } /* *---------------------------------------------------------------------- * * Tcl_Tell -- * * Returns the position of the next character to be read/written on * this channel. * * Results: * A nonnegative integer on success, -1 on failure. If failed, * use Tcl_GetErrno() to retrieve the POSIX error code for the * error that occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Tell(chan) Tcl_Channel chan; /* The channel to return pos for. */ { 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. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * Get the current position in the device and compute the position * where the next character will be read or written. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) 0, SEEK_CUR, &result); if (curPos == -1) { Tcl_SetErrno(result); 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. * * Results: * 1 or 0, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Eof(chan) Tcl_Channel chan; /* Does this channel have EOF? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_STICKY_EOF) || ((chanPtr->flags & CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * * Results: * 0 or 1, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBlocked(chan) Tcl_Channel chan; /* Is this channel blocked? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return (chanPtr->flags & CHANNEL_BLOCKED) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBuffered -- * * Returns the number of bytes of input currently buffered in the * internal buffer of a channel. * * Results: * The number of input bytes buffered, or zero if the channel is not * open for reading. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBuffered(chan) Tcl_Channel chan; /* The channel to query. */ { Channel *chanPtr; int bytesBuffered; ChannelBuffer *bufPtr; chanPtr = (Channel *) chan; for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } return bytesBuffered; } /* *---------------------------------------------------------------------- * * Tcl_SetChannelBufferSize -- * * Sets the size of buffers to allocate to store input or output * in the channel. The size must be between 10 bytes and 1 MByte. * * Results: * None. * * Side effects: * Sets the size of buffers subsequently allocated for this channel. * *---------------------------------------------------------------------- */ void Tcl_SetChannelBufferSize(chan, sz) Tcl_Channel chan; /* The channel whose buffer size * to set. */ int sz; /* The size to set. */ { Channel *chanPtr; /* * If the buffer size is smaller than 10 bytes or larger than one MByte, * do not accept the requested size and leave the current buffer size. */ if (sz < 10) { return; } 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 -- * * Retrieves the size of buffers to allocate for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelBufferSize(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->bufSize; } /* *---------------------------------------------------------------------- * * Tcl_BadChannelOption -- * * This procedure generates a "bad option" error message in an * (optional) interpreter. It is used by channel drivers when * a invalid Set/Get option is requested. Its purpose is to concatenate * the generic options list to the specific ones and factorize * the generic options error message string. * * Results: * TCL_ERROR. * * Side effects: * An error message is generated in interp's result object to * indicate that a command was invoked with the a bad option * The message has the form * bad option "blah": should be one of * <...generic options...>+<...specific options...> * "blah" is the optionName argument and "" * is a space separated list of specific option words. * The function takes good care of inserting minus signs before * each option, commas after, and an "or" before the last option. * *---------------------------------------------------------------------- */ int Tcl_BadChannelOption(interp, optionName, optionList) Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/ char *optionName; /* 'bad option' name */ char *optionList; /* Specific options list to append * to the standard generic options. * can be NULL for generic options * only. */ { if (interp) { CONST char *genericopt = "blocking buffering buffersize eofchar translation"; char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, (char *) genericopt, -1); if (optionList && (*optionList)) { Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad option \"", optionName, "\": should be one of ", (char *) NULL); argc--; for (i = 0; i < argc; i++) { Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL); } Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL); Tcl_DStringFree(&ds); ckfree((char *) argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelOption -- * * 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: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelOption(interp, chan, optionName, dsPtr) Tcl_Interp *interp; /* For error reporting - can be NULL. */ Tcl_Channel chan; /* Channel on which to get option. */ char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */ { size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; int flags; /* * If we are in the middle of a background copy, use the saved flags. */ if (chanPtr->csPtr) { if (chanPtr == chanPtr->csPtr->readPtr) { flags = chanPtr->csPtr->readFlags; } else { flags = chanPtr->csPtr->writeFlags; } } else { flags = chanPtr->flags; } /* * Disallow options 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(interp,chanPtr)) return TCL_ERROR; /* * If the optionName is NULL it means that we want a list of all * options and values. */ if (optionName == (char *) NULL) { len = 0; } else { len = strlen(optionName); } if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blocking"); } Tcl_DStringAppendElement(dsPtr, (flags & CHANNEL_NONBLOCKING) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffering", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffering"); } if (flags & CHANNEL_LINEBUFFERED) { Tcl_DStringAppendElement(dsPtr, "line"); } else if (flags & CHANNEL_UNBUFFERED) { Tcl_DStringAppendElement(dsPtr, "none"); } else { Tcl_DStringAppendElement(dsPtr, "full"); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffersize", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffersize"); } 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); } if (flags & TCL_READABLE) { if (chanPtr->inEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->inEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (flags & TCL_WRITABLE) { if (chanPtr->outEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->outEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 1) && (optionName[1] == 't') && (strncmp(optionName, "-translation", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-translation"); } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringStartSublist(dsPtr); } if (flags & TCL_READABLE) { if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (flags & TCL_WRITABLE) { if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) { /* * let the driver specific handle additional options * and result code and message. */ return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData, interp, optionName, dsPtr); } else { /* * no driver specific options case. */ if (len == 0) { 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? */ char *newValue; /* New value for option. */ { int newMode; /* New (numeric) mode to sert. */ Channel *chanPtr; /* The real IO channel. */ size_t len; /* Length of optionName string. */ int argc; char **argv; chanPtr = (Channel *) chan; /* * If the channel is in the middle of a background copy, fail. */ if (chanPtr->csPtr) { if (interp) { Tcl_AppendResult(interp, "unable to set channel options: background copy in progress", (char *) NULL); } return TCL_ERROR; } /* * Disallow options 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 TCL_ERROR; len = strlen(optionName); if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0)) { if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) { return TCL_ERROR; } 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)) { chanPtr->flags &= (~(CHANNEL_UNBUFFERED)); chanPtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { chanPtr->flags &= (~(CHANNEL_LINEBUFFERED)); chanPtr->flags |= CHANNEL_UNBUFFERED; } else { 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; } else if (argc == 1) { if (chanPtr->flags & TCL_WRITABLE) { chanPtr->outEofChar = (int) argv[0][0]; } if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } } else if (argc != 2) { if (interp) { Tcl_AppendResult(interp, "bad value for -eofchar: should be a list of one or", " two elements", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } else { if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } 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; } if (argc == 1) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: must be a one or two", " element list", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } 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) { newMode = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered * 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) { /* * This is a hack to get TCP sockets to produce output * in CRLF mode if they are being set into AUTO mode. * A better solution for achieving this effect will be * coded later. */ if (strcmp(chanPtr->typePtr->typeName, "tcp") == 0) { 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) { chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } 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 -- * * Removes channel handlers that refer to the supplied interpreter, * so that if the actual channel is not closed now, these handlers * will not run on subsequent events on the channel. This would be * erroneous, because the interpreter no longer has a reference to * this channel. * * Results: * None. * * Side effects: * Removes channel handlers. * *---------------------------------------------------------------------- */ static void CleanupChannelHandlers(interp, chanPtr) Tcl_Interp *interp; Channel *chanPtr; { EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* * Remove fileevent records on this channel that refer to the * given interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } } /* *---------------------------------------------------------------------- * * Tcl_NotifyChannel -- * * This procedure is called by a channel driver when a driver * detects an event on a channel. This procedure is responsible * for actually handling the event by invoking any channel * handler callbacks. * * Results: * None. * * Side effects: * Whatever the channel handler callback procedure does. * *---------------------------------------------------------------------- */ void Tcl_NotifyChannel(channel, mask) 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. */ if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; (*(chPtr->proc))(chPtr->clientData, mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; } } /* * 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 -- * * Arrange for the notifier to call us back at appropriate times * based on the current state of the channel. * * Results: * None. * * Side effects: * May schedule a timer or driver handler. * *---------------------------------------------------------------------- */ static void UpdateInterest(chanPtr) Channel *chanPtr; /* Channel to update. */ { int mask = chanPtr->interestMask; /* * If there are flushed buffers waiting to be written, then * we need to watch for the channel to become writable. */ 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); } } } (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask); } /* *---------------------------------------------------------------------- * * ChannelTimerProc -- * * Timer handler scheduled by UpdateInterest to monitor the * channel buffers until they are empty. * * Results: * None. * * Side effects: * May invoke channel handlers. * *---------------------------------------------------------------------- */ 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. */ chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc, (ClientData) chanPtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); } else { chanPtr->timer = NULL; UpdateInterest(chanPtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * * Arrange for a given procedure to be invoked whenever the * channel indicated by the chanPtr arg becomes readable or * writable. * * Results: * None. * * Side effects: * From now on, whenever the I/O channel given by chanPtr becomes * ready in the way indicated by mask, proc will be invoked. * See the manual entry for details on the calling sequence * to proc. If there is already an event handler for chan, proc * and clientData, then the mask will be updated. * *---------------------------------------------------------------------- */ void Tcl_CreateChannelHandler(chan, mask, proc, clientData) Tcl_Channel chan; /* The channel to create the handler for. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions under which * proc should be called. Use 0 to * disable a registered handler. */ Tcl_ChannelProc *proc; /* Procedure to call for each * selected event. */ ClientData clientData; /* Arbitrary data to pass to proc. */ { ChannelHandler *chPtr; Channel *chanPtr; chanPtr = (Channel *) chan; /* * Check whether this channel handler is not already registered. If * it is not, create a new record, else reuse existing record (smash * current values). */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) && (chPtr->clientData == clientData)) { break; } } if (chPtr == (ChannelHandler *) NULL) { chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler)); chPtr->mask = 0; chPtr->proc = proc; chPtr->clientData = clientData; chPtr->chanPtr = chanPtr; chPtr->nextPtr = chanPtr->chPtr; chanPtr->chPtr = chPtr; } /* * The remainder of the initialization below is done regardless of * whether or not this is a new record or a modification of an old * one. */ chPtr->mask = mask; /* * Recompute the interest mask for the channel - this call may actually * be disabling an existing handler. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * Tcl_DeleteChannelHandler -- * * Cancel a previously arranged callback arrangement for an IO * channel. * * Results: * None. * * Side effects: * If a callback was previously registered for this chan, proc and * clientData , it is removed and the callback will no longer be called * when the channel becomes ready for IO. * *---------------------------------------------------------------------- */ void Tcl_DeleteChannelHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to remove the * callback. */ 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. */ for (prevChPtr = (ChannelHandler *) NULL, chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData) && (chPtr->proc == proc)) { break; } prevChPtr = chPtr; } /* * If not found, return without doing anything. */ if (chPtr == (ChannelHandler *) NULL) { return; } /* * 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_DeleteChanelHandler is called inside an event. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * DeleteScriptRecord -- * * Delete a script record for this combination of channel, interp * and mask. * * Results: * None. * * Side effects: * Deletes a script record and cancels a channel event handler. * *---------------------------------------------------------------------- */ static void DeleteScriptRecord(interp, chanPtr, mask) Tcl_Interp *interp; /* Interpreter in which script was to be * executed. */ Channel *chanPtr; /* The channel for which to delete the * script record (if any). */ int mask; /* Events in mask must exactly match mask * of script to delete. */ { EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = chanPtr->scriptRecordPtr, prevEsPtr = (EventScriptRecord *) NULL; esPtr != (EventScriptRecord *) NULL; prevEsPtr = esPtr, esPtr = esPtr->nextPtr) { if ((esPtr->interp == interp) && (esPtr->mask == mask)) { if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { prevEsPtr->nextPtr = esPtr->nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) esPtr); Tcl_DecrRefCount(esPtr->scriptPtr); ckfree((char *) esPtr); break; } } } /* *---------------------------------------------------------------------- * * CreateScriptRecord -- * * Creates a record to store a script to be executed when a specific * event fires on a specific channel. * * Results: * None. * * 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 -- * * Invokes a script scheduled by "fileevent" for when the channel * becomes ready for IO. This function is invoked by the channel * handler which was created by the Tcl "fileevent" command. * * Results: * None. * * Side effects: * Whatever the script does. * *---------------------------------------------------------------------- */ static void 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. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundError(interp); } 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; } /* *---------------------------------------------------------------------- * * TclTestChannelCmd -- * * Implements the Tcl "testchannel" debugging command and its * subcommands. This is part of the testing environment but must be * in this file instead of tclTest.c because it needs access to the * fields of struct Channel. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int TclTestChannelCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Interpreter for result. */ int argc; /* Count of additional args. */ char **argv; /* Additional arg strings. */ { char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ 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]); Tcl_AppendElement(interp, chanPtr->typePtr->typeName); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_NONBLOCKING) { Tcl_AppendElement(interp, "nonblocking"); } else { Tcl_AppendElement(interp, "blocking"); } if (chanPtr->flags & CHANNEL_LINEBUFFERED) { Tcl_AppendElement(interp, "line"); } else if (chanPtr->flags & CHANNEL_UNBUFFERED) { Tcl_AppendElement(interp, "none"); } else { Tcl_AppendElement(interp, "full"); } if (chanPtr->flags & BG_FLUSH_SCHEDULED) { Tcl_AppendElement(interp, "async_flush"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_EOF) { Tcl_AppendElement(interp, "eof"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_BLOCKED) { Tcl_AppendElement(interp, "blocked"); } else { Tcl_AppendElement(interp, "unblocked"); } if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "saw_cr"); } else { Tcl_AppendElement(interp, ""); } } else if (chanPtr->inputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "queued_cr"); } else { Tcl_AppendElement(interp, ""); } } if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); } for (IOQueued = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved; } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved; } for (bufPtr = chanPtr->outQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved); } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr)); Tcl_AppendElement(interp, buf); TclFormatInt(buf, chanPtr->refCount); Tcl_AppendElement(interp, buf); return TCL_OK; } if ((cmdName[0] == 'i') && (strncmp(cmdName, "inputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; } if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } return TCL_OK; } if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "outputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - 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) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (chanPtr->flags & INPUT_SAW_CR) ? "1" : "0", (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } 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", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ", "info, open, readable, or writable", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclTestChannelEventCmd -- * * This procedure implements the "testchannelevent" command. It is * used to test the Tcl channel event mechanism. It is present in * this file instead of tclTest.c because it needs access to the * internal structure of the channel. * * Results: * A standard Tcl result. * * Side effects: * Creates, deletes and returns channel event handlers. * *---------------------------------------------------------------------- */ /* ARGSUSED */ 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], " channelName cmd ?arg1? ?arg2?\"", (char *) NULL); return TCL_ERROR; } chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL); if (chanPtr == (Channel *) NULL) { return TCL_ERROR; } cmd = argv[2]; len = strlen(cmd); if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName add eventSpec script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[3], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[3], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[3], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr = (EventScriptRecord *) ckalloc((unsigned) 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; } if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) { if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { for (prevEsPtr = chanPtr->scriptRecordPtr; (prevEsPtr != (EventScriptRecord *) NULL) && (prevEsPtr->nextPtr != esPtr); prevEsPtr = prevEsPtr->nextPtr) { /* Empty loop body. */ } 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)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index event\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[4], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[4], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[4], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[4], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr->mask = mask; 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 -- * * This routine copies data from one channel to another, either * synchronously or asynchronously. If a command script is * supplied, the operation runs in the background. The script * is invoked when the copy completes. Otherwise the function * waits until the copy is completed before returning. * * Results: * A standard Tcl result. * * Side effects: * May schedule a background copy operation that causes both * channels to be marked busy. * *---------------------------------------------------------------------- */ int TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Channel inChan; /* Channel to read from. */ Tcl_Channel outChan; /* Channel to write to. */ int toRead; /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */ { Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; if (inPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); return TCL_ERROR; } if (outPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); return TCL_ERROR; } readFlags = inPtr->flags; writeFlags = outPtr->flags; /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. * If there is an error, restore the old blocking mode. */ if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(interp, inPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) { return TCL_ERROR; } } if (inPtr != outPtr) { if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(NULL, outPtr, nonBlocking ? TCL_MODE_BLOCKING : TCL_MODE_NONBLOCKING) != TCL_OK) { if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING) ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); return TCL_ERROR; } } } } /* * Make sure the output side is unbuffered. */ outPtr->flags = (outPtr->flags & ~(CHANNEL_LINEBUFFERED)) | CHANNEL_UNBUFFERED; /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inPtr->bufSize); csPtr->bufSize = inPtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; inPtr->csPtr = csPtr; outPtr->csPtr = csPtr; /* * Start copying data between the channels. */ return CopyData(csPtr, 0); } /* *---------------------------------------------------------------------- * * CopyData -- * * This function implements the lowest level of the copying * mechanism for TclCopyChannel. * * Results: * Returns TCL_OK on success, else TCL_ERROR. * * Side effects: * Moves data between channels, may create channel handlers. * *---------------------------------------------------------------------- */ static int CopyData(csPtr, mask) CopyState *csPtr; /* State of copy operation. */ int mask; /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL; Tcl_Channel inChan, outChan; int result = TCL_OK; int size; int total; inChan = (Tcl_Channel)csPtr->readPtr; outChan = (Tcl_Channel)csPtr->writePtr; interp = csPtr->interp; cmdPtr = csPtr->cmdPtr; /* * Copy the data the slow way, using the translation mechanism. */ while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ if (csPtr->readPtr->unreportedError != 0) { Tcl_SetErrno(csPtr->readPtr->unreportedError); csPtr->readPtr->unreportedError = 0; goto readError; } if (csPtr->writePtr->unreportedError != 0) { Tcl_SetErrno(csPtr->writePtr->unreportedError); csPtr->writePtr->unreportedError = 0; goto writeError; } /* * Read up to bufSize bytes. */ if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { size = csPtr->bufSize; } else { size = csPtr->toRead; } size = DoRead(csPtr->readPtr, csPtr->buffer, size); if (size < 0) { readError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error reading \"", Tcl_GetChannelName(inChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } else if (size == 0) { /* * We had an underflow on the read side. If we are at EOF, * then the copying is done, otherwise set up a channel * handler to detect when the channel becomes readable again. */ if (Tcl_Eof(inChan)) { break; } else if (!(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Now write the buffer out. */ size = DoWrite(csPtr->writePtr, csPtr->buffer, size); if (size < 0) { writeError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error writing \"", Tcl_GetChannelName(outChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } /* * Check to see if the write is happening in the background. If so, * stop copying and wait for the channel to become writable again. */ if (csPtr->writePtr->flags & BG_FLUSH_SCHEDULED) { if (!(mask & TCL_WRITABLE)) { if (mask & TCL_READABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Update the current byte count if we care. */ if (csPtr->toRead != -1) { csPtr->toRead -= size; } csPtr->total += size; /* * For background copies, we only do one buffer per invocation so * we don't starve the rest of the system. */ if (cmdPtr) { /* * The first time we enter this code, there won't be a * channel handler established yet, so do it here. */ if (mask == 0) { Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } } /* * Make the callback or return the number of bytes transferred. * The local total is used because StopCopy frees csPtr. */ total = csPtr->total; if (cmdPtr) { /* * Get a private copy of the command so we can mutate it * by adding arguments. Note that StopCopy frees our saved * reference to the original command obj. */ cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); 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 * the background copy operation. It is just a trivial wrapper * around the CopyData routine. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void CopyEventProc(clientData, mask) ClientData clientData; int mask; { (void) CopyData((CopyState *)clientData, mask); } /* *---------------------------------------------------------------------- * * StopCopy -- * * This routine halts a copy that is in progress. * * Results: * None. * * Side effects: * Removes any pending channel handlers and restores the blocking * and buffering modes of the channels. The CopyState is freed. * *---------------------------------------------------------------------- */ static void StopCopy(csPtr) CopyState *csPtr; /* State for bg copy to stop . */ { int nonBlocking; if (!csPtr) { return; } /* * Restore the old blocking mode and output buffering mode. */ nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING); if (nonBlocking != (csPtr->readPtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->readPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } if (csPtr->writePtr != csPtr->writePtr) { if (nonBlocking != (csPtr->writePtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->writePtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } } csPtr->writePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); csPtr->writePtr->flags |= csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc, (ClientData)csPtr); if (csPtr->readPtr != csPtr->writePtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr, CopyEventProc, (ClientData)csPtr); } 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; } trf2.1.4/patches/v8.1b3/tclStubInit.c0000644000175000017500000004773111216344362016550 0ustar sergeisergei/* * 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.2 1999/04/19 18:29:42 aku 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 */ Tcl_ReplaceChannel, /* 281 */ Tcl_UndoReplaceChannel, /* 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. */ trf2.1.4/patches/v8.1b3/tclDecls.h0000644000175000017500000033452711216344361016047 0ustar sergeisergei/* * 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.2 1999/04/19 18:29:40 aku 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)); /* 281 */ EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 282 */ EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Channel chan)); /* 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 */ Tcl_Channel (*tcl_ReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 281 */ void (*tcl_UndoReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 282 */ 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 #ifndef Tcl_ReplaceChannel #define Tcl_ReplaceChannel \ (tclStubsPtr->tcl_ReplaceChannel) /* 281 */ #endif #ifndef Tcl_UndoReplaceChannel #define Tcl_UndoReplaceChannel \ (tclStubsPtr->tcl_UndoReplaceChannel) /* 282 */ #endif /* 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 */ trf2.1.4/patches/v8.1.1/0000755000175000017500000000000011216344734014041 5ustar sergeisergeitrf2.1.4/patches/v8.1.1/README0000644000175000017500000000017011216344361014713 0ustar sergeisergei Tcl 8.1.1 does not need a separate patch kit. The patch kit for Tcl 8.1 is applicable, see Trf2.1.3/patches/v8.1/ trf2.1.4/patches/v8.1b2/0000755000175000017500000000000011216344734014126 5ustar sergeisergeitrf2.1.4/patches/v8.1b2/tclStubs.c0000644000175000017500000017112411216344361016077 0ustar sergeisergei/* * 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.2 1999/03/28 15:16:04 aku 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, string, boolPtr) Tcl_Interp * interp; char * string; int * boolPtr; { return (tclStubsPtr->tcl_GetBoolean)(interp, string, 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, string, doublePtr) Tcl_Interp * interp; char * string; double * doublePtr; { return (tclStubsPtr->tcl_GetDouble)(interp, string, 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, string, intPtr) Tcl_Interp * interp; char * string; int * intPtr; { return (tclStubsPtr->tcl_GetInt)(interp, string, 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, string, length) Tcl_DString * dsPtr; CONST char * string; int length; { return (tclStubsPtr->tcl_DStringAppend)(dsPtr, string, 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, string, ptr) Tcl_Interp * interp; char * string; int * ptr; { return (tclStubsPtr->tcl_ExprBoolean)(interp, string, 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, string, ptr) Tcl_Interp * interp; char * string; double * ptr; { return (tclStubsPtr->tcl_ExprDouble)(interp, string, 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, string, ptr) Tcl_Interp * interp; char * string; long * ptr; { return (tclStubsPtr->tcl_ExprLong)(interp, string, 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, string, write, checkUsage, filePtr) Tcl_Interp * interp; char * string; int write; int checkUsage; ClientData * filePtr; { return (tclStubsPtr->tcl_GetOpenFile)(interp, string, 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; 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, string, start) Tcl_Interp * interp; Tcl_RegExp regexp; CONST char * string; CONST char * start; { return (tclStubsPtr->tcl_RegExpExec)(interp, regexp, string, start); } /* Slot 214 */ int Tcl_RegExpMatch(interp, string, pattern) Tcl_Interp * interp; char * string; char * pattern; { return (tclStubsPtr->tcl_RegExpMatch)(interp, string, 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(string, flagPtr) CONST char * string; int * flagPtr; { return (tclStubsPtr->tcl_ScanElement)(string, flagPtr); } /* Slot 219 */ int Tcl_ScanCountedElement(string, length, flagPtr) CONST char * string; int length; int * flagPtr; { return (tclStubsPtr->tcl_ScanCountedElement)(string, 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, string, freeProc) Tcl_Interp * interp; char * string; Tcl_FreeProc * freeProc; { (tclStubsPtr->tcl_SetResult)(interp, string, 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, list, argcPtr, argvPtr) Tcl_Interp * interp; CONST char * list; int * argcPtr; char *** argvPtr; { return (tclStubsPtr->tcl_SplitList)(interp, list, 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(string, pattern) CONST char * string; CONST char * pattern; { return (tclStubsPtr->tcl_StringMatch)(string, 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; 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, string, termPtr) Tcl_Interp * interp; char * string; char ** termPtr; { return (tclStubsPtr->tcl_ParseVar)(interp, string, 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 345 */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp * interp; Tcl_ChannelType * typePtr; ClientData instanceData; int mask; Tcl_Channel prevChan; { return (tclStubsPtr->tcl_ReplaceChannel)(interp, typePtr, instanceData, mask, prevChan); } /* Slot 346 */ void Tcl_UndoReplaceChannel(interp, chan) Tcl_Interp * interp; Tcl_Channel chan; { (tclStubsPtr->tcl_UndoReplaceChannel)(interp, chan); } /* !END!: Do not edit above this line. */ trf2.1.4/patches/v8.1b2/standard.patch0000644000175000017500000004105711216344361016752 0ustar sergeisergei*** tcl.decls.orig Sun Mar 21 13:58:14 1999 --- tcl.decls Sun Mar 21 14:01:56 1999 *************** *** 1168,1173 **** --- 1168,1196 ---- void Tcl_SetDefaultEncodingDir(char *path) } + # Andreas Kupries , 03/21/1999 + # "Trf-Patch for filtering channels" + # + # C-Level API for (un)stacking of channels. This allows the introduction + # of filtering channels with relatively little changes to the core. + # This patch was created in cooperation with Jan Nijtmans + # and is therefore part of his plus-patches too. + # + # It would have been possible to place the following definitions according + # to the alphabetical order used elsewhere in this file, but I decided + # against that to ease the maintenance of the patch across new tcl versions + # (patch usually has no problems to integrate the patch file for the last + # version into the new one). + + declare 345 generic { + Tcl_Channel Tcl_ReplaceChannel(Tcl_Interp *interp, \ + Tcl_ChannelType *typePtr, ClientData instanceData, \ + int mask, Tcl_Channel prevChan) + } + declare 346 generic { + void Tcl_UndoReplaceChannel(Tcl_Interp *interp, Tcl_Channel chan) + } + ############################################################################## # Define the platform specific public Tcl interface. These functions are *** tclDecls.h.orig Sun Mar 21 13:57:37 1999 --- tclDecls.h Sun Mar 21 14:16:44 1999 *************** *** 1048,1053 **** --- 1048,1061 ---- EXTERN char * Tcl_GetDefaultEncodingDir _ANSI_ARGS_((void)); /* 342 */ EXTERN void Tcl_SetDefaultEncodingDir _ANSI_ARGS_((char * path)); + /* 345 */ + EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_((Tcl_Interp * interp, + Tcl_ChannelType * typePtr, + ClientData instanceData, int mask, + Tcl_Channel prevChan)); + /* 346 */ + EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_(( + Tcl_Interp * interp, Tcl_Channel chan)); typedef struct TclStubHooks { struct TclPlatStubs *tclPlatStubs; *************** *** 1426,1431 **** --- 1434,1441 ---- 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* reserved343; void* reserved344; + Tcl_Channel (*tcl_ReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 345 */ + void (*tcl_UndoReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 346 */ } TclStubs; extern TclStubs *tclStubsPtr; *************** *** 2792,2797 **** --- 2802,2815 ---- #ifndef Tcl_SetDefaultEncodingDir #define Tcl_SetDefaultEncodingDir(path) \ (tclStubsPtr->tcl_SetDefaultEncodingDir)(path) /* 342 */ + #endif + #ifndef Tcl_ReplaceChannel + #define Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) \ + (tclStubsPtr->tcl_ReplaceChannel)(interp, typePtr, instanceData, mask, prevChan) /* 345 */ + #endif + #ifndef Tcl_UndoReplaceChannel + #define Tcl_UndoReplaceChannel(interp, chan) \ + (tclStubsPtr->tcl_UndoReplaceChannel)(interp, chan) /* 346 */ #endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ *** tclStubInit.c.orig Sun Mar 21 14:04:02 1999 --- tclStubInit.c Sun Mar 21 14:16:51 1999 *************** *** 412,417 **** --- 412,419 ---- Tcl_GetString, /* 340 */ Tcl_GetDefaultEncodingDir, /* 341 */ Tcl_SetDefaultEncodingDir, /* 342 */ NULL, NULL, + Tcl_ReplaceChannel, /* 345 */ + Tcl_UndoReplaceChannel, /* 346 */ }; TclStubs *tclStubsPtr = &tclStubs; *** tclStubs.c.orig Sun Mar 21 14:04:02 1999 --- tclStubs.c Sun Mar 21 14:16:46 1999 *************** *** 3247,3251 **** --- 3247,3272 ---- (tclStubsPtr->tcl_SetDefaultEncodingDir)(path); } + /* Slot 345 */ + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp * interp; + Tcl_ChannelType * typePtr; + ClientData instanceData; + int mask; + Tcl_Channel prevChan; + { + return (tclStubsPtr->tcl_ReplaceChannel)(interp, typePtr, instanceData, mask, prevChan); + } + + /* Slot 346 */ + void + Tcl_UndoReplaceChannel(interp, chan) + Tcl_Interp * interp; + Tcl_Channel chan; + { + (tclStubsPtr->tcl_UndoReplaceChannel)(interp, chan); + } + /* !END!: Do not edit above this line. */ *** tclIO.c.orig Thu Mar 11 06:14:58 1999 --- tclIO.c Sun Mar 21 13:50:55 1999 *************** *** 202,207 **** --- 202,229 ---- int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ + + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * The single change to the internal datastructures of the core. Every + * channel now maintains a reference to the channel he is stacked upon. + * This reference is NULL for normal channels. Only the two exported + * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the + * end of 'tcl.h') use this field in a non-trivial way. + * + * Of the existing procedures the only following are affected by this + * change: + * + * - Tcl_RegisterChannel + * - Tcl_CreateChannel + * - CloseChannel + * + * The why is explained at the changed locations. + */ + + struct Channel* supercedes; /* Refers to channel this one was stacked upon */ + } Channel; /* *************** *** 1038,1044 **** if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! panic("Tcl_RegisterChannel: duplicate channel names"); } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } --- 1060,1080 ---- if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! ! /* Andreas Kupries , 12/13/1998 ! * "Trf-Patch for filtering channels" ! * ! * This is the change to 'Tcl_RegisterChannel'. ! * ! * Explanation: ! * The moment a channel is stacked upon another he ! * takes the identity of the channel he supercedes, ! * i.e. he gets the *same* name. Because of this we ! * cannot check for duplicate names anymore, they ! * have to be allowed now. ! */ ! ! /* panic("Tcl_RegisterChannel: duplicate channel names"); */ } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } *************** *** 1297,1302 **** --- 1333,1352 ---- chanPtr->timer = NULL; chanPtr->csPtr = NULL; + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * This is the change to 'Tcl_CreateChannel'. + * + * Explanation: + * It is of course necessary to initialize the new field + * in the Channel structure. The chosen value indicates + * that the created channel is a normal one, and not + * stacked upon another. + */ + + chanPtr->supercedes = (Channel*) NULL; + chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) *************** *** 1330,1335 **** --- 1380,1622 ---- return (Tcl_Channel) chanPtr; } + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * The following two procedures are the new, exported ones. They + * - create a channel stacked upon an existing one and + * - pop a stacked channel off, thus revealing the superceded one. + * + * Please read the following completely. + */ + + /* + *---------------------------------------------------------------------- + * + * Tcl_ReplaceChannel -- + * + * Replaces an entry in the hash table for a Tcl_Channel + * record. The replacement is a new channel with same name, + * it supercedes the replaced channel. Input and output of + * the superceded channel is now going through the newly + * created channel and allows the arbitrary filtering/manipulation + * of the dataflow. + * + * Results: + * Returns the new Tcl_Channel. + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_ChannelType *typePtr; /* The channel type record for the new + * channel. */ + ClientData instanceData; /* Instance specific data for the new + * channel. */ + int mask; /* TCL_READABLE & TCL_WRITABLE to indicate + * if the channel is readable, writable. */ + Tcl_Channel prevChan; /* The channel structure to replace */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr, *pt, *prevPt; + + /* + * Find the given channel in the list of all channels, compute enough + * information to allow easy removal after the conditions are met. + */ + + prevPt = (Channel*) NULL; + pt = (Channel*) tsdPtr->firstChanPtr; + + while (pt != (Channel *) prevChan) { + prevPt = pt; + pt = pt->nextChanPtr; + } + + /* + * 'pt == prevChan' now + */ + + if (!pt) { + return (Tcl_Channel) NULL; + } + + /* + * Here we check if the given "mask" matches the "flags" + * of the already existing channel. + * + * | - | R | W | RW | + * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) + * - | | | | | + * R | | + | | + | The superceding channel is allowed to + * W | | | + | + | restrict the capabilities of the + * RW| | + | + | + | superceded one ! + * --+---+---+---+----+ + */ + + if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { + return (Tcl_Channel) NULL; + } + + + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); + chanPtr->flags = mask; + + /* + * Set the channel up initially in no Input translation mode and + * no Output translation mode. + */ + + chanPtr->inputTranslation = TCL_TRANSLATE_LF; + chanPtr->outputTranslation = TCL_TRANSLATE_LF; + chanPtr->inEofChar = 0; + chanPtr->outEofChar = 0; + + chanPtr->unreportedError = 0; + chanPtr->instanceData = instanceData; + chanPtr->typePtr = typePtr; + chanPtr->refCount = 0; + chanPtr->closeCbPtr = (CloseCallback *) NULL; + chanPtr->curOutPtr = (ChannelBuffer *) NULL; + chanPtr->outQueueHead = (ChannelBuffer *) NULL; + chanPtr->outQueueTail = (ChannelBuffer *) NULL; + chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; + chanPtr->inQueueHead = (ChannelBuffer *) NULL; + 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; + + /* 06/12/1998: New for Tcl 8.1 + * + * Take over the encoding from the superceded channel, so that it will be + * executed in the future despite the replacement, and at the proper time + * (*after* / *before* our transformation, depending on the direction of + * the dataflow). + * + * *Important* + * The I/O functionality of the filtering channel has to use 'Tcl_Read' to + * get at the underlying information. This will circumvent the de/encoder + * stage [*] in the superceded channel and removes the need to trouble + * ourselves with 'ByteArray's too. + * + * [*] I'm talking about the conversion between UNICODE and other + * representations, like ASCII. + */ + + chanPtr->encoding=Tcl_GetEncoding(interp,Tcl_GetEncodingName(pt->encoding)); + chanPtr->inputEncodingState = pt->inputEncodingState; + chanPtr->inputEncodingFlags = pt->inputEncodingFlags; + chanPtr->outputEncodingState = pt->outputEncodingState; + chanPtr->outputEncodingFlags = pt->outputEncodingFlags; + + chanPtr->outputStage = NULL; + + if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { + chanPtr->outputStage = (char *) + ckalloc((unsigned) (chanPtr->bufSize + 2)); + } + + chanPtr->supercedes = (Channel*) prevChan; + + chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); + strcpy (chanPtr->channelName, pt->channelName); + + if (prevPt) { + prevPt->nextChanPtr = chanPtr; + } else { + tsdPtr->firstChanPtr = chanPtr; + } + + chanPtr->nextChanPtr = pt->nextChanPtr; + + Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); + + /* + * The superceded channel is effectively unregistered + */ + + /*chanPtr->supercedes->refCount --;*/ + + return (Tcl_Channel) chanPtr; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_UndoReplaceChannel -- + * + * Unstacks an entry in the hash table for a Tcl_Channel + * record. This is the reverse to 'Tcl_ReplaceChannel'. + * The old, superceded channel is uncovered and re-registered + * in the appropriate datastructures. + * + * Results: + * Returns the old Tcl_Channel, i.e. the one which was stacked over. + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + + void + Tcl_UndoReplaceChannel (interp, chan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_Channel chan; /* The channel to unstack */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel* chanPtr = (Channel*) chan; + + if (chanPtr->supercedes != (Channel*) NULL) { + Tcl_HashTable *hTblPtr; /* Hash table of channels. */ + Tcl_HashEntry *hPtr; /* Search variable. */ + int new; /* Is the hash entry new or does it exist? */ + + /* + * Insert the channel we were stacked upon back into + * the list of open channels. Place it back into the hashtable too. + * Correct 'refCount', as this actually unregisters 'chan'. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + + hTblPtr = GetChannelTable (interp); + hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); + + Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); + chanPtr->refCount --; + + /* + * The superceded channel is effectively registered again + */ + + /*chanPtr->supercedes->refCount ++;*/ + } + + /* + * Disconnect the channels, then do a regular close upon the + * stacked one, the filtering channel. This may cause flushing + * of data into the superceded channel (if the filtering channel + * ('chan') remembered its parent in itself). + */ + + chanPtr->supercedes = NULL; + + if (chanPtr->refCount == 0) { + Tcl_Close (interp, chan); + } + } + /* *---------------------------------------------------------------------- * *************** *** 2003,2008 **** --- 2290,2330 ---- if (errorCode != 0) { Tcl_SetErrno(errorCode); } + } + + /* Andreas Kupries , 12/13/1998 + * "Trf-Patch for filtering channels" + * + * This is the change to 'CloseChannel'. + * + * Explanation + * Closing a filtering channel closes the one it + * superceded too. This basically ripples through + * the whole chain of filters until it reaches + * the underlying normal channel. + * + * This is done by reintegrating the superceded + * channel into the (thread) global list of open + * channels and then invoking a regular close. + * There is no need to handle the complexities of + * this process by ourselves. + * + * *Note* + * This has to be done after the call to the + * 'closeProc' of the filtering channel to allow + * that one the flushing of internal buffers into + * the underlying channel. + */ + + if (chanPtr->supercedes != (Channel*) NULL) { + /* Insert the channel we were stacked upon back into + * the list of open channels, then do a regular close. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + chanPtr->supercedes->refCount --; /* is deregistered */ + Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* trf2.1.4/patches/v8.1b2/README0000644000175000017500000000012111216344361014774 0ustar sergeisergeiThe byteorder patch for 8.1b2 was written by Jan Nijtmans . trf2.1.4/patches/v8.1b2/tcl.decls0000644000175000017500000010611711216344361015726 0ustar sergeisergei# 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.2 1999/03/28 15:16:04 aku 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 *string, 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 *string, 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 *string, 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 *string, \ 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 *string, 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 *string, 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 *string, 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 *string, 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 *string, CONST char *start) } declare 214 generic { int Tcl_RegExpMatch(Tcl_Interp *interp, char *string, 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 *string, int *flagPtr) } declare 219 generic { int Tcl_ScanCountedElement(CONST char *string, 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 *string, \ 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 *list, 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 *string, 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 *string, 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) } # Reserved for future use (8.0.x vs. 8.1) # declare 280 generic { # } # 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) } # Andreas Kupries , 03/21/1999 # "Trf-Patch for filtering channels" # # C-Level API for (un)stacking of channels. This allows the introduction # of filtering channels with relatively little changes to the core. # This patch was created in cooperation with Jan Nijtmans # and is therefore part of his plus-patches too. # # It would have been possible to place the following definitions according # to the alphabetical order used elsewhere in this file, but I decided # against that to ease the maintenance of the patch across new tcl versions # (patch usually has no problems to integrate the patch file for the last # version into the new one). declare 345 generic { Tcl_Channel Tcl_ReplaceChannel(Tcl_Interp *interp, \ Tcl_ChannelType *typePtr, ClientData instanceData, \ int mask, Tcl_Channel prevChan) } declare 346 generic { void Tcl_UndoReplaceChannel(Tcl_Interp *interp, Tcl_Channel chan) } ############################################################################## # Define the platform specific public Tcl interface. These functions are # only available on the designated platform. interface tclPlat ################## # 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) } trf2.1.4/patches/v8.1b2/byteorder.patch0000644000175000017500000001246711216344361017154 0ustar sergeisergei*** tcl.h.orig Sat Mar 20 19:59:09 1999 --- tcl.h Sat Mar 20 19:59:11 1999 *************** *** 1336,1341 **** --- 1336,1348 ---- EXTERN int Tcl_AppInit _ANSI_ARGS_((Tcl_Interp *interp)); + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + */ + EXTERN int Tcl_GetChannelByteorder _ANSI_ARGS_(( + Tcl_Channel chan)); + #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS *** tclIO.c.orig Thu Mar 11 06:14:58 1999 --- tclIO.c Sat Mar 20 19:58:01 1999 *************** *** 261,266 **** --- 261,270 ---- * When set, file events will not be * delivered for buffered data until * the state of the channel changes. */ + /* Andreas Kupries , 03/21/1997. + * "Trf-Patch for channels with a switchable byteorder" + */ + #define CHANNEL_IS_SMALLENDIAN (1<<16) /* Multibyte words are stored with MSB last */ /* * For each channel handler registered in a call to Tcl_CreateChannelHandler, *************** *** 1241,1246 **** --- 1245,1264 ---- CONST char *name; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + * Location: Tcl_CreateChannel. + */ + union { + char c[sizeof(short)]; + short s; + } order; + + order.s = 1; + if (order.c[0] == 1) { + mask |= CHANNEL_IS_SMALLENDIAN; + } + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); if (chanName != (char *) NULL) { *************** *** 4924,4930 **** { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize eofchar translation"; char **argv; int argc, i; Tcl_DString ds; --- 4942,4948 ---- { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; *************** *** 4954,4959 **** --- 4972,5009 ---- return TCL_ERROR; } + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + * Exported functionality. + */ + + /* + *---------------------------------------------------------------------- + * + * Tcl_GetChannelByteorder -- + * + * Retrieves the byteorder set for this channel. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + int + Tcl_GetChannelByteorder(chan) + Tcl_Channel chan; /* The channel for which to find the + * buffer size. */ + { + Channel *chanPtr; + + chanPtr = (Channel *) chan; + return ((chanPtr->flags & CHANNEL_IS_SMALLENDIAN) != 0); + } + /* *---------------------------------------------------------------------- * *************** *** 5074,5079 **** --- 5124,5148 ---- return TCL_OK; } } + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + * Location: Tcl_GetChannelOption + */ + + if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0))) { + if (len == 0) { + Tcl_DStringAppendElement(dsPtr, "-byteorder"); + } + Tcl_DStringAppendElement(dsPtr, + (chanPtr->flags & CHANNEL_IS_SMALLENDIAN) ? + "smallendian" : "bigendian"); + if (len > 0) { + return TCL_OK; + } + } + if ((len == 0) || ((len > 2) && (optionName[1] == 'e') && (strncmp(optionName, "-eofchar", len) == 0))) { *************** *** 5269,5274 **** --- 5338,5378 ---- if ((chanPtr->bufSize < 10) || (chanPtr->bufSize > (1024 * 1024))) { chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; } + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for channels with a switchable byteorder" + * Location: Tcl_SetChannelOption. + */ + + } else if ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0)) { + int nv_len = strlen (newValue); + + if ((nv_len > 0) && + (strncmp (newValue, "smallendian", nv_len) == 0)) { + chanPtr->flags |= CHANNEL_IS_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "littleendian", nv_len) == 0)) { + chanPtr->flags |= CHANNEL_IS_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "network", nv_len) == 0)) { + chanPtr->flags &= ~CHANNEL_IS_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "bigendian", nv_len) == 0)) { + chanPtr->flags &= ~CHANNEL_IS_SMALLENDIAN; + return TCL_OK; + } + + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, + "bad value for -byteorder: ", + "must be one of smallendian, littleendian, bigendian or network", + (char *) NULL); + } + return TCL_ERROR; } else if ((len > 2) && (optionName[1] == 'e') && (strncmp(optionName, "-encoding", len) == 0)) { Tcl_Encoding encoding; trf2.1.4/patches/v8.1b2/tclIO.c0000644000175000017500000073430311216344361015312 0ustar sergeisergei/* * 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.2 1999/04/18 13:27:08 aku 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. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) # define EWOULDBLOCK EAGAIN #endif #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) error one of EWOULDBLOCK or EAGAIN must be defined #endif /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this * structure. */ typedef struct CopyState { struct Channel *readPtr; /* Pointer to input channel. */ struct Channel *writePtr; /* Pointer to output channel. */ int readFlags; /* Original read channel flags. */ int writeFlags; /* Original write channel flags. */ int toRead; /* Number of bytes to copy, or -1. */ int total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ 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) /* * Structure to record a close callback. One such record exists for * each close callback registered for a channel. */ typedef struct CloseCallback { Tcl_CloseProc *proc; /* The procedure to call. */ ClientData clientData; /* Arbitrary one-word data to pass * to the callback. */ struct CloseCallback *nextPtr; /* For chaining close callbacks. */ } CloseCallback; /* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to * invoke the saved script in the interpreter designed in this record. */ 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; /* * struct Channel: * * One of these structures is allocated for each open channel. It contains data * specific to the channel but which belongs to the generic part of the Tcl * channel mechanism, and it points at an instance specific (and type * specific) * instance data, and at a channel type structure. */ 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. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ struct ChannelHandler *chPtr;/* List of channel handlers registered * for this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ struct Channel *nextChanPtr;/* Next in list of channels currently open. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for * event handlers ("fileevent") on this * channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * The single change to the internal datastructures of the core. Every * channel now maintains a reference to the channel he is stacked upon. * This reference is NULL for normal channels. Only the two exported * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the * end of 'tcl.h') use this field in a non-trivial way. * * Of the existing procedures the only following are affected by this * change: * * - Tcl_RegisterChannel * - Tcl_CreateChannel * - CloseChannel * * The why is explained at the changed locations. */ struct Channel* supercedes; /* Refers to channel this one was stacked upon */ } Channel; /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in * nonblocking mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the * curOutPtr field in the * channel structure) should be * output as soon as possible even * though it may not be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the * queued output buffers has been * scheduled. */ #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No * further Tcl-level IO on the * channel is allowed. */ #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. * This bit is cleared before every * input operation. */ #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because * we saw the input eofChar. This bit * prevents clearing of the EOF bit * before every input operation. */ #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. */ /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" */ #define CHANNEL_IS_SMALLENDIAN (1<<16) /* Multibyte words are stored with MSB last */ /* * 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. */ typedef struct ChannelHandler { Channel *chanPtr; /* The channel structure for this channel. */ int mask; /* Mask of desired events. */ Tcl_ChannelProc *proc; /* Procedure to call in the type of * Tcl_CreateChannelHandler. */ ClientData clientData; /* Argument to pass to procedure. */ struct ChannelHandler *nextPtr; /* Next one in list of registered handlers. */ } ChannelHandler; /* * This structure keeps track of the current ChannelHandler being invoked in * the current invocation of ChannelHandlerEventProc. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. * The nextPtr field is used to chain together all recursive invocations, so * that Tcl_DeleteChannelHandler can find all the recursively nested * invocations of ChannelHandlerEventProc and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. */ typedef struct NextChannelHandler { 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 * for stdin/stdout/stderr in new interpreters. * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ 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 * closed. * * Results: * None. * * Side effects: * Causes the callback to be called in the future when the channel * will be closed. * *---------------------------------------------------------------------- */ void Tcl_CreateCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to create the * close callback. */ Tcl_CloseProc *proc; /* The callback routine to call when the * channel will be closed. */ ClientData clientData; /* Arbitrary data to pass to the * close callback. */ { Channel *chanPtr; CloseCallback *cbPtr; chanPtr = (Channel *) chan; cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; cbPtr->nextPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr; } /* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * * Removes a callback that would have been called on closing * the channel. If there is no matching callback then this * function has no effect. * * Results: * None. * * Side effects: * The callback will not be called in the future when the channel * is eventually closed. * *---------------------------------------------------------------------- */ void Tcl_DeleteCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to cancel the * close callback. */ Tcl_CloseProc *proc; /* The procedure for the callback to * remove. */ ClientData clientData; /* The callback data for the callback * to remove. */ { Channel *chanPtr; CloseCallback *cbPtr, *cbPrevPtr; chanPtr = (Channel *) chan; for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL; cbPtr != (CloseCallback *) NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == (CloseCallback *) NULL) { chanPtr->closeCbPtr = cbPtr->nextPtr; } ckfree((char *) cbPtr); break; } else { cbPrevPtr = cbPtr; } } } /* *---------------------------------------------------------------------- * * GetChannelTable -- * * Gets and potentially initializes the channel table for an * interpreter. If it is initializing the table it also inserts * channels for stdin, stdout and stderr if the interpreter is * trusted. * * Results: * A pointer to the hash table created, for use by the caller. * * Side effects: * Initializes the channel table for an interpreter. May create * channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */ static Tcl_HashTable * GetChannelTable(interp) Tcl_Interp *interp; { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); (void) Tcl_SetAssocData(interp, "tclIO", (Tcl_InterpDeleteProc *) DeleteChannelTable, (ClientData) hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels * for stdin, stdout and stderr (possibly creating them in the * process). */ if (Tcl_IsSafe(interp) == 0) { stdinChan = Tcl_GetStdChannel(TCL_STDIN); if (stdinChan != NULL) { Tcl_RegisterChannel(interp, stdinChan); } stdoutChan = Tcl_GetStdChannel(TCL_STDOUT); if (stdoutChan != NULL) { Tcl_RegisterChannel(interp, stdoutChan); } stderrChan = Tcl_GetStdChannel(TCL_STDERR); if (stderrChan != NULL) { Tcl_RegisterChannel(interp, stderrChan); } } } return hTblPtr; } /* *---------------------------------------------------------------------- * * DeleteChannelTable -- * * Deletes the channel table for an interpreter, closing any open * channels whose refcount reaches zero. This procedure is invoked * when an interpreter is deleted, via the AssocData cleanup * mechanism. * * Results: * None. * * Side effects: * Deletes the hash table of channels. May close channels. May flush * output on closed channels. Removes any channeEvent handlers that were * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable(clientData, interp) ClientData clientData; /* The per-interpreter data structure. */ Tcl_Interp *interp; /* The interpreter being deleted. */ { Tcl_HashTable *hTblPtr; /* The hash table. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* Channel being deleted. */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* Variables to loop over all channel events * registered, to delete the ones that refer * to the interpreter being deleted. */ /* * Delete all the registered channels - this will close channels whose * refcount reaches zero. */ hTblPtr = (Tcl_HashTable *) clientData; for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); /* * Remove any fileevents registered in this interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } /* * Cannot call Tcl_UnregisterChannel because that procedure calls * Tcl_GetAssocData to get the channel table, which might already * be inaccessible from the interpreter structure. Instead, we * emulate the behavior of Tcl_UnregisterChannel directly here. */ Tcl_DeleteHashEntry(hPtr); chanPtr->refCount--; if (chanPtr->refCount <= 0) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } } Tcl_DeleteHashTable(hTblPtr); ckfree((char *) hTblPtr); } /* *---------------------------------------------------------------------- * * CheckForStdChannelsBeingClosed -- * * Perform special handling for standard channels being closed. When * given a standard channel, if the refcount is now 1, it means that * the last reference to the standard channel is being explicitly * closed. Now bump the refcount artificially down to 0, to ensure the * normal handling of channels being closed will occur. Also reset the * static pointer to the channel to NULL, to avoid dangling references. * * Results: * None. * * Side effects: * Manipulates the refcount on standard channels. May smash the global * static pointer to a standard channel. * *---------------------------------------------------------------------- */ 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; } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_RegisterChannel'. * * Explanation: * The moment a channel is stacked upon another he * takes the identity of the channel he supercedes, * i.e. he gets the *same* name. Because of this we * cannot check for duplicate names anymore, they * have to be allowed now. */ /* 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. * If the interpreter given as argument is NULL, it only decrements the * reference count. * * Results: * A standard Tcl result. * * Side effects: * Deletes the hash entry for a channel associated with an interpreter. * *---------------------------------------------------------------------- */ int Tcl_UnregisterChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which channel is defined. */ Tcl_Channel chan; /* Channel to delete. */ { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The real IO channel. */ chanPtr = (Channel *) chan; if (interp != (Tcl_Interp *) NULL) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } hPtr = Tcl_FindHashEntry(hTblPtr, chanPtr->channelName); if (hPtr == (Tcl_HashEntry *) NULL) { return TCL_OK; } if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) { return TCL_OK; } Tcl_DeleteHashEntry(hPtr); /* * Remove channel handlers that refer to this interpreter, so that they * will not be present if the actual close is delayed and more events * happen on the channel. This may occur if the channel is shared * between several interpreters, or if the channel has async * flushing active. */ CleanupChannelHandlers(interp, chanPtr); } chanPtr->refCount--; /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); /* * If the refCount reached zero, close the actual channel. */ if (chanPtr->refCount <= 0) { /* * Ensure that if there is another buffer, it gets flushed * whether or not we are doing a background flush. */ if ((chanPtr->curOutPtr != NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; } chanPtr->flags |= CHANNEL_CLOSED; if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { if (Tcl_Close(interp, chan) != TCL_OK) { return TCL_ERROR; } } } 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. */ int *modePtr; /* Where to store the mode in which the * channel was opened? Will contain an ORed * combination of TCL_READABLE and * TCL_WRITABLE, if non-NULL. */ { Channel *chanPtr; /* The actual channel. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ char *name; /* Translated name. */ /* * Substitute "stdin", etc. Note that even though we immediately * find the channel using Tcl_GetStdChannel, we still need to look * it up in the specified interpreter to ensure that it is present * in the channel table. Otherwise, safe interpreters would always * have access to the standard channels. */ name = chanName; if ((chanName[0] == 's') && (chanName[1] == 't')) { chanPtr = NULL; if (strcmp(chanName, "stdin") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDIN); } else if (strcmp(chanName, "stdout") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDOUT); } else if (strcmp(chanName, "stderr") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDERR); } if (chanPtr != NULL) { name = chanPtr->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == (Tcl_HashEntry *) NULL) { Tcl_AppendResult(interp, "can not find channel named \"", chanName, "\"", (char *) NULL); return NULL; } chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (modePtr != NULL) { *modePtr = (chanPtr->flags & (TCL_READABLE|TCL_WRITABLE)); } return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_CreateChannel -- * * Creates a new entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Creates a new Tcl_Channel instance and inserts it into the * hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_CreateChannel(typePtr, chanName, instanceData, mask) 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); /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" * Location: Tcl_CreateChannel. */ union { char c[sizeof(short)]; short s; } order; order.s = 1; if (order.c[0] == 1) { mask |= CHANNEL_IS_SMALLENDIAN; } 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. */ chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_CreateChannel'. * * Explanation: * It is of course necessary to initialize the new field * in the Channel structure. The chosen value indicates * that the created channel is a normal one, and not * stacked upon another. */ chanPtr->supercedes = (Channel*) 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; } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * The following two procedures are the new, exported ones. They * - create a channel stacked upon an existing one and * - pop a stacked channel off, thus revealing the superceded one. * * Please read the following completely. */ /* *---------------------------------------------------------------------- * * Tcl_ReplaceChannel -- * * Replaces an entry in the hash table for a Tcl_Channel * record. The replacement is a new channel with same name, * it supercedes the replaced channel. Input and output of * the superceded channel is now going through the newly * created channel and allows the arbitrary filtering/manipulation * of the dataflow. * * Results: * Returns the new Tcl_Channel. * * Side effects: * See above. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_ChannelType *typePtr; /* The channel type record for the new * channel. */ ClientData instanceData; /* Instance specific data for the new * channel. */ int mask; /* TCL_READABLE & TCL_WRITABLE to indicate * if the channel is readable, writable. */ Tcl_Channel prevChan; /* The channel structure to replace */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel *chanPtr, *pt, *prevPt; /* * Find the given channel in the list of all channels, compute enough * information to allow easy removal after the conditions are met. */ prevPt = (Channel*) NULL; pt = (Channel*) tsdPtr->firstChanPtr; while (pt != (Channel *) prevChan) { prevPt = pt; pt = pt->nextChanPtr; } /* * 'pt == prevChan' now */ if (!pt) { return (Tcl_Channel) NULL; } /* * Here we check if the given "mask" matches the "flags" * of the already existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to * W | | | + | + | restrict the capabilities of the * RW| | + | + | + | superceded one ! * --+---+---+---+----+ */ if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { return (Tcl_Channel) NULL; } chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); chanPtr->flags = mask; /* * Set the channel up initially in no Input translation mode and * no Output translation mode. */ chanPtr->inputTranslation = TCL_TRANSLATE_LF; chanPtr->outputTranslation = TCL_TRANSLATE_LF; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* 06/12/1998: New for Tcl 8.1 * * Take over the encoding from the superceded channel, so that it will be * executed in the future despite the replacement, and at the proper time * (*after* / *before* our transformation, depending on the direction of * the dataflow). * * *Important* * The I/O functionality of the filtering channel has to use 'Tcl_Read' to * get at the underlying information. This will circumvent the de/encoder * stage [*] in the superceded channel and removes the need to trouble * ourselves with 'ByteArray's too. * * [*] I'm talking about the conversion between UNICODE and other * representations, like ASCII. */ chanPtr->encoding = pt->encoding; chanPtr->inputEncodingState = pt->inputEncodingState; chanPtr->inputEncodingFlags = pt->inputEncodingFlags; chanPtr->outputEncodingState = pt->outputEncodingState; chanPtr->outputEncodingFlags = pt->outputEncodingFlags; chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) ckalloc((unsigned) (chanPtr->bufSize + 2)); } chanPtr->supercedes = (Channel*) prevChan; chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); strcpy (chanPtr->channelName, pt->channelName); if (prevPt) { prevPt->nextChanPtr = chanPtr; } else { tsdPtr->firstChanPtr = chanPtr; } chanPtr->nextChanPtr = pt->nextChanPtr; Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); /* * The superceded channel is effectively unregistered */ /*chanPtr->supercedes->refCount --;*/ return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_UndoReplaceChannel -- * * Unstacks an entry in the hash table for a Tcl_Channel * record. This is the reverse to 'Tcl_ReplaceChannel'. * The old, superceded channel is uncovered and re-registered * in the appropriate datastructures. * * Results: * Returns the old Tcl_Channel, i.e. the one which was stacked over. * * Side effects: * See above. * *---------------------------------------------------------------------- */ void Tcl_UndoReplaceChannel (interp, chan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_Channel chan; /* The channel to unstack */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel* chanPtr = (Channel*) chan; if (chanPtr->supercedes != (Channel*) NULL) { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ int new; /* Is the hash entry new or does it exist? */ /* * Insert the channel we were stacked upon back into * the list of open channels. Place it back into the hashtable too. * Correct 'refCount', as this actually unregisters 'chan'. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; hTblPtr = GetChannelTable (interp); hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); chanPtr->refCount --; /* * The superceded channel is effectively registered again */ /*chanPtr->supercedes->refCount ++;*/ } /* * Disconnect the channels, then do a regular close upon the * stacked one, the filtering channel. This may cause flushing * of data into the superceded channel (if the filtering channel * ('chan') remembered its parent in itself). */ chanPtr->supercedes = NULL; if (chanPtr->refCount == 0) { Tcl_Close (interp, chan); } } /* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * * Computes a mask indicating whether the channel is open for * reading and writing. * * Results: * An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelMode(chan) Tcl_Channel chan; /* The channel for which the mode is * being computed. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE)); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * * Returns the string identifying the channel name. * * Results: * The string containing the channel name. This memory is * owned by the generic layer and should not be modified by * the caller. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Tcl_GetChannelName(chan) Tcl_Channel chan; /* The channel for which to return the name. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->channelName; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * * Given a channel structure, returns the channel type structure. * * Results: * Returns a pointer to the channel type structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ChannelType * Tcl_GetChannelType(chan) Tcl_Channel chan; /* The channel to return type for. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->typePtr; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * * Returns an OS handle associated with a channel. * * Results: * Returns TCL_OK and places the handle in handlePtr, or returns * TCL_ERROR on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelHandle(chan, direction, handlePtr) Tcl_Channel chan; /* The channel to get file from. */ int direction; /* TCL_WRITABLE or TCL_READABLE. */ ClientData *handlePtr; /* Where to store handle */ { Channel *chanPtr; /* The actual channel. */ ClientData handle; int result; chanPtr = (Channel *) chan; result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData, direction, &handle); if (handlePtr) { *handlePtr = handle; } return result; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * * Returns the client data associated with a channel. * * Results: * The client data. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_GetChannelInstanceData(chan) 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 * that two input buffers are saved (one in the input queue and * another in the saveInBufPtr field) and that curOutPtr is set * to a buffer. Only if these conditions are met is the buffer * freed to the OS. * * Results: * None. * * Side effects: * May free a buffer to the OS. * *---------------------------------------------------------------------- */ static void RecycleBuffer(chanPtr, bufPtr, mustDiscard) Channel *chanPtr; /* Channel for which to recycle buffers. */ ChannelBuffer *bufPtr; /* The buffer to recycle. */ int mustDiscard; /* If nonzero, free the buffer to the * OS, always. */ { /* * Do we have to free the buffer to the OS? */ if (mustDiscard) { ckfree((char *) bufPtr); return; } /* * Only save buffers for the input queue if the channel is readable. */ if (chanPtr->flags & TCL_READABLE) { if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) { chanPtr->inQueueHead = bufPtr; chanPtr->inQueueTail = bufPtr; goto keepit; } if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) { chanPtr->saveInBufPtr = bufPtr; goto keepit; } } /* * Only save buffers for the output queue if the channel is writable. */ if (chanPtr->flags & TCL_WRITABLE) { if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) { chanPtr->curOutPtr = bufPtr; goto keepit; } } /* * 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 -- * * Discards all output queued in the output queue of a channel. * * Results: * None. * * Side effects: * Recycles buffers. * *---------------------------------------------------------------------- */ static void DiscardOutputQueued(chanPtr) Channel *chanPtr; /* The channel for which to discard output. */ { ChannelBuffer *bufPtr; while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { bufPtr = chanPtr->outQueueHead; chanPtr->outQueueHead = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, 0); } chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; } /* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * * This function checks is a given channel is Dead. * (A channel that has been closed but not yet deallocated.) * * Results: * True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: * None * *---------------------------------------------------------------------- */ static int CheckForDeadChannel(interp, chanPtr) Tcl_Interp *interp; /* For error reporting (can be NULL) */ Channel *chanPtr; /* The channel to check. */ { if (chanPtr->flags & CHANNEL_DEAD) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, "unable to access channel: invalid channel", (char *) NULL); } return 1; } return 0; } /* *---------------------------------------------------------------------- * * FlushChannel -- * * This function flushes as much of the queued output as is possible * now. If calledFromAsyncFlush is nonzero, it is being called in an * event handler to flush channel output asynchronously. * * Results: * 0 if successful, else the error code that was returned by the * channel type operation. * * Side effects: * May produce output on a channel. May block indefinitely if the * channel is synchronous. May schedule an async flush on the channel. * May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */ static int FlushChannel(interp, chanPtr, calledFromAsyncFlush) Tcl_Interp *interp; /* For error reporting during close. */ Channel *chanPtr; /* The channel to flush on. */ int calledFromAsyncFlush; /* If nonzero then we are being * called from an asynchronous * flush callback. */ { 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. */ if (CheckForDeadChannel(interp,chanPtr)) return -1; /* * Loop over the queued buffers and attempt to flush as * much as possible of the queued output to the channel. */ while (1) { /* * 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 { chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr; } chanPtr->outQueueTail = chanPtr->curOutPtr; chanPtr->curOutPtr = (ChannelBuffer *) NULL; } bufPtr = chanPtr->outQueueHead; /* * If we are not being called from an async flush and an async * flush is active, we just return without producing any output. */ if ((!calledFromAsyncFlush) && (chanPtr->flags & BG_FLUSH_SCHEDULED)) { return 0; } /* * If the output queue is still empty, break out of the while loop. */ if (bufPtr == (ChannelBuffer *) NULL) { break; /* Out of the "while (1)". */ } /* * 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. */ if (written < 0) { /* * If the last attempt to write was interrupted, simply retry. */ if (errorCode == EINTR) { errorCode = 0; continue; } /* * If the channel is non-blocking and we would have blocked, * start a background flushing handler and break out of the loop. */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { if (chanPtr->flags & CHANNEL_NONBLOCKING) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { chanPtr->flags |= BG_FLUSH_SCHEDULED; UpdateInterest(chanPtr); } errorCode = 0; break; } else { panic("Blocking channel driver did not block on output"); } } /* * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { if (chanPtr->unreportedError == 0) { chanPtr->unreportedError = errorCode; } } else { Tcl_SetErrno(errorCode); if (interp != NULL) { Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } } /* * 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. */ if ((chanPtr->flags & CHANNEL_CLOSED) && (chanPtr->refCount <= 0) && (chanPtr->outQueueHead == (ChannelBuffer *) NULL) && ((chanPtr->curOutPtr == (ChannelBuffer *) NULL) || (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->nextRemoved))) { return CloseChannel(interp, chanPtr, errorCode); } return errorCode; } /* *---------------------------------------------------------------------- * * CloseChannel -- * * Utility procedure to close a channel and free its associated * resources. * * Results: * 0 on success or a POSIX error code if the operation failed. * * Side effects: * May close the actual channel; may free memory. * *---------------------------------------------------------------------- */ static int CloseChannel(interp, chanPtr, errorCode) Tcl_Interp *interp; /* For error reporting. */ Channel *chanPtr; /* The channel to close. */ 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. */ DiscardInputQueued(chanPtr, 1); /* * Discard a leftover buffer in the current output buffer field. */ if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { ckfree((char *) chanPtr->curOutPtr); chanPtr->curOutPtr = (ChannelBuffer *) NULL; } /* * The caller guarantees that there are no more buffers * queued for output. */ if (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { panic("TclFlush, closed channel: queued output left"); } /* * If the EOF character is set in the channel, append that to the * output device. */ if ((chanPtr->outEofChar != 0) && (chanPtr->flags & TCL_WRITABLE)) { int dummy; char c; c = (char) chanPtr->outEofChar; (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy); } /* * Remove TCL_READABLE and TCL_WRITABLE from chanPtr->flags, so * that close callbacks can not do input or output (assuming they * squirreled the channel away in their clientData). This also * prevents infinite loops if the callback calls any C API that * could call FlushChannel. */ 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. */ if (chanPtr->unreportedError != 0) { errorCode = chanPtr->unreportedError; } if (errorCode == 0) { errorCode = result; if (errorCode != 0) { Tcl_SetErrno(errorCode); } } /* Andreas Kupries , 12/13/1998 * "Trf-Patch for filtering channels" * * This is the change to 'CloseChannel'. * * Explanation * Closing a filtering channel closes the one it * superceded too. This basically ripples through * the whole chain of filters until it reaches * the underlying normal channel. * * This is done by reintegrating the superceded * channel into the (thread) global list of open * channels and then invoking a regular close. * There is no need to handle the complexities of * this process by ourselves. * * *Note* * This has to be done after the call to the * 'closeProc' of the filtering channel to allow * that one the flushing of internal buffers into * the underlying channel. */ if (chanPtr->supercedes != (Channel*) NULL) { /* Insert the channel we were stacked upon back into * the list of open channels, then do a regular close. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; chanPtr->supercedes->refCount --; /* is deregistered */ Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* * Cancel any outstanding timer. */ Tcl_DeleteTimerHandler(chanPtr->timer); /* * Mark the channel as deleted by clearing the type structure. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC); return errorCode; } /* *---------------------------------------------------------------------- * * Tcl_Close -- * * Closes a channel. * * Results: * A standard Tcl result. * * Side effects: * Closes the channel if this is the last reference. * * NOTE: * Tcl_Close removes the channel as far as the user is concerned. * However, it may continue to exist for a while longer if it has * a background flush scheduled. The device itself is eventually * closed and the channel record removed, in CloseChannel, above. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_Close(interp, chan) Tcl_Interp *interp; /* Interpreter for errors. */ Tcl_Channel chan; /* The channel being closed. Must * not be referenced in any * interpreter. */ { 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; } /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); chanPtr = (Channel *) chan; if (chanPtr->refCount > 0) { panic("called Tcl_Close on channel with refCount > 0"); } /* * 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; } } /* * Remove all the channel handler records attached to the channel * itself. */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chNext) { chNext = chPtr->nextPtr; ckfree((char *) chPtr); } chanPtr->chPtr = (ChannelHandler *) NULL; /* * Cancel any pending copy operation. */ StopCopy(chanPtr->csPtr); /* * Must set the interest mask now to 0, otherwise infinite loops * will occur if Tcl_DoOneEvent is called before the channel is * finally deleted in FlushChannel. This can happen if the channel * has a background flush active. */ chanPtr->interestMask = 0; /* * 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. */ while (chanPtr->closeCbPtr != (CloseCallback *) NULL) { cbPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr->nextPtr; (cbPtr->proc) (cbPtr->clientData); ckfree((char *) cbPtr); } /* * 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 -- * * Flushes output data on a channel. * * Results: * A standard Tcl result. * * Side effects: * May flush output queued on this channel. * *---------------------------------------------------------------------- */ int 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; } return TCL_OK; } /* *---------------------------------------------------------------------- * * DiscardInputQueued -- * * Discards any input read from the channel but not yet consumed * by Tcl reading commands. * * Results: * None. * * Side effects: * May discard input from the channel. If discardLastBuffer is zero, * leaves one buffer in place for back-filling. * *---------------------------------------------------------------------- */ static void DiscardInputQueued(chanPtr, discardSavedBuffers) Channel *chanPtr; /* Channel on which to discard * the queued input. */ int discardSavedBuffers; /* If non-zero, discard all buffers including * last one. */ { ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ bufPtr = chanPtr->inQueueHead; chanPtr->inQueueHead = (ChannelBuffer *) NULL; chanPtr->inQueueTail = (ChannelBuffer *) NULL; for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) { nxtPtr = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, discardSavedBuffers); } /* * If discardSavedBuffers is nonzero, must also discard any previously * saved buffer in the saveInBufPtr field. */ if (discardSavedBuffers) { if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) { 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 -- * * Implements seeking on Tcl Channels. This is a public function * so that other C facilities may be implemented on top of it. * * Results: * The new access point or -1 on error. If error, use Tcl_GetErrno() * to retrieve the POSIX error code for the error that occurred. * * Side effects: * May flush output on the channel. May discard queued input. * *---------------------------------------------------------------------- */ int Tcl_Seek(chan, offset, mode) Tcl_Channel chan; /* The channel on which to seek. */ int offset; /* Offset to seek to. */ int mode; /* Relative to which location to seek? */ { Channel *chanPtr; /* The real IO channel. */ ChannelBuffer *bufPtr; int inputBuffered, outputBuffered; 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 * registered in an interpreter. */ if (CheckForDeadChannel(NULL,chanPtr)) return -1; /* * Disallow seek on channels whose type does not have a seek procedure * defined. This means that the channel does not support seeking. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * If we are seeking relative to the current position, compute the * corrected offset taking into account the amount of unread input. */ if (mode == SEEK_CUR) { offset -= inputBuffered; } /* * Discard any queued input - this input should not be read after * the seek. */ DiscardInputQueued(chanPtr, 0); /* * Reset EOF and BLOCKED flags. We invalidate them by moving the * access point. Also clear CR related flags. */ chanPtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR)); /* * If the channel is in asynchronous output mode, switch it back * to synchronous mode and cancel any async flush that may be * scheduled. After the flush, the channel will be put back into * asynchronous output mode. */ wasAsync = 0; if (chanPtr->flags & CHANNEL_NONBLOCKING) { wasAsync = 1; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_BLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } chanPtr->flags &= (~(CHANNEL_NONBLOCKING)); if (chanPtr->flags & BG_FLUSH_SCHEDULED) { chanPtr->flags &= (~(BG_FLUSH_SCHEDULED)); } } /* * If the flush fails we cannot recover the original position. In * that case the seek is not attempted because we do not know where * the access position is - instead we return the error. FlushChannel * has already called Tcl_SetErrno() to report the error upwards. * If the flush succeeds we do the seek also. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { curPos = -1; } else { /* * Now seek to the new position in the channel as requested by the * caller. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) offset, mode, &result); if (curPos == -1) { Tcl_SetErrno(result); } } /* * Restore to nonblocking mode if that was the previous behavior. * * NOTE: Even if there was an async flush active we do not restore * it now because we already flushed all the queued output, above. */ if (wasAsync) { chanPtr->flags |= CHANNEL_NONBLOCKING; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_NONBLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } } return curPos; } /* *---------------------------------------------------------------------- * * Tcl_Tell -- * * Returns the position of the next character to be read/written on * this channel. * * Results: * A nonnegative integer on success, -1 on failure. If failed, * use Tcl_GetErrno() to retrieve the POSIX error code for the * error that occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Tell(chan) Tcl_Channel chan; /* The channel to return pos for. */ { 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. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * Get the current position in the device and compute the position * where the next character will be read or written. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) 0, SEEK_CUR, &result); if (curPos == -1) { Tcl_SetErrno(result); 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. * * Results: * 1 or 0, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Eof(chan) Tcl_Channel chan; /* Does this channel have EOF? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_STICKY_EOF) || ((chanPtr->flags & CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * * Results: * 0 or 1, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBlocked(chan) Tcl_Channel chan; /* Is this channel blocked? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return (chanPtr->flags & CHANNEL_BLOCKED) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBuffered -- * * Returns the number of bytes of input currently buffered in the * internal buffer of a channel. * * Results: * The number of input bytes buffered, or zero if the channel is not * open for reading. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBuffered(chan) Tcl_Channel chan; /* The channel to query. */ { Channel *chanPtr; int bytesBuffered; ChannelBuffer *bufPtr; chanPtr = (Channel *) chan; for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } return bytesBuffered; } /* *---------------------------------------------------------------------- * * Tcl_SetChannelBufferSize -- * * Sets the size of buffers to allocate to store input or output * in the channel. The size must be between 10 bytes and 1 MByte. * * Results: * None. * * Side effects: * Sets the size of buffers subsequently allocated for this channel. * *---------------------------------------------------------------------- */ void Tcl_SetChannelBufferSize(chan, sz) Tcl_Channel chan; /* The channel whose buffer size * to set. */ int sz; /* The size to set. */ { Channel *chanPtr; /* * If the buffer size is smaller than 10 bytes or larger than one MByte, * do not accept the requested size and leave the current buffer size. */ if (sz < 10) { return; } 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 -- * * Retrieves the size of buffers to allocate for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelBufferSize(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->bufSize; } /* *---------------------------------------------------------------------- * * Tcl_BadChannelOption -- * * This procedure generates a "bad option" error message in an * (optional) interpreter. It is used by channel drivers when * a invalid Set/Get option is requested. Its purpose is to concatenate * the generic options list to the specific ones and factorize * the generic options error message string. * * Results: * TCL_ERROR. * * Side effects: * An error message is generated in interp's result object to * indicate that a command was invoked with the a bad option * The message has the form * bad option "blah": should be one of * <...generic options...>+<...specific options...> * "blah" is the optionName argument and "" * is a space separated list of specific option words. * The function takes good care of inserting minus signs before * each option, commas after, and an "or" before the last option. * *---------------------------------------------------------------------- */ int Tcl_BadChannelOption(interp, optionName, optionList) Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/ char *optionName; /* 'bad option' name */ char *optionList; /* Specific options list to append * to the standard generic options. * can be NULL for generic options * only. */ { if (interp) { CONST char *genericopt = "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, (char *) genericopt, -1); if (optionList && (*optionList)) { Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad option \"", optionName, "\": should be one of ", (char *) NULL); argc--; for (i = 0; i < argc; i++) { Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL); } Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL); Tcl_DStringFree(&ds); ckfree((char *) argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" * Exported functionality. */ /* *---------------------------------------------------------------------- * * Tcl_GetChannelByteorder -- * * Retrieves the byteorder set for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelByteorder(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_IS_SMALLENDIAN) != 0); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelOption -- * * 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: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelOption(interp, chan, optionName, dsPtr) Tcl_Interp *interp; /* For error reporting - can be NULL. */ Tcl_Channel chan; /* Channel on which to get option. */ char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */ { size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; int flags; /* * If we are in the middle of a background copy, use the saved flags. */ if (chanPtr->csPtr) { if (chanPtr == chanPtr->csPtr->readPtr) { flags = chanPtr->csPtr->readFlags; } else { flags = chanPtr->csPtr->writeFlags; } } else { flags = chanPtr->flags; } /* * Disallow options 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(interp,chanPtr)) return TCL_ERROR; /* * If the optionName is NULL it means that we want a list of all * options and values. */ if (optionName == (char *) NULL) { len = 0; } else { len = strlen(optionName); } if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blocking"); } Tcl_DStringAppendElement(dsPtr, (flags & CHANNEL_NONBLOCKING) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffering", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffering"); } if (flags & CHANNEL_LINEBUFFERED) { Tcl_DStringAppendElement(dsPtr, "line"); } else if (flags & CHANNEL_UNBUFFERED) { Tcl_DStringAppendElement(dsPtr, "none"); } else { Tcl_DStringAppendElement(dsPtr, "full"); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffersize", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffersize"); } 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; } } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" * Location: Tcl_GetChannelOption */ if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-byteorder"); } Tcl_DStringAppendElement(dsPtr, (chanPtr->flags & CHANNEL_IS_SMALLENDIAN) ? "smallendian" : "bigendian"); 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); } if (flags & TCL_READABLE) { if (chanPtr->inEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->inEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (flags & TCL_WRITABLE) { if (chanPtr->outEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->outEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 1) && (optionName[1] == 't') && (strncmp(optionName, "-translation", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-translation"); } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringStartSublist(dsPtr); } if (flags & TCL_READABLE) { if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (flags & TCL_WRITABLE) { if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) { /* * let the driver specific handle additional options * and result code and message. */ return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData, interp, optionName, dsPtr); } else { /* * no driver specific options case. */ if (len == 0) { 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? */ char *newValue; /* New value for option. */ { int newMode; /* New (numeric) mode to sert. */ Channel *chanPtr; /* The real IO channel. */ size_t len; /* Length of optionName string. */ int argc; char **argv; chanPtr = (Channel *) chan; /* * If the channel is in the middle of a background copy, fail. */ if (chanPtr->csPtr) { if (interp) { Tcl_AppendResult(interp, "unable to set channel options: background copy in progress", (char *) NULL); } return TCL_ERROR; } /* * Disallow options 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 TCL_ERROR; len = strlen(optionName); if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0)) { if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) { return TCL_ERROR; } 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)) { chanPtr->flags &= (~(CHANNEL_UNBUFFERED)); chanPtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { chanPtr->flags &= (~(CHANNEL_LINEBUFFERED)); chanPtr->flags |= CHANNEL_UNBUFFERED; } else { 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; } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" * Location: Tcl_SetChannelOption. */ } else if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0)) { int nv_len = strlen (newValue); if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { chanPtr->flags |= CHANNEL_IS_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { chanPtr->flags |= CHANNEL_IS_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { chanPtr->flags &= ~CHANNEL_IS_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { chanPtr->flags &= ~CHANNEL_IS_SMALLENDIAN; return TCL_OK; } if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "bad value for -byteorder: ", "must be one of smallendian, littleendian, bigendian or network", (char *) NULL); } return TCL_ERROR; } 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; } else if (argc == 1) { if (chanPtr->flags & TCL_WRITABLE) { chanPtr->outEofChar = (int) argv[0][0]; } if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } } else if (argc != 2) { if (interp) { Tcl_AppendResult(interp, "bad value for -eofchar: should be a list of one or", " two elements", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } else { if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } 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; } if (argc == 1) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: must be a one or two", " element list", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } 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) { newMode = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered * 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) { /* * This is a hack to get TCP sockets to produce output * in CRLF mode if they are being set into AUTO mode. * A better solution for achieving this effect will be * coded later. */ if (strcmp(chanPtr->typePtr->typeName, "tcp") == 0) { 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) { chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } 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 -- * * Removes channel handlers that refer to the supplied interpreter, * so that if the actual channel is not closed now, these handlers * will not run on subsequent events on the channel. This would be * erroneous, because the interpreter no longer has a reference to * this channel. * * Results: * None. * * Side effects: * Removes channel handlers. * *---------------------------------------------------------------------- */ static void CleanupChannelHandlers(interp, chanPtr) Tcl_Interp *interp; Channel *chanPtr; { EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* * Remove fileevent records on this channel that refer to the * given interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } } /* *---------------------------------------------------------------------- * * Tcl_NotifyChannel -- * * This procedure is called by a channel driver when a driver * detects an event on a channel. This procedure is responsible * for actually handling the event by invoking any channel * handler callbacks. * * Results: * None. * * Side effects: * Whatever the channel handler callback procedure does. * *---------------------------------------------------------------------- */ void Tcl_NotifyChannel(channel, mask) 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. */ if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; (*(chPtr->proc))(chPtr->clientData, mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; } } /* * 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 -- * * Arrange for the notifier to call us back at appropriate times * based on the current state of the channel. * * Results: * None. * * Side effects: * May schedule a timer or driver handler. * *---------------------------------------------------------------------- */ static void UpdateInterest(chanPtr) Channel *chanPtr; /* Channel to update. */ { int mask = chanPtr->interestMask; /* * If there are flushed buffers waiting to be written, then * we need to watch for the channel to become writable. */ 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); } } } (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask); } /* *---------------------------------------------------------------------- * * ChannelTimerProc -- * * Timer handler scheduled by UpdateInterest to monitor the * channel buffers until they are empty. * * Results: * None. * * Side effects: * May invoke channel handlers. * *---------------------------------------------------------------------- */ 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. */ chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc, (ClientData) chanPtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); } else { chanPtr->timer = NULL; UpdateInterest(chanPtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * * Arrange for a given procedure to be invoked whenever the * channel indicated by the chanPtr arg becomes readable or * writable. * * Results: * None. * * Side effects: * From now on, whenever the I/O channel given by chanPtr becomes * ready in the way indicated by mask, proc will be invoked. * See the manual entry for details on the calling sequence * to proc. If there is already an event handler for chan, proc * and clientData, then the mask will be updated. * *---------------------------------------------------------------------- */ void Tcl_CreateChannelHandler(chan, mask, proc, clientData) Tcl_Channel chan; /* The channel to create the handler for. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions under which * proc should be called. Use 0 to * disable a registered handler. */ Tcl_ChannelProc *proc; /* Procedure to call for each * selected event. */ ClientData clientData; /* Arbitrary data to pass to proc. */ { ChannelHandler *chPtr; Channel *chanPtr; chanPtr = (Channel *) chan; /* * Check whether this channel handler is not already registered. If * it is not, create a new record, else reuse existing record (smash * current values). */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) && (chPtr->clientData == clientData)) { break; } } if (chPtr == (ChannelHandler *) NULL) { chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler)); chPtr->mask = 0; chPtr->proc = proc; chPtr->clientData = clientData; chPtr->chanPtr = chanPtr; chPtr->nextPtr = chanPtr->chPtr; chanPtr->chPtr = chPtr; } /* * The remainder of the initialization below is done regardless of * whether or not this is a new record or a modification of an old * one. */ chPtr->mask = mask; /* * Recompute the interest mask for the channel - this call may actually * be disabling an existing handler. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * Tcl_DeleteChannelHandler -- * * Cancel a previously arranged callback arrangement for an IO * channel. * * Results: * None. * * Side effects: * If a callback was previously registered for this chan, proc and * clientData , it is removed and the callback will no longer be called * when the channel becomes ready for IO. * *---------------------------------------------------------------------- */ void Tcl_DeleteChannelHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to remove the * callback. */ 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. */ for (prevChPtr = (ChannelHandler *) NULL, chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData) && (chPtr->proc == proc)) { break; } prevChPtr = chPtr; } /* * If not found, return without doing anything. */ if (chPtr == (ChannelHandler *) NULL) { return; } /* * 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_DeleteChanelHandler is called inside an event. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * DeleteScriptRecord -- * * Delete a script record for this combination of channel, interp * and mask. * * Results: * None. * * Side effects: * Deletes a script record and cancels a channel event handler. * *---------------------------------------------------------------------- */ static void DeleteScriptRecord(interp, chanPtr, mask) Tcl_Interp *interp; /* Interpreter in which script was to be * executed. */ Channel *chanPtr; /* The channel for which to delete the * script record (if any). */ int mask; /* Events in mask must exactly match mask * of script to delete. */ { EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = chanPtr->scriptRecordPtr, prevEsPtr = (EventScriptRecord *) NULL; esPtr != (EventScriptRecord *) NULL; prevEsPtr = esPtr, esPtr = esPtr->nextPtr) { if ((esPtr->interp == interp) && (esPtr->mask == mask)) { if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { prevEsPtr->nextPtr = esPtr->nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) esPtr); Tcl_DecrRefCount(esPtr->scriptPtr); ckfree((char *) esPtr); break; } } } /* *---------------------------------------------------------------------- * * CreateScriptRecord -- * * Creates a record to store a script to be executed when a specific * event fires on a specific channel. * * Results: * None. * * 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 -- * * Invokes a script scheduled by "fileevent" for when the channel * becomes ready for IO. This function is invoked by the channel * handler which was created by the Tcl "fileevent" command. * * Results: * None. * * Side effects: * Whatever the script does. * *---------------------------------------------------------------------- */ static void 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. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundError(interp); } 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; } /* *---------------------------------------------------------------------- * * TclTestChannelCmd -- * * Implements the Tcl "testchannel" debugging command and its * subcommands. This is part of the testing environment but must be * in this file instead of tclTest.c because it needs access to the * fields of struct Channel. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int TclTestChannelCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Interpreter for result. */ int argc; /* Count of additional args. */ char **argv; /* Additional arg strings. */ { char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ 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]); Tcl_AppendElement(interp, chanPtr->typePtr->typeName); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_NONBLOCKING) { Tcl_AppendElement(interp, "nonblocking"); } else { Tcl_AppendElement(interp, "blocking"); } if (chanPtr->flags & CHANNEL_LINEBUFFERED) { Tcl_AppendElement(interp, "line"); } else if (chanPtr->flags & CHANNEL_UNBUFFERED) { Tcl_AppendElement(interp, "none"); } else { Tcl_AppendElement(interp, "full"); } if (chanPtr->flags & BG_FLUSH_SCHEDULED) { Tcl_AppendElement(interp, "async_flush"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_EOF) { Tcl_AppendElement(interp, "eof"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_BLOCKED) { Tcl_AppendElement(interp, "blocked"); } else { Tcl_AppendElement(interp, "unblocked"); } if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "saw_cr"); } else { Tcl_AppendElement(interp, ""); } } else if (chanPtr->inputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "queued_cr"); } else { Tcl_AppendElement(interp, ""); } } if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); } for (IOQueued = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved; } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved; } for (bufPtr = chanPtr->outQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved); } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr)); Tcl_AppendElement(interp, buf); TclFormatInt(buf, chanPtr->refCount); Tcl_AppendElement(interp, buf); return TCL_OK; } if ((cmdName[0] == 'i') && (strncmp(cmdName, "inputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; } if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } return TCL_OK; } if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "outputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - 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) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (chanPtr->flags & INPUT_SAW_CR) ? "1" : "0", (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } 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", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ", "info, open, readable, or writable", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclTestChannelEventCmd -- * * This procedure implements the "testchannelevent" command. It is * used to test the Tcl channel event mechanism. It is present in * this file instead of tclTest.c because it needs access to the * internal structure of the channel. * * Results: * A standard Tcl result. * * Side effects: * Creates, deletes and returns channel event handlers. * *---------------------------------------------------------------------- */ /* ARGSUSED */ 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], " channelName cmd ?arg1? ?arg2?\"", (char *) NULL); return TCL_ERROR; } chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL); if (chanPtr == (Channel *) NULL) { return TCL_ERROR; } cmd = argv[2]; len = strlen(cmd); if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName add eventSpec script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[3], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[3], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[3], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr = (EventScriptRecord *) ckalloc((unsigned) 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; } if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) { if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { for (prevEsPtr = chanPtr->scriptRecordPtr; (prevEsPtr != (EventScriptRecord *) NULL) && (prevEsPtr->nextPtr != esPtr); prevEsPtr = prevEsPtr->nextPtr) { /* Empty loop body. */ } 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)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index event\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[4], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[4], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[4], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[4], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr->mask = mask; 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 -- * * This routine copies data from one channel to another, either * synchronously or asynchronously. If a command script is * supplied, the operation runs in the background. The script * is invoked when the copy completes. Otherwise the function * waits until the copy is completed before returning. * * Results: * A standard Tcl result. * * Side effects: * May schedule a background copy operation that causes both * channels to be marked busy. * *---------------------------------------------------------------------- */ int TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Channel inChan; /* Channel to read from. */ Tcl_Channel outChan; /* Channel to write to. */ int toRead; /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */ { Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; if (inPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); return TCL_ERROR; } if (outPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); return TCL_ERROR; } readFlags = inPtr->flags; writeFlags = outPtr->flags; /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. * If there is an error, restore the old blocking mode. */ if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(interp, inPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) { return TCL_ERROR; } } if (inPtr != outPtr) { if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(NULL, outPtr, nonBlocking ? TCL_MODE_BLOCKING : TCL_MODE_NONBLOCKING) != TCL_OK) { if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING) ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); return TCL_ERROR; } } } } /* * Make sure the output side is unbuffered. */ outPtr->flags = (outPtr->flags & ~(CHANNEL_LINEBUFFERED)) | CHANNEL_UNBUFFERED; /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inPtr->bufSize); csPtr->bufSize = inPtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; inPtr->csPtr = csPtr; outPtr->csPtr = csPtr; /* * Start copying data between the channels. */ return CopyData(csPtr, 0); } /* *---------------------------------------------------------------------- * * CopyData -- * * This function implements the lowest level of the copying * mechanism for TclCopyChannel. * * Results: * Returns TCL_OK on success, else TCL_ERROR. * * Side effects: * Moves data between channels, may create channel handlers. * *---------------------------------------------------------------------- */ static int CopyData(csPtr, mask) CopyState *csPtr; /* State of copy operation. */ int mask; /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL; Tcl_Channel inChan, outChan; int result = TCL_OK; int size; int total; inChan = (Tcl_Channel)csPtr->readPtr; outChan = (Tcl_Channel)csPtr->writePtr; interp = csPtr->interp; cmdPtr = csPtr->cmdPtr; /* * Copy the data the slow way, using the translation mechanism. */ while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ if (csPtr->readPtr->unreportedError != 0) { Tcl_SetErrno(csPtr->readPtr->unreportedError); csPtr->readPtr->unreportedError = 0; goto readError; } if (csPtr->writePtr->unreportedError != 0) { Tcl_SetErrno(csPtr->writePtr->unreportedError); csPtr->writePtr->unreportedError = 0; goto writeError; } /* * Read up to bufSize bytes. */ if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { size = csPtr->bufSize; } else { size = csPtr->toRead; } size = DoRead(csPtr->readPtr, csPtr->buffer, size); if (size < 0) { readError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error reading \"", Tcl_GetChannelName(inChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } else if (size == 0) { /* * We had an underflow on the read side. If we are at EOF, * then the copying is done, otherwise set up a channel * handler to detect when the channel becomes readable again. */ if (Tcl_Eof(inChan)) { break; } else if (!(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Now write the buffer out. */ size = DoWrite(csPtr->writePtr, csPtr->buffer, size); if (size < 0) { writeError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error writing \"", Tcl_GetChannelName(outChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } /* * Check to see if the write is happening in the background. If so, * stop copying and wait for the channel to become writable again. */ if (csPtr->writePtr->flags & BG_FLUSH_SCHEDULED) { if (!(mask & TCL_WRITABLE)) { if (mask & TCL_READABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Update the current byte count if we care. */ if (csPtr->toRead != -1) { csPtr->toRead -= size; } csPtr->total += size; /* * For background copies, we only do one buffer per invocation so * we don't starve the rest of the system. */ if (cmdPtr) { /* * The first time we enter this code, there won't be a * channel handler established yet, so do it here. */ if (mask == 0) { Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } } /* * Make the callback or return the number of bytes transferred. * The local total is used because StopCopy frees csPtr. */ total = csPtr->total; if (cmdPtr) { /* * Get a private copy of the command so we can mutate it * by adding arguments. Note that StopCopy frees our saved * reference to the original command obj. */ cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); 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 * the background copy operation. It is just a trivial wrapper * around the CopyData routine. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void CopyEventProc(clientData, mask) ClientData clientData; int mask; { (void) CopyData((CopyState *)clientData, mask); } /* *---------------------------------------------------------------------- * * StopCopy -- * * This routine halts a copy that is in progress. * * Results: * None. * * Side effects: * Removes any pending channel handlers and restores the blocking * and buffering modes of the channels. The CopyState is freed. * *---------------------------------------------------------------------- */ static void StopCopy(csPtr) CopyState *csPtr; /* State for bg copy to stop . */ { int nonBlocking; if (!csPtr) { return; } /* * Restore the old blocking mode and output buffering mode. */ nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING); if (nonBlocking != (csPtr->readPtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->readPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } if (csPtr->writePtr != csPtr->writePtr) { if (nonBlocking != (csPtr->writePtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->writePtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } } csPtr->writePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); csPtr->writePtr->flags |= csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc, (ClientData)csPtr); if (csPtr->readPtr != csPtr->writePtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr, CopyEventProc, (ClientData)csPtr); } 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; } trf2.1.4/patches/v8.1b2/tclStubInit.c0000644000175000017500000004655311216344361016547 0ustar sergeisergei/* * 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.2 1999/03/28 15:16:04 aku 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 */ NULL, /* 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 */ NULL, NULL Tcl_ReplaceChannel, /* 345 */ Tcl_UndoReplaceChannel, /* 346 */ }; TclStubs *tclStubsPtr = &tclStubs; 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 */ }; TclIntStubs *tclIntStubsPtr = &tclIntStubs; 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 */ Tcl_WinUtfToTChar, /* 25 */ Tcl_WinTCharToUtf, /* 26 */ #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 */ }; TclIntPlatStubs *tclIntPlatStubsPtr = &tclIntPlatStubs; TclPlatStubs tclPlatStubs = { TCL_STUB_MAGIC, NULL, #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 */ }; TclPlatStubs *tclPlatStubsPtr = &tclPlatStubs; static TclStubHooks tclStubHooks = { &tclPlatStubs, &tclIntStubs, &tclIntPlatStubs }; /* !END!: Do not edit above this line. */ trf2.1.4/patches/v8.1b2/tclDecls.h0000644000175000017500000035023011216344361016033 0ustar sergeisergei/* * 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.2 1999/03/28 15:16:04 aku 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, CONST char * start)); /* 214 */ EXTERN int Tcl_RegExpMatch _ANSI_ARGS_((Tcl_Interp * interp, char * string, 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 * string, int * flagPtr)); /* 219 */ EXTERN int Tcl_ScanCountedElement _ANSI_ARGS_(( CONST char * string, 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 * string, 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 * list, 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 * string, 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 * string, 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)); /* Slot 280 is reserved */ /* 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)); /* 345 */ EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 346 */ EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Channel chan)); 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, 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 * string, CONST char * start)); /* 213 */ int (*tcl_RegExpMatch) _ANSI_ARGS_((Tcl_Interp * interp, char * string, 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 * string, int * flagPtr)); /* 218 */ int (*tcl_ScanCountedElement) _ANSI_ARGS_((CONST char * string, 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 * string, 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 * list, 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 * string, 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 * string, 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 *reserved280; 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 *reserved343; void *reserved344; Tcl_Channel (*tcl_ReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 345 */ void (*tcl_UndoReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 346 */ } TclStubs; extern TclStubs *tclStubsPtr; #if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) /* * Inline function declarations: */ #ifndef Tcl_PkgProvideEx #define Tcl_PkgProvideEx(interp, name, version, clientData) \ (tclStubsPtr->tcl_PkgProvideEx)(interp, name, version, clientData) /* 0 */ #endif #ifndef Tcl_PkgRequireEx #define Tcl_PkgRequireEx(interp, name, version, exact, clientDataPtr) \ (tclStubsPtr->tcl_PkgRequireEx)(interp, name, version, exact, clientDataPtr) /* 1 */ #endif #ifndef Tcl_Panic #define Tcl_Panic \ (tclStubsPtr->tcl_Panic) /* 2 */ #endif #ifndef Tcl_Alloc #define Tcl_Alloc(size) \ (tclStubsPtr->tcl_Alloc)(size) /* 3 */ #endif #ifndef Tcl_Free #define Tcl_Free(ptr) \ (tclStubsPtr->tcl_Free)(ptr) /* 4 */ #endif #ifndef Tcl_Realloc #define Tcl_Realloc(ptr, size) \ (tclStubsPtr->tcl_Realloc)(ptr, size) /* 5 */ #endif #ifndef Tcl_DbCkalloc #define Tcl_DbCkalloc(size, file, line) \ (tclStubsPtr->tcl_DbCkalloc)(size, file, line) /* 6 */ #endif #ifndef Tcl_DbCkfree #define Tcl_DbCkfree(ptr, file, line) \ (tclStubsPtr->tcl_DbCkfree)(ptr, file, line) /* 7 */ #endif #ifndef Tcl_DbCkrealloc #define Tcl_DbCkrealloc(ptr, size, file, line) \ (tclStubsPtr->tcl_DbCkrealloc)(ptr, size, file, line) /* 8 */ #endif #if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */ #ifndef Tcl_CreateFileHandler #define Tcl_CreateFileHandler(fd, mask, proc, clientData) \ (tclStubsPtr->tcl_CreateFileHandler)(fd, mask, proc, clientData) /* 9 */ #endif #endif /* UNIX */ #if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */ #ifndef Tcl_DeleteFileHandler #define Tcl_DeleteFileHandler(fd) \ (tclStubsPtr->tcl_DeleteFileHandler)(fd) /* 10 */ #endif #endif /* UNIX */ #ifndef Tcl_SetTimer #define Tcl_SetTimer(timePtr) \ (tclStubsPtr->tcl_SetTimer)(timePtr) /* 11 */ #endif #ifndef Tcl_Sleep #define Tcl_Sleep(ms) \ (tclStubsPtr->tcl_Sleep)(ms) /* 12 */ #endif #ifndef Tcl_WaitForEvent #define Tcl_WaitForEvent(timePtr) \ (tclStubsPtr->tcl_WaitForEvent)(timePtr) /* 13 */ #endif #ifndef Tcl_AppendAllObjTypes #define Tcl_AppendAllObjTypes(interp, objPtr) \ (tclStubsPtr->tcl_AppendAllObjTypes)(interp, objPtr) /* 14 */ #endif #ifndef Tcl_AppendStringsToObj #define Tcl_AppendStringsToObj \ (tclStubsPtr->tcl_AppendStringsToObj) /* 15 */ #endif #ifndef Tcl_AppendToObj #define Tcl_AppendToObj(objPtr, bytes, length) \ (tclStubsPtr->tcl_AppendToObj)(objPtr, bytes, length) /* 16 */ #endif #ifndef Tcl_ConcatObj #define Tcl_ConcatObj(objc, objv) \ (tclStubsPtr->tcl_ConcatObj)(objc, objv) /* 17 */ #endif #ifndef Tcl_ConvertToType #define Tcl_ConvertToType(interp, objPtr, typePtr) \ (tclStubsPtr->tcl_ConvertToType)(interp, objPtr, typePtr) /* 18 */ #endif #ifndef Tcl_DbDecrRefCount #define Tcl_DbDecrRefCount(objPtr, file, line) \ (tclStubsPtr->tcl_DbDecrRefCount)(objPtr, file, line) /* 19 */ #endif #ifndef Tcl_DbIncrRefCount #define Tcl_DbIncrRefCount(objPtr, file, line) \ (tclStubsPtr->tcl_DbIncrRefCount)(objPtr, file, line) /* 20 */ #endif #ifndef Tcl_DbIsShared #define Tcl_DbIsShared(objPtr, file, line) \ (tclStubsPtr->tcl_DbIsShared)(objPtr, file, line) /* 21 */ #endif #ifndef Tcl_DbNewBooleanObj #define Tcl_DbNewBooleanObj(boolValue, file, line) \ (tclStubsPtr->tcl_DbNewBooleanObj)(boolValue, file, line) /* 22 */ #endif #ifndef Tcl_DbNewByteArrayObj #define Tcl_DbNewByteArrayObj(bytes, length, file, line) \ (tclStubsPtr->tcl_DbNewByteArrayObj)(bytes, length, file, line) /* 23 */ #endif #ifndef Tcl_DbNewDoubleObj #define Tcl_DbNewDoubleObj(doubleValue, file, line) \ (tclStubsPtr->tcl_DbNewDoubleObj)(doubleValue, file, line) /* 24 */ #endif #ifndef Tcl_DbNewListObj #define Tcl_DbNewListObj(objc, objv, file, line) \ (tclStubsPtr->tcl_DbNewListObj)(objc, objv, file, line) /* 25 */ #endif #ifndef Tcl_DbNewLongObj #define Tcl_DbNewLongObj(longValue, file, line) \ (tclStubsPtr->tcl_DbNewLongObj)(longValue, file, line) /* 26 */ #endif #ifndef Tcl_DbNewObj #define Tcl_DbNewObj(file, line) \ (tclStubsPtr->tcl_DbNewObj)(file, line) /* 27 */ #endif #ifndef Tcl_DbNewStringObj #define Tcl_DbNewStringObj(bytes, length, file, line) \ (tclStubsPtr->tcl_DbNewStringObj)(bytes, length, file, line) /* 28 */ #endif #ifndef Tcl_DuplicateObj #define Tcl_DuplicateObj(objPtr) \ (tclStubsPtr->tcl_DuplicateObj)(objPtr) /* 29 */ #endif #ifndef TclFreeObj #define TclFreeObj(objPtr) \ (tclStubsPtr->tclFreeObj)(objPtr) /* 30 */ #endif #ifndef Tcl_GetBoolean #define Tcl_GetBoolean(interp, string, boolPtr) \ (tclStubsPtr->tcl_GetBoolean)(interp, string, boolPtr) /* 31 */ #endif #ifndef Tcl_GetBooleanFromObj #define Tcl_GetBooleanFromObj(interp, objPtr, boolPtr) \ (tclStubsPtr->tcl_GetBooleanFromObj)(interp, objPtr, boolPtr) /* 32 */ #endif #ifndef Tcl_GetByteArrayFromObj #define Tcl_GetByteArrayFromObj(objPtr, lengthPtr) \ (tclStubsPtr->tcl_GetByteArrayFromObj)(objPtr, lengthPtr) /* 33 */ #endif #ifndef Tcl_GetDouble #define Tcl_GetDouble(interp, string, doublePtr) \ (tclStubsPtr->tcl_GetDouble)(interp, string, doublePtr) /* 34 */ #endif #ifndef Tcl_GetDoubleFromObj #define Tcl_GetDoubleFromObj(interp, objPtr, doublePtr) \ (tclStubsPtr->tcl_GetDoubleFromObj)(interp, objPtr, doublePtr) /* 35 */ #endif #ifndef Tcl_GetIndexFromObj #define Tcl_GetIndexFromObj(interp, objPtr, tablePtr, msg, flags, indexPtr) \ (tclStubsPtr->tcl_GetIndexFromObj)(interp, objPtr, tablePtr, msg, flags, indexPtr) /* 36 */ #endif #ifndef Tcl_GetInt #define Tcl_GetInt(interp, string, intPtr) \ (tclStubsPtr->tcl_GetInt)(interp, string, intPtr) /* 37 */ #endif #ifndef Tcl_GetIntFromObj #define Tcl_GetIntFromObj(interp, objPtr, intPtr) \ (tclStubsPtr->tcl_GetIntFromObj)(interp, objPtr, intPtr) /* 38 */ #endif #ifndef Tcl_GetLongFromObj #define Tcl_GetLongFromObj(interp, objPtr, longPtr) \ (tclStubsPtr->tcl_GetLongFromObj)(interp, objPtr, longPtr) /* 39 */ #endif #ifndef Tcl_GetObjType #define Tcl_GetObjType(typeName) \ (tclStubsPtr->tcl_GetObjType)(typeName) /* 40 */ #endif #ifndef Tcl_GetStringFromObj #define Tcl_GetStringFromObj(objPtr, lengthPtr) \ (tclStubsPtr->tcl_GetStringFromObj)(objPtr, lengthPtr) /* 41 */ #endif #ifndef Tcl_InvalidateStringRep #define Tcl_InvalidateStringRep(objPtr) \ (tclStubsPtr->tcl_InvalidateStringRep)(objPtr) /* 42 */ #endif #ifndef Tcl_ListObjAppendList #define Tcl_ListObjAppendList(interp, listPtr, elemListPtr) \ (tclStubsPtr->tcl_ListObjAppendList)(interp, listPtr, elemListPtr) /* 43 */ #endif #ifndef Tcl_ListObjAppendElement #define Tcl_ListObjAppendElement(interp, listPtr, objPtr) \ (tclStubsPtr->tcl_ListObjAppendElement)(interp, listPtr, objPtr) /* 44 */ #endif #ifndef Tcl_ListObjGetElements #define Tcl_ListObjGetElements(interp, listPtr, objcPtr, objvPtr) \ (tclStubsPtr->tcl_ListObjGetElements)(interp, listPtr, objcPtr, objvPtr) /* 45 */ #endif #ifndef Tcl_ListObjIndex #define Tcl_ListObjIndex(interp, listPtr, index, objPtrPtr) \ (tclStubsPtr->tcl_ListObjIndex)(interp, listPtr, index, objPtrPtr) /* 46 */ #endif #ifndef Tcl_ListObjLength #define Tcl_ListObjLength(interp, listPtr, intPtr) \ (tclStubsPtr->tcl_ListObjLength)(interp, listPtr, intPtr) /* 47 */ #endif #ifndef Tcl_ListObjReplace #define Tcl_ListObjReplace(interp, listPtr, first, count, objc, objv) \ (tclStubsPtr->tcl_ListObjReplace)(interp, listPtr, first, count, objc, objv) /* 48 */ #endif #ifndef Tcl_NewBooleanObj #define Tcl_NewBooleanObj(boolValue) \ (tclStubsPtr->tcl_NewBooleanObj)(boolValue) /* 49 */ #endif #ifndef Tcl_NewByteArrayObj #define Tcl_NewByteArrayObj(bytes, length) \ (tclStubsPtr->tcl_NewByteArrayObj)(bytes, length) /* 50 */ #endif #ifndef Tcl_NewDoubleObj #define Tcl_NewDoubleObj(doubleValue) \ (tclStubsPtr->tcl_NewDoubleObj)(doubleValue) /* 51 */ #endif #ifndef Tcl_NewIntObj #define Tcl_NewIntObj(intValue) \ (tclStubsPtr->tcl_NewIntObj)(intValue) /* 52 */ #endif #ifndef Tcl_NewListObj #define Tcl_NewListObj(objc, objv) \ (tclStubsPtr->tcl_NewListObj)(objc, objv) /* 53 */ #endif #ifndef Tcl_NewLongObj #define Tcl_NewLongObj(longValue) \ (tclStubsPtr->tcl_NewLongObj)(longValue) /* 54 */ #endif #ifndef Tcl_NewObj #define Tcl_NewObj() \ (tclStubsPtr->tcl_NewObj)() /* 55 */ #endif #ifndef Tcl_NewStringObj #define Tcl_NewStringObj(bytes, length) \ (tclStubsPtr->tcl_NewStringObj)(bytes, length) /* 56 */ #endif #ifndef Tcl_SetBooleanObj #define Tcl_SetBooleanObj(objPtr, boolValue) \ (tclStubsPtr->tcl_SetBooleanObj)(objPtr, boolValue) /* 57 */ #endif #ifndef Tcl_SetByteArrayLength #define Tcl_SetByteArrayLength(objPtr, length) \ (tclStubsPtr->tcl_SetByteArrayLength)(objPtr, length) /* 58 */ #endif #ifndef Tcl_SetByteArrayObj #define Tcl_SetByteArrayObj(objPtr, bytes, length) \ (tclStubsPtr->tcl_SetByteArrayObj)(objPtr, bytes, length) /* 59 */ #endif #ifndef Tcl_SetDoubleObj #define Tcl_SetDoubleObj(objPtr, doubleValue) \ (tclStubsPtr->tcl_SetDoubleObj)(objPtr, doubleValue) /* 60 */ #endif #ifndef Tcl_SetIntObj #define Tcl_SetIntObj(objPtr, intValue) \ (tclStubsPtr->tcl_SetIntObj)(objPtr, intValue) /* 61 */ #endif #ifndef Tcl_SetListObj #define Tcl_SetListObj(objPtr, objc, objv) \ (tclStubsPtr->tcl_SetListObj)(objPtr, objc, objv) /* 62 */ #endif #ifndef Tcl_SetLongObj #define Tcl_SetLongObj(objPtr, longValue) \ (tclStubsPtr->tcl_SetLongObj)(objPtr, longValue) /* 63 */ #endif #ifndef Tcl_SetObjLength #define Tcl_SetObjLength(objPtr, length) \ (tclStubsPtr->tcl_SetObjLength)(objPtr, length) /* 64 */ #endif #ifndef Tcl_SetStringObj #define Tcl_SetStringObj(objPtr, bytes, length) \ (tclStubsPtr->tcl_SetStringObj)(objPtr, bytes, length) /* 65 */ #endif #ifndef Tcl_AddErrorInfo #define Tcl_AddErrorInfo(interp, message) \ (tclStubsPtr->tcl_AddErrorInfo)(interp, message) /* 66 */ #endif #ifndef Tcl_AddObjErrorInfo #define Tcl_AddObjErrorInfo(interp, message, length) \ (tclStubsPtr->tcl_AddObjErrorInfo)(interp, message, length) /* 67 */ #endif #ifndef Tcl_AllowExceptions #define Tcl_AllowExceptions(interp) \ (tclStubsPtr->tcl_AllowExceptions)(interp) /* 68 */ #endif #ifndef Tcl_AppendElement #define Tcl_AppendElement(interp, string) \ (tclStubsPtr->tcl_AppendElement)(interp, string) /* 69 */ #endif #ifndef Tcl_AppendResult #define Tcl_AppendResult \ (tclStubsPtr->tcl_AppendResult) /* 70 */ #endif #ifndef Tcl_AsyncCreate #define Tcl_AsyncCreate(proc, clientData) \ (tclStubsPtr->tcl_AsyncCreate)(proc, clientData) /* 71 */ #endif #ifndef Tcl_AsyncDelete #define Tcl_AsyncDelete(async) \ (tclStubsPtr->tcl_AsyncDelete)(async) /* 72 */ #endif #ifndef Tcl_AsyncInvoke #define Tcl_AsyncInvoke(interp, code) \ (tclStubsPtr->tcl_AsyncInvoke)(interp, code) /* 73 */ #endif #ifndef Tcl_AsyncMark #define Tcl_AsyncMark(async) \ (tclStubsPtr->tcl_AsyncMark)(async) /* 74 */ #endif #ifndef Tcl_AsyncReady #define Tcl_AsyncReady() \ (tclStubsPtr->tcl_AsyncReady)() /* 75 */ #endif #ifndef Tcl_BackgroundError #define Tcl_BackgroundError(interp) \ (tclStubsPtr->tcl_BackgroundError)(interp) /* 76 */ #endif #ifndef Tcl_Backslash #define Tcl_Backslash(src, readPtr) \ (tclStubsPtr->tcl_Backslash)(src, readPtr) /* 77 */ #endif #ifndef Tcl_BadChannelOption #define Tcl_BadChannelOption(interp, optionName, optionList) \ (tclStubsPtr->tcl_BadChannelOption)(interp, optionName, optionList) /* 78 */ #endif #ifndef Tcl_CallWhenDeleted #define Tcl_CallWhenDeleted(interp, proc, clientData) \ (tclStubsPtr->tcl_CallWhenDeleted)(interp, proc, clientData) /* 79 */ #endif #ifndef Tcl_CancelIdleCall #define Tcl_CancelIdleCall(idleProc, clientData) \ (tclStubsPtr->tcl_CancelIdleCall)(idleProc, clientData) /* 80 */ #endif #ifndef Tcl_Close #define Tcl_Close(interp, chan) \ (tclStubsPtr->tcl_Close)(interp, chan) /* 81 */ #endif #ifndef Tcl_CommandComplete #define Tcl_CommandComplete(cmd) \ (tclStubsPtr->tcl_CommandComplete)(cmd) /* 82 */ #endif #ifndef Tcl_Concat #define Tcl_Concat(argc, argv) \ (tclStubsPtr->tcl_Concat)(argc, argv) /* 83 */ #endif #ifndef Tcl_ConvertElement #define Tcl_ConvertElement(src, dst, flags) \ (tclStubsPtr->tcl_ConvertElement)(src, dst, flags) /* 84 */ #endif #ifndef Tcl_ConvertCountedElement #define Tcl_ConvertCountedElement(src, length, dst, flags) \ (tclStubsPtr->tcl_ConvertCountedElement)(src, length, dst, flags) /* 85 */ #endif #ifndef Tcl_CreateAlias #define Tcl_CreateAlias(slave, slaveCmd, target, targetCmd, argc, argv) \ (tclStubsPtr->tcl_CreateAlias)(slave, slaveCmd, target, targetCmd, argc, argv) /* 86 */ #endif #ifndef Tcl_CreateAliasObj #define Tcl_CreateAliasObj(slave, slaveCmd, target, targetCmd, objc, objv) \ (tclStubsPtr->tcl_CreateAliasObj)(slave, slaveCmd, target, targetCmd, objc, objv) /* 87 */ #endif #ifndef Tcl_CreateChannel #define Tcl_CreateChannel(typePtr, chanName, instanceData, mask) \ (tclStubsPtr->tcl_CreateChannel)(typePtr, chanName, instanceData, mask) /* 88 */ #endif #ifndef Tcl_CreateChannelHandler #define Tcl_CreateChannelHandler(chan, mask, proc, clientData) \ (tclStubsPtr->tcl_CreateChannelHandler)(chan, mask, proc, clientData) /* 89 */ #endif #ifndef Tcl_CreateCloseHandler #define Tcl_CreateCloseHandler(chan, proc, clientData) \ (tclStubsPtr->tcl_CreateCloseHandler)(chan, proc, clientData) /* 90 */ #endif #ifndef Tcl_CreateCommand #define Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc) \ (tclStubsPtr->tcl_CreateCommand)(interp, cmdName, proc, clientData, deleteProc) /* 91 */ #endif #ifndef Tcl_CreateEventSource #define Tcl_CreateEventSource(setupProc, checkProc, clientData) \ (tclStubsPtr->tcl_CreateEventSource)(setupProc, checkProc, clientData) /* 92 */ #endif #ifndef Tcl_CreateExitHandler #define Tcl_CreateExitHandler(proc, clientData) \ (tclStubsPtr->tcl_CreateExitHandler)(proc, clientData) /* 93 */ #endif #ifndef Tcl_CreateInterp #define Tcl_CreateInterp() \ (tclStubsPtr->tcl_CreateInterp)() /* 94 */ #endif #ifndef Tcl_CreateMathFunc #define Tcl_CreateMathFunc(interp, name, numArgs, argTypes, proc, clientData) \ (tclStubsPtr->tcl_CreateMathFunc)(interp, name, numArgs, argTypes, proc, clientData) /* 95 */ #endif #ifndef Tcl_CreateObjCommand #define Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc) \ (tclStubsPtr->tcl_CreateObjCommand)(interp, cmdName, proc, clientData, deleteProc) /* 96 */ #endif #ifndef Tcl_CreateSlave #define Tcl_CreateSlave(interp, slaveName, isSafe) \ (tclStubsPtr->tcl_CreateSlave)(interp, slaveName, isSafe) /* 97 */ #endif #ifndef Tcl_CreateTimerHandler #define Tcl_CreateTimerHandler(milliseconds, proc, clientData) \ (tclStubsPtr->tcl_CreateTimerHandler)(milliseconds, proc, clientData) /* 98 */ #endif #ifndef Tcl_CreateTrace #define Tcl_CreateTrace(interp, level, proc, clientData) \ (tclStubsPtr->tcl_CreateTrace)(interp, level, proc, clientData) /* 99 */ #endif #ifndef Tcl_DeleteAssocData #define Tcl_DeleteAssocData(interp, name) \ (tclStubsPtr->tcl_DeleteAssocData)(interp, name) /* 100 */ #endif #ifndef Tcl_DeleteChannelHandler #define Tcl_DeleteChannelHandler(chan, proc, clientData) \ (tclStubsPtr->tcl_DeleteChannelHandler)(chan, proc, clientData) /* 101 */ #endif #ifndef Tcl_DeleteCloseHandler #define Tcl_DeleteCloseHandler(chan, proc, clientData) \ (tclStubsPtr->tcl_DeleteCloseHandler)(chan, proc, clientData) /* 102 */ #endif #ifndef Tcl_DeleteCommand #define Tcl_DeleteCommand(interp, cmdName) \ (tclStubsPtr->tcl_DeleteCommand)(interp, cmdName) /* 103 */ #endif #ifndef Tcl_DeleteCommandFromToken #define Tcl_DeleteCommandFromToken(interp, command) \ (tclStubsPtr->tcl_DeleteCommandFromToken)(interp, command) /* 104 */ #endif #ifndef Tcl_DeleteEvents #define Tcl_DeleteEvents(proc, clientData) \ (tclStubsPtr->tcl_DeleteEvents)(proc, clientData) /* 105 */ #endif #ifndef Tcl_DeleteEventSource #define Tcl_DeleteEventSource(setupProc, checkProc, clientData) \ (tclStubsPtr->tcl_DeleteEventSource)(setupProc, checkProc, clientData) /* 106 */ #endif #ifndef Tcl_DeleteExitHandler #define Tcl_DeleteExitHandler(proc, clientData) \ (tclStubsPtr->tcl_DeleteExitHandler)(proc, clientData) /* 107 */ #endif #ifndef Tcl_DeleteHashEntry #define Tcl_DeleteHashEntry(entryPtr) \ (tclStubsPtr->tcl_DeleteHashEntry)(entryPtr) /* 108 */ #endif #ifndef Tcl_DeleteHashTable #define Tcl_DeleteHashTable(tablePtr) \ (tclStubsPtr->tcl_DeleteHashTable)(tablePtr) /* 109 */ #endif #ifndef Tcl_DeleteInterp #define Tcl_DeleteInterp(interp) \ (tclStubsPtr->tcl_DeleteInterp)(interp) /* 110 */ #endif #ifndef Tcl_DetachPids #define Tcl_DetachPids(numPids, pidPtr) \ (tclStubsPtr->tcl_DetachPids)(numPids, pidPtr) /* 111 */ #endif #ifndef Tcl_DeleteTimerHandler #define Tcl_DeleteTimerHandler(token) \ (tclStubsPtr->tcl_DeleteTimerHandler)(token) /* 112 */ #endif #ifndef Tcl_DeleteTrace #define Tcl_DeleteTrace(interp, trace) \ (tclStubsPtr->tcl_DeleteTrace)(interp, trace) /* 113 */ #endif #ifndef Tcl_DontCallWhenDeleted #define Tcl_DontCallWhenDeleted(interp, proc, clientData) \ (tclStubsPtr->tcl_DontCallWhenDeleted)(interp, proc, clientData) /* 114 */ #endif #ifndef Tcl_DoOneEvent #define Tcl_DoOneEvent(flags) \ (tclStubsPtr->tcl_DoOneEvent)(flags) /* 115 */ #endif #ifndef Tcl_DoWhenIdle #define Tcl_DoWhenIdle(proc, clientData) \ (tclStubsPtr->tcl_DoWhenIdle)(proc, clientData) /* 116 */ #endif #ifndef Tcl_DStringAppend #define Tcl_DStringAppend(dsPtr, string, length) \ (tclStubsPtr->tcl_DStringAppend)(dsPtr, string, length) /* 117 */ #endif #ifndef Tcl_DStringAppendElement #define Tcl_DStringAppendElement(dsPtr, string) \ (tclStubsPtr->tcl_DStringAppendElement)(dsPtr, string) /* 118 */ #endif #ifndef Tcl_DStringEndSublist #define Tcl_DStringEndSublist(dsPtr) \ (tclStubsPtr->tcl_DStringEndSublist)(dsPtr) /* 119 */ #endif #ifndef Tcl_DStringFree #define Tcl_DStringFree(dsPtr) \ (tclStubsPtr->tcl_DStringFree)(dsPtr) /* 120 */ #endif #ifndef Tcl_DStringGetResult #define Tcl_DStringGetResult(interp, dsPtr) \ (tclStubsPtr->tcl_DStringGetResult)(interp, dsPtr) /* 121 */ #endif #ifndef Tcl_DStringInit #define Tcl_DStringInit(dsPtr) \ (tclStubsPtr->tcl_DStringInit)(dsPtr) /* 122 */ #endif #ifndef Tcl_DStringResult #define Tcl_DStringResult(interp, dsPtr) \ (tclStubsPtr->tcl_DStringResult)(interp, dsPtr) /* 123 */ #endif #ifndef Tcl_DStringSetLength #define Tcl_DStringSetLength(dsPtr, length) \ (tclStubsPtr->tcl_DStringSetLength)(dsPtr, length) /* 124 */ #endif #ifndef Tcl_DStringStartSublist #define Tcl_DStringStartSublist(dsPtr) \ (tclStubsPtr->tcl_DStringStartSublist)(dsPtr) /* 125 */ #endif #ifndef Tcl_Eof #define Tcl_Eof(chan) \ (tclStubsPtr->tcl_Eof)(chan) /* 126 */ #endif #ifndef Tcl_ErrnoId #define Tcl_ErrnoId() \ (tclStubsPtr->tcl_ErrnoId)() /* 127 */ #endif #ifndef Tcl_ErrnoMsg #define Tcl_ErrnoMsg(err) \ (tclStubsPtr->tcl_ErrnoMsg)(err) /* 128 */ #endif #ifndef Tcl_Eval #define Tcl_Eval(interp, string) \ (tclStubsPtr->tcl_Eval)(interp, string) /* 129 */ #endif #ifndef Tcl_EvalFile #define Tcl_EvalFile(interp, fileName) \ (tclStubsPtr->tcl_EvalFile)(interp, fileName) /* 130 */ #endif #ifndef Tcl_EvalObj #define Tcl_EvalObj(interp, objPtr) \ (tclStubsPtr->tcl_EvalObj)(interp, objPtr) /* 131 */ #endif #ifndef Tcl_EventuallyFree #define Tcl_EventuallyFree(clientData, freeProc) \ (tclStubsPtr->tcl_EventuallyFree)(clientData, freeProc) /* 132 */ #endif #ifndef Tcl_Exit #define Tcl_Exit(status) \ (tclStubsPtr->tcl_Exit)(status) /* 133 */ #endif #ifndef Tcl_ExposeCommand #define Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName) \ (tclStubsPtr->tcl_ExposeCommand)(interp, hiddenCmdToken, cmdName) /* 134 */ #endif #ifndef Tcl_ExprBoolean #define Tcl_ExprBoolean(interp, string, ptr) \ (tclStubsPtr->tcl_ExprBoolean)(interp, string, ptr) /* 135 */ #endif #ifndef Tcl_ExprBooleanObj #define Tcl_ExprBooleanObj(interp, objPtr, ptr) \ (tclStubsPtr->tcl_ExprBooleanObj)(interp, objPtr, ptr) /* 136 */ #endif #ifndef Tcl_ExprDouble #define Tcl_ExprDouble(interp, string, ptr) \ (tclStubsPtr->tcl_ExprDouble)(interp, string, ptr) /* 137 */ #endif #ifndef Tcl_ExprDoubleObj #define Tcl_ExprDoubleObj(interp, objPtr, ptr) \ (tclStubsPtr->tcl_ExprDoubleObj)(interp, objPtr, ptr) /* 138 */ #endif #ifndef Tcl_ExprLong #define Tcl_ExprLong(interp, string, ptr) \ (tclStubsPtr->tcl_ExprLong)(interp, string, ptr) /* 139 */ #endif #ifndef Tcl_ExprLongObj #define Tcl_ExprLongObj(interp, objPtr, ptr) \ (tclStubsPtr->tcl_ExprLongObj)(interp, objPtr, ptr) /* 140 */ #endif #ifndef Tcl_ExprObj #define Tcl_ExprObj(interp, objPtr, resultPtrPtr) \ (tclStubsPtr->tcl_ExprObj)(interp, objPtr, resultPtrPtr) /* 141 */ #endif #ifndef Tcl_ExprString #define Tcl_ExprString(interp, string) \ (tclStubsPtr->tcl_ExprString)(interp, string) /* 142 */ #endif #ifndef Tcl_Finalize #define Tcl_Finalize() \ (tclStubsPtr->tcl_Finalize)() /* 143 */ #endif #ifndef Tcl_FindExecutable #define Tcl_FindExecutable(argv0) \ (tclStubsPtr->tcl_FindExecutable)(argv0) /* 144 */ #endif #ifndef Tcl_FirstHashEntry #define Tcl_FirstHashEntry(tablePtr, searchPtr) \ (tclStubsPtr->tcl_FirstHashEntry)(tablePtr, searchPtr) /* 145 */ #endif #ifndef Tcl_Flush #define Tcl_Flush(chan) \ (tclStubsPtr->tcl_Flush)(chan) /* 146 */ #endif #ifndef Tcl_FreeResult #define Tcl_FreeResult(interp) \ (tclStubsPtr->tcl_FreeResult)(interp) /* 147 */ #endif #ifndef Tcl_GetAlias #define Tcl_GetAlias(interp, slaveCmd, targetInterpPtr, targetCmdPtr, argcPtr, argvPtr) \ (tclStubsPtr->tcl_GetAlias)(interp, slaveCmd, targetInterpPtr, targetCmdPtr, argcPtr, argvPtr) /* 148 */ #endif #ifndef Tcl_GetAliasObj #define Tcl_GetAliasObj(interp, slaveCmd, targetInterpPtr, targetCmdPtr, objcPtr, objv) \ (tclStubsPtr->tcl_GetAliasObj)(interp, slaveCmd, targetInterpPtr, targetCmdPtr, objcPtr, objv) /* 149 */ #endif #ifndef Tcl_GetAssocData #define Tcl_GetAssocData(interp, name, procPtr) \ (tclStubsPtr->tcl_GetAssocData)(interp, name, procPtr) /* 150 */ #endif #ifndef Tcl_GetChannel #define Tcl_GetChannel(interp, chanName, modePtr) \ (tclStubsPtr->tcl_GetChannel)(interp, chanName, modePtr) /* 151 */ #endif #ifndef Tcl_GetChannelBufferSize #define Tcl_GetChannelBufferSize(chan) \ (tclStubsPtr->tcl_GetChannelBufferSize)(chan) /* 152 */ #endif #ifndef Tcl_GetChannelHandle #define Tcl_GetChannelHandle(chan, direction, handlePtr) \ (tclStubsPtr->tcl_GetChannelHandle)(chan, direction, handlePtr) /* 153 */ #endif #ifndef Tcl_GetChannelInstanceData #define Tcl_GetChannelInstanceData(chan) \ (tclStubsPtr->tcl_GetChannelInstanceData)(chan) /* 154 */ #endif #ifndef Tcl_GetChannelMode #define Tcl_GetChannelMode(chan) \ (tclStubsPtr->tcl_GetChannelMode)(chan) /* 155 */ #endif #ifndef Tcl_GetChannelName #define Tcl_GetChannelName(chan) \ (tclStubsPtr->tcl_GetChannelName)(chan) /* 156 */ #endif #ifndef Tcl_GetChannelOption #define Tcl_GetChannelOption(interp, chan, optionName, dsPtr) \ (tclStubsPtr->tcl_GetChannelOption)(interp, chan, optionName, dsPtr) /* 157 */ #endif #ifndef Tcl_GetChannelType #define Tcl_GetChannelType(chan) \ (tclStubsPtr->tcl_GetChannelType)(chan) /* 158 */ #endif #ifndef Tcl_GetCommandInfo #define Tcl_GetCommandInfo(interp, cmdName, infoPtr) \ (tclStubsPtr->tcl_GetCommandInfo)(interp, cmdName, infoPtr) /* 159 */ #endif #ifndef Tcl_GetCommandName #define Tcl_GetCommandName(interp, command) \ (tclStubsPtr->tcl_GetCommandName)(interp, command) /* 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(askInterp, slaveInterp) \ (tclStubsPtr->tcl_GetInterpPath)(askInterp, slaveInterp) /* 163 */ #endif #ifndef Tcl_GetMaster #define Tcl_GetMaster(interp) \ (tclStubsPtr->tcl_GetMaster)(interp) /* 164 */ #endif #ifndef Tcl_GetNameOfExecutable #define Tcl_GetNameOfExecutable() \ (tclStubsPtr->tcl_GetNameOfExecutable)() /* 165 */ #endif #ifndef Tcl_GetObjResult #define Tcl_GetObjResult(interp) \ (tclStubsPtr->tcl_GetObjResult)(interp) /* 166 */ #endif #if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */ #ifndef Tcl_GetOpenFile #define Tcl_GetOpenFile(interp, string, write, checkUsage, filePtr) \ (tclStubsPtr->tcl_GetOpenFile)(interp, string, write, checkUsage, filePtr) /* 167 */ #endif #endif /* UNIX */ #ifndef Tcl_GetPathType #define Tcl_GetPathType(path) \ (tclStubsPtr->tcl_GetPathType)(path) /* 168 */ #endif #ifndef Tcl_Gets #define Tcl_Gets(chan, dsPtr) \ (tclStubsPtr->tcl_Gets)(chan, dsPtr) /* 169 */ #endif #ifndef Tcl_GetsObj #define Tcl_GetsObj(chan, objPtr) \ (tclStubsPtr->tcl_GetsObj)(chan, objPtr) /* 170 */ #endif #ifndef Tcl_GetServiceMode #define Tcl_GetServiceMode() \ (tclStubsPtr->tcl_GetServiceMode)() /* 171 */ #endif #ifndef Tcl_GetSlave #define Tcl_GetSlave(interp, slaveName) \ (tclStubsPtr->tcl_GetSlave)(interp, slaveName) /* 172 */ #endif #ifndef Tcl_GetStdChannel #define Tcl_GetStdChannel(type) \ (tclStubsPtr->tcl_GetStdChannel)(type) /* 173 */ #endif #ifndef Tcl_GetStringResult #define Tcl_GetStringResult(interp) \ (tclStubsPtr->tcl_GetStringResult)(interp) /* 174 */ #endif #ifndef Tcl_GetVar #define Tcl_GetVar(interp, varName, flags) \ (tclStubsPtr->tcl_GetVar)(interp, varName, flags) /* 175 */ #endif #ifndef Tcl_GetVar2 #define Tcl_GetVar2(interp, part1, part2, flags) \ (tclStubsPtr->tcl_GetVar2)(interp, part1, part2, flags) /* 176 */ #endif #ifndef Tcl_GlobalEval #define Tcl_GlobalEval(interp, command) \ (tclStubsPtr->tcl_GlobalEval)(interp, command) /* 177 */ #endif #ifndef Tcl_GlobalEvalObj #define Tcl_GlobalEvalObj(interp, objPtr) \ (tclStubsPtr->tcl_GlobalEvalObj)(interp, objPtr) /* 178 */ #endif #ifndef Tcl_HideCommand #define Tcl_HideCommand(interp, cmdName, hiddenCmdToken) \ (tclStubsPtr->tcl_HideCommand)(interp, cmdName, hiddenCmdToken) /* 179 */ #endif #ifndef Tcl_Init #define Tcl_Init(interp) \ (tclStubsPtr->tcl_Init)(interp) /* 180 */ #endif #ifndef Tcl_InitHashTable #define Tcl_InitHashTable(tablePtr, keyType) \ (tclStubsPtr->tcl_InitHashTable)(tablePtr, keyType) /* 181 */ #endif #ifndef Tcl_InputBlocked #define Tcl_InputBlocked(chan) \ (tclStubsPtr->tcl_InputBlocked)(chan) /* 182 */ #endif #ifndef Tcl_InputBuffered #define Tcl_InputBuffered(chan) \ (tclStubsPtr->tcl_InputBuffered)(chan) /* 183 */ #endif #ifndef Tcl_InterpDeleted #define Tcl_InterpDeleted(interp) \ (tclStubsPtr->tcl_InterpDeleted)(interp) /* 184 */ #endif #ifndef Tcl_IsSafe #define Tcl_IsSafe(interp) \ (tclStubsPtr->tcl_IsSafe)(interp) /* 185 */ #endif #ifndef Tcl_JoinPath #define Tcl_JoinPath(argc, argv, resultPtr) \ (tclStubsPtr->tcl_JoinPath)(argc, argv, resultPtr) /* 186 */ #endif #ifndef Tcl_LinkVar #define Tcl_LinkVar(interp, varName, addr, type) \ (tclStubsPtr->tcl_LinkVar)(interp, varName, addr, type) /* 187 */ #endif /* Slot 188 is reserved */ #ifndef Tcl_MakeFileChannel #define Tcl_MakeFileChannel(handle, mode) \ (tclStubsPtr->tcl_MakeFileChannel)(handle, mode) /* 189 */ #endif #ifndef Tcl_MakeSafe #define Tcl_MakeSafe(interp) \ (tclStubsPtr->tcl_MakeSafe)(interp) /* 190 */ #endif #ifndef Tcl_MakeTcpClientChannel #define Tcl_MakeTcpClientChannel(tcpSocket) \ (tclStubsPtr->tcl_MakeTcpClientChannel)(tcpSocket) /* 191 */ #endif #ifndef Tcl_Merge #define Tcl_Merge(argc, argv) \ (tclStubsPtr->tcl_Merge)(argc, argv) /* 192 */ #endif #ifndef Tcl_NextHashEntry #define Tcl_NextHashEntry(searchPtr) \ (tclStubsPtr->tcl_NextHashEntry)(searchPtr) /* 193 */ #endif #ifndef Tcl_NotifyChannel #define Tcl_NotifyChannel(channel, mask) \ (tclStubsPtr->tcl_NotifyChannel)(channel, mask) /* 194 */ #endif #ifndef Tcl_ObjGetVar2 #define Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags) \ (tclStubsPtr->tcl_ObjGetVar2)(interp, part1Ptr, part2Ptr, flags) /* 195 */ #endif #ifndef Tcl_ObjSetVar2 #define Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, newValuePtr, flags) \ (tclStubsPtr->tcl_ObjSetVar2)(interp, part1Ptr, part2Ptr, newValuePtr, flags) /* 196 */ #endif #ifndef Tcl_OpenCommandChannel #define Tcl_OpenCommandChannel(interp, argc, argv, flags) \ (tclStubsPtr->tcl_OpenCommandChannel)(interp, argc, argv, flags) /* 197 */ #endif #ifndef Tcl_OpenFileChannel #define Tcl_OpenFileChannel(interp, fileName, modeString, permissions) \ (tclStubsPtr->tcl_OpenFileChannel)(interp, fileName, modeString, permissions) /* 198 */ #endif #ifndef Tcl_OpenTcpClient #define Tcl_OpenTcpClient(interp, port, address, myaddr, myport, async) \ (tclStubsPtr->tcl_OpenTcpClient)(interp, port, address, myaddr, myport, async) /* 199 */ #endif #ifndef Tcl_OpenTcpServer #define Tcl_OpenTcpServer(interp, port, host, acceptProc, callbackData) \ (tclStubsPtr->tcl_OpenTcpServer)(interp, port, host, acceptProc, callbackData) /* 200 */ #endif #ifndef Tcl_Preserve #define Tcl_Preserve(data) \ (tclStubsPtr->tcl_Preserve)(data) /* 201 */ #endif #ifndef Tcl_PrintDouble #define Tcl_PrintDouble(interp, value, dst) \ (tclStubsPtr->tcl_PrintDouble)(interp, value, dst) /* 202 */ #endif #ifndef Tcl_PutEnv #define Tcl_PutEnv(string) \ (tclStubsPtr->tcl_PutEnv)(string) /* 203 */ #endif #ifndef Tcl_PosixError #define Tcl_PosixError(interp) \ (tclStubsPtr->tcl_PosixError)(interp) /* 204 */ #endif #ifndef Tcl_QueueEvent #define Tcl_QueueEvent(evPtr, position) \ (tclStubsPtr->tcl_QueueEvent)(evPtr, position) /* 205 */ #endif #ifndef Tcl_Read #define Tcl_Read(chan, bufPtr, toRead) \ (tclStubsPtr->tcl_Read)(chan, bufPtr, toRead) /* 206 */ #endif #ifndef Tcl_ReapDetachedProcs #define Tcl_ReapDetachedProcs() \ (tclStubsPtr->tcl_ReapDetachedProcs)() /* 207 */ #endif #ifndef Tcl_RecordAndEval #define Tcl_RecordAndEval(interp, cmd, flags) \ (tclStubsPtr->tcl_RecordAndEval)(interp, cmd, flags) /* 208 */ #endif #ifndef Tcl_RecordAndEvalObj #define Tcl_RecordAndEvalObj(interp, cmdPtr, flags) \ (tclStubsPtr->tcl_RecordAndEvalObj)(interp, cmdPtr, flags) /* 209 */ #endif #ifndef Tcl_RegisterChannel #define Tcl_RegisterChannel(interp, chan) \ (tclStubsPtr->tcl_RegisterChannel)(interp, chan) /* 210 */ #endif #ifndef Tcl_RegisterObjType #define Tcl_RegisterObjType(typePtr) \ (tclStubsPtr->tcl_RegisterObjType)(typePtr) /* 211 */ #endif #ifndef Tcl_RegExpCompile #define Tcl_RegExpCompile(interp, string) \ (tclStubsPtr->tcl_RegExpCompile)(interp, string) /* 212 */ #endif #ifndef Tcl_RegExpExec #define Tcl_RegExpExec(interp, regexp, string, start) \ (tclStubsPtr->tcl_RegExpExec)(interp, regexp, string, start) /* 213 */ #endif #ifndef Tcl_RegExpMatch #define Tcl_RegExpMatch(interp, string, pattern) \ (tclStubsPtr->tcl_RegExpMatch)(interp, string, pattern) /* 214 */ #endif #ifndef Tcl_RegExpRange #define Tcl_RegExpRange(regexp, index, startPtr, endPtr) \ (tclStubsPtr->tcl_RegExpRange)(regexp, index, startPtr, endPtr) /* 215 */ #endif #ifndef Tcl_Release #define Tcl_Release(clientData) \ (tclStubsPtr->tcl_Release)(clientData) /* 216 */ #endif #ifndef Tcl_ResetResult #define Tcl_ResetResult(interp) \ (tclStubsPtr->tcl_ResetResult)(interp) /* 217 */ #endif #ifndef Tcl_ScanElement #define Tcl_ScanElement(string, flagPtr) \ (tclStubsPtr->tcl_ScanElement)(string, flagPtr) /* 218 */ #endif #ifndef Tcl_ScanCountedElement #define Tcl_ScanCountedElement(string, length, flagPtr) \ (tclStubsPtr->tcl_ScanCountedElement)(string, length, flagPtr) /* 219 */ #endif #ifndef Tcl_Seek #define Tcl_Seek(chan, offset, mode) \ (tclStubsPtr->tcl_Seek)(chan, offset, mode) /* 220 */ #endif #ifndef Tcl_ServiceAll #define Tcl_ServiceAll() \ (tclStubsPtr->tcl_ServiceAll)() /* 221 */ #endif #ifndef Tcl_ServiceEvent #define Tcl_ServiceEvent(flags) \ (tclStubsPtr->tcl_ServiceEvent)(flags) /* 222 */ #endif #ifndef Tcl_SetAssocData #define Tcl_SetAssocData(interp, name, proc, clientData) \ (tclStubsPtr->tcl_SetAssocData)(interp, name, proc, clientData) /* 223 */ #endif #ifndef Tcl_SetChannelBufferSize #define Tcl_SetChannelBufferSize(chan, sz) \ (tclStubsPtr->tcl_SetChannelBufferSize)(chan, sz) /* 224 */ #endif #ifndef Tcl_SetChannelOption #define Tcl_SetChannelOption(interp, chan, optionName, newValue) \ (tclStubsPtr->tcl_SetChannelOption)(interp, chan, optionName, newValue) /* 225 */ #endif #ifndef Tcl_SetCommandInfo #define Tcl_SetCommandInfo(interp, cmdName, infoPtr) \ (tclStubsPtr->tcl_SetCommandInfo)(interp, cmdName, infoPtr) /* 226 */ #endif #ifndef Tcl_SetErrno #define Tcl_SetErrno(err) \ (tclStubsPtr->tcl_SetErrno)(err) /* 227 */ #endif #ifndef Tcl_SetErrorCode #define Tcl_SetErrorCode \ (tclStubsPtr->tcl_SetErrorCode) /* 228 */ #endif #ifndef Tcl_SetMaxBlockTime #define Tcl_SetMaxBlockTime(timePtr) \ (tclStubsPtr->tcl_SetMaxBlockTime)(timePtr) /* 229 */ #endif #ifndef Tcl_SetPanicProc #define Tcl_SetPanicProc(panicProc) \ (tclStubsPtr->tcl_SetPanicProc)(panicProc) /* 230 */ #endif #ifndef Tcl_SetRecursionLimit #define Tcl_SetRecursionLimit(interp, depth) \ (tclStubsPtr->tcl_SetRecursionLimit)(interp, depth) /* 231 */ #endif #ifndef Tcl_SetResult #define Tcl_SetResult(interp, string, freeProc) \ (tclStubsPtr->tcl_SetResult)(interp, string, freeProc) /* 232 */ #endif #ifndef Tcl_SetServiceMode #define Tcl_SetServiceMode(mode) \ (tclStubsPtr->tcl_SetServiceMode)(mode) /* 233 */ #endif #ifndef Tcl_SetObjErrorCode #define Tcl_SetObjErrorCode(interp, errorObjPtr) \ (tclStubsPtr->tcl_SetObjErrorCode)(interp, errorObjPtr) /* 234 */ #endif #ifndef Tcl_SetObjResult #define Tcl_SetObjResult(interp, resultObjPtr) \ (tclStubsPtr->tcl_SetObjResult)(interp, resultObjPtr) /* 235 */ #endif #ifndef Tcl_SetStdChannel #define Tcl_SetStdChannel(channel, type) \ (tclStubsPtr->tcl_SetStdChannel)(channel, type) /* 236 */ #endif #ifndef Tcl_SetVar #define Tcl_SetVar(interp, varName, newValue, flags) \ (tclStubsPtr->tcl_SetVar)(interp, varName, newValue, flags) /* 237 */ #endif #ifndef Tcl_SetVar2 #define Tcl_SetVar2(interp, part1, part2, newValue, flags) \ (tclStubsPtr->tcl_SetVar2)(interp, part1, part2, newValue, flags) /* 238 */ #endif #ifndef Tcl_SignalId #define Tcl_SignalId(sig) \ (tclStubsPtr->tcl_SignalId)(sig) /* 239 */ #endif #ifndef Tcl_SignalMsg #define Tcl_SignalMsg(sig) \ (tclStubsPtr->tcl_SignalMsg)(sig) /* 240 */ #endif #ifndef Tcl_SourceRCFile #define Tcl_SourceRCFile(interp) \ (tclStubsPtr->tcl_SourceRCFile)(interp) /* 241 */ #endif #ifndef Tcl_SplitList #define Tcl_SplitList(interp, list, argcPtr, argvPtr) \ (tclStubsPtr->tcl_SplitList)(interp, list, argcPtr, argvPtr) /* 242 */ #endif #ifndef Tcl_SplitPath #define Tcl_SplitPath(path, argcPtr, argvPtr) \ (tclStubsPtr->tcl_SplitPath)(path, argcPtr, argvPtr) /* 243 */ #endif #ifndef Tcl_StaticPackage #define Tcl_StaticPackage(interp, pkgName, initProc, safeInitProc) \ (tclStubsPtr->tcl_StaticPackage)(interp, pkgName, initProc, safeInitProc) /* 244 */ #endif #ifndef Tcl_StringMatch #define Tcl_StringMatch(string, pattern) \ (tclStubsPtr->tcl_StringMatch)(string, pattern) /* 245 */ #endif #ifndef Tcl_Tell #define Tcl_Tell(chan) \ (tclStubsPtr->tcl_Tell)(chan) /* 246 */ #endif #ifndef Tcl_TraceVar #define Tcl_TraceVar(interp, varName, flags, proc, clientData) \ (tclStubsPtr->tcl_TraceVar)(interp, varName, flags, proc, clientData) /* 247 */ #endif #ifndef Tcl_TraceVar2 #define Tcl_TraceVar2(interp, part1, part2, flags, proc, clientData) \ (tclStubsPtr->tcl_TraceVar2)(interp, part1, part2, flags, proc, clientData) /* 248 */ #endif #ifndef Tcl_TranslateFileName #define Tcl_TranslateFileName(interp, name, bufferPtr) \ (tclStubsPtr->tcl_TranslateFileName)(interp, name, bufferPtr) /* 249 */ #endif #ifndef Tcl_Ungets #define Tcl_Ungets(chan, str, len, atHead) \ (tclStubsPtr->tcl_Ungets)(chan, str, len, atHead) /* 250 */ #endif #ifndef Tcl_UnlinkVar #define Tcl_UnlinkVar(interp, varName) \ (tclStubsPtr->tcl_UnlinkVar)(interp, varName) /* 251 */ #endif #ifndef Tcl_UnregisterChannel #define Tcl_UnregisterChannel(interp, chan) \ (tclStubsPtr->tcl_UnregisterChannel)(interp, chan) /* 252 */ #endif #ifndef Tcl_UnsetVar #define Tcl_UnsetVar(interp, varName, flags) \ (tclStubsPtr->tcl_UnsetVar)(interp, varName, flags) /* 253 */ #endif #ifndef Tcl_UnsetVar2 #define Tcl_UnsetVar2(interp, part1, part2, flags) \ (tclStubsPtr->tcl_UnsetVar2)(interp, part1, part2, flags) /* 254 */ #endif #ifndef Tcl_UntraceVar #define Tcl_UntraceVar(interp, varName, flags, proc, clientData) \ (tclStubsPtr->tcl_UntraceVar)(interp, varName, flags, proc, clientData) /* 255 */ #endif #ifndef Tcl_UntraceVar2 #define Tcl_UntraceVar2(interp, part1, part2, flags, proc, clientData) \ (tclStubsPtr->tcl_UntraceVar2)(interp, part1, part2, flags, proc, clientData) /* 256 */ #endif #ifndef Tcl_UpdateLinkedVar #define Tcl_UpdateLinkedVar(interp, varName) \ (tclStubsPtr->tcl_UpdateLinkedVar)(interp, varName) /* 257 */ #endif #ifndef Tcl_UpVar #define Tcl_UpVar(interp, frameName, varName, localName, flags) \ (tclStubsPtr->tcl_UpVar)(interp, frameName, varName, localName, flags) /* 258 */ #endif #ifndef Tcl_UpVar2 #define Tcl_UpVar2(interp, frameName, part1, part2, localName, flags) \ (tclStubsPtr->tcl_UpVar2)(interp, frameName, part1, part2, localName, flags) /* 259 */ #endif #ifndef Tcl_VarEval #define Tcl_VarEval \ (tclStubsPtr->tcl_VarEval) /* 260 */ #endif #ifndef Tcl_VarTraceInfo #define Tcl_VarTraceInfo(interp, varName, flags, procPtr, prevClientData) \ (tclStubsPtr->tcl_VarTraceInfo)(interp, varName, flags, procPtr, prevClientData) /* 261 */ #endif #ifndef Tcl_VarTraceInfo2 #define Tcl_VarTraceInfo2(interp, part1, part2, flags, procPtr, prevClientData) \ (tclStubsPtr->tcl_VarTraceInfo2)(interp, part1, part2, flags, procPtr, prevClientData) /* 262 */ #endif #ifndef Tcl_Write #define Tcl_Write(chan, s, slen) \ (tclStubsPtr->tcl_Write)(chan, s, slen) /* 263 */ #endif #ifndef Tcl_WrongNumArgs #define Tcl_WrongNumArgs(interp, objc, objv, message) \ (tclStubsPtr->tcl_WrongNumArgs)(interp, objc, objv, message) /* 264 */ #endif #ifndef Tcl_DumpActiveMemory #define Tcl_DumpActiveMemory(fileName) \ (tclStubsPtr->tcl_DumpActiveMemory)(fileName) /* 265 */ #endif #ifndef Tcl_ValidateAllMemory #define Tcl_ValidateAllMemory(file, line) \ (tclStubsPtr->tcl_ValidateAllMemory)(file, line) /* 266 */ #endif #ifndef Tcl_AppendResultVA #define Tcl_AppendResultVA(interp, argList) \ (tclStubsPtr->tcl_AppendResultVA)(interp, argList) /* 267 */ #endif #ifndef Tcl_AppendStringsToObjVA #define Tcl_AppendStringsToObjVA(objPtr, argList) \ (tclStubsPtr->tcl_AppendStringsToObjVA)(objPtr, argList) /* 268 */ #endif #ifndef Tcl_HashStats #define Tcl_HashStats(tablePtr) \ (tclStubsPtr->tcl_HashStats)(tablePtr) /* 269 */ #endif #ifndef Tcl_ParseVar #define Tcl_ParseVar(interp, string, termPtr) \ (tclStubsPtr->tcl_ParseVar)(interp, string, termPtr) /* 270 */ #endif #ifndef Tcl_PkgPresent #define Tcl_PkgPresent(interp, name, version, exact) \ (tclStubsPtr->tcl_PkgPresent)(interp, name, version, exact) /* 271 */ #endif #ifndef Tcl_PkgPresentEx #define Tcl_PkgPresentEx(interp, name, version, exact, clientDataPtr) \ (tclStubsPtr->tcl_PkgPresentEx)(interp, name, version, exact, clientDataPtr) /* 272 */ #endif #ifndef Tcl_PkgProvide #define Tcl_PkgProvide(interp, name, version) \ (tclStubsPtr->tcl_PkgProvide)(interp, name, version) /* 273 */ #endif #ifndef Tcl_PkgRequire #define Tcl_PkgRequire(interp, name, version, exact) \ (tclStubsPtr->tcl_PkgRequire)(interp, name, version, exact) /* 274 */ #endif #ifndef Tcl_SetErrorCodeVA #define Tcl_SetErrorCodeVA(interp, argList) \ (tclStubsPtr->tcl_SetErrorCodeVA)(interp, argList) /* 275 */ #endif #ifndef Tcl_VarEvalVA #define Tcl_VarEvalVA(interp, argList) \ (tclStubsPtr->tcl_VarEvalVA)(interp, argList) /* 276 */ #endif #ifndef Tcl_WaitPid #define Tcl_WaitPid(pid, statPtr, options) \ (tclStubsPtr->tcl_WaitPid)(pid, statPtr, options) /* 277 */ #endif #ifndef Tcl_PanicVA #define Tcl_PanicVA(format, argList) \ (tclStubsPtr->tcl_PanicVA)(format, argList) /* 278 */ #endif #ifndef Tcl_GetVersion #define Tcl_GetVersion(major, minor, patchLevel, type) \ (tclStubsPtr->tcl_GetVersion)(major, minor, patchLevel, type) /* 279 */ #endif /* Slot 280 is reserved */ /* 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(objPtr, appendObjPtr) \ (tclStubsPtr->tcl_AppendObjToObj)(objPtr, appendObjPtr) /* 286 */ #endif #ifndef Tcl_CreateEncoding #define Tcl_CreateEncoding(typePtr) \ (tclStubsPtr->tcl_CreateEncoding)(typePtr) /* 287 */ #endif #ifndef Tcl_CreateThreadExitHandler #define Tcl_CreateThreadExitHandler(proc, clientData) \ (tclStubsPtr->tcl_CreateThreadExitHandler)(proc, clientData) /* 288 */ #endif #ifndef Tcl_DeleteThreadExitHandler #define Tcl_DeleteThreadExitHandler(proc, clientData) \ (tclStubsPtr->tcl_DeleteThreadExitHandler)(proc, clientData) /* 289 */ #endif #ifndef Tcl_DiscardResult #define Tcl_DiscardResult(statePtr) \ (tclStubsPtr->tcl_DiscardResult)(statePtr) /* 290 */ #endif #ifndef Tcl_EvalEx #define Tcl_EvalEx(interp, script, numBytes, flags) \ (tclStubsPtr->tcl_EvalEx)(interp, script, numBytes, flags) /* 291 */ #endif #ifndef Tcl_EvalObjv #define Tcl_EvalObjv(interp, objc, objv, flags) \ (tclStubsPtr->tcl_EvalObjv)(interp, objc, objv, flags) /* 292 */ #endif #ifndef Tcl_EvalObjEx #define Tcl_EvalObjEx(interp, objPtr, flags) \ (tclStubsPtr->tcl_EvalObjEx)(interp, objPtr, flags) /* 293 */ #endif #ifndef Tcl_ExitThread #define Tcl_ExitThread(status) \ (tclStubsPtr->tcl_ExitThread)(status) /* 294 */ #endif #ifndef Tcl_ExternalToUtf #define Tcl_ExternalToUtf(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) \ (tclStubsPtr->tcl_ExternalToUtf)(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) /* 295 */ #endif #ifndef Tcl_ExternalToUtfDString #define Tcl_ExternalToUtfDString(encoding, src, srcLen, dsPtr) \ (tclStubsPtr->tcl_ExternalToUtfDString)(encoding, src, srcLen, dsPtr) /* 296 */ #endif #ifndef Tcl_FinalizeThread #define Tcl_FinalizeThread() \ (tclStubsPtr->tcl_FinalizeThread)() /* 297 */ #endif #ifndef Tcl_FinalizeNotifier #define Tcl_FinalizeNotifier(clientData) \ (tclStubsPtr->tcl_FinalizeNotifier)(clientData) /* 298 */ #endif #ifndef Tcl_FreeEncoding #define Tcl_FreeEncoding(encoding) \ (tclStubsPtr->tcl_FreeEncoding)(encoding) /* 299 */ #endif #ifndef Tcl_GetCurrentThread #define Tcl_GetCurrentThread() \ (tclStubsPtr->tcl_GetCurrentThread)() /* 300 */ #endif #ifndef Tcl_GetEncoding #define Tcl_GetEncoding(interp, name) \ (tclStubsPtr->tcl_GetEncoding)(interp, name) /* 301 */ #endif #ifndef Tcl_GetEncodingName #define Tcl_GetEncodingName(encoding) \ (tclStubsPtr->tcl_GetEncodingName)(encoding) /* 302 */ #endif #ifndef Tcl_GetEncodingNames #define Tcl_GetEncodingNames(interp) \ (tclStubsPtr->tcl_GetEncodingNames)(interp) /* 303 */ #endif #ifndef Tcl_GetIndexFromObjStruct #define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \ (tclStubsPtr->tcl_GetIndexFromObjStruct)(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) /* 304 */ #endif #ifndef Tcl_GetThreadData #define Tcl_GetThreadData(keyPtr, size) \ (tclStubsPtr->tcl_GetThreadData)(keyPtr, size) /* 305 */ #endif #ifndef Tcl_GetVar2Ex #define Tcl_GetVar2Ex(interp, part1, part2, flags) \ (tclStubsPtr->tcl_GetVar2Ex)(interp, part1, part2, flags) /* 306 */ #endif #ifndef Tcl_InitNotifier #define Tcl_InitNotifier() \ (tclStubsPtr->tcl_InitNotifier)() /* 307 */ #endif #ifndef Tcl_MutexLock #define Tcl_MutexLock(mutexPtr) \ (tclStubsPtr->tcl_MutexLock)(mutexPtr) /* 308 */ #endif #ifndef Tcl_MutexUnlock #define Tcl_MutexUnlock(mutexPtr) \ (tclStubsPtr->tcl_MutexUnlock)(mutexPtr) /* 309 */ #endif #ifndef Tcl_ConditionNotify #define Tcl_ConditionNotify(condPtr) \ (tclStubsPtr->tcl_ConditionNotify)(condPtr) /* 310 */ #endif #ifndef Tcl_ConditionWait #define Tcl_ConditionWait(condPtr, mutexPtr, timePtr) \ (tclStubsPtr->tcl_ConditionWait)(condPtr, mutexPtr, timePtr) /* 311 */ #endif #ifndef Tcl_NumUtfChars #define Tcl_NumUtfChars(src, len) \ (tclStubsPtr->tcl_NumUtfChars)(src, len) /* 312 */ #endif #ifndef Tcl_ReadChars #define Tcl_ReadChars(channel, objPtr, charsToRead, appendFlag) \ (tclStubsPtr->tcl_ReadChars)(channel, objPtr, charsToRead, appendFlag) /* 313 */ #endif #ifndef Tcl_RestoreResult #define Tcl_RestoreResult(interp, statePtr) \ (tclStubsPtr->tcl_RestoreResult)(interp, statePtr) /* 314 */ #endif #ifndef Tcl_SaveResult #define Tcl_SaveResult(interp, statePtr) \ (tclStubsPtr->tcl_SaveResult)(interp, statePtr) /* 315 */ #endif #ifndef Tcl_SetSystemEncoding #define Tcl_SetSystemEncoding(interp, name) \ (tclStubsPtr->tcl_SetSystemEncoding)(interp, name) /* 316 */ #endif #ifndef Tcl_SetVar2Ex #define Tcl_SetVar2Ex(interp, part1, part2, newValuePtr, flags) \ (tclStubsPtr->tcl_SetVar2Ex)(interp, part1, part2, newValuePtr, flags) /* 317 */ #endif #ifndef Tcl_ThreadAlert #define Tcl_ThreadAlert(threadId) \ (tclStubsPtr->tcl_ThreadAlert)(threadId) /* 318 */ #endif #ifndef Tcl_ThreadQueueEvent #define Tcl_ThreadQueueEvent(threadId, evPtr, position) \ (tclStubsPtr->tcl_ThreadQueueEvent)(threadId, evPtr, position) /* 319 */ #endif #ifndef Tcl_UniCharAtIndex #define Tcl_UniCharAtIndex(src, index) \ (tclStubsPtr->tcl_UniCharAtIndex)(src, index) /* 320 */ #endif #ifndef Tcl_UniCharToLower #define Tcl_UniCharToLower(ch) \ (tclStubsPtr->tcl_UniCharToLower)(ch) /* 321 */ #endif #ifndef Tcl_UniCharToTitle #define Tcl_UniCharToTitle(ch) \ (tclStubsPtr->tcl_UniCharToTitle)(ch) /* 322 */ #endif #ifndef Tcl_UniCharToUpper #define Tcl_UniCharToUpper(ch) \ (tclStubsPtr->tcl_UniCharToUpper)(ch) /* 323 */ #endif #ifndef Tcl_UniCharToUtf #define Tcl_UniCharToUtf(ch, buf) \ (tclStubsPtr->tcl_UniCharToUtf)(ch, buf) /* 324 */ #endif #ifndef Tcl_UtfAtIndex #define Tcl_UtfAtIndex(src, index) \ (tclStubsPtr->tcl_UtfAtIndex)(src, index) /* 325 */ #endif #ifndef Tcl_UtfCharComplete #define Tcl_UtfCharComplete(src, len) \ (tclStubsPtr->tcl_UtfCharComplete)(src, len) /* 326 */ #endif #ifndef Tcl_UtfBackslash #define Tcl_UtfBackslash(src, readPtr, dst) \ (tclStubsPtr->tcl_UtfBackslash)(src, readPtr, dst) /* 327 */ #endif #ifndef Tcl_UtfFindFirst #define Tcl_UtfFindFirst(src, ch) \ (tclStubsPtr->tcl_UtfFindFirst)(src, ch) /* 328 */ #endif #ifndef Tcl_UtfFindLast #define Tcl_UtfFindLast(src, ch) \ (tclStubsPtr->tcl_UtfFindLast)(src, ch) /* 329 */ #endif #ifndef Tcl_UtfNext #define Tcl_UtfNext(src) \ (tclStubsPtr->tcl_UtfNext)(src) /* 330 */ #endif #ifndef Tcl_UtfPrev #define Tcl_UtfPrev(src, start) \ (tclStubsPtr->tcl_UtfPrev)(src, start) /* 331 */ #endif #ifndef Tcl_UtfToExternal #define Tcl_UtfToExternal(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) \ (tclStubsPtr->tcl_UtfToExternal)(interp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr) /* 332 */ #endif #ifndef Tcl_UtfToExternalDString #define Tcl_UtfToExternalDString(encoding, src, srcLen, dsPtr) \ (tclStubsPtr->tcl_UtfToExternalDString)(encoding, src, srcLen, dsPtr) /* 333 */ #endif #ifndef Tcl_UtfToLower #define Tcl_UtfToLower(src) \ (tclStubsPtr->tcl_UtfToLower)(src) /* 334 */ #endif #ifndef Tcl_UtfToTitle #define Tcl_UtfToTitle(src) \ (tclStubsPtr->tcl_UtfToTitle)(src) /* 335 */ #endif #ifndef Tcl_UtfToUniChar #define Tcl_UtfToUniChar(src, chPtr) \ (tclStubsPtr->tcl_UtfToUniChar)(src, chPtr) /* 336 */ #endif #ifndef Tcl_UtfToUpper #define Tcl_UtfToUpper(src) \ (tclStubsPtr->tcl_UtfToUpper)(src) /* 337 */ #endif #ifndef Tcl_WriteChars #define Tcl_WriteChars(chan, src, srcLen) \ (tclStubsPtr->tcl_WriteChars)(chan, src, srcLen) /* 338 */ #endif #ifndef Tcl_WriteObj #define Tcl_WriteObj(chan, objPtr) \ (tclStubsPtr->tcl_WriteObj)(chan, objPtr) /* 339 */ #endif #ifndef Tcl_GetString #define Tcl_GetString(objPtr) \ (tclStubsPtr->tcl_GetString)(objPtr) /* 340 */ #endif #ifndef Tcl_GetDefaultEncodingDir #define Tcl_GetDefaultEncodingDir() \ (tclStubsPtr->tcl_GetDefaultEncodingDir)() /* 341 */ #endif #ifndef Tcl_SetDefaultEncodingDir #define Tcl_SetDefaultEncodingDir(path) \ (tclStubsPtr->tcl_SetDefaultEncodingDir)(path) /* 342 */ #endif #ifndef Tcl_ReplaceChannel #define Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) \ (tclStubsPtr->tcl_ReplaceChannel)(interp, typePtr, instanceData, mask, prevChan) /* 345 */ #endif #ifndef Tcl_UndoReplaceChannel #define Tcl_UndoReplaceChannel(interp, chan) \ (tclStubsPtr->tcl_UndoReplaceChannel)(interp, chan) /* 346 */ #endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLDECLS */ trf2.1.4/patches/v8.1b2/tcl.h0000644000175000017500000013053411216344361015063 0ustar sergeisergei/* * 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 1999/03/21 15:10:58 aku 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) * README * mac/README * win/README * win/README.binary * unix/README * */ #define TCL_MAJOR_VERSION 8 #define TCL_MINOR_VERSION 1 #define TCL_RELEASE_LEVEL TCL_BETA_RELEASE #define TCL_RELEASE_SERIAL 2 #define TCL_VERSION "8.1" #define TCL_PATCH_LEVEL "8.1b2" /* * The following definitions set up the proper options for Windows * compilers. We use this method because there is no autoconf equivalent. */ #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) # define __WIN32__ # endif #endif #ifdef __WIN32__ # ifndef STRICT # define STRICT # endif # ifndef USE_PROTOTYPE # define USE_PROTOTYPE 1 # 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. */ #ifndef RESOURCE_INCLUDED #ifndef BUFSIZ #include #endif /* * Definitions that allow Tcl functions with variable numbers of * arguments to be used with either varargs.h or stdarg.h. TCL_VARARGS * is used in procedure prototypes. TCL_VARARGS_DEF is used to declare * 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 # 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 # 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. */ #ifndef __WIN32__ #ifndef VOID # ifdef __STDC__ # define VOID void # else # define VOID char # endif #endif #else /* __WIN32__ */ /* * The following code is copied from winnt.h */ #ifndef VOID #define VOID void typedef char CHAR; typedef short SHORT; typedef long LONG; #endif #endif /* __WIN32__ */ /* * Miscellaneous declarations. */ #ifndef NULL #define NULL 0 #endif #ifndef _CLIENTDATA # if defined(__STDC__) || defined(__cplusplus) typedef void *ClientData; # else typedef int *ClientData; # endif /* __STDC__ */ #define _CLIENTDATA #endif /* * Data structures defined opaquely in this module. The definitions below * just provide dummy types. A few fields are made visible in Tcl_Interp * structures, namely those used for returning a string result from * commands. Direct access to the result field is discouraged in Tcl 8.0. * The interpreter result is either an object or a string, and the two * values are kept consistent unless some C code sets interp->result * directly. Programmers should use either the procedure Tcl_GetObjResult() * or Tcl_GetStringResult() to read the interpreter's result. See the * SetResult man page for details. * * Note: any change to the Tcl_Interp definition below must be mirrored * in the "real" definition in tclInt.h. * * Note: Tcl_ObjCmdProc procedures do not directly set result and freeProc. * Instead, they set a Tcl_Obj member in the "real" structure that can be * accessed with Tcl_GetObjResult() and Tcl_SetObjResult(). */ typedef struct Tcl_Interp { char *result; /* If the last command returned a string * result, this points to it. */ void (*freeProc) _ANSI_ARGS_((char *blockPtr)); /* Zero means the string result is * statically allocated. TCL_DYNAMIC means * it was allocated with ckalloc and should * be freed with ckfree. Other values give * the address of procedure to invoke to * free the result. Tcl_Eval must free it * before executing next command. */ int errorLine; /* When TCL_ERROR is returned, this gives * 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 * procedures Tcl_GetObjResult() or Tcl_GetStringResult() to read the * interpreter's result. See the SetResult man page for details. Besides * this result, the command procedure returns an integer code, which is * one of the following: * * TCL_OK Command completed normally; the interpreter's * result contains the command's result. * TCL_ERROR The command couldn't be completed successfully; * the interpreter's result describes what went wrong. * TCL_RETURN The command requests that the current procedure * return; the interpreter's result contains the * procedure's return value. * TCL_BREAK The command requests that the innermost loop * be exited; the interpreter's result is meaningless. * TCL_CONTINUE Go on to the next iteration of the current loop; * the interpreter's result is meaningless. */ #define TCL_OK 0 #define TCL_ERROR 1 #define TCL_RETURN 2 #define TCL_BREAK 3 #define TCL_CONTINUE 4 #define TCL_RESULT_SIZE 200 /* * Argument descriptors for math function callbacks in expressions: */ typedef enum {TCL_INT, TCL_DOUBLE, TCL_EITHER} Tcl_ValueType; typedef struct Tcl_Value { Tcl_ValueType type; /* Indicates intValue or doubleValue is * valid, or both. */ long intValue; /* Integer value. */ double doubleValue; /* Double-precision floating value. */ } Tcl_Value; /* * Forward declaration of Tcl_Obj to prevent an error when the forward * reference to Tcl_Obj is encountered in the procedure types declared * below. */ struct Tcl_Obj; /* * Procedure types defined by Tcl: */ typedef int (Tcl_AppInitProc) _ANSI_ARGS_((Tcl_Interp *interp)); typedef int (Tcl_AsyncProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int code)); typedef void (Tcl_ChannelProc) _ANSI_ARGS_((ClientData clientData, int mask)); typedef void (Tcl_CloseProc) _ANSI_ARGS_((ClientData data)); typedef void (Tcl_CmdDeleteProc) _ANSI_ARGS_((ClientData clientData)); 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, Tcl_Interp *interp, char *part1, char *part2, int flags)); /* * The following structure represents a type of object, which is a * particular internal representation for an object plus a set of * procedures that provide standard operations on objects of that type. */ typedef struct Tcl_ObjType { char *name; /* Name of the type, e.g. "int". */ Tcl_FreeInternalRepProc *freeIntRepProc; /* Called to free any storage for the type's * internal rep. NULL if the internal rep * does not need freeing. */ Tcl_DupInternalRepProc *dupIntRepProc; /* Called to create a new object as a copy * of an existing object. */ Tcl_UpdateStringProc *updateStringProc; /* Called to update the string rep from the * type's internal representation. */ Tcl_SetFromAnyProc *setFromAnyProc; /* Called to convert the object's internal * rep to this type. Frees the internal rep * of the old type. Returns TCL_ERROR on * failure. */ } Tcl_ObjType; /* * One of the following structures exists for each object in the Tcl * system. An object stores a value as either a string, some internal * representation, or both. */ typedef struct Tcl_Obj { int refCount; /* When 0 the object will be freed. */ char *bytes; /* This points to the first byte of the * object's string representation. The array * 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: */ long longValue; /* - an long integer value */ double doubleValue; /* - a double-precision floating value */ VOID *otherValuePtr; /* - another, type-specific value */ struct { /* - internal rep as two pointers */ VOID *ptr1; VOID *ptr2; } twoPtrValue; } internalRep; } Tcl_Obj; /* * Macros to increment and decrement a Tcl_Obj's reference count, and to * test whether an object is shared (i.e. has reference count > 1). * Note: clients should use Tcl_DecrRefCount() when they are finished using * an object, and should never call TclFreeObj() directly. TclFreeObj() is * only defined and made public in tcl.h to support Tcl_DecrRefCount's macro * definition. Note also that Tcl_DecrRefCount() refers to the parameter * "obj" twice. This means that you should avoid calling it with an * expression that is expensive to compute or has side effects. */ EXTERN void Tcl_IncrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN void Tcl_DecrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN int Tcl_IsShared _ANSI_ARGS_((Tcl_Obj *objPtr)); #ifdef TCL_MEM_DEBUG # define Tcl_IncrRefCount(objPtr) \ Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_DecrRefCount(objPtr) \ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_IsShared(objPtr) \ Tcl_DbIsShared(objPtr, __FILE__, __LINE__) #else # define Tcl_IncrRefCount(objPtr) \ ++(objPtr)->refCount # define Tcl_DecrRefCount(objPtr) \ 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). */ typedef struct Tcl_Namespace { char *name; /* The namespace's name within its parent * namespace. This contains no ::'s. The * name of the global namespace is "" * although "::" is an synonym. */ char *fullName; /* The namespace's fully qualified name. * This starts with ::. */ ClientData clientData; /* Arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc* deleteProc; /* Procedure invoked when deleting the * namespace to, e.g., free clientData. */ struct Tcl_Namespace* parentPtr; /* Points to the namespace that contains * this one. NULL if this is the global * namespace. */ } Tcl_Namespace; /* * The following structure represents a call frame, or activation record. * A call frame defines a naming context for a procedure call: its local * scope (for local variables) and its namespace scope (used for non-local * variables; often 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 command's code should execute. The * Tcl_CallFrame structures exist only while procedures or namespace * eval/inscope's are being executed, and provide a Tcl call stack. * * A call frame is initialized and pushed using Tcl_PushCallFrame and * popped using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be * provided by the Tcl_PushCallFrame caller, and callers typically allocate * them on the C call stack for efficiency. For this reason, Tcl_CallFrame * is defined as a structure and not as an opaque token. However, most * Tcl_CallFrame fields are hidden since applications should not access * them directly; others are declared as "dummyX". * * WARNING!! The structure definition must be kept consistent with the * CallFrame structure in tclInt.h. If you change one, change the other. */ typedef struct Tcl_CallFrame { Tcl_Namespace *nsPtr; int dummy1; int dummy2; char *dummy3; char *dummy4; char *dummy5; int dummy6; char *dummy7; char *dummy8; int dummy9; char* dummy10; } Tcl_CallFrame; /* * Information about commands that is returned by Tcl_GetCommandInfo and * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based * command procedure while proc is a traditional Tcl argc/argv * string-based procedure. Tcl_CreateObjCommand and Tcl_CreateCommand * ensure that both objProc and proc are non-NULL and can be called to * execute the command. However, it may be faster to call one instead of * the other. The member isNativeObjectProc is set to 1 if an * object-based procedure was registered by Tcl_CreateObjCommand, and to * 0 if a string-based procedure was registered by Tcl_CreateCommand. * The other procedure is typically set to a compatibility wrapper that * does string-to-object or object-to-string argument conversions then * calls the other procedure. */ typedef struct Tcl_CmdInfo { int isNativeObjectProc; /* 1 if objProc was registered by a call to * Tcl_CreateObjCommand; 0 otherwise. * Tcl_SetCmdInfo does not modify this * field. */ Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ ClientData objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based procedure. */ ClientData clientData; /* ClientData for string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure to call when command is * deleted. */ ClientData deleteData; /* Value to pass to deleteProc (usually * the same as clientData). */ Tcl_Namespace *namespacePtr; /* Points to the namespace that contains * this command. Note that Tcl_SetCmdInfo * will not change a command's namespace; * use Tcl_RenameCommand to do that. */ } Tcl_CmdInfo; /* * The structure defined below is used to hold dynamic strings. The only * field that clients should use is the string field, and they should * never modify it. */ #define TCL_DSTRING_STATIC_SIZE 200 typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ int length; /* Number of non-NULL characters in the * string. */ int spaceAvl; /* Total number of bytes available for the * string and its terminating NULL char. */ char staticSpace[TCL_DSTRING_STATIC_SIZE]; /* Space to use in common case where string * is small. */ } Tcl_DString; #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) #define TCL_STATIC ((Tcl_FreeProc *) 0) #define TCL_DYNAMIC ((Tcl_FreeProc *) 3) /* * Flag values passed to variable-related procedures. */ #define TCL_GLOBAL_ONLY 1 #define TCL_NAMESPACE_ONLY 2 #define TCL_APPEND_VALUE 4 #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 /* * 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 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__) #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 */ /* * 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 struct Tcl_HashTable; #endif /* * Structure definition for an entry in a hash table. No-one outside * Tcl should access any of these fields directly; use the macros * defined below. */ typedef struct Tcl_HashEntry { struct Tcl_HashEntry *nextPtr; /* Pointer to next entry in this * hash bucket, or NULL for end of * chain. */ struct Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */ struct Tcl_HashEntry **bucketPtr; /* Pointer to bucket that points to * first entry in this entry's chain: * used for deleting the entry. */ ClientData clientData; /* Application stores something here * with Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ int words[1]; /* Multiple integer words for key. * The actual size will be as large * as necessary for this table's * keys. */ char string[4]; /* String for key. The actual size * will be as large as needed to hold * the key. */ } key; /* MUST BE LAST FIELD IN RECORD!! */ } Tcl_HashEntry; /* * Structure definition for a hash table. Must be in tcl.h so clients * can allocate space for these structures, but clients should never * access any fields in this structure. */ #define TCL_SMALL_HASH_TABLE 4 typedef struct Tcl_HashTable { Tcl_HashEntry **buckets; /* Pointer to bucket array. Each * element points to first entry in * bucket's hash chain, or NULL. */ Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables * (to avoid mallocs and frees). */ int numBuckets; /* Total number of buckets allocated * at **bucketPtr. */ int numEntries; /* Total number of entries present * in table. */ int rebuildSize; /* Enlarge table when numEntries gets * to be this large. */ int downShift; /* Shift count used in hashing * function. Designed to use high- * order bits of randomized keys. */ int mask; /* Mask value used in hashing * function. */ int keyType; /* Type of keys used in this table. * It's either TCL_STRING_KEYS, * TCL_ONE_WORD_KEYS, or an integer * giving the number of ints that * is the size of the key. */ Tcl_HashEntry *(*findProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key)); Tcl_HashEntry *(*createProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key, int *newPtr)); } Tcl_HashTable; /* * Structure definition for information used to keep track of searches * through hash tables: */ typedef struct Tcl_HashSearch { Tcl_HashTable *tablePtr; /* Table being searched. */ int nextIndex; /* Index of next bucket to be * enumerated after present one. */ Tcl_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the * the current bucket. */ } Tcl_HashSearch; /* * Acceptable key types for hash tables: */ #define TCL_STRING_KEYS 0 #define TCL_ONE_WORD_KEYS 1 /* * Macros for clients to use to access fields of hash entries: */ #define Tcl_GetHashValue(h) ((h)->clientData) #define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value)) #define Tcl_GetHashKey(tablePtr, h) \ ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS) ? (h)->key.oneWordValue \ : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create procedures * for hash tables: */ #define Tcl_FindHashEntry(tablePtr, key) \ (*((tablePtr)->findProc))(tablePtr, key) #define Tcl_CreateHashEntry(tablePtr, key, newPtr) \ (*((tablePtr)->createProc))(tablePtr, key, newPtr) /* * Flag values to pass to Tcl_DoOneEvent to disable searches * for some kinds of events: */ #define TCL_DONT_WAIT (1<<1) #define TCL_WINDOW_EVENTS (1<<2) #define TCL_FILE_EVENTS (1<<3) #define TCL_TIMER_EVENTS (1<<4) #define TCL_IDLE_EVENTS (1<<5) /* WAS 0x10 ???? */ #define TCL_ALL_EVENTS (~TCL_DONT_WAIT) /* * The following structure defines a generic event for the Tcl event * system. These are the things that are queued in calls to Tcl_QueueEvent * and serviced later by Tcl_DoOneEvent. There can be many different * kinds of events with different fields, corresponding to window events, * timer events, etc. The structure for a particular event consists of * a Tcl_Event header followed by additional information specific to that * event. */ struct Tcl_Event { Tcl_EventProc *proc; /* Procedure to call to service this event. */ struct Tcl_Event *nextPtr; /* Next in list of pending events, or NULL. */ }; /* * Positions to pass to Tcl_QueueEvent: */ typedef enum { TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK } Tcl_QueuePosition; /* * Values to pass to Tcl_SetServiceMode to specify the behavior of notifier * event routines. */ #define TCL_SERVICE_NONE 0 #define TCL_SERVICE_ALL 1 /* * The following structure keeps is used to hold a time value, either as * an absolute time (the number of seconds from the epoch) or as an * elapsed time. On Unix systems the epoch is Midnight Jan 1, 1970 GMT. * On Macintosh systems the epoch is Midnight Jan 1, 1904 GMT. */ typedef struct Tcl_Time { long sec; /* Seconds. */ long usec; /* Microseconds. */ } Tcl_Time; /* * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler * to indicate what sorts of events are of interest: */ #define TCL_READABLE (1<<1) #define TCL_WRITABLE (1<<2) #define TCL_EXCEPTION (1<<3) /* * Flag values to pass to Tcl_OpenCommandChannel to indicate the * disposition of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, * are also used in Tcl_GetStdChannel. */ #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)); /* * 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. */ TCL_TRANSLATE_LF, /* Eol == \n. */ TCL_TRANSLATE_CRLF /* Eol == \r\n. */ } Tcl_EolTranslation; /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. * It collects together in one place all the functions that are * part of the specific channel type. */ 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. */ #define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */ #define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking * mode. */ /* * Enum for different types of file paths. */ 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 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)); /* * 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_InitMemory _ANSI_ARGS_((Tcl_Interp *interp)); 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)); /* Andreas Kupries , 05/31/1997. * "Trf-Patch for channels with a switchable byteorder" */ EXTERN int Tcl_GetChannelByteorder _ANSI_ARGS_(( Tcl_Channel chan)); #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TCL */ trf2.1.4/patches/v8.1b2/tclStubLib.c0000644000175000017500000000535011216344361016340 0ustar sergeisergei/* * 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.1 1999/03/21 15:11:02 aku 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; } trf2.1.4/patches/v8.1a2/0000755000175000017500000000000011216344734014125 5ustar sergeisergeitrf2.1.4/patches/v8.1a2/standard.patch0000644000175000017500000002410111216344361016740 0ustar sergeisergei*** tcl.h.orig Fri Jun 12 15:52:49 1998 --- tcl.h Sat Jun 13 21:11:47 1998 *************** *** 1795,1799 **** --- 1795,1813 ---- EXTERN void Tcl_WrongNumArgs _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], char *message)); + /* Andreas Kupries , 05/31/1997. + * Support for Tcl-Trf (channel interceptors). + */ + + EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_ChannelType* typePtr, + ClientData instanceData, + int mask, + Tcl_Channel prevChan)); + + EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_Channel chan)); + + #endif /* RESOURCE_INCLUDED */ #endif /* _TCL */ *** tclIO.c.orig Fri Jun 12 15:52:49 1998 --- tclIO.c Sat Jun 13 21:11:47 1998 *************** *** 201,206 **** --- 201,213 ---- int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ + + /* Andreas Kupries , 05/31/1997. + * Support for Tcl-Trf (channel interceptors). + */ + + struct Channel* supercedes; /* Refers to channel this one was stacked upon */ + } Channel; /* *************** *** 1036,1043 **** if (new == 0) { if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; ! } ! panic("Tcl_RegisterChannel: duplicate channel names"); } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } --- 1043,1053 ---- if (new == 0) { if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; ! } ! /* Andreas Kupries , 05/31/1997. ! * Support for Tcl-Trf (channel interceptors). ! */ ! /* panic("Tcl_RegisterChannel: duplicate channel names"); */ } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } *************** *** 1296,1301 **** --- 1306,1318 ---- chanPtr->timer = NULL; chanPtr->csPtr = NULL; + /* Andreas Kupries , 05/31/1997. + * Support for Tcl-Trf (channel interceptors). + */ + + chanPtr->supercedes = (Channel*) NULL; + + chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) *************** *** 1329,1334 **** --- 1346,1558 ---- return (Tcl_Channel) chanPtr; } + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf. + */ + /* + *---------------------------------------------------------------------- + * + * Tcl_ReplaceChannel -- + * + * Replaces an entry in the hash table for a Tcl_Channel + * record. + * + * Results: + * Returns the new Tcl_Channel. + * + * Side effects: + * Replaces a Tcl_Channel instance into the hash table. + * + *---------------------------------------------------------------------- + */ + + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp* interp; /* the interpreter we are working in */ + Tcl_ChannelType *typePtr; /* The channel type record. */ + ClientData instanceData; /* Instance specific data. */ + int mask; /* TCL_READABLE & TCL_WRITABLE to indicate + * if the channel is readable, writable. */ + Tcl_Channel prevChan; /* The channel structure that should + * be replaced. */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr, *pt, *prevPt; + + /* + * Replace the channel into the list of all channels; + */ + + prevPt = (Channel*) NULL; + pt = (Channel*) tsdPtr->firstChanPtr; + + while (pt != (Channel *) prevChan) { + prevPt = pt; + pt = pt->nextChanPtr; + } + + /* 'pt == prevChan' now */ + + if (!pt) { + return (Tcl_Channel) NULL; + } + + /* + * Here we check if the "mask" matches the "flags" + * of the already existing channel. + * + * | - | R | W | RW | + * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) + * - | | | | | + * R | | + | | + | The superceding channel is allowed to + * W | | | + | + | restrict the capabilities of the + * RW| | + | + | + | superceded one ! + * --+---+---+---+----+ + */ + + if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { + return (Tcl_Channel) NULL; + } + + + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); + chanPtr->flags = mask; + + /* + * Set the channel up initially in no Input translation mode and + * no Output translation mode. + */ + + chanPtr->inputTranslation = TCL_TRANSLATE_LF; + chanPtr->outputTranslation = TCL_TRANSLATE_LF; + chanPtr->inEofChar = 0; + chanPtr->outEofChar = 0; + + chanPtr->unreportedError = 0; + chanPtr->instanceData = instanceData; + chanPtr->typePtr = typePtr; + chanPtr->refCount = 0; + chanPtr->closeCbPtr = (CloseCallback *) NULL; + chanPtr->curOutPtr = (ChannelBuffer *) NULL; + chanPtr->outQueueHead = (ChannelBuffer *) NULL; + chanPtr->outQueueTail = (ChannelBuffer *) NULL; + chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; + chanPtr->inQueueHead = (ChannelBuffer *) NULL; + 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; + + /* 06/12/1998: New for Tcl 8.1 + * + * Take over the encoding from the superceded channel, so that it will be + * executed in future despite the replacement, and at the proper time (after + * our transformation). + * + * Tcl-Trf uses 'Tcl_Read' to get at the underlying information, thus + * circumventing data de/encoding in the superceded channel. Because of this + * there is no need to trouble ourselves with 'ByteArray's too. + */ + + chanPtr->encoding=Tcl_GetEncoding(interp,Tcl_GetEncodingName(pt->encoding)); + chanPtr->inputEncodingState = pt->inputEncodingState; + chanPtr->inputEncodingFlags = pt->inputEncodingFlags; + chanPtr->outputEncodingState = pt->outputEncodingState; + chanPtr->outputEncodingFlags = pt->outputEncodingFlags; + + + chanPtr->outputStage = NULL; + if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { + chanPtr->outputStage = (char *) + ckalloc((unsigned) (chanPtr->bufSize + 2)); + } + + chanPtr->supercedes = (Channel*) prevChan; + + chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); + strcpy (chanPtr->channelName, pt->channelName); + + if (prevPt) { + prevPt->nextChanPtr = chanPtr; + } else { + tsdPtr->firstChanPtr = chanPtr; + } + + chanPtr->nextChanPtr = pt->nextChanPtr; + + Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); + + /* The superceded channel is effectively unregistered */ + /*chanPtr->supercedes->refCount --;*/ + + return (Tcl_Channel) chanPtr; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_UndoReplaceChannel -- + * + * Unstacks an entry in the hash table for a Tcl_Channel + * record. + * + * Results: + * Returns the old Tcl_Channel, i.e. the one which was stacked over. + * + * Side effects: + * Replaces a Tcl_Channel instance into the hash table. + * + *---------------------------------------------------------------------- + */ + + void + Tcl_UndoReplaceChannel (interp, chan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_Channel chan; /* The channel to unstack */ + { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel* chanPtr = (Channel*) chan; + + if (chanPtr->supercedes != (Channel*) NULL) { + Tcl_HashTable *hTblPtr; /* Hash table of channels. */ + Tcl_HashEntry *hPtr; /* Search variable. */ + int new; /* Is the hash entry new or does it exist? */ + + /* + * Insert the channel we were stacked upon back into + * the list of open channels. Place it back into the hashtable too. + * Correct 'refCount', as this actually unregisters 'chan'. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + + hTblPtr = GetChannelTable (interp); + hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); + + Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); + chanPtr->refCount --; + + /* The superceded channel is effectively registered again */ + /*chanPtr->supercedes->refCount ++;*/ + } + + /* + * Disconnect the channels, then do a regular close upon the + * stacked one. This may cause flushing of data into the + * superceded channel (if 'chan' remembered its parent in itself). + */ + + chanPtr->supercedes = NULL; + + if (chanPtr->refCount == 0) { + Tcl_Close (interp, chan); + } + } + /* *---------------------------------------------------------------------- * *************** *** 2002,2007 **** --- 2226,2250 ---- if (errorCode != 0) { Tcl_SetErrno(errorCode); } + } + + /* -- CloseChannel -- + * Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (channel interceptors). + * + * Handle stacking of channels. Must be done after 'closeProc' + * to allow for flushing of data into the underlying channel. + */ + + if (chanPtr->supercedes != (Channel*) NULL) { + /* Insert the channel we were stacked upon back into + * the list of open channels, then do a regular close. + */ + + chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; + tsdPtr->firstChanPtr = chanPtr->supercedes; + chanPtr->supercedes->refCount --; /* is deregistered */ + Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* trf2.1.4/patches/v8.1a2/byteorder.patch0000644000175000017500000001431711216344361017147 0ustar sergeisergei*** tcl.h.orig Fri Jun 12 15:52:49 1998 --- tcl.h Wed Jun 17 21:28:59 1998 *************** *** 1432,1437 **** --- 1432,1444 ---- char *chanName, int *modePtr)); EXTERN int Tcl_GetChannelBufferSize _ANSI_ARGS_(( Tcl_Channel chan)); + + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + EXTERN int Tcl_GetChannelByteorder _ANSI_ARGS_(( + Tcl_Channel chan)); + EXTERN int Tcl_GetChannelHandle _ANSI_ARGS_((Tcl_Channel chan, int direction, ClientData *handlePtr)); EXTERN ClientData Tcl_GetChannelInstanceData _ANSI_ARGS_(( *** tclIO.c.orig Fri Jun 12 15:52:49 1998 --- tclIO.c Wed Jun 17 21:28:59 1998 *************** *** 154,159 **** --- 154,165 ---- * data bytes. May be TCL_ENCODING_START * before converting first byte and * TCL_ENCODING_END when EOF is seen. */ + + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + int byteOrder; /* byteorder associated to this channel */ + Tcl_EolTranslation inputTranslation; /* What translation to apply for end of line * sequences on input? */ *************** *** 465,470 **** --- 471,484 ---- static int WriteChars _ANSI_ARGS_((Channel *chanPtr, CONST char *src, int srcLen)); + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + static int Tcl_GetHostByteorder _ANSI_ARGS_ (()); + + #define TCL_BIGENDIAN (0) /* Multibyte words are stored with MSB first */ + #define TCL_SMALLENDIAN (1) /* Multibyte words are stored with MSB last */ + /* *--------------------------------------------------------------------------- *************** *** 1273,1278 **** --- 1287,1297 ---- * indicator (e.g. ^Z) and does not append an EOF indicator to files. */ + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + chanPtr->byteOrder = Tcl_GetHostByteorder (); + chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; *************** *** 4890,4896 **** { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize eofchar translation"; char **argv; int argc, i; Tcl_DString ds; --- 4909,4915 ---- { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; *************** *** 4920,4925 **** --- 4939,5002 ---- return TCL_ERROR; } + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + /* + *---------------------------------------------------------------------- + * + * Tcl_GetChannelByteorder -- + * + * Retrieves the byteorder set for this channel. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + int + Tcl_GetChannelByteorder(chan) + Tcl_Channel chan; /* The channel for which to find the + * buffer size. */ + { + Channel *chanPtr; + + chanPtr = (Channel *) chan; + return chanPtr->byteOrder; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_GetHostByteorder -- + * + * Retrieves the byteorder of the machine we are running on. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + static int + Tcl_GetHostByteorder() + { + union { + char c[sizeof(short)]; + short s; + } order; + + order.s = 1; + return (order.c[0] == 1) ? TCL_SMALLENDIAN : TCL_BIGENDIAN; + } + /* *---------------------------------------------------------------------- * *************** *** 5040,5045 **** --- 5117,5139 ---- return TCL_OK; } } + + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0))) { + if (len == 0) { + Tcl_DStringAppendElement(dsPtr, "-byteorder"); + } + Tcl_DStringAppendElement(dsPtr, + (chanPtr->byteOrder == TCL_BIGENDIAN) ? + "bigendian" : "smallendian"); + if (len > 0) { + return TCL_OK; + } + } + if ((len == 0) || ((len > 2) && (optionName[1] == 'e') && (strncmp(optionName, "-eofchar", len) == 0))) { *************** *** 5235,5240 **** --- 5329,5367 ---- if ((chanPtr->bufSize < 10) || (chanPtr->bufSize > (1024 * 1024))) { chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; } + + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + } else if ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0)) { + int nv_len = strlen (newValue); + + if ((nv_len > 0) && + (strncmp (newValue, "smallendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "littleendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "network", nv_len) == 0)) { + chanPtr->byteOrder = TCL_BIGENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && + (strncmp (newValue, "bigendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_BIGENDIAN; + return TCL_OK; + } + + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, + "bad value for -byteorder: ", + "must be one of smallendian, littleendian, bigendian or network", + (char *) NULL); + } + return TCL_ERROR; } else if ((len > 2) && (optionName[1] == 'e') && (strncmp(optionName, "-encoding", len) == 0)) { Tcl_Encoding encoding; trf2.1.4/patches/v8.1a2/tclIO.c0000644000175000017500000072676111216344361015322 0ustar sergeisergei/* * 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.283 98/02/18 16:14:30 */ #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. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) # define EWOULDBLOCK EAGAIN #endif #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) error one of EWOULDBLOCK or EAGAIN must be defined #endif /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this * structure. */ typedef struct CopyState { struct Channel *readPtr; /* Pointer to input channel. */ struct Channel *writePtr; /* Pointer to output channel. */ int readFlags; /* Original read channel flags. */ int writeFlags; /* Original write channel flags. */ int toRead; /* Number of bytes to copy, or -1. */ int total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ 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) /* * Structure to record a close callback. One such record exists for * each close callback registered for a channel. */ typedef struct CloseCallback { Tcl_CloseProc *proc; /* The procedure to call. */ ClientData clientData; /* Arbitrary one-word data to pass * to the callback. */ struct CloseCallback *nextPtr; /* For chaining close callbacks. */ } CloseCallback; /* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to * invoke the saved script in the interpreter designed in this record. */ 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; /* * struct Channel: * * One of these structures is allocated for each open channel. It contains data * specific to the channel but which belongs to the generic part of the Tcl * channel mechanism, and it points at an instance specific (and type * specific) * instance data, and at a channel type structure. */ 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. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ int byteOrder; /* byteorder associated to this channel */ 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. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ struct ChannelHandler *chPtr;/* List of channel handlers registered * for this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ struct Channel *nextChanPtr;/* Next in list of channels currently open. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for * event handlers ("fileevent") on this * channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ /* Andreas Kupries , 05/31/1997. * Support for Tcl-Trf (channel interceptors). */ struct Channel* supercedes; /* Refers to channel this one was stacked upon */ } Channel; /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in * nonblocking mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the * curOutPtr field in the * channel structure) should be * output as soon as possible even * though it may not be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the * queued output buffers has been * scheduled. */ #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No * further Tcl-level IO on the * channel is allowed. */ #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. * This bit is cleared before every * input operation. */ #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because * we saw the input eofChar. This bit * prevents clearing of the EOF bit * before every input operation. */ #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. */ typedef struct ChannelHandler { Channel *chanPtr; /* The channel structure for this channel. */ int mask; /* Mask of desired events. */ Tcl_ChannelProc *proc; /* Procedure to call in the type of * Tcl_CreateChannelHandler. */ ClientData clientData; /* Argument to pass to procedure. */ struct ChannelHandler *nextPtr; /* Next one in list of registered handlers. */ } ChannelHandler; /* * This structure keeps track of the current ChannelHandler being invoked in * the current invocation of ChannelHandlerEventProc. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. * The nextPtr field is used to chain together all recursive invocations, so * that Tcl_DeleteChannelHandler can find all the recursively nested * invocations of ChannelHandlerEventProc and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. */ typedef struct NextChannelHandler { 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)); /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ static int Tcl_GetHostByteorder _ANSI_ARGS_ (()); #define TCL_BIGENDIAN (0) /* Multibyte words are stored with MSB first */ #define TCL_SMALLENDIAN (1) /* Multibyte words are stored with MSB last */ /* *--------------------------------------------------------------------------- * * 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 * for stdin/stdout/stderr in new interpreters. * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ 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 * closed. * * Results: * None. * * Side effects: * Causes the callback to be called in the future when the channel * will be closed. * *---------------------------------------------------------------------- */ void Tcl_CreateCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to create the * close callback. */ Tcl_CloseProc *proc; /* The callback routine to call when the * channel will be closed. */ ClientData clientData; /* Arbitrary data to pass to the * close callback. */ { Channel *chanPtr; CloseCallback *cbPtr; chanPtr = (Channel *) chan; cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; cbPtr->nextPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr; } /* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * * Removes a callback that would have been called on closing * the channel. If there is no matching callback then this * function has no effect. * * Results: * None. * * Side effects: * The callback will not be called in the future when the channel * is eventually closed. * *---------------------------------------------------------------------- */ void Tcl_DeleteCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to cancel the * close callback. */ Tcl_CloseProc *proc; /* The procedure for the callback to * remove. */ ClientData clientData; /* The callback data for the callback * to remove. */ { Channel *chanPtr; CloseCallback *cbPtr, *cbPrevPtr; chanPtr = (Channel *) chan; for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL; cbPtr != (CloseCallback *) NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == (CloseCallback *) NULL) { chanPtr->closeCbPtr = cbPtr->nextPtr; } ckfree((char *) cbPtr); break; } else { cbPrevPtr = cbPtr; } } } /* *---------------------------------------------------------------------- * * GetChannelTable -- * * Gets and potentially initializes the channel table for an * interpreter. If it is initializing the table it also inserts * channels for stdin, stdout and stderr if the interpreter is * trusted. * * Results: * A pointer to the hash table created, for use by the caller. * * Side effects: * Initializes the channel table for an interpreter. May create * channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */ static Tcl_HashTable * GetChannelTable(interp) Tcl_Interp *interp; { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); (void) Tcl_SetAssocData(interp, "tclIO", (Tcl_InterpDeleteProc *) DeleteChannelTable, (ClientData) hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels * for stdin, stdout and stderr (possibly creating them in the * process). */ if (Tcl_IsSafe(interp) == 0) { stdinChan = Tcl_GetStdChannel(TCL_STDIN); if (stdinChan != NULL) { Tcl_RegisterChannel(interp, stdinChan); } stdoutChan = Tcl_GetStdChannel(TCL_STDOUT); if (stdoutChan != NULL) { Tcl_RegisterChannel(interp, stdoutChan); } stderrChan = Tcl_GetStdChannel(TCL_STDERR); if (stderrChan != NULL) { Tcl_RegisterChannel(interp, stderrChan); } } } return hTblPtr; } /* *---------------------------------------------------------------------- * * DeleteChannelTable -- * * Deletes the channel table for an interpreter, closing any open * channels whose refcount reaches zero. This procedure is invoked * when an interpreter is deleted, via the AssocData cleanup * mechanism. * * Results: * None. * * Side effects: * Deletes the hash table of channels. May close channels. May flush * output on closed channels. Removes any channeEvent handlers that were * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable(clientData, interp) ClientData clientData; /* The per-interpreter data structure. */ Tcl_Interp *interp; /* The interpreter being deleted. */ { Tcl_HashTable *hTblPtr; /* The hash table. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* Channel being deleted. */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* Variables to loop over all channel events * registered, to delete the ones that refer * to the interpreter being deleted. */ /* * Delete all the registered channels - this will close channels whose * refcount reaches zero. */ hTblPtr = (Tcl_HashTable *) clientData; for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); /* * Remove any fileevents registered in this interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } /* * Cannot call Tcl_UnregisterChannel because that procedure calls * Tcl_GetAssocData to get the channel table, which might already * be inaccessible from the interpreter structure. Instead, we * emulate the behavior of Tcl_UnregisterChannel directly here. */ Tcl_DeleteHashEntry(hPtr); chanPtr->refCount--; if (chanPtr->refCount <= 0) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } } Tcl_DeleteHashTable(hTblPtr); ckfree((char *) hTblPtr); } /* *---------------------------------------------------------------------- * * CheckForStdChannelsBeingClosed -- * * Perform special handling for standard channels being closed. When * given a standard channel, if the refcount is now 1, it means that * the last reference to the standard channel is being explicitly * closed. Now bump the refcount artificially down to 0, to ensure the * normal handling of channels being closed will occur. Also reset the * static pointer to the channel to NULL, to avoid dangling references. * * Results: * None. * * Side effects: * Manipulates the refcount on standard channels. May smash the global * static pointer to a standard channel. * *---------------------------------------------------------------------- */ 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; } /* Andreas Kupries , 05/31/1997. * Support for Tcl-Trf (channel interceptors). */ /* 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. * If the interpreter given as argument is NULL, it only decrements the * reference count. * * Results: * A standard Tcl result. * * Side effects: * Deletes the hash entry for a channel associated with an interpreter. * *---------------------------------------------------------------------- */ int Tcl_UnregisterChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which channel is defined. */ Tcl_Channel chan; /* Channel to delete. */ { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The real IO channel. */ chanPtr = (Channel *) chan; if (interp != (Tcl_Interp *) NULL) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } hPtr = Tcl_FindHashEntry(hTblPtr, chanPtr->channelName); if (hPtr == (Tcl_HashEntry *) NULL) { return TCL_OK; } if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) { return TCL_OK; } Tcl_DeleteHashEntry(hPtr); /* * Remove channel handlers that refer to this interpreter, so that they * will not be present if the actual close is delayed and more events * happen on the channel. This may occur if the channel is shared * between several interpreters, or if the channel has async * flushing active. */ CleanupChannelHandlers(interp, chanPtr); } chanPtr->refCount--; /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); /* * If the refCount reached zero, close the actual channel. */ if (chanPtr->refCount <= 0) { /* * Ensure that if there is another buffer, it gets flushed * whether or not we are doing a background flush. */ if ((chanPtr->curOutPtr != NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; } chanPtr->flags |= CHANNEL_CLOSED; if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { if (Tcl_Close(interp, chan) != TCL_OK) { return TCL_ERROR; } } } 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. */ int *modePtr; /* Where to store the mode in which the * channel was opened? Will contain an ORed * combination of TCL_READABLE and * TCL_WRITABLE, if non-NULL. */ { Channel *chanPtr; /* The actual channel. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ char *name; /* Translated name. */ /* * Substitute "stdin", etc. Note that even though we immediately * find the channel using Tcl_GetStdChannel, we still need to look * it up in the specified interpreter to ensure that it is present * in the channel table. Otherwise, safe interpreters would always * have access to the standard channels. */ name = chanName; if ((chanName[0] == 's') && (chanName[1] == 't')) { chanPtr = NULL; if (strcmp(chanName, "stdin") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDIN); } else if (strcmp(chanName, "stdout") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDOUT); } else if (strcmp(chanName, "stderr") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDERR); } if (chanPtr != NULL) { name = chanPtr->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == (Tcl_HashEntry *) NULL) { Tcl_AppendResult(interp, "can not find channel named \"", chanName, "\"", (char *) NULL); return NULL; } chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (modePtr != NULL) { *modePtr = (chanPtr->flags & (TCL_READABLE|TCL_WRITABLE)); } return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_CreateChannel -- * * Creates a new entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Creates a new Tcl_Channel instance and inserts it into the * hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_CreateChannel(typePtr, chanName, instanceData, mask) 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. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ chanPtr->byteOrder = Tcl_GetHostByteorder (); chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* Andreas Kupries , 05/31/1997. * Support for Tcl-Trf (channel interceptors). */ chanPtr->supercedes = (Channel*) 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; } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf. */ /* *---------------------------------------------------------------------- * * Tcl_ReplaceChannel -- * * Replaces an entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Replaces a Tcl_Channel instance into the hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp* interp; /* the interpreter we are working in */ Tcl_ChannelType *typePtr; /* The channel type record. */ ClientData instanceData; /* Instance specific data. */ int mask; /* TCL_READABLE & TCL_WRITABLE to indicate * if the channel is readable, writable. */ Tcl_Channel prevChan; /* The channel structure that should * be replaced. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel *chanPtr, *pt, *prevPt; /* * Replace the channel into the list of all channels; */ prevPt = (Channel*) NULL; pt = (Channel*) tsdPtr->firstChanPtr; while (pt != (Channel *) prevChan) { prevPt = pt; pt = pt->nextChanPtr; } /* 'pt == prevChan' now */ if (!pt) { return (Tcl_Channel) NULL; } /* * Here we check if the "mask" matches the "flags" * of the already existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to * W | | | + | + | restrict the capabilities of the * RW| | + | + | + | superceded one ! * --+---+---+---+----+ */ if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { return (Tcl_Channel) NULL; } chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); chanPtr->flags = mask; /* * Set the channel up initially in no Input translation mode and * no Output translation mode. */ chanPtr->inputTranslation = TCL_TRANSLATE_LF; chanPtr->outputTranslation = TCL_TRANSLATE_LF; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* 06/12/1998: New for Tcl 8.1 * * Take over the encoding from the superceded channel, so that it will be * executed in future despite the replacement, and at the proper time (after * our transformation). * * Tcl-Trf uses 'Tcl_Read' to get at the underlying information, thus * circumventing data de/encoding in the superceded channel. Because of this * there is no need to trouble ourselves with 'ByteArray's too. */ chanPtr->encoding = pt->encoding; chanPtr->inputEncodingState = pt->inputEncodingState; chanPtr->inputEncodingFlags = pt->inputEncodingFlags; chanPtr->outputEncodingState = pt->outputEncodingState; chanPtr->outputEncodingFlags = pt->outputEncodingFlags; chanPtr->outputStage = NULL; if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) { chanPtr->outputStage = (char *) ckalloc((unsigned) (chanPtr->bufSize + 2)); } chanPtr->supercedes = (Channel*) prevChan; chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); strcpy (chanPtr->channelName, pt->channelName); if (prevPt) { prevPt->nextChanPtr = chanPtr; } else { tsdPtr->firstChanPtr = chanPtr; } chanPtr->nextChanPtr = pt->nextChanPtr; Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); /* The superceded channel is effectively unregistered */ /*chanPtr->supercedes->refCount --;*/ return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_UndoReplaceChannel -- * * Unstacks an entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the old Tcl_Channel, i.e. the one which was stacked over. * * Side effects: * Replaces a Tcl_Channel instance into the hash table. * *---------------------------------------------------------------------- */ void Tcl_UndoReplaceChannel (interp, chan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_Channel chan; /* The channel to unstack */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel* chanPtr = (Channel*) chan; if (chanPtr->supercedes != (Channel*) NULL) { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ int new; /* Is the hash entry new or does it exist? */ /* * Insert the channel we were stacked upon back into * the list of open channels. Place it back into the hashtable too. * Correct 'refCount', as this actually unregisters 'chan'. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; hTblPtr = GetChannelTable (interp); hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); chanPtr->refCount --; /* The superceded channel is effectively registered again */ /*chanPtr->supercedes->refCount ++;*/ } /* * Disconnect the channels, then do a regular close upon the * stacked one. This may cause flushing of data into the * superceded channel (if 'chan' remembered its parent in itself). */ chanPtr->supercedes = NULL; if (chanPtr->refCount == 0) { Tcl_Close (interp, chan); } } /* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * * Computes a mask indicating whether the channel is open for * reading and writing. * * Results: * An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelMode(chan) Tcl_Channel chan; /* The channel for which the mode is * being computed. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE)); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * * Returns the string identifying the channel name. * * Results: * The string containing the channel name. This memory is * owned by the generic layer and should not be modified by * the caller. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Tcl_GetChannelName(chan) Tcl_Channel chan; /* The channel for which to return the name. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->channelName; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * * Given a channel structure, returns the channel type structure. * * Results: * Returns a pointer to the channel type structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ChannelType * Tcl_GetChannelType(chan) Tcl_Channel chan; /* The channel to return type for. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->typePtr; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * * Returns an OS handle associated with a channel. * * Results: * Returns TCL_OK and places the handle in handlePtr, or returns * TCL_ERROR on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelHandle(chan, direction, handlePtr) Tcl_Channel chan; /* The channel to get file from. */ int direction; /* TCL_WRITABLE or TCL_READABLE. */ ClientData *handlePtr; /* Where to store handle */ { Channel *chanPtr; /* The actual channel. */ ClientData handle; int result; chanPtr = (Channel *) chan; result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData, direction, &handle); if (handlePtr) { *handlePtr = handle; } return result; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * * Returns the client data associated with a channel. * * Results: * The client data. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_GetChannelInstanceData(chan) 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 * that two input buffers are saved (one in the input queue and * another in the saveInBufPtr field) and that curOutPtr is set * to a buffer. Only if these conditions are met is the buffer * freed to the OS. * * Results: * None. * * Side effects: * May free a buffer to the OS. * *---------------------------------------------------------------------- */ static void RecycleBuffer(chanPtr, bufPtr, mustDiscard) Channel *chanPtr; /* Channel for which to recycle buffers. */ ChannelBuffer *bufPtr; /* The buffer to recycle. */ int mustDiscard; /* If nonzero, free the buffer to the * OS, always. */ { /* * Do we have to free the buffer to the OS? */ if (mustDiscard) { ckfree((char *) bufPtr); return; } /* * Only save buffers for the input queue if the channel is readable. */ if (chanPtr->flags & TCL_READABLE) { if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) { chanPtr->inQueueHead = bufPtr; chanPtr->inQueueTail = bufPtr; goto keepit; } if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) { chanPtr->saveInBufPtr = bufPtr; goto keepit; } } /* * Only save buffers for the output queue if the channel is writable. */ if (chanPtr->flags & TCL_WRITABLE) { if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) { chanPtr->curOutPtr = bufPtr; goto keepit; } } /* * 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 -- * * Discards all output queued in the output queue of a channel. * * Results: * None. * * Side effects: * Recycles buffers. * *---------------------------------------------------------------------- */ static void DiscardOutputQueued(chanPtr) Channel *chanPtr; /* The channel for which to discard output. */ { ChannelBuffer *bufPtr; while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { bufPtr = chanPtr->outQueueHead; chanPtr->outQueueHead = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, 0); } chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; } /* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * * This function checks is a given channel is Dead. * (A channel that has been closed but not yet deallocated.) * * Results: * True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: * None * *---------------------------------------------------------------------- */ static int CheckForDeadChannel(interp, chanPtr) Tcl_Interp *interp; /* For error reporting (can be NULL) */ Channel *chanPtr; /* The channel to check. */ { if (chanPtr->flags & CHANNEL_DEAD) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, "unable to access channel: invalid channel", (char *) NULL); } return 1; } return 0; } /* *---------------------------------------------------------------------- * * FlushChannel -- * * This function flushes as much of the queued output as is possible * now. If calledFromAsyncFlush is nonzero, it is being called in an * event handler to flush channel output asynchronously. * * Results: * 0 if successful, else the error code that was returned by the * channel type operation. * * Side effects: * May produce output on a channel. May block indefinitely if the * channel is synchronous. May schedule an async flush on the channel. * May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */ static int FlushChannel(interp, chanPtr, calledFromAsyncFlush) Tcl_Interp *interp; /* For error reporting during close. */ Channel *chanPtr; /* The channel to flush on. */ int calledFromAsyncFlush; /* If nonzero then we are being * called from an asynchronous * flush callback. */ { 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. */ if (CheckForDeadChannel(interp,chanPtr)) return -1; /* * Loop over the queued buffers and attempt to flush as * much as possible of the queued output to the channel. */ while (1) { /* * 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 { chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr; } chanPtr->outQueueTail = chanPtr->curOutPtr; chanPtr->curOutPtr = (ChannelBuffer *) NULL; } bufPtr = chanPtr->outQueueHead; /* * If we are not being called from an async flush and an async * flush is active, we just return without producing any output. */ if ((!calledFromAsyncFlush) && (chanPtr->flags & BG_FLUSH_SCHEDULED)) { return 0; } /* * If the output queue is still empty, break out of the while loop. */ if (bufPtr == (ChannelBuffer *) NULL) { break; /* Out of the "while (1)". */ } /* * 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. */ if (written < 0) { /* * If the last attempt to write was interrupted, simply retry. */ if (errorCode == EINTR) { errorCode = 0; continue; } /* * If the channel is non-blocking and we would have blocked, * start a background flushing handler and break out of the loop. */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { if (chanPtr->flags & CHANNEL_NONBLOCKING) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { chanPtr->flags |= BG_FLUSH_SCHEDULED; UpdateInterest(chanPtr); } errorCode = 0; break; } else { panic("Blocking channel driver did not block on output"); } } /* * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { if (chanPtr->unreportedError == 0) { chanPtr->unreportedError = errorCode; } } else { Tcl_SetErrno(errorCode); if (interp != NULL) { Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } } /* * 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. */ if ((chanPtr->flags & CHANNEL_CLOSED) && (chanPtr->refCount <= 0) && (chanPtr->outQueueHead == (ChannelBuffer *) NULL) && ((chanPtr->curOutPtr == (ChannelBuffer *) NULL) || (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->nextRemoved))) { return CloseChannel(interp, chanPtr, errorCode); } return errorCode; } /* *---------------------------------------------------------------------- * * CloseChannel -- * * Utility procedure to close a channel and free its associated * resources. * * Results: * 0 on success or a POSIX error code if the operation failed. * * Side effects: * May close the actual channel; may free memory. * *---------------------------------------------------------------------- */ static int CloseChannel(interp, chanPtr, errorCode) Tcl_Interp *interp; /* For error reporting. */ Channel *chanPtr; /* The channel to close. */ 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. */ DiscardInputQueued(chanPtr, 1); /* * Discard a leftover buffer in the current output buffer field. */ if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { ckfree((char *) chanPtr->curOutPtr); chanPtr->curOutPtr = (ChannelBuffer *) NULL; } /* * The caller guarantees that there are no more buffers * queued for output. */ if (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { panic("TclFlush, closed channel: queued output left"); } /* * If the EOF character is set in the channel, append that to the * output device. */ if ((chanPtr->outEofChar != 0) && (chanPtr->flags & TCL_WRITABLE)) { int dummy; char c; c = (char) chanPtr->outEofChar; (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy); } /* * Remove TCL_READABLE and TCL_WRITABLE from chanPtr->flags, so * that close callbacks can not do input or output (assuming they * squirreled the channel away in their clientData). This also * prevents infinite loops if the callback calls any C API that * could call FlushChannel. */ 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. */ if (chanPtr->unreportedError != 0) { errorCode = chanPtr->unreportedError; } if (errorCode == 0) { errorCode = result; if (errorCode != 0) { Tcl_SetErrno(errorCode); } } /* -- CloseChannel -- * Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (channel interceptors). * * Handle stacking of channels. Must be done after 'closeProc' * to allow for flushing of data into the underlying channel. */ if (chanPtr->supercedes != (Channel*) NULL) { /* Insert the channel we were stacked upon back into * the list of open channels, then do a regular close. */ chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr; tsdPtr->firstChanPtr = chanPtr->supercedes; chanPtr->supercedes->refCount --; /* is deregistered */ Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* * Cancel any outstanding timer. */ Tcl_DeleteTimerHandler(chanPtr->timer); /* * Mark the channel as deleted by clearing the type structure. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC); return errorCode; } /* *---------------------------------------------------------------------- * * Tcl_Close -- * * Closes a channel. * * Results: * A standard Tcl result. * * Side effects: * Closes the channel if this is the last reference. * * NOTE: * Tcl_Close removes the channel as far as the user is concerned. * However, it may continue to exist for a while longer if it has * a background flush scheduled. The device itself is eventually * closed and the channel record removed, in CloseChannel, above. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_Close(interp, chan) Tcl_Interp *interp; /* Interpreter for errors. */ Tcl_Channel chan; /* The channel being closed. Must * not be referenced in any * interpreter. */ { 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; } /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); chanPtr = (Channel *) chan; if (chanPtr->refCount > 0) { panic("called Tcl_Close on channel with refCount > 0"); } /* * 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; } } /* * Remove all the channel handler records attached to the channel * itself. */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chNext) { chNext = chPtr->nextPtr; ckfree((char *) chPtr); } chanPtr->chPtr = (ChannelHandler *) NULL; /* * Cancel any pending copy operation. */ StopCopy(chanPtr->csPtr); /* * Must set the interest mask now to 0, otherwise infinite loops * will occur if Tcl_DoOneEvent is called before the channel is * finally deleted in FlushChannel. This can happen if the channel * has a background flush active. */ chanPtr->interestMask = 0; /* * 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. */ while (chanPtr->closeCbPtr != (CloseCallback *) NULL) { cbPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr->nextPtr; (cbPtr->proc) (cbPtr->clientData); ckfree((char *) cbPtr); } /* * 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; } 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; } } 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. */ { int srcLen, newlineFound; newlineFound = 0; srcLen = *srcLenPtr; switch (chanPtr->outputTranslation) { case TCL_TRANSLATE_LF: { memcpy((VOID *) dst, (VOID *) src, (size_t) srcLen); if (chanPtr->flags & CHANNEL_LINEBUFFERED) { char *dstEnd; for (dstEnd = dst + srcLen; dst < dstEnd; dst++) { if (*dst == '\n') { newlineFound = 1; break; } } } *dstLenPtr = srcLen; break; } case TCL_TRANSLATE_CR: { char *dstEnd; memcpy((VOID *) dst, (VOID *) src, (size_t) srcLen); for (dstEnd = dst + srcLen; dst < dstEnd; dst++) { if (*dst == '\n') { *dst = '\r'; newlineFound = 1; } } *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, *dstEnd; CONST char *srcStart; dstStart = dst; dstMax = dst + *dstLenPtr; srcStart = src; for (dstEnd = dst + srcLen; 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; 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) { return -1; } 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); return -1; } 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; return gs.totalChars + gs.charsWrote - skip; /* * 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; return -1; } /* *--------------------------------------------------------------------------- * * 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) { return -1; } 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; } return -1; } } else { copied += copiedNow; toRead -= copiedNow; } } chanPtr->flags &= ~CHANNEL_BLOCKED; if (encoding == NULL) { Tcl_SetByteArrayLength(objPtr, offset); } else { Tcl_SetObjLength(objPtr, offset); } 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) { return -1; } 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) { return len; } 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; } return len; } /* *---------------------------------------------------------------------- * * Tcl_Flush -- * * Flushes output data on a channel. * * Results: * A standard Tcl result. * * Side effects: * May flush output queued on this channel. * *---------------------------------------------------------------------- */ int 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; } return TCL_OK; } /* *---------------------------------------------------------------------- * * DiscardInputQueued -- * * Discards any input read from the channel but not yet consumed * by Tcl reading commands. * * Results: * None. * * Side effects: * May discard input from the channel. If discardLastBuffer is zero, * leaves one buffer in place for back-filling. * *---------------------------------------------------------------------- */ static void DiscardInputQueued(chanPtr, discardSavedBuffers) Channel *chanPtr; /* Channel on which to discard * the queued input. */ int discardSavedBuffers; /* If non-zero, discard all buffers including * last one. */ { ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ bufPtr = chanPtr->inQueueHead; chanPtr->inQueueHead = (ChannelBuffer *) NULL; chanPtr->inQueueTail = (ChannelBuffer *) NULL; for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) { nxtPtr = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, discardSavedBuffers); } /* * If discardSavedBuffers is nonzero, must also discard any previously * saved buffer in the saveInBufPtr field. */ if (discardSavedBuffers) { if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) { 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 -- * * Implements seeking on Tcl Channels. This is a public function * so that other C facilities may be implemented on top of it. * * Results: * The new access point or -1 on error. If error, use Tcl_GetErrno() * to retrieve the POSIX error code for the error that occurred. * * Side effects: * May flush output on the channel. May discard queued input. * *---------------------------------------------------------------------- */ int Tcl_Seek(chan, offset, mode) Tcl_Channel chan; /* The channel on which to seek. */ int offset; /* Offset to seek to. */ int mode; /* Relative to which location to seek? */ { Channel *chanPtr; /* The real IO channel. */ ChannelBuffer *bufPtr; int inputBuffered, outputBuffered; 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 * registered in an interpreter. */ if (CheckForDeadChannel(NULL,chanPtr)) return -1; /* * Disallow seek on channels whose type does not have a seek procedure * defined. This means that the channel does not support seeking. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * If we are seeking relative to the current position, compute the * corrected offset taking into account the amount of unread input. */ if (mode == SEEK_CUR) { offset -= inputBuffered; } /* * Discard any queued input - this input should not be read after * the seek. */ DiscardInputQueued(chanPtr, 0); /* * Reset EOF and BLOCKED flags. We invalidate them by moving the * access point. Also clear CR related flags. */ chanPtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR)); /* * If the channel is in asynchronous output mode, switch it back * to synchronous mode and cancel any async flush that may be * scheduled. After the flush, the channel will be put back into * asynchronous output mode. */ wasAsync = 0; if (chanPtr->flags & CHANNEL_NONBLOCKING) { wasAsync = 1; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_BLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } chanPtr->flags &= (~(CHANNEL_NONBLOCKING)); if (chanPtr->flags & BG_FLUSH_SCHEDULED) { chanPtr->flags &= (~(BG_FLUSH_SCHEDULED)); } } /* * If the flush fails we cannot recover the original position. In * that case the seek is not attempted because we do not know where * the access position is - instead we return the error. FlushChannel * has already called Tcl_SetErrno() to report the error upwards. * If the flush succeeds we do the seek also. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { curPos = -1; } else { /* * Now seek to the new position in the channel as requested by the * caller. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) offset, mode, &result); if (curPos == -1) { Tcl_SetErrno(result); } } /* * Restore to nonblocking mode if that was the previous behavior. * * NOTE: Even if there was an async flush active we do not restore * it now because we already flushed all the queued output, above. */ if (wasAsync) { chanPtr->flags |= CHANNEL_NONBLOCKING; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_NONBLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } } return curPos; } /* *---------------------------------------------------------------------- * * Tcl_Tell -- * * Returns the position of the next character to be read/written on * this channel. * * Results: * A nonnegative integer on success, -1 on failure. If failed, * use Tcl_GetErrno() to retrieve the POSIX error code for the * error that occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Tell(chan) Tcl_Channel chan; /* The channel to return pos for. */ { 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. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * Get the current position in the device and compute the position * where the next character will be read or written. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) 0, SEEK_CUR, &result); if (curPos == -1) { Tcl_SetErrno(result); 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. * * Results: * 1 or 0, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Eof(chan) Tcl_Channel chan; /* Does this channel have EOF? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_STICKY_EOF) || ((chanPtr->flags & CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * * Results: * 0 or 1, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBlocked(chan) Tcl_Channel chan; /* Is this channel blocked? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return (chanPtr->flags & CHANNEL_BLOCKED) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBuffered -- * * Returns the number of bytes of input currently buffered in the * internal buffer of a channel. * * Results: * The number of input bytes buffered, or zero if the channel is not * open for reading. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBuffered(chan) Tcl_Channel chan; /* The channel to query. */ { Channel *chanPtr; int bytesBuffered; ChannelBuffer *bufPtr; chanPtr = (Channel *) chan; for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } return bytesBuffered; } /* *---------------------------------------------------------------------- * * Tcl_SetChannelBufferSize -- * * Sets the size of buffers to allocate to store input or output * in the channel. The size must be between 10 bytes and 1 MByte. * * Results: * None. * * Side effects: * Sets the size of buffers subsequently allocated for this channel. * *---------------------------------------------------------------------- */ void Tcl_SetChannelBufferSize(chan, sz) Tcl_Channel chan; /* The channel whose buffer size * to set. */ int sz; /* The size to set. */ { Channel *chanPtr; /* * If the buffer size is smaller than 10 bytes or larger than one MByte, * do not accept the requested size and leave the current buffer size. */ if (sz < 10) { return; } 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 -- * * Retrieves the size of buffers to allocate for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelBufferSize(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->bufSize; } /* *---------------------------------------------------------------------- * * Tcl_BadChannelOption -- * * This procedure generates a "bad option" error message in an * (optional) interpreter. It is used by channel drivers when * a invalid Set/Get option is requested. Its purpose is to concatenate * the generic options list to the specific ones and factorize * the generic options error message string. * * Results: * TCL_ERROR. * * Side effects: * An error message is generated in interp's result object to * indicate that a command was invoked with the a bad option * The message has the form * bad option "blah": should be one of * <...generic options...>+<...specific options...> * "blah" is the optionName argument and "" * is a space separated list of specific option words. * The function takes good care of inserting minus signs before * each option, commas after, and an "or" before the last option. * *---------------------------------------------------------------------- */ int Tcl_BadChannelOption(interp, optionName, optionList) Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/ char *optionName; /* 'bad option' name */ char *optionList; /* Specific options list to append * to the standard generic options. * can be NULL for generic options * only. */ { if (interp) { CONST char *genericopt = "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, (char *) genericopt, -1); if (optionList && (*optionList)) { Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad option \"", optionName, "\": should be one of ", (char *) NULL); argc--; for (i = 0; i < argc; i++) { Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL); } Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL); Tcl_DStringFree(&ds); ckfree((char *) argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ /* *---------------------------------------------------------------------- * * Tcl_GetChannelByteorder -- * * Retrieves the byteorder set for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelByteorder(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->byteOrder; } /* *---------------------------------------------------------------------- * * Tcl_GetHostByteorder -- * * Retrieves the byteorder of the machine we are running on. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int Tcl_GetHostByteorder() { union { char c[sizeof(short)]; short s; } order; order.s = 1; return (order.c[0] == 1) ? TCL_SMALLENDIAN : TCL_BIGENDIAN; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelOption -- * * 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: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelOption(interp, chan, optionName, dsPtr) Tcl_Interp *interp; /* For error reporting - can be NULL. */ Tcl_Channel chan; /* Channel on which to get option. */ char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */ { size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; int flags; /* * If we are in the middle of a background copy, use the saved flags. */ if (chanPtr->csPtr) { if (chanPtr == chanPtr->csPtr->readPtr) { flags = chanPtr->csPtr->readFlags; } else { flags = chanPtr->csPtr->writeFlags; } } else { flags = chanPtr->flags; } /* * Disallow options 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(interp,chanPtr)) return TCL_ERROR; /* * If the optionName is NULL it means that we want a list of all * options and values. */ if (optionName == (char *) NULL) { len = 0; } else { len = strlen(optionName); } if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blocking"); } Tcl_DStringAppendElement(dsPtr, (flags & CHANNEL_NONBLOCKING) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffering", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffering"); } if (flags & CHANNEL_LINEBUFFERED) { Tcl_DStringAppendElement(dsPtr, "line"); } else if (flags & CHANNEL_UNBUFFERED) { Tcl_DStringAppendElement(dsPtr, "none"); } else { Tcl_DStringAppendElement(dsPtr, "full"); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffersize", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffersize"); } 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; } } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-byteorder"); } Tcl_DStringAppendElement(dsPtr, (chanPtr->byteOrder == TCL_BIGENDIAN) ? "bigendian" : "smallendian"); 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); } if (flags & TCL_READABLE) { if (chanPtr->inEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->inEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (flags & TCL_WRITABLE) { if (chanPtr->outEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->outEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 1) && (optionName[1] == 't') && (strncmp(optionName, "-translation", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-translation"); } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringStartSublist(dsPtr); } if (flags & TCL_READABLE) { if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (flags & TCL_WRITABLE) { if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) { /* * let the driver specific handle additional options * and result code and message. */ return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData, interp, optionName, dsPtr); } else { /* * no driver specific options case. */ if (len == 0) { 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? */ char *newValue; /* New value for option. */ { int newMode; /* New (numeric) mode to sert. */ Channel *chanPtr; /* The real IO channel. */ size_t len; /* Length of optionName string. */ int argc; char **argv; chanPtr = (Channel *) chan; /* * If the channel is in the middle of a background copy, fail. */ if (chanPtr->csPtr) { if (interp) { Tcl_AppendResult(interp, "unable to set channel options: background copy in progress", (char *) NULL); } return TCL_ERROR; } /* * Disallow options 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 TCL_ERROR; len = strlen(optionName); if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0)) { if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) { return TCL_ERROR; } 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)) { chanPtr->flags &= (~(CHANNEL_UNBUFFERED)); chanPtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { chanPtr->flags &= (~(CHANNEL_LINEBUFFERED)); chanPtr->flags |= CHANNEL_UNBUFFERED; } else { 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; } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ } else if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0)) { int nv_len = strlen (newValue); if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { chanPtr->byteOrder = TCL_BIGENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_BIGENDIAN; return TCL_OK; } if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "bad value for -byteorder: ", "must be one of smallendian, littleendian, bigendian or network", (char *) NULL); } return TCL_ERROR; } 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; } else if (argc == 1) { if (chanPtr->flags & TCL_WRITABLE) { chanPtr->outEofChar = (int) argv[0][0]; } if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } } else if (argc != 2) { if (interp) { Tcl_AppendResult(interp, "bad value for -eofchar: should be a list of one or", " two elements", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } else { if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } 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; } if (argc == 1) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: must be a one or two", " element list", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } 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) { newMode = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered * 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) { /* * This is a hack to get TCP sockets to produce output * in CRLF mode if they are being set into AUTO mode. * A better solution for achieving this effect will be * coded later. */ if (strcmp(chanPtr->typePtr->typeName, "tcp") == 0) { 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) { chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } 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 -- * * Removes channel handlers that refer to the supplied interpreter, * so that if the actual channel is not closed now, these handlers * will not run on subsequent events on the channel. This would be * erroneous, because the interpreter no longer has a reference to * this channel. * * Results: * None. * * Side effects: * Removes channel handlers. * *---------------------------------------------------------------------- */ static void CleanupChannelHandlers(interp, chanPtr) Tcl_Interp *interp; Channel *chanPtr; { EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* * Remove fileevent records on this channel that refer to the * given interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); Tcl_DecrRefCount(sPtr->scriptPtr); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } } /* *---------------------------------------------------------------------- * * Tcl_NotifyChannel -- * * This procedure is called by a channel driver when a driver * detects an event on a channel. This procedure is responsible * for actually handling the event by invoking any channel * handler callbacks. * * Results: * None. * * Side effects: * Whatever the channel handler callback procedure does. * *---------------------------------------------------------------------- */ void Tcl_NotifyChannel(channel, mask) 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; /* * Prevent the event handler from deleting the channel by incrementing * the channel's ref count. Case in point: ChannelEventScriptInvoker() * was evaling a script (owned by the channel) which caused the channel * to be closed and then the byte codes no longer existed. */ Tcl_RegisterChannel(NULL, 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. */ if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; (*(chPtr->proc))(chPtr->clientData, mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; } } /* * Update the notifier interest, since it may have changed after * invoking event handlers. */ if (chanPtr->typePtr != NULL) { UpdateInterest(chanPtr); } /* * No longer need to protect the channel from being deleted. * After this point it is unsafe to use the value of "channel". */ Tcl_UnregisterChannel((Tcl_Interp *) NULL, channel); tsdPtr->nestedHandlerPtr = nh.nestedHandlerPtr; } /* *---------------------------------------------------------------------- * * UpdateInterest -- * * Arrange for the notifier to call us back at appropriate times * based on the current state of the channel. * * Results: * None. * * Side effects: * May schedule a timer or driver handler. * *---------------------------------------------------------------------- */ static void UpdateInterest(chanPtr) Channel *chanPtr; /* Channel to update. */ { int mask = chanPtr->interestMask; /* * If there are flushed buffers waiting to be written, then * we need to watch for the channel to become writable. */ 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); } } } (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask); } /* *---------------------------------------------------------------------- * * ChannelTimerProc -- * * Timer handler scheduled by UpdateInterest to monitor the * channel buffers until they are empty. * * Results: * None. * * Side effects: * May invoke channel handlers. * *---------------------------------------------------------------------- */ 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. */ chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc, (ClientData) chanPtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); } else { chanPtr->timer = NULL; UpdateInterest(chanPtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * * Arrange for a given procedure to be invoked whenever the * channel indicated by the chanPtr arg becomes readable or * writable. * * Results: * None. * * Side effects: * From now on, whenever the I/O channel given by chanPtr becomes * ready in the way indicated by mask, proc will be invoked. * See the manual entry for details on the calling sequence * to proc. If there is already an event handler for chan, proc * and clientData, then the mask will be updated. * *---------------------------------------------------------------------- */ void Tcl_CreateChannelHandler(chan, mask, proc, clientData) Tcl_Channel chan; /* The channel to create the handler for. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions under which * proc should be called. Use 0 to * disable a registered handler. */ Tcl_ChannelProc *proc; /* Procedure to call for each * selected event. */ ClientData clientData; /* Arbitrary data to pass to proc. */ { ChannelHandler *chPtr; Channel *chanPtr; chanPtr = (Channel *) chan; /* * Check whether this channel handler is not already registered. If * it is not, create a new record, else reuse existing record (smash * current values). */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) && (chPtr->clientData == clientData)) { break; } } if (chPtr == (ChannelHandler *) NULL) { chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler)); chPtr->mask = 0; chPtr->proc = proc; chPtr->clientData = clientData; chPtr->chanPtr = chanPtr; chPtr->nextPtr = chanPtr->chPtr; chanPtr->chPtr = chPtr; } /* * The remainder of the initialization below is done regardless of * whether or not this is a new record or a modification of an old * one. */ chPtr->mask = mask; /* * Recompute the interest mask for the channel - this call may actually * be disabling an existing handler. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * Tcl_DeleteChannelHandler -- * * Cancel a previously arranged callback arrangement for an IO * channel. * * Results: * None. * * Side effects: * If a callback was previously registered for this chan, proc and * clientData , it is removed and the callback will no longer be called * when the channel becomes ready for IO. * *---------------------------------------------------------------------- */ void Tcl_DeleteChannelHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to remove the * callback. */ 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. */ for (prevChPtr = (ChannelHandler *) NULL, chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData) && (chPtr->proc == proc)) { break; } prevChPtr = chPtr; } /* * If not found, return without doing anything. */ if (chPtr == (ChannelHandler *) NULL) { return; } /* * 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_DeleteChanelHandler is called inside an event. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * DeleteScriptRecord -- * * Delete a script record for this combination of channel, interp * and mask. * * Results: * None. * * Side effects: * Deletes a script record and cancels a channel event handler. * *---------------------------------------------------------------------- */ static void DeleteScriptRecord(interp, chanPtr, mask) Tcl_Interp *interp; /* Interpreter in which script was to be * executed. */ Channel *chanPtr; /* The channel for which to delete the * script record (if any). */ int mask; /* Events in mask must exactly match mask * of script to delete. */ { EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = chanPtr->scriptRecordPtr, prevEsPtr = (EventScriptRecord *) NULL; esPtr != (EventScriptRecord *) NULL; prevEsPtr = esPtr, esPtr = esPtr->nextPtr) { if ((esPtr->interp == interp) && (esPtr->mask == mask)) { if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { prevEsPtr->nextPtr = esPtr->nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) esPtr); Tcl_DecrRefCount(esPtr->scriptPtr); ckfree((char *) esPtr); break; } } } /* *---------------------------------------------------------------------- * * CreateScriptRecord -- * * Creates a record to store a script to be executed when a specific * event fires on a specific channel. * * Results: * None. * * 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 -- * * Invokes a script scheduled by "fileevent" for when the channel * becomes ready for IO. This function is invoked by the channel * handler which was created by the Tcl "fileevent" command. * * Results: * None. * * Side effects: * Whatever the script does. * *---------------------------------------------------------------------- */ static void 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_EvalObj(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. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundError(interp); } 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; } /* *---------------------------------------------------------------------- * * TclTestChannelCmd -- * * Implements the Tcl "testchannel" debugging command and its * subcommands. This is part of the testing environment but must be * in this file instead of tclTest.c because it needs access to the * fields of struct Channel. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int TclTestChannelCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Interpreter for result. */ int argc; /* Count of additional args. */ char **argv; /* Additional arg strings. */ { char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ 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]); Tcl_AppendElement(interp, chanPtr->typePtr->typeName); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_NONBLOCKING) { Tcl_AppendElement(interp, "nonblocking"); } else { Tcl_AppendElement(interp, "blocking"); } if (chanPtr->flags & CHANNEL_LINEBUFFERED) { Tcl_AppendElement(interp, "line"); } else if (chanPtr->flags & CHANNEL_UNBUFFERED) { Tcl_AppendElement(interp, "none"); } else { Tcl_AppendElement(interp, "full"); } if (chanPtr->flags & BG_FLUSH_SCHEDULED) { Tcl_AppendElement(interp, "async_flush"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_EOF) { Tcl_AppendElement(interp, "eof"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_BLOCKED) { Tcl_AppendElement(interp, "blocked"); } else { Tcl_AppendElement(interp, "unblocked"); } if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "saw_cr"); } else { Tcl_AppendElement(interp, ""); } } else if (chanPtr->inputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "queued_cr"); } else { Tcl_AppendElement(interp, ""); } } if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); } for (IOQueued = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved; } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved; } for (bufPtr = chanPtr->outQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved); } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr)); Tcl_AppendElement(interp, buf); TclFormatInt(buf, chanPtr->refCount); Tcl_AppendElement(interp, buf); return TCL_OK; } if ((cmdName[0] == 'i') && (strncmp(cmdName, "inputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; } if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } return TCL_OK; } if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "outputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - 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) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (chanPtr->flags & INPUT_SAW_CR) ? "1" : "0", (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } 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", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ", "info, open, readable, or writable", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclTestChannelEventCmd -- * * This procedure implements the "testchannelevent" command. It is * used to test the Tcl channel event mechanism. It is present in * this file instead of tclTest.c because it needs access to the * internal structure of the channel. * * Results: * A standard Tcl result. * * Side effects: * Creates, deletes and returns channel event handlers. * *---------------------------------------------------------------------- */ /* ARGSUSED */ 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], " channelName cmd ?arg1? ?arg2?\"", (char *) NULL); return TCL_ERROR; } chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL); if (chanPtr == (Channel *) NULL) { return TCL_ERROR; } cmd = argv[2]; len = strlen(cmd); if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName add eventSpec script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[3], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[3], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[3], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr = (EventScriptRecord *) ckalloc((unsigned) 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; } if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) { if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { for (prevEsPtr = chanPtr->scriptRecordPtr; (prevEsPtr != (EventScriptRecord *) NULL) && (prevEsPtr->nextPtr != esPtr); prevEsPtr = prevEsPtr->nextPtr) { /* Empty loop body. */ } 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)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index event\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[4], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[4], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[4], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[4], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr->mask = mask; 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 -- * * This routine copies data from one channel to another, either * synchronously or asynchronously. If a command script is * supplied, the operation runs in the background. The script * is invoked when the copy completes. Otherwise the function * waits until the copy is completed before returning. * * Results: * A standard Tcl result. * * Side effects: * May schedule a background copy operation that causes both * channels to be marked busy. * *---------------------------------------------------------------------- */ int TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Channel inChan; /* Channel to read from. */ Tcl_Channel outChan; /* Channel to write to. */ int toRead; /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */ { Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; if (inPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); return TCL_ERROR; } if (outPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); return TCL_ERROR; } readFlags = inPtr->flags; writeFlags = outPtr->flags; /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. * If there is an error, restore the old blocking mode. */ if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(interp, inPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) { return TCL_ERROR; } } if (inPtr != outPtr) { if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(NULL, outPtr, nonBlocking ? TCL_MODE_BLOCKING : TCL_MODE_NONBLOCKING) != TCL_OK) { if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING) ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); return TCL_ERROR; } } } } /* * Make sure the output side is unbuffered. */ outPtr->flags = (outPtr->flags & ~(CHANNEL_LINEBUFFERED)) | CHANNEL_UNBUFFERED; /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inPtr->bufSize); csPtr->bufSize = inPtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; inPtr->csPtr = csPtr; outPtr->csPtr = csPtr; /* * Start copying data between the channels. */ return CopyData(csPtr, 0); } /* *---------------------------------------------------------------------- * * CopyData -- * * This function implements the lowest level of the copying * mechanism for TclCopyChannel. * * Results: * Returns TCL_OK on success, else TCL_ERROR. * * Side effects: * Moves data between channels, may create channel handlers. * *---------------------------------------------------------------------- */ static int CopyData(csPtr, mask) CopyState *csPtr; /* State of copy operation. */ int mask; /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL; Tcl_Channel inChan, outChan; int result = TCL_OK; int size; int total; inChan = (Tcl_Channel)csPtr->readPtr; outChan = (Tcl_Channel)csPtr->writePtr; interp = csPtr->interp; cmdPtr = csPtr->cmdPtr; /* * Copy the data the slow way, using the translation mechanism. */ while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ if (csPtr->readPtr->unreportedError != 0) { Tcl_SetErrno(csPtr->readPtr->unreportedError); csPtr->readPtr->unreportedError = 0; goto readError; } if (csPtr->writePtr->unreportedError != 0) { Tcl_SetErrno(csPtr->writePtr->unreportedError); csPtr->writePtr->unreportedError = 0; goto writeError; } /* * Read up to bufSize bytes. */ if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { size = csPtr->bufSize; } else { size = csPtr->toRead; } size = DoRead(csPtr->readPtr, csPtr->buffer, size); if (size < 0) { readError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error reading \"", Tcl_GetChannelName(inChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } else if (size == 0) { /* * We had an underflow on the read side. If we are at EOF, * then the copying is done, otherwise set up a channel * handler to detect when the channel becomes readable again. */ if (Tcl_Eof(inChan)) { break; } else if (!(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Now write the buffer out. */ size = DoWrite(csPtr->writePtr, csPtr->buffer, size); if (size < 0) { writeError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error writing \"", Tcl_GetChannelName(outChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } /* * Check to see if the write is happening in the background. If so, * stop copying and wait for the channel to become writable again. */ if (csPtr->writePtr->flags & BG_FLUSH_SCHEDULED) { if (!(mask & TCL_WRITABLE)) { if (mask & TCL_READABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Update the current byte count if we care. */ if (csPtr->toRead != -1) { csPtr->toRead -= size; } csPtr->total += size; /* * For background copies, we only do one buffer per invocation so * we don't starve the rest of the system. */ if (cmdPtr) { /* * The first time we enter this code, there won't be a * channel handler established yet, so do it here. */ if (mask == 0) { Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } } /* * Make the callback or return the number of bytes transferred. * The local total is used because StopCopy frees csPtr. */ total = csPtr->total; if (cmdPtr) { /* * Get a private copy of the command so we can mutate it * by adding arguments. Note that StopCopy frees our saved * reference to the original command obj. */ cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); StopCopy(csPtr); Tcl_Preserve((ClientData) interp); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(total)); if (errObj) { Tcl_ListObjAppendElement(interp, cmdPtr, errObj); } if (Tcl_EvalObj(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) { 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; } /* *---------------------------------------------------------------------- * * 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 * the background copy operation. It is just a trivial wrapper * around the CopyData routine. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void CopyEventProc(clientData, mask) ClientData clientData; int mask; { (void) CopyData((CopyState *)clientData, mask); } /* *---------------------------------------------------------------------- * * StopCopy -- * * This routine halts a copy that is in progress. * * Results: * None. * * Side effects: * Removes any pending channel handlers and restores the blocking * and buffering modes of the channels. The CopyState is freed. * *---------------------------------------------------------------------- */ static void StopCopy(csPtr) CopyState *csPtr; /* State for bg copy to stop . */ { int nonBlocking; if (!csPtr) { return; } /* * Restore the old blocking mode and output buffering mode. */ nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING); if (nonBlocking != (csPtr->readPtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->readPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } if (csPtr->writePtr != csPtr->writePtr) { if (nonBlocking != (csPtr->writePtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->writePtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } } csPtr->writePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); csPtr->writePtr->flags |= csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc, (ClientData)csPtr); if (csPtr->readPtr != csPtr->writePtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr, CopyEventProc, (ClientData)csPtr); } 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; } trf2.1.4/patches/v8.1a2/tcl.h0000644000175000017500000021434411216344361015064 0ustar sergeisergei/* * 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. * * 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.352 98/02/19 13:53:28 */ #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 * win/pkgIndex.tcl (for tclregNN.dll) * README * mac/README * win/README * unix/README * * 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 1 #define TCL_RELEASE_LEVEL 0 #define TCL_RELEASE_SERIAL 2 #define TCL_VERSION "8.1" #define TCL_PATCH_LEVEL "8.1a2" /* * The following definitions set up the proper options for Windows * compilers. We use this method because there is no autoconf equivalent. */ #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) # define __WIN32__ # endif #endif #ifdef __WIN32__ # ifndef STRICT # define STRICT # endif # ifndef USE_PROTOTYPE # define USE_PROTOTYPE 1 # 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 # define INLINE #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 /* * 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. */ #ifndef RESOURCE_INCLUDED #ifndef BUFSIZ #include #endif /* * Definitions that allow Tcl functions with variable numbers of * arguments to be used with either varargs.h or stdarg.h. TCL_VARARGS * is used in procedure prototypes. TCL_VARARGS_DEF is used to declare * 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 #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" #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. */ #ifndef __WIN32__ #ifndef VOID # ifdef __STDC__ # define VOID void # else # define VOID char # endif #endif #else /* __WIN32__ */ /* * The following code is copied from winnt.h */ #ifndef VOID #define VOID void typedef char CHAR; typedef short SHORT; typedef long LONG; #endif #endif /* __WIN32__ */ /* * Miscellaneous declarations. */ #ifndef NULL #define NULL 0 #endif #ifndef _CLIENTDATA # if defined(__STDC__) || defined(__cplusplus) typedef void *ClientData; # else typedef int *ClientData; # endif /* __STDC__ */ #define _CLIENTDATA #endif /* * Data structures defined opaquely in this module. The definitions below * just provide dummy types. A few fields are made visible in Tcl_Interp * structures, namely those used for returning a string result from * commands. Direct access to the result field is discouraged in Tcl 8.0. * The interpreter result is either an object or a string, and the two * values are kept consistent unless some C code sets interp->result * directly. Programmers should use either the procedure Tcl_GetObjResult() * or Tcl_GetStringResult() to read the interpreter's result. See the * SetResult man page for details. * * Note: any change to the Tcl_Interp definition below must be mirrored * in the "real" definition in tclInt.h. * * Note: Tcl_ObjCmdProc procedures do not directly set result and freeProc. * Instead, they set a Tcl_Obj member in the "real" structure that can be * accessed with Tcl_GetObjResult() and Tcl_SetObjResult(). */ typedef struct Tcl_Interp { char *result; /* If the last command returned a string * result, this points to it. */ void (*freeProc) _ANSI_ARGS_((char *blockPtr)); /* Zero means the string result is * statically allocated. TCL_DYNAMIC means * it was allocated with ckalloc and should * be freed with ckfree. Other values give * the address of procedure to invoke to * free the result. Tcl_Eval must free it * before executing next command. */ int errorLine; /* When TCL_ERROR is returned, this gives * 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 * procedures Tcl_GetObjResult() or Tcl_GetStringResult() to read the * interpreter's result. See the SetResult man page for details. Besides * this result, the command procedure returns an integer code, which is * one of the following: * * TCL_OK Command completed normally; the interpreter's * result contains the command's result. * TCL_ERROR The command couldn't be completed successfully; * the interpreter's result describes what went wrong. * TCL_RETURN The command requests that the current procedure * return; the interpreter's result contains the * procedure's return value. * TCL_BREAK The command requests that the innermost loop * be exited; the interpreter's result is meaningless. * TCL_CONTINUE Go on to the next iteration of the current loop; * the interpreter's result is meaningless. */ #define TCL_OK 0 #define TCL_ERROR 1 #define TCL_RETURN 2 #define TCL_BREAK 3 #define TCL_CONTINUE 4 #define TCL_RESULT_SIZE 200 /* * Argument descriptors for math function callbacks in expressions: */ typedef enum {TCL_INT, TCL_DOUBLE, TCL_EITHER} Tcl_ValueType; typedef struct Tcl_Value { Tcl_ValueType type; /* Indicates intValue or doubleValue is * valid, or both. */ long intValue; /* Integer value. */ double doubleValue; /* Double-precision floating value. */ } Tcl_Value; /* * Forward declaration of Tcl_Obj to prevent an error when the forward * reference to Tcl_Obj is encountered in the procedure types declared * below. */ struct Tcl_Obj; /* * Procedure types defined by Tcl: */ typedef int (Tcl_AppInitProc) _ANSI_ARGS_((Tcl_Interp *interp)); typedef int (Tcl_AsyncProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int code)); typedef void (Tcl_ChannelProc) _ANSI_ARGS_((ClientData clientData, int mask)); typedef void (Tcl_CloseProc) _ANSI_ARGS_((ClientData data)); typedef void (Tcl_CmdDeleteProc) _ANSI_ARGS_((ClientData clientData)); 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_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, Tcl_Interp *interp, char *part1, char *part2, int flags)); /* * The following structure represents a type of object, which is a * particular internal representation for an object plus a set of * procedures that provide standard operations on objects of that type. */ typedef struct Tcl_ObjType { char *name; /* Name of the type, e.g. "int". */ Tcl_FreeInternalRepProc *freeIntRepProc; /* Called to free any storage for the type's * internal rep. NULL if the internal rep * does not need freeing. */ Tcl_DupInternalRepProc *dupIntRepProc; /* Called to create a new object as a copy * of an existing object. */ Tcl_UpdateStringProc *updateStringProc; /* Called to update the string rep from the * type's internal representation. */ Tcl_SetFromAnyProc *setFromAnyProc; /* Called to convert the object's internal * rep to this type. Frees the internal rep * of the old type. Returns TCL_ERROR on * failure. */ } Tcl_ObjType; /* * One of the following structures exists for each object in the Tcl * system. An object stores a value as either a string, some internal * representation, or both. */ typedef struct Tcl_Obj { int refCount; /* When 0 the object will be freed. */ char *bytes; /* This points to the first byte of the * object's string representation. The array * 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: */ long longValue; /* - an long integer value */ double doubleValue; /* - a double-precision floating value */ VOID *otherValuePtr; /* - another, type-specific value */ struct { /* - internal rep as two pointers */ VOID *ptr1; VOID *ptr2; } twoPtrValue; } internalRep; } Tcl_Obj; /* * Macros to increment and decrement a Tcl_Obj's reference count, and to * test whether an object is shared (i.e. has reference count > 1). * Note: clients should use Tcl_DecrRefCount() when they are finished using * an object, and should never call TclFreeObj() directly. TclFreeObj() is * only defined and made public in tcl.h to support Tcl_DecrRefCount's macro * definition. Note also that Tcl_DecrRefCount() refers to the parameter * "obj" twice. This means that you should avoid calling it with an * expression that is expensive to compute or has side effects. */ EXTERN void Tcl_IncrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN void Tcl_DecrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN int Tcl_IsShared _ANSI_ARGS_((Tcl_Obj *objPtr)); #ifdef TCL_MEM_DEBUG # define Tcl_IncrRefCount(objPtr) \ Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_DecrRefCount(objPtr) \ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_IsShared(objPtr) \ Tcl_DbIsShared(objPtr, __FILE__, __LINE__) #else # define Tcl_IncrRefCount(objPtr) \ ++(objPtr)->refCount # define Tcl_DecrRefCount(objPtr) \ 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_NewByteArrayObj _ANSI_ARGS_((unsigned char *bytes, int length)); 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_((CONST 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 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). */ typedef struct Tcl_Namespace { char *name; /* The namespace's name within its parent * namespace. This contains no ::'s. The * name of the global namespace is "" * although "::" is an synonym. */ char *fullName; /* The namespace's fully qualified name. * This starts with ::. */ ClientData clientData; /* Arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc* deleteProc; /* Procedure invoked when deleting the * namespace to, e.g., free clientData. */ struct Tcl_Namespace* parentPtr; /* Points to the namespace that contains * this one. NULL if this is the global * namespace. */ } Tcl_Namespace; /* * The following structure represents a call frame, or activation record. * A call frame defines a naming context for a procedure call: its local * scope (for local variables) and its namespace scope (used for non-local * variables; often 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 command's code should execute. The * Tcl_CallFrame structures exist only while procedures or namespace * eval/inscope's are being executed, and provide a Tcl call stack. * * A call frame is initialized and pushed using Tcl_PushCallFrame and * popped using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be * provided by the Tcl_PushCallFrame caller, and callers typically allocate * them on the C call stack for efficiency. For this reason, Tcl_CallFrame * is defined as a structure and not as an opaque token. However, most * Tcl_CallFrame fields are hidden since applications should not access * them directly; others are declared as "dummyX". * * WARNING!! The structure definition must be kept consistent with the * CallFrame structure in tclInt.h. If you change one, change the other. */ typedef struct Tcl_CallFrame { Tcl_Namespace *nsPtr; int dummy1; int dummy2; char *dummy3; char *dummy4; char *dummy5; int dummy6; char *dummy7; char *dummy8; int dummy9; char* dummy10; } Tcl_CallFrame; /* * Information about commands that is returned by Tcl_GetCommandInfo and * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based * command procedure while proc is a traditional Tcl argc/argv * string-based procedure. Tcl_CreateObjCommand and Tcl_CreateCommand * ensure that both objProc and proc are non-NULL and can be called to * execute the command. However, it may be faster to call one instead of * the other. The member isNativeObjectProc is set to 1 if an * object-based procedure was registered by Tcl_CreateObjCommand, and to * 0 if a string-based procedure was registered by Tcl_CreateCommand. * The other procedure is typically set to a compatibility wrapper that * does string-to-object or object-to-string argument conversions then * calls the other procedure. */ typedef struct Tcl_CmdInfo { int isNativeObjectProc; /* 1 if objProc was registered by a call to * Tcl_CreateObjCommand; 0 otherwise. * Tcl_SetCmdInfo does not modify this * field. */ Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ ClientData objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based procedure. */ ClientData clientData; /* ClientData for string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure to call when command is * deleted. */ ClientData deleteData; /* Value to pass to deleteProc (usually * the same as clientData). */ Tcl_Namespace *namespacePtr; /* Points to the namespace that contains * this command. Note that Tcl_SetCmdInfo * will not change a command's namespace; * use Tcl_RenameCommand to do that. */ } Tcl_CmdInfo; /* * The structure defined below is used to hold dynamic strings. The only * field that clients should use is the string field, and they should * never modify it. */ #define TCL_DSTRING_STATIC_SIZE 200 typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ int length; /* Number of non-NULL characters in the * string. */ int spaceAvl; /* Total number of bytes available for the * string and its terminating NULL char. */ char staticSpace[TCL_DSTRING_STATIC_SIZE]; /* Space to use in common case where string * is small. */ } Tcl_DString; #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) #define TCL_STATIC ((Tcl_FreeProc *) 0) #define TCL_DYNAMIC ((Tcl_FreeProc *) 3) /* * Flag values passed to variable-related procedures. */ #define TCL_GLOBAL_ONLY 1 #define TCL_NAMESPACE_ONLY 2 #define TCL_APPEND_VALUE 4 #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 0x400 /* * 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 /* * 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)); EXTERN void Tcl_InitMemory _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int Tcl_DumpActiveMemory _ANSI_ARGS_((char *fileName)); EXTERN void Tcl_ValidateAllMemory _ANSI_ARGS_((char *file, int line)); #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__) #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_InitMemory(x) # 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 struct Tcl_HashTable; #endif /* * Structure definition for an entry in a hash table. No-one outside * Tcl should access any of these fields directly; use the macros * defined below. */ typedef struct Tcl_HashEntry { struct Tcl_HashEntry *nextPtr; /* Pointer to next entry in this * hash bucket, or NULL for end of * chain. */ struct Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */ struct Tcl_HashEntry **bucketPtr; /* Pointer to bucket that points to * first entry in this entry's chain: * used for deleting the entry. */ ClientData clientData; /* Application stores something here * with Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ int words[1]; /* Multiple integer words for key. * The actual size will be as large * as necessary for this table's * keys. */ char string[4]; /* String for key. The actual size * will be as large as needed to hold * the key. */ } key; /* MUST BE LAST FIELD IN RECORD!! */ } Tcl_HashEntry; /* * Structure definition for a hash table. Must be in tcl.h so clients * can allocate space for these structures, but clients should never * access any fields in this structure. */ #define TCL_SMALL_HASH_TABLE 4 typedef struct Tcl_HashTable { Tcl_HashEntry **buckets; /* Pointer to bucket array. Each * element points to first entry in * bucket's hash chain, or NULL. */ Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables * (to avoid mallocs and frees). */ int numBuckets; /* Total number of buckets allocated * at **bucketPtr. */ int numEntries; /* Total number of entries present * in table. */ int rebuildSize; /* Enlarge table when numEntries gets * to be this large. */ int downShift; /* Shift count used in hashing * function. Designed to use high- * order bits of randomized keys. */ int mask; /* Mask value used in hashing * function. */ int keyType; /* Type of keys used in this table. * It's either TCL_STRING_KEYS, * TCL_ONE_WORD_KEYS, or an integer * giving the number of ints that * is the size of the key. */ Tcl_HashEntry *(*findProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key)); Tcl_HashEntry *(*createProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key, int *newPtr)); } Tcl_HashTable; /* * Structure definition for information used to keep track of searches * through hash tables: */ typedef struct Tcl_HashSearch { Tcl_HashTable *tablePtr; /* Table being searched. */ int nextIndex; /* Index of next bucket to be * enumerated after present one. */ Tcl_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the * the current bucket. */ } Tcl_HashSearch; /* * Acceptable key types for hash tables: */ #define TCL_STRING_KEYS 0 #define TCL_ONE_WORD_KEYS 1 /* * Macros for clients to use to access fields of hash entries: */ #define Tcl_GetHashValue(h) ((h)->clientData) #define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value)) #define Tcl_GetHashKey(tablePtr, h) \ ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS) ? (h)->key.oneWordValue \ : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create procedures * for hash tables: */ #define Tcl_FindHashEntry(tablePtr, key) \ (*((tablePtr)->findProc))(tablePtr, key) #define Tcl_CreateHashEntry(tablePtr, key, newPtr) \ (*((tablePtr)->createProc))(tablePtr, key, newPtr) /* * Flag values to pass to Tcl_DoOneEvent to disable searches * for some kinds of events: */ #define TCL_DONT_WAIT (1<<1) #define TCL_WINDOW_EVENTS (1<<2) #define TCL_FILE_EVENTS (1<<3) #define TCL_TIMER_EVENTS (1<<4) #define TCL_IDLE_EVENTS (1<<5) /* WAS 0x10 ???? */ #define TCL_ALL_EVENTS (~TCL_DONT_WAIT) /* * The following structure defines a generic event for the Tcl event * system. These are the things that are queued in calls to Tcl_QueueEvent * and serviced later by Tcl_DoOneEvent. There can be many different * kinds of events with different fields, corresponding to window events, * timer events, etc. The structure for a particular event consists of * a Tcl_Event header followed by additional information specific to that * event. */ struct Tcl_Event { Tcl_EventProc *proc; /* Procedure to call to service this event. */ struct Tcl_Event *nextPtr; /* Next in list of pending events, or NULL. */ }; /* * Positions to pass to Tcl_QueueEvent: */ typedef enum { TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK } Tcl_QueuePosition; /* * Values to pass to Tcl_SetServiceMode to specify the behavior of notifier * event routines. */ #define TCL_SERVICE_NONE 0 #define TCL_SERVICE_ALL 1 /* * The following structure keeps is used to hold a time value, either as * an absolute time (the number of seconds from the epoch) or as an * elapsed time. On Unix systems the epoch is Midnight Jan 1, 1970 GMT. * On Macintosh systems the epoch is Midnight Jan 1, 1904 GMT. */ typedef struct Tcl_Time { long sec; /* Seconds. */ long usec; /* Microseconds. */ } Tcl_Time; /* * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler * to indicate what sorts of events are of interest: */ #define TCL_READABLE (1<<1) #define TCL_WRITABLE (1<<2) #define TCL_EXCEPTION (1<<3) /* * Flag values to pass to Tcl_OpenCommandChannel to indicate the * disposition of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, * are also used in Tcl_GetStdChannel. */ #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)); /* * 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. */ TCL_TRANSLATE_LF, /* Eol == \n. */ TCL_TRANSLATE_CRLF /* Eol == \r\n. */ } Tcl_EolTranslation; /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. * It collects together in one place all the functions that are * part of the specific channel type. */ 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. */ #define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */ #define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking * mode. */ /* * Enum for different types of file paths. */ 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 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; /* * Exported Tcl procedures: */ EXTERN void Tcl_AddErrorInfo _ANSI_ARGS_((Tcl_Interp *interp, CONST char *message)); EXTERN void Tcl_AddObjErrorInfo _ANSI_ARGS_((Tcl_Interp *interp, CONST 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, CONST char *string)); EXTERN void Tcl_AppendResult _ANSI_ARGS_( TCL_VARARGS(Tcl_Interp *,interp)); EXTERN void Tcl_AppendObjToObj _ANSI_ARGS_((Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr)); 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 void Tcl_AlertNotifier _ANSI_ARGS_((ClientData clientData)); 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 Tcl_Encoding Tcl_CreateEncoding _ANSI_ARGS_(( Tcl_EncodingType *typePtr)); 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 void Tcl_CreateThreadExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc, ClientData clientData)); 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_((CONST 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_DeleteThreadExitHandler _ANSI_ARGS_((Tcl_ExitProc *proc, ClientData clientData)); 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_DiscardResult _ANSI_ARGS_(( Tcl_SavedResult *statePtr)); 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_Eval2 _ANSI_ARGS_((Tcl_Interp *interp, char *script, int numBytes, int flags)); EXTERN int Tcl_EvalFile _ANSI_ARGS_((Tcl_Interp *interp, char *fileName)); EXTERN int Tcl_EvalObjv _ANSI_ARGS_ ((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], char *string, int length, int flags)); EXTERN int Tcl_EvalObj _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)); EXTERN void Tcl_EventuallyFree _ANSI_ARGS_((ClientData clientData, Tcl_FreeProc *freeProc)); EXTERN void Tcl_Exit _ANSI_ARGS_((int status)); EXTERN void Tcl_ExitThread _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 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)); EXTERN char * Tcl_ExternalToUtfDString _ANSI_ARGS_(( Tcl_Encoding encoding, CONST char *src, int srcLen, Tcl_DString *dsPtr)); EXTERN void Tcl_Finalize _ANSI_ARGS_((void)); EXTERN void Tcl_FinalizeThread _ANSI_ARGS_((void)); EXTERN void Tcl_FinalizeNotifier _ANSI_ARGS_(( ClientData clientData)); EXTERN void Tcl_FindExecutable _ANSI_ARGS_((CONST 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 Tcl_FreeEncoding _ANSI_ARGS_((Tcl_Encoding encoding)); 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 unsigned char * Tcl_GetByteArrayFromObj _ANSI_ARGS_(( Tcl_Obj *objPtr, int *lengthPtr)); EXTERN Tcl_Channel Tcl_GetChannel _ANSI_ARGS_((Tcl_Interp *interp, char *chanName, int *modePtr)); EXTERN int Tcl_GetChannelBufferSize _ANSI_ARGS_(( Tcl_Channel chan)); /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ EXTERN int Tcl_GetChannelByteorder _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 Tcl_ThreadId Tcl_GetCurrentThread _ANSI_ARGS_((void)); 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 Tcl_Encoding Tcl_GetEncoding _ANSI_ARGS_((Tcl_Interp *interp, CONST char *name)); EXTERN char * Tcl_GetEncodingName _ANSI_ARGS_(( Tcl_Encoding encoding)); EXTERN void Tcl_GetEncodingNames _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN Tcl_Obj * Tcl_GetEncodingPath _ANSI_ARGS_((void)); 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_GetIndexFromObjStruct _ANSI_ARGS_(( Tcl_Interp *interp, Tcl_Obj *objPtr, char **tablePtr, int offset, 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_Obj * Tcl_GetObjVar2 _ANSI_ARGS_((Tcl_Interp *interp, char *part1, char *part2, int flags)); 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_GetString _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN char * Tcl_GetStringFromObj _ANSI_ARGS_((Tcl_Obj *objPtr, int *lengthPtr)); EXTERN char * Tcl_GetStringResult _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN VOID * Tcl_GetThreadData _ANSI_ARGS_(( Tcl_ThreadDataKey *keyPtr, int size)); 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 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 ClientData Tcl_InitNotifier _ANSI_ARGS_((void)); 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)); #ifdef TCL_THREADS EXTERN void Tcl_MutexLock _ANSI_ARGS_((Tcl_Mutex *mutexPtr)); EXTERN void Tcl_MutexUnlock _ANSI_ARGS_((Tcl_Mutex *mutexPtr)); EXTERN void Tcl_ConditionNotify _ANSI_ARGS_((Tcl_Condition *condPtr)); EXTERN void Tcl_ConditionWait _ANSI_ARGS_((Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, Tcl_Time *timePtr)); #else #define Tcl_MutexLock(mutexPtr) #define Tcl_MutexUnlock(mutexPtr) #define Tcl_ConditionNotify(condPtr) #define Tcl_ConditionWait(condPtr, mutexPtr, timePtr) #endif /* TCL_THREADS */ EXTERN Tcl_HashEntry * Tcl_NextHashEntry _ANSI_ARGS_(( Tcl_HashSearch *searchPtr)); EXTERN void Tcl_NotifyChannel _ANSI_ARGS_((Tcl_Channel channel, int mask)); EXTERN int Tcl_NumUtfChars _ANSI_ARGS_((CONST char *src, int len)); 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 int Tcl_ReadChars _ANSI_ARGS_((Tcl_Channel channel, Tcl_Obj *objPtr, int charsToRead, int appendFlag)); 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, CONST char *string, CONST 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)); EXTERN void Tcl_RestoreResult _ANSI_ARGS_((Tcl_Interp *interp, Tcl_SavedResult *statePtr)); #define Tcl_Return Tcl_SetResult EXTERN void Tcl_SaveResult _ANSI_ARGS_((Tcl_Interp *interp, Tcl_SavedResult *statePtr)); 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 unsigned char * Tcl_SetByteArrayLength _ANSI_ARGS_((Tcl_Obj *objPtr, int length)); EXTERN void Tcl_SetByteArrayObj _ANSI_ARGS_((Tcl_Obj *objPtr, unsigned char *bytes, int length)); 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 Tcl_Obj * Tcl_SetObjVar2 _ANSI_ARGS_((Tcl_Interp *interp, char *part1, char *part2, Tcl_Obj *newValuePtr, int flags)); 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 int Tcl_SetSystemEncoding _ANSI_ARGS_((Tcl_Interp *interp, CONST char *name)); 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, CONST char *list, int *argcPtr, char ***argvPtr)); EXTERN void Tcl_SplitPath _ANSI_ARGS_((CONST 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_((CONST char *string, CONST char *pattern)); EXTERN int Tcl_Tell _ANSI_ARGS_((Tcl_Channel chan)); EXTERN void Tcl_ThreadAlert _ANSI_ARGS_((Tcl_ThreadId threadId)); EXTERN void Tcl_ThreadQueueEvent _ANSI_ARGS_(( Tcl_ThreadId threadId, Tcl_Event* evPtr, Tcl_QueuePosition position)); #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 Tcl_UniChar Tcl_UniCharAtIndex _ANSI_ARGS_((CONST char *src, int index)); EXTERN Tcl_UniChar Tcl_UniCharToLower _ANSI_ARGS_((int ch)); EXTERN Tcl_UniChar Tcl_UniCharToTitle _ANSI_ARGS_((int ch)); EXTERN Tcl_UniChar Tcl_UniCharToUpper _ANSI_ARGS_((int ch)); EXTERN int Tcl_UniCharToUtf _ANSI_ARGS_((int ch, char *buf)); 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 char * Tcl_UtfAtIndex _ANSI_ARGS_((CONST char *src, int index)); EXTERN int Tcl_UtfCharComplete _ANSI_ARGS_((CONST char *src, int len)); EXTERN int Tcl_UtfBackslash _ANSI_ARGS_((CONST char *src, int *readPtr, char *dst)); EXTERN char * Tcl_UtfFindFirst _ANSI_ARGS_((CONST char *src, int ch)); EXTERN char * Tcl_UtfFindLast _ANSI_ARGS_((CONST char *src, int ch)); EXTERN int Tcl_UtfIsLower _ANSI_ARGS_((CONST char *src)); EXTERN int Tcl_UtfIsUpper _ANSI_ARGS_((CONST char *src)); EXTERN char * Tcl_UtfNext _ANSI_ARGS_((CONST char *src)); EXTERN char * Tcl_UtfPrev _ANSI_ARGS_((CONST char *src, CONST char *start)); 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)); EXTERN char * Tcl_UtfToExternalDString _ANSI_ARGS_(( Tcl_Encoding encoding, CONST char *src, int srcLen, Tcl_DString *dsPtr)); EXTERN int Tcl_UtfToLower _ANSI_ARGS_((char *src)); EXTERN int Tcl_UtfToTitle _ANSI_ARGS_((char *src)); EXTERN int Tcl_UtfToUniChar _ANSI_ARGS_((CONST char *src, Tcl_UniChar *chPtr)); EXTERN int Tcl_UtfToUpper _ANSI_ARGS_((char *src)); 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 *src, int srcLen)); EXTERN int Tcl_WriteChars _ANSI_ARGS_((Tcl_Channel chan, CONST char *src, int srcLen)); EXTERN int Tcl_WriteObj _ANSI_ARGS_((Tcl_Channel chan, Tcl_Obj *objPtr)); EXTERN void Tcl_WrongNumArgs _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], char *message)); /* Andreas Kupries , 05/31/1997. * Support for Tcl-Trf (channel interceptors). */ EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_ChannelType* typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_Channel chan)); #endif /* RESOURCE_INCLUDED */ #endif /* _TCL */ trf2.1.4/patches/v8.0.4/0000755000175000017500000000000011216344734014043 5ustar sergeisergeitrf2.1.4/patches/v8.0.4/standard.patch0000644000175000017500000002707011216344361016666 0ustar sergeisergei*** tcl.h.orig Fri Oct 23 23:21:39 1998 --- tcl.h Sun Mar 14 16:31:36 1999 *************** *** 1547,1552 **** --- 1547,1574 ---- EXTERN void Tcl_WrongNumArgs _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], char *message)); + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * C-Level API for (un)stacking of channels. This allows the introduction + * of filtering channels with relatively little changes to the core. + * This patch was created in cooperation with Jan Nijtmans + * and is therefore part of his plus-patches too. + * + * It would have been possible to place the following definitions according + * to the alphabetical order used elsewhere in this file, but I decided + * against that to ease the maintenance of the patch across new tcl versions + * (patch usually has no problems to integrate the patch file for the last + * version into the new one). + */ + + EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_ChannelType* typePtr, ClientData instanceData, + int mask, Tcl_Channel prevChan)); + + EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, + Tcl_Channel chan)); + #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS *** tclIO.c.orig Fri Oct 30 01:38:38 1998 --- tclIO.c Sun Mar 14 16:35:19 1999 *************** *** 170,175 **** --- 170,197 ---- int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ + + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * The single change to the internal datastructures of the core. Every + * channel now maintains a reference to the channel he is stacked upon. + * This reference is NULL for normal channels. Only the two exported + * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the + * end of 'tcl.h') use this field in a non-trivial way. + * + * Of the existing procedures the only following are affected by this + * change: + * + * - Tcl_RegisterChannel + * - Tcl_CreateChannel + * - CloseChannel + * + * The why is explained at the changed locations. + */ + struct Channel* supercedes; /* Refers to channel this one was stacked upon */ + } Channel; /* *************** *** 1067,1073 **** if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! panic("Tcl_RegisterChannel: duplicate channel names"); } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } --- 1089,1108 ---- if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) { return; } ! /* Andreas Kupries , 05/31/1997. ! * "Trf-Patch for filtering channels" ! * ! * This is the change to 'Tcl_RegisterChannel'. ! * ! * Explanation: ! * The moment a channel is stacked upon another he ! * takes the identity of the channel he supercedes, ! * i.e. he gets the *same* name. Because of this we ! * cannot check for duplicate names anymore, they ! * have to be allowed now. ! */ ! ! /* panic("Tcl_RegisterChannel: duplicate channel names"); */ } Tcl_SetHashValue(hPtr, (ClientData) chanPtr); } *************** *** 1218,1223 **** --- 1253,1272 ---- chanPtr->timer = NULL; chanPtr->csPtr = NULL; + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * This is the change to 'Tcl_CreateChannel'. + * + * Explanation: + * It is of course necessary to initialize the new field + * in the Channel structure. The chosen value indicates + * that the created channel is a normal one, and not + * stacked upon another. + */ + + chanPtr->supercedes = (Channel*) 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 *************** *** 1250,1255 **** --- 1299,1490 ---- return (Tcl_Channel) chanPtr; } + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * The following two procedures are the new, exported ones. They + * - create a channel stacked upon an existing one and + * - pop a stacked channel off, thus revealing the superceded one. + * + * Please read the following completely. + */ + /* + *---------------------------------------------------------------------- + * + * Tcl_ReplaceChannel -- + * + * Replaces an entry in the hash table for a Tcl_Channel + * record. + * + * Results: + * Returns the new Tcl_Channel. + * + * Side effects: + * Replaces a Tcl_Channel instance into the hash table. + * + *---------------------------------------------------------------------- + */ + + Tcl_Channel + Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) + Tcl_Interp* interp; /* the interpreter we are working in */ + Tcl_ChannelType *typePtr; /* The channel type record. */ + ClientData instanceData; /* Instance specific data. */ + int mask; /* TCL_READABLE & TCL_WRITABLE to indicate + * if the channel is readable, writable. */ + Tcl_Channel prevChan; /* The channel structure that should + * be replaced. */ + { + Channel *chanPtr, *pt, *prevPt; + + /* + * Replace the channel into the list of all channels; + */ + + prevPt = (Channel*) NULL; + pt = (Channel*) firstChanPtr; + + while (pt != (Channel *) prevChan) { + prevPt = pt; + pt = pt->nextChanPtr; + } + + if (!pt) { + return (Tcl_Channel) NULL; + } + + /* + * Here we check if the "mask" matches the "flags" + * of the already existing channel. + * + * | - | R | W | RW | + * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) + * - | | | | | + * R | | + | | + | The superceding channel is allowed to + * W | | | + | + | restrict the capabilities of the + * RW| | + | + | + | superceded one ! + * --+---+---+---+----+ + */ + + if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { + return (Tcl_Channel) NULL; + } + + + chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); + chanPtr->flags = mask; + + /* + * Set the channel up initially in no Input translation mode and + * no Output translation mode. + */ + + chanPtr->inputTranslation = TCL_TRANSLATE_LF; + chanPtr->outputTranslation = TCL_TRANSLATE_LF; + chanPtr->inEofChar = 0; + chanPtr->outEofChar = 0; + + chanPtr->unreportedError = 0; + chanPtr->instanceData = instanceData; + chanPtr->typePtr = typePtr; + chanPtr->refCount = 0; + chanPtr->closeCbPtr = (CloseCallback *) NULL; + chanPtr->curOutPtr = (ChannelBuffer *) NULL; + chanPtr->outQueueHead = (ChannelBuffer *) NULL; + chanPtr->outQueueTail = (ChannelBuffer *) NULL; + chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; + chanPtr->inQueueHead = (ChannelBuffer *) NULL; + 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->supercedes = (Channel*) prevChan; + + chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); + strcpy (chanPtr->channelName, pt->channelName); + + if (prevPt) { + prevPt->nextChanPtr = chanPtr; + } else { + firstChanPtr = chanPtr; + } + + chanPtr->nextChanPtr = pt->nextChanPtr; + + + Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); + + /* The superceded channel is effectively unregistered */ + /*chanPtr->supercedes->refCount --;*/ + + return (Tcl_Channel) chanPtr; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_UndoReplaceChannel -- + * + * Unstacks an entry in the hash table for a Tcl_Channel + * record. + * + * Results: + * Returns the old Tcl_Channel, i.e. the one which was stacked over. + * + * Side effects: + * Replaces a Tcl_Channel instance into the hash table. + * + *---------------------------------------------------------------------- + */ + + void + Tcl_UndoReplaceChannel (interp, chan) + Tcl_Interp* interp; /* The interpreter we are working in */ + Tcl_Channel chan; /* The channel to unstack */ + { + Channel* chanPtr = (Channel*) chan; + + if (chanPtr->supercedes != (Channel*) NULL) { + Tcl_HashTable *hTblPtr; /* Hash table of channels. */ + Tcl_HashEntry *hPtr; /* Search variable. */ + int new; /* Is the hash entry new or does it exist? */ + + /* + * Insert the channel we were stacked upon back into + * the list of open channels. Place it back into the hashtable too. + * Correct 'refCount', as this actually unregisters 'chan'. + */ + + chanPtr->supercedes->nextChanPtr = firstChanPtr; + firstChanPtr = chanPtr->supercedes; + + hTblPtr = GetChannelTable (interp); + hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); + + Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); + chanPtr->refCount --; + + /* The superceded channel is effectively registered again */ + /*chanPtr->supercedes->refCount ++;*/ + } + + /* + * Disconnect the channels, then do a regular close upon the + * stacked one. This may cause flushing of data into the + * superceded channel (if 'chan' remembered its parent in itself). + */ + + chanPtr->supercedes = NULL; + + if (chanPtr->refCount == 0) { + Tcl_Close (interp, chan); + } + } + /* *---------------------------------------------------------------------- * *************** *** 1863,1868 **** --- 2098,2138 ---- if (errorCode != 0) { Tcl_SetErrno(errorCode); } + } + + /* Andreas Kupries , 05/31/1997. + * "Trf-Patch for filtering channels" + * + * This is the change to 'CloseChannel'. + * + * Explanation + * Closing a filtering channel closes the one it + * superceded too. This basically ripples through + * the whole chain of filters until it reaches + * the underlying normal channel. + * + * This is done by reintegrating the superceded + * channel into the (thread) global list of open + * channels and then invoking a regular close. + * There is no need to handle the complexities of + * this process by ourselves. + * + * *Note* + * This has to be done after the call to the + * 'closeProc' of the filtering channel to allow + * that one the flushing of internal buffers into + * the underlying channel. + */ + + if (chanPtr->supercedes != (Channel*) NULL) { + /* Insert the channel we were stacked upon back into + * the list of open channels, then do a regular close. + */ + + chanPtr->supercedes->nextChanPtr = firstChanPtr; + firstChanPtr = chanPtr->supercedes; + chanPtr->supercedes->refCount --; /* is deregistered */ + Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* trf2.1.4/patches/v8.0.4/byteorder.patch0000644000175000017500000001431111216344361017057 0ustar sergeisergei*** tcl.h.orig Sun Mar 14 16:37:27 1999 --- tcl.h Sun Mar 14 16:38:27 1999 *************** *** 984,989 **** --- 984,1001 ---- } Tcl_EolTranslation; /* + * Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + * + * Enum for different byteorders. + */ + + typedef enum Tcl_ByteOrder { + TCL_BIGENDIAN, /* Multibyte words are stored with MSB first */ + TCL_SMALLENDIAN /* Multibyte words are stored with MSB last */ + } Tcl_ByteOrder; + + /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. *************** *** 1268,1273 **** --- 1280,1291 ---- char *chanName, int *modePtr)); EXTERN int Tcl_GetChannelBufferSize _ANSI_ARGS_(( Tcl_Channel chan)); + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + EXTERN Tcl_ByteOrder Tcl_GetChannelByteorder _ANSI_ARGS_(( + Tcl_Channel chan)); + EXTERN Tcl_ByteOrder Tcl_GetHostByteorder _ANSI_ARGS_((void)); EXTERN int Tcl_GetChannelHandle _ANSI_ARGS_((Tcl_Channel chan, int direction, ClientData *handlePtr)); EXTERN ClientData Tcl_GetChannelInstanceData _ANSI_ARGS_(( *** tclIO.c.orig Sun Mar 14 16:37:27 1999 --- tclIO.c Sun Mar 14 16:38:28 1999 *************** *** 128,133 **** --- 128,137 ---- * code, is dynamically allocated. */ int flags; /* ORed combination of the flags defined * below. */ + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + Tcl_ByteOrder byteOrder; /* byteorder associated to this channel */ Tcl_EolTranslation inputTranslation; /* What translation to apply for end of line * sequences on input? */ *************** *** 1195,1200 **** --- 1199,1208 ---- * indicator (e.g. ^Z) and does not append an EOF indicator to files. */ + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + chanPtr->byteOrder = Tcl_GetHostByteorder (); chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; *************** *** 3947,3953 **** { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize eofchar translation"; char **argv; int argc, i; Tcl_DString ds; --- 3955,3961 ---- { if (interp) { CONST char *genericopt = ! "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; *************** *** 3980,3985 **** --- 3988,4048 ---- /* *---------------------------------------------------------------------- * + * Tcl_GetChannelByteorder -- + * + * Retrieves the byteorder set for this channel. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + Tcl_ByteOrder + Tcl_GetChannelByteorder(chan) + Tcl_Channel chan; /* The channel for which to find the + * buffer size. */ + { + Channel *chanPtr; + + chanPtr = (Channel *) chan; + return chanPtr->byteOrder; + } + + /* + *---------------------------------------------------------------------- + * + * Tcl_GetHostByteorder -- + * + * Retrieves the byteorder of the machine we are running on. + * + * Results: + * The size. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + Tcl_ByteOrder + Tcl_GetHostByteorder() + { + union { + char c[sizeof(short)]; + short s; + } order; + + order.s = 1; + return (order.c[0] == 1) ? TCL_SMALLENDIAN : TCL_BIGENDIAN; + } + + /* + *---------------------------------------------------------------------- + * * Tcl_GetChannelOption -- * * Gets a mode associated with an IO channel. If the optionName arg *************** *** 4081,4086 **** --- 4144,4163 ---- return TCL_OK; } } + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0))) { + if (len == 0) { + Tcl_DStringAppendElement(dsPtr, "-byteorder"); + } + Tcl_DStringAppendElement(dsPtr, + (chanPtr->byteOrder == TCL_BIGENDIAN) ? "bigendian" : "smallendian"); + if (len > 0) { + return TCL_OK; + } + } if ((len == 0) || ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-eofchar", len) == 0))) { *************** *** 4281,4286 **** --- 4358,4393 ---- chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; } return TCL_OK; + } + + /* Andreas Kupries , 05/31/1997. + * Support of Tcl-Trf (binio). + */ + if ((len > 2) && (optionName[1] == 'b') && + (strncmp(optionName, "-byteorder", len) == 0)) { + int nv_len = strlen (newValue); + + if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_SMALLENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { + chanPtr->byteOrder = TCL_BIGENDIAN; + return TCL_OK; + } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { + chanPtr->byteOrder = TCL_BIGENDIAN; + return TCL_OK; + } + + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, + "bad value for -byteorder: ", + "must be one of smallendian, littleendian, bigendian or network", + (char *) NULL); + } + return TCL_ERROR; } if ((len > 1) && (optionName[1] == 'e') && trf2.1.4/patches/v8.0.4/tclIO.c0000644000175000017500000060732311216344361015230 0ustar sergeisergei/* * 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.2 1999/04/18 13:27:01 aku 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. */ #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN))) # define EWOULDBLOCK EAGAIN #endif #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK))) # define EAGAIN EWOULDBLOCK #endif #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK))) error one of EWOULDBLOCK or EAGAIN must be defined #endif /* * The following structure encapsulates the state for a background channel * copy. Note that the data buffer for the copy will be appended to this * structure. */ typedef struct CopyState { struct Channel *readPtr; /* Pointer to input channel. */ struct Channel *writePtr; /* Pointer to output channel. */ int readFlags; /* Original read channel flags. */ int writeFlags; /* Original write channel flags. */ int toRead; /* Number of bytes to copy, or -1. */ int total; /* Total bytes transferred (written). */ Tcl_Interp *interp; /* Interp that started the copy. */ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */ int bufSize; /* Size of appended buffer. */ char buffer[1]; /* Copy buffer, this must be the last * field. */ } CopyState; /* * struct ChannelBuffer: * * Buffers data being sent to or from a channel. */ 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) /* * Structure to record a close callback. One such record exists for * each close callback registered for a channel. */ typedef struct CloseCallback { Tcl_CloseProc *proc; /* The procedure to call. */ ClientData clientData; /* Arbitrary one-word data to pass * to the callback. */ struct CloseCallback *nextPtr; /* For chaining close callbacks. */ } CloseCallback; /* * The following structure describes the information saved from a call to * "fileevent". This is used later when the event being waited for to * invoke the saved script in the interpreter designed in this record. */ 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; /* * struct Channel: * * One of these structures is allocated for each open channel. It contains data * specific to the channel but which belongs to the generic part of the Tcl * channel mechanism, and it points at an instance specific (and type * specific) * instance data, and at a channel type structure. */ 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. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ Tcl_ByteOrder byteOrder; /* byteorder associated to this channel */ 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. */ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ struct ChannelHandler *chPtr;/* List of channel handlers registered * for this channel. */ int interestMask; /* Mask of all events this channel has * handlers for. */ struct Channel *nextChanPtr;/* Next in list of channels currently open. */ EventScriptRecord *scriptRecordPtr; /* Chain of all scripts registered for * event handlers ("fileevent") on this * channel. */ int bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ CopyState *csPtr; /* State of background copy, or NULL. */ /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * The single change to the internal datastructures of the core. Every * channel now maintains a reference to the channel he is stacked upon. * This reference is NULL for normal channels. Only the two exported * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the * end of 'tcl.h') use this field in a non-trivial way. * * Of the existing procedures the only following are affected by this * change: * * - Tcl_RegisterChannel * - Tcl_CreateChannel * - CloseChannel * * The why is explained at the changed locations. */ struct Channel* supercedes; /* Refers to channel this one was stacked upon */ } Channel; /* * Values for the flags field in Channel. Any ORed combination of the * following flags can be stored in the field. These flags record various * options and state bits about the channel. In addition to the flags below, * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set. */ #define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in * nonblocking mode. */ #define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ #define BUFFER_READY (1<<6) /* Current output buffer (the * curOutPtr field in the * channel structure) should be * output as soon as possible even * though it may not be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the * queued output buffers has been * scheduled. */ #define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No * further Tcl-level IO on the * channel is allowed. */ #define CHANNEL_EOF (1<<9) /* EOF occurred on this channel. * This bit is cleared before every * input operation. */ #define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because * we saw the input eofChar. This bit * prevents clearing of the EOF bit * before every input operation. */ #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. */ typedef struct ChannelHandler { Channel *chanPtr; /* The channel structure for this channel. */ int mask; /* Mask of desired events. */ Tcl_ChannelProc *proc; /* Procedure to call in the type of * Tcl_CreateChannelHandler. */ ClientData clientData; /* Argument to pass to procedure. */ struct ChannelHandler *nextPtr; /* Next one in list of registered handlers. */ } ChannelHandler; /* * This structure keeps track of the current ChannelHandler being invoked in * the current invocation of ChannelHandlerEventProc. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. * The nextPtr field is used to chain together all recursive invocations, so * that Tcl_DeleteChannelHandler can find all the recursively nested * invocations of ChannelHandlerEventProc and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. */ typedef struct NextChannelHandler { 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 * for stdin/stdout/stderr in new interpreters. * * Results: * None * * Side effects: * None. * *---------------------------------------------------------------------- */ 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 * closed. * * Results: * None. * * Side effects: * Causes the callback to be called in the future when the channel * will be closed. * *---------------------------------------------------------------------- */ void Tcl_CreateCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to create the * close callback. */ Tcl_CloseProc *proc; /* The callback routine to call when the * channel will be closed. */ ClientData clientData; /* Arbitrary data to pass to the * close callback. */ { Channel *chanPtr; CloseCallback *cbPtr; chanPtr = (Channel *) chan; cbPtr = (CloseCallback *) ckalloc((unsigned) sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; cbPtr->nextPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr; } /* *---------------------------------------------------------------------- * * Tcl_DeleteCloseHandler -- * * Removes a callback that would have been called on closing * the channel. If there is no matching callback then this * function has no effect. * * Results: * None. * * Side effects: * The callback will not be called in the future when the channel * is eventually closed. * *---------------------------------------------------------------------- */ void Tcl_DeleteCloseHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to cancel the * close callback. */ Tcl_CloseProc *proc; /* The procedure for the callback to * remove. */ ClientData clientData; /* The callback data for the callback * to remove. */ { Channel *chanPtr; CloseCallback *cbPtr, *cbPrevPtr; chanPtr = (Channel *) chan; for (cbPtr = chanPtr->closeCbPtr, cbPrevPtr = (CloseCallback *) NULL; cbPtr != (CloseCallback *) NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { if (cbPrevPtr == (CloseCallback *) NULL) { chanPtr->closeCbPtr = cbPtr->nextPtr; } 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 * interpreter. If it is initializing the table it also inserts * channels for stdin, stdout and stderr if the interpreter is * trusted. * * Results: * A pointer to the hash table created, for use by the caller. * * Side effects: * Initializes the channel table for an interpreter. May create * channels for stdin, stdout and stderr. * *---------------------------------------------------------------------- */ static Tcl_HashTable * GetChannelTable(interp) Tcl_Interp *interp; { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { hTblPtr = (Tcl_HashTable *) ckalloc((unsigned) sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); (void) Tcl_SetAssocData(interp, "tclIO", (Tcl_InterpDeleteProc *) DeleteChannelTable, (ClientData) hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels * for stdin, stdout and stderr (possibly creating them in the * process). */ if (Tcl_IsSafe(interp) == 0) { stdinChan = Tcl_GetStdChannel(TCL_STDIN); if (stdinChan != NULL) { Tcl_RegisterChannel(interp, stdinChan); } stdoutChan = Tcl_GetStdChannel(TCL_STDOUT); if (stdoutChan != NULL) { Tcl_RegisterChannel(interp, stdoutChan); } stderrChan = Tcl_GetStdChannel(TCL_STDERR); if (stderrChan != NULL) { Tcl_RegisterChannel(interp, stderrChan); } } } return hTblPtr; } /* *---------------------------------------------------------------------- * * DeleteChannelTable -- * * Deletes the channel table for an interpreter, closing any open * channels whose refcount reaches zero. This procedure is invoked * when an interpreter is deleted, via the AssocData cleanup * mechanism. * * Results: * None. * * Side effects: * Deletes the hash table of channels. May close channels. May flush * output on closed channels. Removes any channeEvent handlers that were * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable(clientData, interp) ClientData clientData; /* The per-interpreter data structure. */ Tcl_Interp *interp; /* The interpreter being deleted. */ { Tcl_HashTable *hTblPtr; /* The hash table. */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* Channel being deleted. */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* Variables to loop over all channel events * registered, to delete the ones that refer * to the interpreter being deleted. */ /* * Delete all the registered channels - this will close channels whose * refcount reaches zero. */ hTblPtr = (Tcl_HashTable *) clientData; for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); /* * Remove any fileevents registered in this interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); ckfree(sPtr->script); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } /* * Cannot call Tcl_UnregisterChannel because that procedure calls * Tcl_GetAssocData to get the channel table, which might already * be inaccessible from the interpreter structure. Instead, we * emulate the behavior of Tcl_UnregisterChannel directly here. */ Tcl_DeleteHashEntry(hPtr); chanPtr->refCount--; if (chanPtr->refCount <= 0) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } } Tcl_DeleteHashTable(hTblPtr); ckfree((char *) hTblPtr); } /* *---------------------------------------------------------------------- * * CheckForStdChannelsBeingClosed -- * * Perform special handling for standard channels being closed. When * given a standard channel, if the refcount is now 1, it means that * the last reference to the standard channel is being explicitly * closed. Now bump the refcount artificially down to 0, to ensure the * normal handling of channels being closed will occur. Also reset the * static pointer to the channel to NULL, to avoid dangling references. * * Results: * None. * * Side effects: * Manipulates the refcount on standard channels. May smash the global * static pointer to a standard channel. * *---------------------------------------------------------------------- */ 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. * If the interpreter given as argument is NULL, it only decrements the * reference count. * * Results: * A standard Tcl result. * * Side effects: * Deletes the hash entry for a channel associated with an interpreter. * *---------------------------------------------------------------------- */ int Tcl_UnregisterChannel(interp, chan) Tcl_Interp *interp; /* Interpreter in which channel is defined. */ Tcl_Channel chan; /* Channel to delete. */ { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Channel *chanPtr; /* The real IO channel. */ chanPtr = (Channel *) chan; if (interp != (Tcl_Interp *) NULL) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } hPtr = Tcl_FindHashEntry(hTblPtr, chanPtr->channelName); if (hPtr == (Tcl_HashEntry *) NULL) { return TCL_OK; } if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) { return TCL_OK; } Tcl_DeleteHashEntry(hPtr); /* * Remove channel handlers that refer to this interpreter, so that they * will not be present if the actual close is delayed and more events * happen on the channel. This may occur if the channel is shared * between several interpreters, or if the channel has async * flushing active. */ CleanupChannelHandlers(interp, chanPtr); } chanPtr->refCount--; /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); /* * If the refCount reached zero, close the actual channel. */ if (chanPtr->refCount <= 0) { /* * Ensure that if there is another buffer, it gets flushed * whether or not we are doing a background flush. */ if ((chanPtr->curOutPtr != NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; } chanPtr->flags |= CHANNEL_CLOSED; if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { if (Tcl_Close(interp, chan) != TCL_OK) { return TCL_ERROR; } } } 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; } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_RegisterChannel'. * * Explanation: * The moment a channel is stacked upon another he * takes the identity of the channel he supercedes, * i.e. he gets the *same* name. Because of this we * cannot check for duplicate names anymore, they * have to be allowed now. */ /* 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. */ int *modePtr; /* Where to store the mode in which the * channel was opened? Will contain an ORed * combination of TCL_READABLE and * TCL_WRITABLE, if non-NULL. */ { Channel *chanPtr; /* The actual channel. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ char *name; /* Translated name. */ /* * Substitute "stdin", etc. Note that even though we immediately * find the channel using Tcl_GetStdChannel, we still need to look * it up in the specified interpreter to ensure that it is present * in the channel table. Otherwise, safe interpreters would always * have access to the standard channels. */ name = chanName; if ((chanName[0] == 's') && (chanName[1] == 't')) { chanPtr = NULL; if (strcmp(chanName, "stdin") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDIN); } else if (strcmp(chanName, "stdout") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDOUT); } else if (strcmp(chanName, "stderr") == 0) { chanPtr = (Channel *)Tcl_GetStdChannel(TCL_STDERR); } if (chanPtr != NULL) { name = chanPtr->channelName; } } hTblPtr = GetChannelTable(interp); hPtr = Tcl_FindHashEntry(hTblPtr, name); if (hPtr == (Tcl_HashEntry *) NULL) { Tcl_AppendResult(interp, "can not find channel named \"", chanName, "\"", (char *) NULL); return NULL; } chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (modePtr != NULL) { *modePtr = (chanPtr->flags & (TCL_READABLE|TCL_WRITABLE)); } return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_CreateChannel -- * * Creates a new entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Creates a new Tcl_Channel instance and inserts it into the * hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_CreateChannel(typePtr, chanName, instanceData, mask) 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. */ /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ chanPtr->byteOrder = Tcl_GetHostByteorder (); chanPtr->inputTranslation = TCL_TRANSLATE_AUTO; chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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; /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * This is the change to 'Tcl_CreateChannel'. * * Explanation: * It is of course necessary to initialize the new field * in the Channel structure. The chosen value indicates * that the created channel is a normal one, and not * stacked upon another. */ chanPtr->supercedes = (Channel*) 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; } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * The following two procedures are the new, exported ones. They * - create a channel stacked upon an existing one and * - pop a stacked channel off, thus revealing the superceded one. * * Please read the following completely. */ /* *---------------------------------------------------------------------- * * Tcl_ReplaceChannel -- * * Replaces an entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the new Tcl_Channel. * * Side effects: * Replaces a Tcl_Channel instance into the hash table. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan) Tcl_Interp* interp; /* the interpreter we are working in */ Tcl_ChannelType *typePtr; /* The channel type record. */ ClientData instanceData; /* Instance specific data. */ int mask; /* TCL_READABLE & TCL_WRITABLE to indicate * if the channel is readable, writable. */ Tcl_Channel prevChan; /* The channel structure that should * be replaced. */ { Channel *chanPtr, *pt, *prevPt; /* * Replace the channel into the list of all channels; */ prevPt = (Channel*) NULL; pt = (Channel*) firstChanPtr; while (pt != (Channel *) prevChan) { prevPt = pt; pt = pt->nextChanPtr; } if (!pt) { return (Tcl_Channel) NULL; } /* * Here we check if the "mask" matches the "flags" * of the already existing channel. * * | - | R | W | RW | * --+---+---+---+----+ <=> 0 != (chan->mask & prevChan->mask) * - | | | | | * R | | + | | + | The superceding channel is allowed to * W | | | + | + | restrict the capabilities of the * RW| | + | + | + | superceded one ! * --+---+---+---+----+ */ if ((mask & Tcl_GetChannelMode (prevChan)) == 0) { return (Tcl_Channel) NULL; } chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel)); chanPtr->flags = mask; /* * Set the channel up initially in no Input translation mode and * no Output translation mode. */ chanPtr->inputTranslation = TCL_TRANSLATE_LF; chanPtr->outputTranslation = TCL_TRANSLATE_LF; chanPtr->inEofChar = 0; chanPtr->outEofChar = 0; chanPtr->unreportedError = 0; chanPtr->instanceData = instanceData; chanPtr->typePtr = typePtr; chanPtr->refCount = 0; chanPtr->closeCbPtr = (CloseCallback *) NULL; chanPtr->curOutPtr = (ChannelBuffer *) NULL; chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; chanPtr->saveInBufPtr = (ChannelBuffer *) NULL; chanPtr->inQueueHead = (ChannelBuffer *) NULL; 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->supercedes = (Channel*) prevChan; chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1); strcpy (chanPtr->channelName, pt->channelName); if (prevPt) { prevPt->nextChanPtr = chanPtr; } else { firstChanPtr = chanPtr; } chanPtr->nextChanPtr = pt->nextChanPtr; Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr); /* The superceded channel is effectively unregistered */ /*chanPtr->supercedes->refCount --;*/ return (Tcl_Channel) chanPtr; } /* *---------------------------------------------------------------------- * * Tcl_UndoReplaceChannel -- * * Unstacks an entry in the hash table for a Tcl_Channel * record. * * Results: * Returns the old Tcl_Channel, i.e. the one which was stacked over. * * Side effects: * Replaces a Tcl_Channel instance into the hash table. * *---------------------------------------------------------------------- */ void Tcl_UndoReplaceChannel (interp, chan) Tcl_Interp* interp; /* The interpreter we are working in */ Tcl_Channel chan; /* The channel to unstack */ { Channel* chanPtr = (Channel*) chan; if (chanPtr->supercedes != (Channel*) NULL) { Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ int new; /* Is the hash entry new or does it exist? */ /* * Insert the channel we were stacked upon back into * the list of open channels. Place it back into the hashtable too. * Correct 'refCount', as this actually unregisters 'chan'. */ chanPtr->supercedes->nextChanPtr = firstChanPtr; firstChanPtr = chanPtr->supercedes; hTblPtr = GetChannelTable (interp); hPtr = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new); Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes); chanPtr->refCount --; /* The superceded channel is effectively registered again */ /*chanPtr->supercedes->refCount ++;*/ } /* * Disconnect the channels, then do a regular close upon the * stacked one. This may cause flushing of data into the * superceded channel (if 'chan' remembered its parent in itself). */ chanPtr->supercedes = NULL; if (chanPtr->refCount == 0) { Tcl_Close (interp, chan); } } /* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * * Computes a mask indicating whether the channel is open for * reading and writing. * * Results: * An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelMode(chan) Tcl_Channel chan; /* The channel for which the mode is * being computed. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE)); } /* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * * Returns the string identifying the channel name. * * Results: * The string containing the channel name. This memory is * owned by the generic layer and should not be modified by * the caller. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Tcl_GetChannelName(chan) Tcl_Channel chan; /* The channel for which to return the name. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->channelName; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * * Given a channel structure, returns the channel type structure. * * Results: * Returns a pointer to the channel type structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ChannelType * Tcl_GetChannelType(chan) Tcl_Channel chan; /* The channel to return type for. */ { Channel *chanPtr; /* The actual channel. */ chanPtr = (Channel *) chan; return chanPtr->typePtr; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * * Returns an OS handle associated with a channel. * * Results: * Returns TCL_OK and places the handle in handlePtr, or returns * TCL_ERROR on failure. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelHandle(chan, direction, handlePtr) Tcl_Channel chan; /* The channel to get file from. */ int direction; /* TCL_WRITABLE or TCL_READABLE. */ ClientData *handlePtr; /* Where to store handle */ { Channel *chanPtr; /* The actual channel. */ ClientData handle; int result; chanPtr = (Channel *) chan; result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData, direction, &handle); if (handlePtr) { *handlePtr = handle; } return result; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * * Returns the client data associated with a channel. * * Results: * The client data. * * Side effects: * None. * *---------------------------------------------------------------------- */ ClientData Tcl_GetChannelInstanceData(chan) 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 * that two input buffers are saved (one in the input queue and * another in the saveInBufPtr field) and that curOutPtr is set * to a buffer. Only if these conditions are met is the buffer * freed to the OS. * * Results: * None. * * Side effects: * May free a buffer to the OS. * *---------------------------------------------------------------------- */ static void RecycleBuffer(chanPtr, bufPtr, mustDiscard) Channel *chanPtr; /* Channel for which to recycle buffers. */ ChannelBuffer *bufPtr; /* The buffer to recycle. */ int mustDiscard; /* If nonzero, free the buffer to the * OS, always. */ { /* * Do we have to free the buffer to the OS? */ if (mustDiscard) { ckfree((char *) bufPtr); return; } /* * Only save buffers for the input queue if the channel is readable. */ if (chanPtr->flags & TCL_READABLE) { if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) { chanPtr->inQueueHead = bufPtr; chanPtr->inQueueTail = bufPtr; goto keepit; } if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) { chanPtr->saveInBufPtr = bufPtr; goto keepit; } } /* * Only save buffers for the output queue if the channel is writable. */ if (chanPtr->flags & TCL_WRITABLE) { if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) { chanPtr->curOutPtr = bufPtr; goto keepit; } } /* * 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 -- * * Discards all output queued in the output queue of a channel. * * Results: * None. * * Side effects: * Recycles buffers. * *---------------------------------------------------------------------- */ static void DiscardOutputQueued(chanPtr) Channel *chanPtr; /* The channel for which to discard output. */ { ChannelBuffer *bufPtr; while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { bufPtr = chanPtr->outQueueHead; chanPtr->outQueueHead = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, 0); } chanPtr->outQueueHead = (ChannelBuffer *) NULL; chanPtr->outQueueTail = (ChannelBuffer *) NULL; } /* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * * This function checks is a given channel is Dead. * (A channel that has been closed but not yet deallocated.) * * Results: * True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: * None * *---------------------------------------------------------------------- */ static int CheckForDeadChannel(interp, chanPtr) Tcl_Interp *interp; /* For error reporting (can be NULL) */ Channel *chanPtr; /* The channel to check. */ { if (chanPtr->flags & CHANNEL_DEAD) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, "unable to access channel: invalid channel", (char *) NULL); } return 1; } return 0; } /* *---------------------------------------------------------------------- * * FlushChannel -- * * This function flushes as much of the queued output as is possible * now. If calledFromAsyncFlush is nonzero, it is being called in an * event handler to flush channel output asynchronously. * * Results: * 0 if successful, else the error code that was returned by the * channel type operation. * * Side effects: * May produce output on a channel. May block indefinitely if the * channel is synchronous. May schedule an async flush on the channel. * May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */ static int FlushChannel(interp, chanPtr, calledFromAsyncFlush) Tcl_Interp *interp; /* For error reporting during close. */ Channel *chanPtr; /* The channel to flush on. */ int calledFromAsyncFlush; /* If nonzero then we are being * called from an asynchronous * flush callback. */ { 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. */ if (CheckForDeadChannel(interp,chanPtr)) return -1; /* * Loop over the queued buffers and attempt to flush as * much as possible of the queued output to the channel. */ while (1) { /* * 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 { chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr; } chanPtr->outQueueTail = chanPtr->curOutPtr; chanPtr->curOutPtr = (ChannelBuffer *) NULL; } bufPtr = chanPtr->outQueueHead; /* * If we are not being called from an async flush and an async * flush is active, we just return without producing any output. */ if ((!calledFromAsyncFlush) && (chanPtr->flags & BG_FLUSH_SCHEDULED)) { return 0; } /* * If the output queue is still empty, break out of the while loop. */ if (bufPtr == (ChannelBuffer *) NULL) { break; /* Out of the "while (1)". */ } /* * 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. */ if (written < 0) { /* * If the last attempt to write was interrupted, simply retry. */ if (errorCode == EINTR) { errorCode = 0; continue; } /* * If the channel is non-blocking and we would have blocked, * start a background flushing handler and break out of the loop. */ if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) { if (chanPtr->flags & CHANNEL_NONBLOCKING) { if (!(chanPtr->flags & BG_FLUSH_SCHEDULED)) { chanPtr->flags |= BG_FLUSH_SCHEDULED; UpdateInterest(chanPtr); } errorCode = 0; break; } else { panic("Blocking channel driver did not block on output"); } } /* * Decide whether to report the error upwards or defer it. */ if (calledFromAsyncFlush) { if (chanPtr->unreportedError == 0) { chanPtr->unreportedError = errorCode; } } else { Tcl_SetErrno(errorCode); if (interp != NULL) { Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } } /* * 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. */ if ((chanPtr->flags & CHANNEL_CLOSED) && (chanPtr->refCount <= 0) && (chanPtr->outQueueHead == (ChannelBuffer *) NULL) && ((chanPtr->curOutPtr == (ChannelBuffer *) NULL) || (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->nextRemoved))) { return CloseChannel(interp, chanPtr, errorCode); } return errorCode; } /* *---------------------------------------------------------------------- * * CloseChannel -- * * Utility procedure to close a channel and free its associated * resources. * * Results: * 0 on success or a POSIX error code if the operation failed. * * Side effects: * May close the actual channel; may free memory. * *---------------------------------------------------------------------- */ static int CloseChannel(interp, chanPtr, errorCode) Tcl_Interp *interp; /* For error reporting. */ Channel *chanPtr; /* The channel to close. */ 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. */ DiscardInputQueued(chanPtr, 1); /* * Discard a leftover buffer in the current output buffer field. */ if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { ckfree((char *) chanPtr->curOutPtr); chanPtr->curOutPtr = (ChannelBuffer *) NULL; } /* * The caller guarantees that there are no more buffers * queued for output. */ if (chanPtr->outQueueHead != (ChannelBuffer *) NULL) { panic("TclFlush, closed channel: queued output left"); } /* * If the EOF character is set in the channel, append that to the * output device. */ if ((chanPtr->outEofChar != 0) && (chanPtr->flags & TCL_WRITABLE)) { int dummy; char c; c = (char) chanPtr->outEofChar; (chanPtr->typePtr->outputProc) (chanPtr->instanceData, &c, 1, &dummy); } /* * Remove TCL_READABLE and TCL_WRITABLE from chanPtr->flags, so * that close callbacks can not do input or output (assuming they * squirreled the channel away in their clientData). This also * prevents infinite loops if the callback calls any C API that * could call FlushChannel. */ 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. */ if (chanPtr->unreportedError != 0) { errorCode = chanPtr->unreportedError; } if (errorCode == 0) { errorCode = result; if (errorCode != 0) { Tcl_SetErrno(errorCode); } } /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * This is the change to 'CloseChannel'. * * Explanation * Closing a filtering channel closes the one it * superceded too. This basically ripples through * the whole chain of filters until it reaches * the underlying normal channel. * * This is done by reintegrating the superceded * channel into the (thread) global list of open * channels and then invoking a regular close. * There is no need to handle the complexities of * this process by ourselves. * * *Note* * This has to be done after the call to the * 'closeProc' of the filtering channel to allow * that one the flushing of internal buffers into * the underlying channel. */ if (chanPtr->supercedes != (Channel*) NULL) { /* Insert the channel we were stacked upon back into * the list of open channels, then do a regular close. */ chanPtr->supercedes->nextChanPtr = firstChanPtr; firstChanPtr = chanPtr->supercedes; chanPtr->supercedes->refCount --; /* is deregistered */ Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes); } /* * Cancel any outstanding timer. */ Tcl_DeleteTimerHandler(chanPtr->timer); /* * Mark the channel as deleted by clearing the type structure. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree((ClientData) chanPtr, TCL_DYNAMIC); return errorCode; } /* *---------------------------------------------------------------------- * * Tcl_Close -- * * Closes a channel. * * Results: * A standard Tcl result. * * Side effects: * Closes the channel if this is the last reference. * * NOTE: * Tcl_Close removes the channel as far as the user is concerned. * However, it may continue to exist for a while longer if it has * a background flush scheduled. The device itself is eventually * closed and the channel record removed, in CloseChannel, above. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int Tcl_Close(interp, chan) Tcl_Interp *interp; /* Interpreter for errors. */ Tcl_Channel chan; /* The channel being closed. Must * not be referenced in any * interpreter. */ { 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; } /* * Perform special handling for standard channels being closed. If the * refCount is now 1 it means that the last reference to the standard * channel is being explicitly closed, so bump the refCount down * artificially to 0. This will ensure that the channel is actually * closed, below. Also set the static pointer to NULL for the channel. */ CheckForStdChannelsBeingClosed(chan); chanPtr = (Channel *) chan; if (chanPtr->refCount > 0) { panic("called Tcl_Close on channel with refCount > 0"); } /* * 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; } } /* * Remove all the channel handler records attached to the channel * itself. */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chNext) { chNext = chPtr->nextPtr; ckfree((char *) chPtr); } chanPtr->chPtr = (ChannelHandler *) NULL; /* * Cancel any pending copy operation. */ StopCopy(chanPtr->csPtr); /* * Must set the interest mask now to 0, otherwise infinite loops * will occur if Tcl_DoOneEvent is called before the channel is * finally deleted in FlushChannel. This can happen if the channel * has a background flush active. */ chanPtr->interestMask = 0; /* * 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. */ while (chanPtr->closeCbPtr != (CloseCallback *) NULL) { cbPtr = chanPtr->closeCbPtr; chanPtr->closeCbPtr = cbPtr->nextPtr; (cbPtr->proc) (cbPtr->clientData); ckfree((char *) cbPtr); } /* * 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 -- * * Flushes output data on a channel. * * Results: * A standard Tcl result. * * Side effects: * May flush output queued on this channel. * *---------------------------------------------------------------------- */ int 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; } return TCL_OK; } /* *---------------------------------------------------------------------- * * DiscardInputQueued -- * * Discards any input read from the channel but not yet consumed * by Tcl reading commands. * * Results: * None. * * Side effects: * May discard input from the channel. If discardLastBuffer is zero, * leaves one buffer in place for back-filling. * *---------------------------------------------------------------------- */ static void DiscardInputQueued(chanPtr, discardSavedBuffers) Channel *chanPtr; /* Channel on which to discard * the queued input. */ int discardSavedBuffers; /* If non-zero, discard all buffers including * last one. */ { ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ bufPtr = chanPtr->inQueueHead; chanPtr->inQueueHead = (ChannelBuffer *) NULL; chanPtr->inQueueTail = (ChannelBuffer *) NULL; for (; bufPtr != (ChannelBuffer *) NULL; bufPtr = nxtPtr) { nxtPtr = bufPtr->nextPtr; RecycleBuffer(chanPtr, bufPtr, discardSavedBuffers); } /* * If discardSavedBuffers is nonzero, must also discard any previously * saved buffer in the saveInBufPtr field. */ if (discardSavedBuffers) { if (chanPtr->saveInBufPtr != (ChannelBuffer *) NULL) { 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) { 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; } /* *---------------------------------------------------------------------- * * 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) { copiedTotal = -1; goto done; } 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); done: /* * Update the notifier state so we don't block while there is still * data in the buffers. */ UpdateInterest(chanPtr); 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) { copiedTotal = -1; goto done; } (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); done: /* * Update the notifier state so we don't block while there is still * data in the buffers. */ UpdateInterest(chanPtr); 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; } /* * Update the notifier state so we don't block while there is still * data in the buffers. */ UpdateInterest(chanPtr); return len; } /* *---------------------------------------------------------------------- * * Tcl_Seek -- * * Implements seeking on Tcl Channels. This is a public function * so that other C facilities may be implemented on top of it. * * Results: * The new access point or -1 on error. If error, use Tcl_GetErrno() * to retrieve the POSIX error code for the error that occurred. * * Side effects: * May flush output on the channel. May discard queued input. * *---------------------------------------------------------------------- */ int Tcl_Seek(chan, offset, mode) Tcl_Channel chan; /* The channel on which to seek. */ int offset; /* Offset to seek to. */ int mode; /* Relative to which location to seek? */ { Channel *chanPtr; /* The real IO channel. */ ChannelBuffer *bufPtr; int inputBuffered, outputBuffered; 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 * registered in an interpreter. */ if (CheckForDeadChannel(NULL,chanPtr)) return -1; /* * Disallow seek on channels whose type does not have a seek procedure * defined. This means that the channel does not support seeking. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * If we are seeking relative to the current position, compute the * corrected offset taking into account the amount of unread input. */ if (mode == SEEK_CUR) { offset -= inputBuffered; } /* * Discard any queued input - this input should not be read after * the seek. */ DiscardInputQueued(chanPtr, 0); /* * Reset EOF and BLOCKED flags. We invalidate them by moving the * access point. Also clear CR related flags. */ chanPtr->flags &= (~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR)); /* * If the channel is in asynchronous output mode, switch it back * to synchronous mode and cancel any async flush that may be * scheduled. After the flush, the channel will be put back into * asynchronous output mode. */ wasAsync = 0; if (chanPtr->flags & CHANNEL_NONBLOCKING) { wasAsync = 1; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_BLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } chanPtr->flags &= (~(CHANNEL_NONBLOCKING)); if (chanPtr->flags & BG_FLUSH_SCHEDULED) { chanPtr->flags &= (~(BG_FLUSH_SCHEDULED)); } } /* * If the flush fails we cannot recover the original position. In * that case the seek is not attempted because we do not know where * the access position is - instead we return the error. FlushChannel * has already called Tcl_SetErrno() to report the error upwards. * If the flush succeeds we do the seek also. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { curPos = -1; } else { /* * Now seek to the new position in the channel as requested by the * caller. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) offset, mode, &result); if (curPos == -1) { Tcl_SetErrno(result); } } /* * Restore to nonblocking mode if that was the previous behavior. * * NOTE: Even if there was an async flush active we do not restore * it now because we already flushed all the queued output, above. */ if (wasAsync) { chanPtr->flags |= CHANNEL_NONBLOCKING; result = 0; if (chanPtr->typePtr->blockModeProc != NULL) { result = (chanPtr->typePtr->blockModeProc) (chanPtr->instanceData, TCL_MODE_NONBLOCKING); } if (result != 0) { Tcl_SetErrno(result); return -1; } } return curPos; } /* *---------------------------------------------------------------------- * * Tcl_Tell -- * * Returns the position of the next character to be read/written on * this channel. * * Results: * A nonnegative integer on success, -1 on failure. If failed, * use Tcl_GetErrno() to retrieve the POSIX error code for the * error that occurred. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Tell(chan) Tcl_Channel chan; /* The channel to return pos for. */ { 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. */ if (chanPtr->typePtr->seekProc == (Tcl_DriverSeekProc *) NULL) { Tcl_SetErrno(EINVAL); return -1; } /* * Compute how much input and output is buffered. If both input and * output is buffered, cannot compute the current position. */ for (bufPtr = chanPtr->inQueueHead, inputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { inputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } for (bufPtr = chanPtr->outQueueHead, outputBuffered = 0; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { outputBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } if ((chanPtr->curOutPtr != (ChannelBuffer *) NULL) && (chanPtr->curOutPtr->nextAdded > chanPtr->curOutPtr->nextRemoved)) { chanPtr->flags |= BUFFER_READY; outputBuffered += (chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved); } if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); return -1; } /* * Get the current position in the device and compute the position * where the next character will be read or written. */ curPos = (chanPtr->typePtr->seekProc) (chanPtr->instanceData, (long) 0, SEEK_CUR, &result); if (curPos == -1) { Tcl_SetErrno(result); return -1; } if (inputBuffered != 0) { return (curPos - inputBuffered); } return (curPos + outputBuffered); } /* *---------------------------------------------------------------------- * * Tcl_Eof -- * * Returns 1 if the channel is at EOF, 0 otherwise. * * Results: * 1 or 0, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_Eof(chan) Tcl_Channel chan; /* Does this channel have EOF? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return ((chanPtr->flags & CHANNEL_STICKY_EOF) || ((chanPtr->flags & CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBlocked -- * * Returns 1 if input is blocked on this channel, 0 otherwise. * * Results: * 0 or 1, always. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBlocked(chan) Tcl_Channel chan; /* Is this channel blocked? */ { Channel *chanPtr; /* The real channel structure. */ chanPtr = (Channel *) chan; return (chanPtr->flags & CHANNEL_BLOCKED) ? 1 : 0; } /* *---------------------------------------------------------------------- * * Tcl_InputBuffered -- * * Returns the number of bytes of input currently buffered in the * internal buffer of a channel. * * Results: * The number of input bytes buffered, or zero if the channel is not * open for reading. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_InputBuffered(chan) Tcl_Channel chan; /* The channel to query. */ { Channel *chanPtr; int bytesBuffered; ChannelBuffer *bufPtr; chanPtr = (Channel *) chan; for (bytesBuffered = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved); } return bytesBuffered; } /* *---------------------------------------------------------------------- * * Tcl_SetChannelBufferSize -- * * Sets the size of buffers to allocate to store input or output * in the channel. The size must be between 10 bytes and 1 MByte. * * Results: * None. * * Side effects: * Sets the size of buffers subsequently allocated for this channel. * *---------------------------------------------------------------------- */ void Tcl_SetChannelBufferSize(chan, sz) Tcl_Channel chan; /* The channel whose buffer size * to set. */ int sz; /* The size to set. */ { Channel *chanPtr; /* * If the buffer size is smaller than 10 bytes or larger than one MByte, * do not accept the requested size and leave the current buffer size. */ if (sz < 10) { return; } if (sz > (1024 * 1024)) { return; } chanPtr = (Channel *) chan; chanPtr->bufSize = sz; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelBufferSize -- * * Retrieves the size of buffers to allocate for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelBufferSize(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->bufSize; } /* *---------------------------------------------------------------------- * * Tcl_BadChannelOption -- * * This procedure generates a "bad option" error message in an * (optional) interpreter. It is used by channel drivers when * a invalid Set/Get option is requested. Its purpose is to concatenate * the generic options list to the specific ones and factorize * the generic options error message string. * * Results: * TCL_ERROR. * * Side effects: * An error message is generated in interp's result object to * indicate that a command was invoked with the a bad option * The message has the form * bad option "blah": should be one of * <...generic options...>+<...specific options...> * "blah" is the optionName argument and "" * is a space separated list of specific option words. * The function takes good care of inserting minus signs before * each option, commas after, and an "or" before the last option. * *---------------------------------------------------------------------- */ int Tcl_BadChannelOption(interp, optionName, optionList) Tcl_Interp *interp; /* Current interpreter. (can be NULL)*/ char *optionName; /* 'bad option' name */ char *optionList; /* Specific options list to append * to the standard generic options. * can be NULL for generic options * only. */ { if (interp) { CONST char *genericopt = "blocking buffering buffersize byteorder eofchar translation"; char **argv; int argc, i; Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, (char *) genericopt, -1); if (optionList && (*optionList)) { Tcl_DStringAppend(&ds, " ", 1); Tcl_DStringAppend(&ds, optionList, -1); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { panic("malformed option list in channel driver"); } Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad option \"", optionName, "\": should be one of ", (char *) NULL); argc--; for (i = 0; i < argc; i++) { Tcl_AppendResult(interp, "-", argv[i], ", ", (char *) NULL); } Tcl_AppendResult(interp, "or -", argv[i], (char *) NULL); Tcl_DStringFree(&ds); ckfree((char *) argv); } Tcl_SetErrno(EINVAL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelByteorder -- * * Retrieves the byteorder set for this channel. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ByteOrder Tcl_GetChannelByteorder(chan) Tcl_Channel chan; /* The channel for which to find the * buffer size. */ { Channel *chanPtr; chanPtr = (Channel *) chan; return chanPtr->byteOrder; } /* *---------------------------------------------------------------------- * * Tcl_GetHostByteorder -- * * Retrieves the byteorder of the machine we are running on. * * Results: * The size. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_ByteOrder Tcl_GetHostByteorder() { union { char c[sizeof(short)]; short s; } order; order.s = 1; return (order.c[0] == 1) ? TCL_SMALLENDIAN : TCL_BIGENDIAN; } /* *---------------------------------------------------------------------- * * Tcl_GetChannelOption -- * * 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: * None. * *---------------------------------------------------------------------- */ int Tcl_GetChannelOption(interp, chan, optionName, dsPtr) Tcl_Interp *interp; /* For error reporting - can be NULL. */ Tcl_Channel chan; /* Channel on which to get option. */ char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */ { size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; int flags; /* * If we are in the middle of a background copy, use the saved flags. */ if (chanPtr->csPtr) { if (chanPtr == chanPtr->csPtr->readPtr) { flags = chanPtr->csPtr->readFlags; } else { flags = chanPtr->csPtr->writeFlags; } } else { flags = chanPtr->flags; } /* * Disallow options 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(interp,chanPtr)) return TCL_ERROR; /* * If the optionName is NULL it means that we want a list of all * options and values. */ if (optionName == (char *) NULL) { len = 0; } else { len = strlen(optionName); } if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blocking"); } Tcl_DStringAppendElement(dsPtr, (flags & CHANNEL_NONBLOCKING) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffering", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffering"); } if (flags & CHANNEL_LINEBUFFERED) { Tcl_DStringAppendElement(dsPtr, "line"); } else if (flags & CHANNEL_UNBUFFERED) { Tcl_DStringAppendElement(dsPtr, "none"); } else { Tcl_DStringAppendElement(dsPtr, "full"); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 7) && (optionName[1] == 'b') && (strncmp(optionName, "-buffersize", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-buffersize"); } TclFormatInt(optionVal, chanPtr->bufSize); Tcl_DStringAppendElement(dsPtr, optionVal); if (len > 0) { return TCL_OK; } } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ if ((len == 0) || ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-byteorder"); } Tcl_DStringAppendElement(dsPtr, (chanPtr->byteOrder == TCL_BIGENDIAN) ? "bigendian" : "smallendian"); 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); } if (flags & TCL_READABLE) { if (chanPtr->inEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->inEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (flags & TCL_WRITABLE) { if (chanPtr->outEofChar == 0) { Tcl_DStringAppendElement(dsPtr, ""); } else { char buf[4]; sprintf(buf, "%c", chanPtr->outEofChar); Tcl_DStringAppendElement(dsPtr, buf); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if ((len == 0) || ((len > 1) && (optionName[1] == 't') && (strncmp(optionName, "-translation", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-translation"); } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringStartSublist(dsPtr); } if (flags & TCL_READABLE) { if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (flags & TCL_WRITABLE) { if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_DStringAppendElement(dsPtr, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_DStringAppendElement(dsPtr, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_DStringAppendElement(dsPtr, "crlf"); } else { Tcl_DStringAppendElement(dsPtr, "lf"); } } if (((flags & (TCL_READABLE|TCL_WRITABLE)) == (TCL_READABLE|TCL_WRITABLE)) && (len == 0)) { Tcl_DStringEndSublist(dsPtr); } if (len > 0) { return TCL_OK; } } if (chanPtr->typePtr->getOptionProc != (Tcl_DriverGetOptionProc *) NULL) { /* * let the driver specific handle additional options * and result code and message. */ return (chanPtr->typePtr->getOptionProc) (chanPtr->instanceData, interp, optionName, dsPtr); } else { /* * no driver specific options case. */ if (len == 0) { 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? */ char *newValue; /* New value for option. */ { int newMode; /* New (numeric) mode to sert. */ Channel *chanPtr; /* The real IO channel. */ size_t len; /* Length of optionName string. */ int argc; char **argv; chanPtr = (Channel *) chan; /* * If the channel is in the middle of a background copy, fail. */ if (chanPtr->csPtr) { if (interp) { Tcl_AppendResult(interp, "unable to set channel options: background copy in progress", (char *) NULL); } return TCL_ERROR; } /* * Disallow options 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 TCL_ERROR; len = strlen(optionName); if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-blocking", len) == 0)) { if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) { return TCL_ERROR; } 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)) { chanPtr->flags &= (~(CHANNEL_UNBUFFERED)); chanPtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { chanPtr->flags &= (~(CHANNEL_LINEBUFFERED)); chanPtr->flags |= CHANNEL_UNBUFFERED; } else { 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; } /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ if ((len > 2) && (optionName[1] == 'b') && (strncmp(optionName, "-byteorder", len) == 0)) { int nv_len = strlen (newValue); if ((nv_len > 0) && (strncmp (newValue, "smallendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "littleendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_SMALLENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "network", nv_len) == 0)) { chanPtr->byteOrder = TCL_BIGENDIAN; return TCL_OK; } else if ((nv_len > 0) && (strncmp (newValue, "bigendian", nv_len) == 0)) { chanPtr->byteOrder = TCL_BIGENDIAN; return TCL_OK; } if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "bad value for -byteorder: ", "must be one of smallendian, littleendian, bigendian or network", (char *) NULL); } return TCL_ERROR; } 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; } else if (argc == 1) { if (chanPtr->flags & TCL_WRITABLE) { chanPtr->outEofChar = (int) argv[0][0]; } if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } } else if (argc != 2) { if (interp) { Tcl_AppendResult(interp, "bad value for -eofchar: should be a list of one or", " two elements", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } else { if (chanPtr->flags & TCL_READABLE) { chanPtr->inEofChar = (int) argv[0][0]; } 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; } if (argc == 1) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { readMode = (chanPtr->flags & TCL_READABLE) ? argv[0] : NULL; writeMode = (chanPtr->flags & TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: must be a one or two", " element list", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } 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) { newMode = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } ckfree((char *) argv); return TCL_ERROR; } /* * Reset the EOL flags since we need to look at any buffered * 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) { /* * This is a hack to get TCP sockets to produce output * in CRLF mode if they are being set into AUTO mode. * A better solution for achieving this effect will be * coded later. */ if (strcmp(chanPtr->typePtr->typeName, "tcp") == 0) { 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) { chanPtr->outputTranslation = TCL_PLATFORM_TRANSLATION; } else { if (interp) { Tcl_AppendResult(interp, "bad value for -translation: ", "must be one of auto, binary, cr, lf, crlf,", " or platform", (char *) NULL); } 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 -- * * Removes channel handlers that refer to the supplied interpreter, * so that if the actual channel is not closed now, these handlers * will not run on subsequent events on the channel. This would be * erroneous, because the interpreter no longer has a reference to * this channel. * * Results: * None. * * Side effects: * Removes channel handlers. * *---------------------------------------------------------------------- */ static void CleanupChannelHandlers(interp, chanPtr) Tcl_Interp *interp; Channel *chanPtr; { EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* * Remove fileevent records on this channel that refer to the * given interpreter. */ for (sPtr = chanPtr->scriptRecordPtr, prevPtr = (EventScriptRecord *) NULL; sPtr != (EventScriptRecord *) NULL; sPtr = nextPtr) { nextPtr = sPtr->nextPtr; if (sPtr->interp == interp) { if (prevPtr == (EventScriptRecord *) NULL) { chanPtr->scriptRecordPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) sPtr); ckfree(sPtr->script); ckfree((char *) sPtr); } else { prevPtr = sPtr; } } } /* *---------------------------------------------------------------------- * * Tcl_NotifyChannel -- * * This procedure is called by a channel driver when a driver * detects an event on a channel. This procedure is responsible * for actually handling the event by invoking any channel * handler callbacks. * * Results: * None. * * Side effects: * Whatever the channel handler callback procedure does. * *---------------------------------------------------------------------- */ void Tcl_NotifyChannel(channel, mask) 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; /* * 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 = 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. */ if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; (*(chPtr->proc))(chPtr->clientData, mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; } } /* * Update the notifier interest, since it may have changed after * invoking event handlers. */ if (chanPtr->typePtr != NULL) { UpdateInterest(chanPtr); } Tcl_Release((ClientData) channel); nestedHandlerPtr = nh.nestedHandlerPtr; } /* *---------------------------------------------------------------------- * * UpdateInterest -- * * Arrange for the notifier to call us back at appropriate times * based on the current state of the channel. * * Results: * None. * * Side effects: * May schedule a timer or driver handler. * *---------------------------------------------------------------------- */ static void UpdateInterest(chanPtr) Channel *chanPtr; /* Channel to update. */ { int mask = chanPtr->interestMask; /* * If there are flushed buffers waiting to be written, then * we need to watch for the channel to become writable. */ 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); } } } (chanPtr->typePtr->watchProc)(chanPtr->instanceData, mask); } /* *---------------------------------------------------------------------- * * ChannelTimerProc -- * * Timer handler scheduled by UpdateInterest to monitor the * channel buffers until they are empty. * * Results: * None. * * Side effects: * May invoke channel handlers. * *---------------------------------------------------------------------- */ 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. */ chanPtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc, (ClientData) chanPtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); } else { chanPtr->timer = NULL; UpdateInterest(chanPtr); } } /* *---------------------------------------------------------------------- * * Tcl_CreateChannelHandler -- * * Arrange for a given procedure to be invoked whenever the * channel indicated by the chanPtr arg becomes readable or * writable. * * Results: * None. * * Side effects: * From now on, whenever the I/O channel given by chanPtr becomes * ready in the way indicated by mask, proc will be invoked. * See the manual entry for details on the calling sequence * to proc. If there is already an event handler for chan, proc * and clientData, then the mask will be updated. * *---------------------------------------------------------------------- */ void Tcl_CreateChannelHandler(chan, mask, proc, clientData) Tcl_Channel chan; /* The channel to create the handler for. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions under which * proc should be called. Use 0 to * disable a registered handler. */ Tcl_ChannelProc *proc; /* Procedure to call for each * selected event. */ ClientData clientData; /* Arbitrary data to pass to proc. */ { ChannelHandler *chPtr; Channel *chanPtr; chanPtr = (Channel *) chan; /* * Check whether this channel handler is not already registered. If * it is not, create a new record, else reuse existing record (smash * current values). */ for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) && (chPtr->clientData == clientData)) { break; } } if (chPtr == (ChannelHandler *) NULL) { chPtr = (ChannelHandler *) ckalloc((unsigned) sizeof(ChannelHandler)); chPtr->mask = 0; chPtr->proc = proc; chPtr->clientData = clientData; chPtr->chanPtr = chanPtr; chPtr->nextPtr = chanPtr->chPtr; chanPtr->chPtr = chPtr; } /* * The remainder of the initialization below is done regardless of * whether or not this is a new record or a modification of an old * one. */ chPtr->mask = mask; /* * Recompute the interest mask for the channel - this call may actually * be disabling an existing handler. */ chanPtr->interestMask = 0; for (chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { chanPtr->interestMask |= chPtr->mask; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * Tcl_DeleteChannelHandler -- * * Cancel a previously arranged callback arrangement for an IO * channel. * * Results: * None. * * Side effects: * If a callback was previously registered for this chan, proc and * clientData , it is removed and the callback will no longer be called * when the channel becomes ready for IO. * *---------------------------------------------------------------------- */ void Tcl_DeleteChannelHandler(chan, proc, clientData) Tcl_Channel chan; /* The channel for which to remove the * callback. */ 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. */ for (prevChPtr = (ChannelHandler *) NULL, chPtr = chanPtr->chPtr; chPtr != (ChannelHandler *) NULL; chPtr = chPtr->nextPtr) { if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData) && (chPtr->proc == proc)) { break; } prevChPtr = chPtr; } /* * If not found, return without doing anything. */ if (chPtr == (ChannelHandler *) NULL) { return; } /* * 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; } UpdateInterest(chanPtr); } /* *---------------------------------------------------------------------- * * DeleteScriptRecord -- * * Delete a script record for this combination of channel, interp * and mask. * * Results: * None. * * Side effects: * Deletes a script record and cancels a channel event handler. * *---------------------------------------------------------------------- */ static void DeleteScriptRecord(interp, chanPtr, mask) Tcl_Interp *interp; /* Interpreter in which script was to be * executed. */ Channel *chanPtr; /* The channel for which to delete the * script record (if any). */ int mask; /* Events in mask must exactly match mask * of script to delete. */ { EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = chanPtr->scriptRecordPtr, prevEsPtr = (EventScriptRecord *) NULL; esPtr != (EventScriptRecord *) NULL; prevEsPtr = esPtr, esPtr = esPtr->nextPtr) { if ((esPtr->interp == interp) && (esPtr->mask == mask)) { if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { prevEsPtr->nextPtr = esPtr->nextPtr; } Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr, ChannelEventScriptInvoker, (ClientData) esPtr); ckfree(esPtr->script); ckfree((char *) esPtr); break; } } } /* *---------------------------------------------------------------------- * * CreateScriptRecord -- * * Creates a record to store a script to be executed when a specific * event fires on a specific channel. * * Results: * None. * * 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 -- * * Invokes a script scheduled by "fileevent" for when the channel * becomes ready for IO. This function is invoked by the channel * handler which was created by the Tcl "fileevent" command. * * Results: * None. * * Side effects: * Whatever the script does. * *---------------------------------------------------------------------- */ static void 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. */ if (result != TCL_OK) { if (chanPtr->typePtr != NULL) { DeleteScriptRecord(interp, chanPtr, mask); } Tcl_BackgroundError(interp); } 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; } /* *---------------------------------------------------------------------- * * TclTestChannelCmd -- * * Implements the Tcl "testchannel" debugging command and its * subcommands. This is part of the testing environment but must be * in this file instead of tclTest.c because it needs access to the * fields of struct Channel. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */ int TclTestChannelCmd(clientData, interp, argc, argv) ClientData clientData; /* Not used. */ Tcl_Interp *interp; /* Interpreter for result. */ int argc; /* Count of additional args. */ char **argv; /* Additional arg strings. */ { char *cmdName; /* Sub command. */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ 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]); Tcl_AppendElement(interp, chanPtr->typePtr->typeName); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_NONBLOCKING) { Tcl_AppendElement(interp, "nonblocking"); } else { Tcl_AppendElement(interp, "blocking"); } if (chanPtr->flags & CHANNEL_LINEBUFFERED) { Tcl_AppendElement(interp, "line"); } else if (chanPtr->flags & CHANNEL_UNBUFFERED) { Tcl_AppendElement(interp, "none"); } else { Tcl_AppendElement(interp, "full"); } if (chanPtr->flags & BG_FLUSH_SCHEDULED) { Tcl_AppendElement(interp, "async_flush"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_EOF) { Tcl_AppendElement(interp, "eof"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & CHANNEL_BLOCKED) { Tcl_AppendElement(interp, "blocked"); } else { Tcl_AppendElement(interp, "unblocked"); } if (chanPtr->inputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "saw_cr"); } else { Tcl_AppendElement(interp, ""); } } else if (chanPtr->inputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); Tcl_AppendElement(interp, ""); } else if (chanPtr->inputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); if (chanPtr->flags & INPUT_SAW_CR) { Tcl_AppendElement(interp, "queued_cr"); } else { Tcl_AppendElement(interp, ""); } } if (chanPtr->outputTranslation == TCL_TRANSLATE_AUTO) { Tcl_AppendElement(interp, "auto"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_LF) { Tcl_AppendElement(interp, "lf"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CR) { Tcl_AppendElement(interp, "cr"); } else if (chanPtr->outputTranslation == TCL_TRANSLATE_CRLF) { Tcl_AppendElement(interp, "crlf"); } for (IOQueued = 0, bufPtr = chanPtr->inQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved; } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - chanPtr->curOutPtr->nextRemoved; } for (bufPtr = chanPtr->outQueueHead; bufPtr != (ChannelBuffer *) NULL; bufPtr = bufPtr->nextPtr) { IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved); } TclFormatInt(buf, IOQueued); Tcl_AppendElement(interp, buf); TclFormatInt(buf, Tcl_Tell((Tcl_Channel) chanPtr)); Tcl_AppendElement(interp, buf); TclFormatInt(buf, chanPtr->refCount); Tcl_AppendElement(interp, buf); return TCL_OK; } if ((cmdName[0] == 'i') && (strncmp(cmdName, "inputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } 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", (char *) NULL); return TCL_ERROR; } if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, "read"); } else { Tcl_AppendElement(interp, ""); } if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, "write"); } else { Tcl_AppendElement(interp, ""); } return TCL_OK; } if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->channelName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } return TCL_OK; } if ((cmdName[0] == 'o') && (strncmp(cmdName, "outputbuffered", len) == 0)) { if (argc != 3) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } IOQueued = 0; if (chanPtr->curOutPtr != (ChannelBuffer *) NULL) { IOQueued = chanPtr->curOutPtr->nextAdded - 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) { Tcl_AppendResult(interp, "channel name required", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, (chanPtr->flags & INPUT_SAW_CR) ? "1" : "0", (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_READABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } 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", (char *) NULL); return TCL_ERROR; } Tcl_AppendResult(interp, chanPtr->typePtr->typeName, (char *) NULL); return TCL_OK; } if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) { hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == (Tcl_HashTable *) NULL) { return TCL_OK; } for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != (Tcl_HashEntry *) NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { chanPtr = (Channel *) Tcl_GetHashValue(hPtr); if (chanPtr->flags & TCL_WRITABLE) { Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr)); } } return TCL_OK; } Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ", "info, open, readable, or writable", (char *) NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * TclTestChannelEventCmd -- * * This procedure implements the "testchannelevent" command. It is * used to test the Tcl channel event mechanism. It is present in * this file instead of tclTest.c because it needs access to the * internal structure of the channel. * * Results: * A standard Tcl result. * * Side effects: * Creates, deletes and returns channel event handlers. * *---------------------------------------------------------------------- */ /* ARGSUSED */ 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], " channelName cmd ?arg1? ?arg2?\"", (char *) NULL); return TCL_ERROR; } chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL); if (chanPtr == (Channel *) NULL) { return TCL_ERROR; } cmd = argv[2]; len = strlen(cmd); if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName add eventSpec script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[3], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[3], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[3], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr = (EventScriptRecord *) ckalloc((unsigned) 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; } if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) { if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (esPtr == chanPtr->scriptRecordPtr) { chanPtr->scriptRecordPtr = esPtr->nextPtr; } else { for (prevEsPtr = chanPtr->scriptRecordPtr; (prevEsPtr != (EventScriptRecord *) NULL) && (prevEsPtr->nextPtr != esPtr); prevEsPtr = prevEsPtr->nextPtr) { /* Empty loop body. */ } 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)) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " channelName delete index event\"", (char *) NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) { return TCL_ERROR; } if (index < 0) { Tcl_AppendResult(interp, "bad event index: ", argv[3], ": must be nonnegative", (char *) NULL); return TCL_ERROR; } for (i = 0, esPtr = chanPtr->scriptRecordPtr; (i < index) && (esPtr != (EventScriptRecord *) NULL); i++, esPtr = esPtr->nextPtr) { /* Empty loop body. */ } if (esPtr == (EventScriptRecord *) NULL) { Tcl_AppendResult(interp, "bad event index ", argv[3], ": out of range", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[4], "readable") == 0) { mask = TCL_READABLE; } else if (strcmp(argv[4], "writable") == 0) { mask = TCL_WRITABLE; } else if (strcmp(argv[4], "none") == 0) { mask = 0; } else { Tcl_AppendResult(interp, "bad event name \"", argv[4], "\": must be readable, writable, or none", (char *) NULL); return TCL_ERROR; } esPtr->mask = mask; 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 -- * * This routine copies data from one channel to another, either * synchronously or asynchronously. If a command script is * supplied, the operation runs in the background. The script * is invoked when the copy completes. Otherwise the function * waits until the copy is completed before returning. * * Results: * A standard Tcl result. * * Side effects: * May schedule a background copy operation that causes both * channels to be marked busy. * *---------------------------------------------------------------------- */ int TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Channel inChan; /* Channel to read from. */ Tcl_Channel outChan; /* Channel to write to. */ int toRead; /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr; /* Pointer to script to execute or NULL. */ { Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; if (inPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); return TCL_ERROR; } if (outPtr->csPtr) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); return TCL_ERROR; } readFlags = inPtr->flags; writeFlags = outPtr->flags; /* * Set up the blocking mode appropriately. Background copies need * non-blocking channels. Foreground copies need blocking channels. * If there is an error, restore the old blocking mode. */ if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(interp, inPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) { return TCL_ERROR; } } if (inPtr != outPtr) { if (nonBlocking != (writeFlags & CHANNEL_NONBLOCKING)) { if (SetBlockMode(NULL, outPtr, nonBlocking ? TCL_MODE_BLOCKING : TCL_MODE_NONBLOCKING) != TCL_OK) { if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING) ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); return TCL_ERROR; } } } } /* * Make sure the output side is unbuffered. */ outPtr->flags = (outPtr->flags & ~(CHANNEL_LINEBUFFERED)) | CHANNEL_UNBUFFERED; /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ csPtr = (CopyState*) ckalloc(sizeof(CopyState) + inPtr->bufSize); csPtr->bufSize = inPtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); } csPtr->cmdPtr = cmdPtr; inPtr->csPtr = csPtr; outPtr->csPtr = csPtr; /* * Start copying data between the channels. */ return CopyData(csPtr, 0); } /* *---------------------------------------------------------------------- * * CopyData -- * * This function implements the lowest level of the copying * mechanism for TclCopyChannel. * * Results: * Returns TCL_OK on success, else TCL_ERROR. * * Side effects: * Moves data between channels, may create channel handlers. * *---------------------------------------------------------------------- */ static int CopyData(csPtr, mask) CopyState *csPtr; /* State of copy operation. */ int mask; /* Current channel event flags. */ { Tcl_Interp *interp; Tcl_Obj *cmdPtr, *errObj = NULL; Tcl_Channel inChan, outChan; int result = TCL_OK; int size; int total; inChan = (Tcl_Channel)csPtr->readPtr; outChan = (Tcl_Channel)csPtr->writePtr; interp = csPtr->interp; cmdPtr = csPtr->cmdPtr; /* * Copy the data the slow way, using the translation mechanism. */ while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ if (csPtr->readPtr->unreportedError != 0) { Tcl_SetErrno(csPtr->readPtr->unreportedError); csPtr->readPtr->unreportedError = 0; goto readError; } if (csPtr->writePtr->unreportedError != 0) { Tcl_SetErrno(csPtr->writePtr->unreportedError); csPtr->writePtr->unreportedError = 0; goto writeError; } /* * Read up to bufSize bytes. */ if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { size = csPtr->bufSize; } else { size = csPtr->toRead; } size = DoRead(csPtr->readPtr, csPtr->buffer, size); if (size < 0) { readError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error reading \"", Tcl_GetChannelName(inChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } else if (size == 0) { /* * We had an underflow on the read side. If we are at EOF, * then the copying is done, otherwise set up a channel * handler to detect when the channel becomes readable again. */ if (Tcl_Eof(inChan)) { break; } else if (!(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Now write the buffer out. */ size = DoWrite(csPtr->writePtr, csPtr->buffer, size); if (size < 0) { writeError: errObj = Tcl_NewObj(); Tcl_AppendStringsToObj(errObj, "error writing \"", Tcl_GetChannelName(outChan), "\": ", Tcl_PosixError(interp), (char *) NULL); break; } /* * Check to see if the write is happening in the background. If so, * stop copying and wait for the channel to become writable again. */ if (csPtr->writePtr->flags & BG_FLUSH_SCHEDULED) { if (!(mask & TCL_WRITABLE)) { if (mask & TCL_READABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, (ClientData) csPtr); } Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } /* * Update the current byte count if we care. */ if (csPtr->toRead != -1) { csPtr->toRead -= size; } csPtr->total += size; /* * For background copies, we only do one buffer per invocation so * we don't starve the rest of the system. */ if (cmdPtr) { /* * The first time we enter this code, there won't be a * channel handler established yet, so do it here. */ if (mask == 0) { Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc, (ClientData) csPtr); } return TCL_OK; } } /* * Make the callback or return the number of bytes transferred. * The local total is used because StopCopy frees csPtr. */ total = csPtr->total; if (cmdPtr) { /* * Get a private copy of the command so we can mutate it * by adding arguments. Note that StopCopy frees our saved * reference to the original command obj. */ cmdPtr = Tcl_DuplicateObj(cmdPtr); Tcl_IncrRefCount(cmdPtr); 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 * the background copy operation. It is just a trivial wrapper * around the CopyData routine. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void CopyEventProc(clientData, mask) ClientData clientData; int mask; { (void) CopyData((CopyState *)clientData, mask); } /* *---------------------------------------------------------------------- * * StopCopy -- * * This routine halts a copy that is in progress. * * Results: * None. * * Side effects: * Removes any pending channel handlers and restores the blocking * and buffering modes of the channels. The CopyState is freed. * *---------------------------------------------------------------------- */ static void StopCopy(csPtr) CopyState *csPtr; /* State for bg copy to stop . */ { int nonBlocking; if (!csPtr) { return; } /* * Restore the old blocking mode and output buffering mode. */ nonBlocking = (csPtr->readFlags & CHANNEL_NONBLOCKING); if (nonBlocking != (csPtr->readPtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->readPtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } if (csPtr->writePtr != csPtr->writePtr) { if (nonBlocking != (csPtr->writePtr->flags & CHANNEL_NONBLOCKING)) { SetBlockMode(NULL, csPtr->writePtr, nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING); } } csPtr->writePtr->flags &= ~(CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); csPtr->writePtr->flags |= csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->readPtr, CopyEventProc, (ClientData)csPtr); if (csPtr->readPtr != csPtr->writePtr) { Tcl_DeleteChannelHandler((Tcl_Channel)csPtr->writePtr, CopyEventProc, (ClientData)csPtr); } Tcl_DecrRefCount(csPtr->cmdPtr); } csPtr->readPtr->csPtr = NULL; csPtr->writePtr->csPtr = NULL; ckfree((char*) csPtr); } trf2.1.4/patches/v8.0.4/tcl.h0000644000175000017500000017170511216344361015005 0ustar sergeisergei/* * 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. * 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: tcl.h,v 1.1 1999/03/14 18:43:55 aku Exp $ */ #ifndef _TCL #define _TCL /* * When version numbers change here, must also go into the following files * and update the version numbers: * * README * 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/README * win/README.binary * * 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 4 #define TCL_VERSION "8.0" #define TCL_PATCH_LEVEL "8.0.4" /* * The following definitions set up the proper options for Windows * compilers. We use this method because there is no autoconf equivalent. */ #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) # define __WIN32__ # endif #endif #ifdef __WIN32__ # ifndef STRICT # define STRICT # endif # ifndef USE_PROTOTYPE # define USE_PROTOTYPE 1 # 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 #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 /* * 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 /* * 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. */ #ifndef RESOURCE_INCLUDED #ifndef BUFSIZ #include #endif /* * Definitions that allow Tcl functions with variable numbers of * arguments to be used with either varargs.h or stdarg.h. TCL_VARARGS * is used in procedure prototypes. TCL_VARARGS_DEF is used to declare * 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 /* * 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. * The support follows the convention 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. See BUILD_tcl in this * file for an example of how the macro is to be used. */ #ifdef __WIN32__ # ifdef STATIC_BUILD # define DLLIMPORT # define DLLEXPORT # else # ifdef _MSC_VER # define DLLIMPORT __declspec(dllimport) # define DLLEXPORT __declspec(dllexport) # else # define DLLIMPORT # define DLLEXPORT # endif # endif #else # define DLLIMPORT # define DLLEXPORT #endif #ifdef TCL_STORAGE_CLASS # undef TCL_STORAGE_CLASS #endif #ifdef BUILD_tcl # define TCL_STORAGE_CLASS DLLEXPORT #else # define TCL_STORAGE_CLASS DLLIMPORT #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" 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. */ #ifndef __WIN32__ #ifndef VOID # ifdef __STDC__ # define VOID void # else # define VOID char # endif #endif #else /* __WIN32__ */ /* * The following code is copied from winnt.h */ #ifndef VOID #define VOID void typedef char CHAR; typedef short SHORT; typedef long LONG; #endif #endif /* __WIN32__ */ /* * Miscellaneous declarations. */ #ifndef NULL #define NULL 0 #endif #ifndef _CLIENTDATA # if defined(__STDC__) || defined(__cplusplus) typedef void *ClientData; # else typedef int *ClientData; # endif /* __STDC__ */ #define _CLIENTDATA #endif /* * Data structures defined opaquely in this module. The definitions below * just provide dummy types. A few fields are made visible in Tcl_Interp * structures, namely those used for returning a string result from * commands. Direct access to the result field is discouraged in Tcl 8.0. * The interpreter result is either an object or a string, and the two * values are kept consistent unless some C code sets interp->result * directly. Programmers should use either the procedure Tcl_GetObjResult() * or Tcl_GetStringResult() to read the interpreter's result. See the * SetResult man page for details. * * Note: any change to the Tcl_Interp definition below must be mirrored * in the "real" definition in tclInt.h. * * Note: Tcl_ObjCmdProc procedures do not directly set result and freeProc. * Instead, they set a Tcl_Obj member in the "real" structure that can be * accessed with Tcl_GetObjResult() and Tcl_SetObjResult(). */ typedef struct Tcl_Interp { char *result; /* If the last command returned a string * result, this points to it. */ void (*freeProc) _ANSI_ARGS_((char *blockPtr)); /* Zero means the string result is * statically allocated. TCL_DYNAMIC means * it was allocated with ckalloc and should * be freed with ckfree. Other values give * the address of procedure to invoke to * free the result. Tcl_Eval must free it * before executing next command. */ int errorLine; /* When TCL_ERROR is returned, this gives * 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 * procedures Tcl_GetObjResult() or Tcl_GetStringResult() to read the * interpreter's result. See the SetResult man page for details. Besides * this result, the command procedure returns an integer code, which is * one of the following: * * TCL_OK Command completed normally; the interpreter's * result contains the command's result. * TCL_ERROR The command couldn't be completed successfully; * the interpreter's result describes what went wrong. * TCL_RETURN The command requests that the current procedure * return; the interpreter's result contains the * procedure's return value. * TCL_BREAK The command requests that the innermost loop * be exited; the interpreter's result is meaningless. * TCL_CONTINUE Go on to the next iteration of the current loop; * the interpreter's result is meaningless. */ #define TCL_OK 0 #define TCL_ERROR 1 #define TCL_RETURN 2 #define TCL_BREAK 3 #define TCL_CONTINUE 4 #define TCL_RESULT_SIZE 200 /* * Argument descriptors for math function callbacks in expressions: */ typedef enum {TCL_INT, TCL_DOUBLE, TCL_EITHER} Tcl_ValueType; typedef struct Tcl_Value { Tcl_ValueType type; /* Indicates intValue or doubleValue is * valid, or both. */ long intValue; /* Integer value. */ double doubleValue; /* Double-precision floating value. */ } Tcl_Value; /* * Forward declaration of Tcl_Obj to prevent an error when the forward * reference to Tcl_Obj is encountered in the procedure types declared * below. */ struct Tcl_Obj; /* * Procedure types defined by Tcl: */ typedef int (Tcl_AppInitProc) _ANSI_ARGS_((Tcl_Interp *interp)); typedef int (Tcl_AsyncProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int code)); typedef void (Tcl_ChannelProc) _ANSI_ARGS_((ClientData clientData, int mask)); typedef void (Tcl_CloseProc) _ANSI_ARGS_((ClientData data)); typedef void (Tcl_CmdDeleteProc) _ANSI_ARGS_((ClientData clientData)); 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, Tcl_Interp *interp, char *part1, char *part2, int flags)); /* * The following structure represents a type of object, which is a * particular internal representation for an object plus a set of * procedures that provide standard operations on objects of that type. */ typedef struct Tcl_ObjType { char *name; /* Name of the type, e.g. "int". */ Tcl_FreeInternalRepProc *freeIntRepProc; /* Called to free any storage for the type's * internal rep. NULL if the internal rep * does not need freeing. */ Tcl_DupInternalRepProc *dupIntRepProc; /* Called to create a new object as a copy * of an existing object. */ Tcl_UpdateStringProc *updateStringProc; /* Called to update the string rep from the * type's internal representation. */ Tcl_SetFromAnyProc *setFromAnyProc; /* Called to convert the object's internal * rep to this type. Frees the internal rep * of the old type. Returns TCL_ERROR on * failure. */ } Tcl_ObjType; /* * One of the following structures exists for each object in the Tcl * system. An object stores a value as either a string, some internal * representation, or both. */ typedef struct Tcl_Obj { int refCount; /* When 0 the object will be freed. */ char *bytes; /* This points to the first byte of the * object's string representation. The array * 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: */ long longValue; /* - an long integer value */ double doubleValue; /* - a double-precision floating value */ VOID *otherValuePtr; /* - another, type-specific value */ struct { /* - internal rep as two pointers */ VOID *ptr1; VOID *ptr2; } twoPtrValue; } internalRep; } Tcl_Obj; /* * Macros to increment and decrement a Tcl_Obj's reference count, and to * test whether an object is shared (i.e. has reference count > 1). * Note: clients should use Tcl_DecrRefCount() when they are finished using * an object, and should never call TclFreeObj() directly. TclFreeObj() is * only defined and made public in tcl.h to support Tcl_DecrRefCount's macro * definition. Note also that Tcl_DecrRefCount() refers to the parameter * "obj" twice. This means that you should avoid calling it with an * expression that is expensive to compute or has side effects. */ EXTERN void Tcl_IncrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN void Tcl_DecrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr)); EXTERN int Tcl_IsShared _ANSI_ARGS_((Tcl_Obj *objPtr)); #ifdef TCL_MEM_DEBUG # define Tcl_IncrRefCount(objPtr) \ Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_DecrRefCount(objPtr) \ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__) # define Tcl_IsShared(objPtr) \ Tcl_DbIsShared(objPtr, __FILE__, __LINE__) #else # define Tcl_IncrRefCount(objPtr) \ ++(objPtr)->refCount # define Tcl_DecrRefCount(objPtr) \ 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). */ typedef struct Tcl_Namespace { char *name; /* The namespace's name within its parent * namespace. This contains no ::'s. The * name of the global namespace is "" * although "::" is an synonym. */ char *fullName; /* The namespace's fully qualified name. * This starts with ::. */ ClientData clientData; /* Arbitrary value associated with this * namespace. */ Tcl_NamespaceDeleteProc* deleteProc; /* Procedure invoked when deleting the * namespace to, e.g., free clientData. */ struct Tcl_Namespace* parentPtr; /* Points to the namespace that contains * this one. NULL if this is the global * namespace. */ } Tcl_Namespace; /* * The following structure represents a call frame, or activation record. * A call frame defines a naming context for a procedure call: its local * scope (for local variables) and its namespace scope (used for non-local * variables; often 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 command's code should execute. The * Tcl_CallFrame structures exist only while procedures or namespace * eval/inscope's are being executed, and provide a Tcl call stack. * * A call frame is initialized and pushed using Tcl_PushCallFrame and * popped using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be * provided by the Tcl_PushCallFrame caller, and callers typically allocate * them on the C call stack for efficiency. For this reason, Tcl_CallFrame * is defined as a structure and not as an opaque token. However, most * Tcl_CallFrame fields are hidden since applications should not access * them directly; others are declared as "dummyX". * * WARNING!! The structure definition must be kept consistent with the * CallFrame structure in tclInt.h. If you change one, change the other. */ typedef struct Tcl_CallFrame { Tcl_Namespace *nsPtr; int dummy1; int dummy2; char *dummy3; char *dummy4; char *dummy5; int dummy6; char *dummy7; char *dummy8; int dummy9; char* dummy10; } Tcl_CallFrame; /* * Information about commands that is returned by Tcl_GetCommandInfo and * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based * command procedure while proc is a traditional Tcl argc/argv * string-based procedure. Tcl_CreateObjCommand and Tcl_CreateCommand * ensure that both objProc and proc are non-NULL and can be called to * execute the command. However, it may be faster to call one instead of * the other. The member isNativeObjectProc is set to 1 if an * object-based procedure was registered by Tcl_CreateObjCommand, and to * 0 if a string-based procedure was registered by Tcl_CreateCommand. * The other procedure is typically set to a compatibility wrapper that * does string-to-object or object-to-string argument conversions then * calls the other procedure. */ typedef struct Tcl_CmdInfo { int isNativeObjectProc; /* 1 if objProc was registered by a call to * Tcl_CreateObjCommand; 0 otherwise. * Tcl_SetCmdInfo does not modify this * field. */ Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ ClientData objClientData; /* ClientData for object proc. */ Tcl_CmdProc *proc; /* Command's string-based procedure. */ ClientData clientData; /* ClientData for string proc. */ Tcl_CmdDeleteProc *deleteProc; /* Procedure to call when command is * deleted. */ ClientData deleteData; /* Value to pass to deleteProc (usually * the same as clientData). */ Tcl_Namespace *namespacePtr; /* Points to the namespace that contains * this command. Note that Tcl_SetCmdInfo * will not change a command's namespace; * use Tcl_RenameCommand to do that. */ } Tcl_CmdInfo; /* * The structure defined below is used to hold dynamic strings. The only * field that clients should use is the string field, and they should * never modify it. */ #define TCL_DSTRING_STATIC_SIZE 200 typedef struct Tcl_DString { char *string; /* Points to beginning of string: either * staticSpace below or a malloced array. */ int length; /* Number of non-NULL characters in the * string. */ int spaceAvl; /* Total number of bytes available for the * string and its terminating NULL char. */ char staticSpace[TCL_DSTRING_STATIC_SIZE]; /* Space to use in common case where string * is small. */ } Tcl_DString; #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) #define TCL_STATIC ((Tcl_FreeProc *) 0) #define TCL_DYNAMIC ((Tcl_FreeProc *) 3) /* * Flag values passed to variable-related procedures. */ #define TCL_GLOBAL_ONLY 1 #define TCL_NAMESPACE_ONLY 2 #define TCL_APPEND_VALUE 4 #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 struct Tcl_HashTable; #endif /* * Structure definition for an entry in a hash table. No-one outside * Tcl should access any of these fields directly; use the macros * defined below. */ typedef struct Tcl_HashEntry { struct Tcl_HashEntry *nextPtr; /* Pointer to next entry in this * hash bucket, or NULL for end of * chain. */ struct Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */ struct Tcl_HashEntry **bucketPtr; /* Pointer to bucket that points to * first entry in this entry's chain: * used for deleting the entry. */ ClientData clientData; /* Application stores something here * with Tcl_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ int words[1]; /* Multiple integer words for key. * The actual size will be as large * as necessary for this table's * keys. */ char string[4]; /* String for key. The actual size * will be as large as needed to hold * the key. */ } key; /* MUST BE LAST FIELD IN RECORD!! */ } Tcl_HashEntry; /* * Structure definition for a hash table. Must be in tcl.h so clients * can allocate space for these structures, but clients should never * access any fields in this structure. */ #define TCL_SMALL_HASH_TABLE 4 typedef struct Tcl_HashTable { Tcl_HashEntry **buckets; /* Pointer to bucket array. Each * element points to first entry in * bucket's hash chain, or NULL. */ Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE]; /* Bucket array used for small tables * (to avoid mallocs and frees). */ int numBuckets; /* Total number of buckets allocated * at **bucketPtr. */ int numEntries; /* Total number of entries present * in table. */ int rebuildSize; /* Enlarge table when numEntries gets * to be this large. */ int downShift; /* Shift count used in hashing * function. Designed to use high- * order bits of randomized keys. */ int mask; /* Mask value used in hashing * function. */ int keyType; /* Type of keys used in this table. * It's either TCL_STRING_KEYS, * TCL_ONE_WORD_KEYS, or an integer * giving the number of ints that * is the size of the key. */ Tcl_HashEntry *(*findProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key)); Tcl_HashEntry *(*createProc) _ANSI_ARGS_((struct Tcl_HashTable *tablePtr, CONST char *key, int *newPtr)); } Tcl_HashTable; /* * Structure definition for information used to keep track of searches * through hash tables: */ typedef struct Tcl_HashSearch { Tcl_HashTable *tablePtr; /* Table being searched. */ int nextIndex; /* Index of next bucket to be * enumerated after present one. */ Tcl_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the * the current bucket. */ } Tcl_HashSearch; /* * Acceptable key types for hash tables: */ #define TCL_STRING_KEYS 0 #define TCL_ONE_WORD_KEYS 1 /* * Macros for clients to use to access fields of hash entries: */ #define Tcl_GetHashValue(h) ((h)->clientData) #define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value)) #define Tcl_GetHashKey(tablePtr, h) \ ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS) ? (h)->key.oneWordValue \ : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create procedures * for hash tables: */ #define Tcl_FindHashEntry(tablePtr, key) \ (*((tablePtr)->findProc))(tablePtr, key) #define Tcl_CreateHashEntry(tablePtr, key, newPtr) \ (*((tablePtr)->createProc))(tablePtr, key, newPtr) /* * Flag values to pass to Tcl_DoOneEvent to disable searches * for some kinds of events: */ #define TCL_DONT_WAIT (1<<1) #define TCL_WINDOW_EVENTS (1<<2) #define TCL_FILE_EVENTS (1<<3) #define TCL_TIMER_EVENTS (1<<4) #define TCL_IDLE_EVENTS (1<<5) /* WAS 0x10 ???? */ #define TCL_ALL_EVENTS (~TCL_DONT_WAIT) /* * The following structure defines a generic event for the Tcl event * system. These are the things that are queued in calls to Tcl_QueueEvent * and serviced later by Tcl_DoOneEvent. There can be many different * kinds of events with different fields, corresponding to window events, * timer events, etc. The structure for a particular event consists of * a Tcl_Event header followed by additional information specific to that * event. */ struct Tcl_Event { Tcl_EventProc *proc; /* Procedure to call to service this event. */ struct Tcl_Event *nextPtr; /* Next in list of pending events, or NULL. */ }; /* * Positions to pass to Tcl_QueueEvent: */ typedef enum { TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK } Tcl_QueuePosition; /* * Values to pass to Tcl_SetServiceMode to specify the behavior of notifier * event routines. */ #define TCL_SERVICE_NONE 0 #define TCL_SERVICE_ALL 1 /* * The following structure keeps is used to hold a time value, either as * an absolute time (the number of seconds from the epoch) or as an * elapsed time. On Unix systems the epoch is Midnight Jan 1, 1970 GMT. * On Macintosh systems the epoch is Midnight Jan 1, 1904 GMT. */ typedef struct Tcl_Time { long sec; /* Seconds. */ long usec; /* Microseconds. */ } Tcl_Time; /* * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler * to indicate what sorts of events are of interest: */ #define TCL_READABLE (1<<1) #define TCL_WRITABLE (1<<2) #define TCL_EXCEPTION (1<<3) /* * Flag values to pass to Tcl_OpenCommandChannel to indicate the * disposition of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, * are also used in Tcl_GetStdChannel. */ #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. */ TCL_TRANSLATE_LF, /* Eol == \n. */ TCL_TRANSLATE_CRLF /* Eol == \r\n. */ } Tcl_EolTranslation; /* * Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). * * Enum for different byteorders. */ typedef enum Tcl_ByteOrder { TCL_BIGENDIAN, /* Multibyte words are stored with MSB first */ TCL_SMALLENDIAN /* Multibyte words are stored with MSB last */ } Tcl_ByteOrder; /* * struct Tcl_ChannelType: * * One such structure exists for each type (kind) of channel. * It collects together in one place all the functions that are * part of the specific channel type. */ 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. */ VOID *reserved; /* reserved for future expansion */ } 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. */ #define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */ #define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking * mode. */ /* * Enum for different types of file paths. */ 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)); /* Andreas Kupries , 05/31/1997. * Support of Tcl-Trf (binio). */ EXTERN Tcl_ByteOrder Tcl_GetChannelByteorder _ANSI_ARGS_(( Tcl_Channel chan)); EXTERN Tcl_ByteOrder Tcl_GetHostByteorder _ANSI_ARGS_((void)); 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 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 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 CONST char * Tcl_GetNameOfExecutable _ANSI_ARGS_((void)); 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_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_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)); /* Andreas Kupries , 05/31/1997. * "Trf-Patch for filtering channels" * * C-Level API for (un)stacking of channels. This allows the introduction * of filtering channels with relatively little changes to the core. * This patch was created in cooperation with Jan Nijtmans * and is therefore part of his plus-patches too. * * It would have been possible to place the following definitions according * to the alphabetical order used elsewhere in this file, but I decided * against that to ease the maintenance of the patch across new tcl versions * (patch usually has no problems to integrate the patch file for the last * version into the new one). */ EXTERN Tcl_Channel Tcl_ReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_ChannelType* typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); EXTERN void Tcl_UndoReplaceChannel _ANSI_ARGS_ ((Tcl_Interp* interp, Tcl_Channel chan)); #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TCL */