diff options
Diffstat (limited to 'mac')
49 files changed, 0 insertions, 21394 deletions
diff --git a/mac/AppleScript.html b/mac/AppleScript.html deleted file mode 100644 index 4a73fbb..0000000 --- a/mac/AppleScript.html +++ /dev/null @@ -1,298 +0,0 @@ -<HTML> - -<HEAD> - -<TITLE>tclOSAScript -- OSA</TITLE> - -</HEAD> - -<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#FF0000" ALINK="#00FF00"> - -<H2 ALIGN="CENTER">TclAppleScript Extension Command</H2> - -<H3>NAME</H3> -<DL> -<DT> -AppleScript - Communicate with the AppleScript OSA component to run - AppleScripts from Tcl. -</DL> -<H3>SYNOPSIS</H3> -<DL><DT> -<B>AppleScript <A NAME="compile">compile</A> </B><I>?-flag value?</I> <I>scriptData1 - ?ScriptData2 ...?</I><I>componentName</I> -<BR> -<B>AppleScript <A NAME="decompile">decompile</A></B> <I>scriptName</I> -<BR> -<B>AppleScript delete </B><I>scriptName</I> -<BR> -<B>AppleScript <A NAME="execute">execute</A> </B><I>?flags value?</I> <I>scriptData1 - ?scriptData2 ...?</I> -<BR> -<B>AppleScript <A NAME="info">info</A> </B><I>what</I> -<BR> -<B>AppleScript <A NAME="load">load</A></B> <I>?flag value? fileName</I> -<BR> -<B>AppleScript <A NAME="run">run</A></B> <I>?flag value?</I> - <I>scriptName</I> -<BR> -<B>AppleScript <A NAME="store">store</A></B> <I>?flag value? scriptName fileName</I> -<BR> -</DL> - -<H3>DESCRIPTION</H3> -<DL> -<DT> - - -This command is used to communicate with the AppleScript OSA component. -You can <A HREF="#compile"><B>compile</B></A> scripts, <A -HREF="#run"><B>run</B></A> compiled scripts, <A -HREF="#execute"><B>execute</B></A> script data (i.e. compile and run at a -blow). You can get script data from a compiled script (<A -HREF="#decompile"><B>decompile</B></A> it), and you can <A -HREF="#load"><B>load</B></A> a compiled script from the scpt resource of a -file, or <A HREF="store"><B>store</B></A> one to a scpt resource. You can -also get <A HREF="#info"><B>info</B></A> on the currently available scripts -and contexts. It has the general form - -<DL> -<DT> -<P> -<I>AppleScript option ?arg arg ...?</I> -<P> -</DL> -The possible sub-commands are: -<P> -<DL> - <DT> - <I>AppleScript</I> <A NAME="compile"><B>compile</A> </B><I>?-flag value?</I> <I>scriptData1 - ?ScriptData2 ...?</I> - <BR> - - <DD> - The scriptData - elements are concatenated (with a space between each), and - sent to AppleScript - for compilation. There is no limitation on the size of - the scriptData, beyond the available memory of the Wish interpreter. - <P> - If the compilation is successful, then the command will return a token - that you can pass to the <A HREF="#run">"run"</A> subcommand. If the - compilation fails, then the return value will be the error message from - AppleScript, and the pertinent line of code, with an "_" to indicate - the place where it thinks the error occured. - <P> - The - compilation is controlled by flag value pairs. The available flags - are: - <P> - <DL> - <DT> - <A NAME="first compile switch"><B>-augment Boolean</B></A> - <DD> - To be used in concert with the <A HREF="#-context">-context</A> flag. - If augment is yes, - then the scriptData augments the handlers and data already in the - script context. If augment is no, then the scriptData replaces the - data and handlers already in the context. The default is yes. - <P> - <!-- I'm leaving this flag out for now, since I can't seem to get the - AE manager to obey it. Even when I hard code the value, applications - still switch to the foreground. Oh, well... - - <DT> - <B>-canswitch Boolean </B> - <DD> - If yes, then applications activated by the code in scriptData will - be allowed to switch to the foreground. If no, then they will use - the notification manager to indicate they need attention (this - usually means they blink the Finder icon, and put a check in the - application's entry in the Finder menu). - --> - - <DT> - <B><A NAME="-context">-context</A> Boolean</B> - <DD> - This flag causes the code given in the scriptData to be compiled - into a "context". In AppleScript, this is the equivalent of creating an Tcl - Namespace. The command in this case returns the name of the context as - the its result, rather than a compiled script name. - <P> - You can store data and procedures (aka - handlers) in a script context. Then later, you can - run other scripts in this context, and they will see all the data and - handlers that were set up with this command. You do this by passing the - name of this context to the -context flag of the run or execute subcommands. - <P> - Unlike the straight compile command, the code compiled into a - script context is run immediatly, when it is compiled, to set up the context. - <DT> - <P> - <B>-name string</B> - <DD> - Use <I>string</I> as the name of the script or script context. If there is - already a script - of this name, it will be discarded. The same is true with script - contexts, unless the <I>-augment</I> flag is true. If no name is provided, then a - unique name will be created for you. - <DT> - <P> - <B>-parent contextName </B> - <DD> - This flag is also to be used in conjunction with the <A HREF="#-context">-context</A> flag. - <I>contextName</I> must be the name of a compiled script context. Then - the new script context will inherit the data and handlers from the - parent context. - </DL> - <P> - <DT> - <I>AppleScript</I> <B><A NAME="decompile">decompile</A></B> <I>scriptName</I> - <BR> - <DD> - This decompiles the script data compiled into the script scriptName, - and returns the source code. - <P> - <DT> - <I>AppleScript</I> <B>delete </B><I>scriptName</I> - <BR> - <DD> - This deletes the script data compiled into the script scriptName, - and frees up all the resources associated with it. - <P> - <DT> - <I>AppleScript</I> <B><A NAME="execute">execute</A> </B><I>?flags value?</I> <I>scriptData1 - ?scriptData2 ...?</I> - <BR> - <DD> - This compiles and runs the script in scriptData (concatenating first), and - returns the results of the script execution. It is the same as doing - <I>compile</I> and then <I>run</I>, except that the compiled script is - immediately discarded. - <P> - <DT> - <I>AppleScript</I> <B><A NAME="info">info</A> </B><I>what</I> - <DD> - This gives info on the connection. The allowed values for "what" are: - <P> - <DL> - <DT> - <P> - <B>contexts </B> <I>?pattern?</I> - <DD> - This gives the list of the script contexts that have been. - If <I>pattern</I> is given, it only reports the contexts - that match this pattern. - <DT> - <!-- <P> - <B>language</B> - <DD> - Returns the language of this OSA component - <DT> - --> - <P> - <B>scripts</B> <I>?pattern?</I> - <DD> - This returns a list of the scripts that have been compiled in the - current connection. If <I>pattern</I> is given, it only reports the - script names that match this pattern. - </DL> - <P> - <DT> - <I>AppleScript</I> <B><A NAME="load">load</A></B> <I>?flag value? fileName</I> - <DD> - This loads compiled script data from a resource of type 'scpt' in the - file fileName, and returns a token for the script data. As with the - <I>compile</I> command, the script is not actually executed. Note that all - scripts compiled with Apple's "Script Editor" are stored as script - contexts. However, unlike with the "<I>compile -context</I>" command, the <I>load</I> - command does not run these scripts automatically. If you want to set up - the handlers contained in the loaded script, you must run it manually. - <P> - <I>load</I> takes the following flags: - <P> - <DL> - <DT> - <B>-rsrcname string</B> - <DD> - load a named resource of type 'scpt' using the rsrcname - flag. - <DT> - <P> - <B>-rsrcid integer</B> - <DD> - load a resource by number with the rsrcid flag. - </DL> - <DD> - <P> - If neither the <I>rsrcname</I> nor the <I>rsrcid</I> flag is provided, then the load - command defaults to -rsrcid = 128. This is the resource in which - Apple's Script Editor puts the script data when it writes out a - compiled script. - <P> - <DT> - <I>AppleScript</I> <B><A NAME="run">run</A></B> <I>?flag value?</I> <I>scriptName</I> - <DD> - This runs the script which was previously compiled into <I>scriptName</I>. If the script - runs successfully, the command returns the return value for this command, - coerced to a text string. - If there is an error in - the script execution, then it returns the error result from the - scripting component. It accepts the following flag: - - <DL> - <DT> - <P> - <B>-context contextName</B> - <DD> - <I>contextName</I> must be a context created by a previous call to <I>compile</I> with - the -<I>context</I> flag set. This flag causes the code given in the - <I>scriptData</I> to be run in this "context". It will see all the data and - handlers that were set up previously. - <!-- <DT> - <B>-canswitch Boolean </B> - <DD> - If yes, then applications activated by the code - in scriptData will be allowed to switch to the foreground. If no, then - they will use the notification manager to indicate they need attention - (this usually means they blink the Finder icon, and put a check in the - application's entry in the Finder menu). --> - </DL> - <P> - <DT> - <I>AppleScript </I> <B> <A NAME="store">store</A></B> <I>?flag value? scriptName fileName</I> - <DD> - This stores a compiled script or script context into a resource of type 'scpt' in the - file fileName. - <P> - store takes the following flags: - <P> - <DL> - <DT> - <B>-rsrcname string</B> - <DD> - store to a named resource of type 'scpt' using the rsrcname - flag. - <DT> - <P> - <B>-rsrcid integer</B> - <DD> - store to a numbered resource with the rsrcid flag. - </DL> - <P> - <DD> - If neither the rsrcname nor the rsrcid flag is provided, then the load - command defaults to -rsrcid = 128. Apple's Script Editor can read in files written by - tclOSAScript with this setting of the <I>-rsrcid</I> flag. -</DL> -</DL> -<H2>Notes:</H2> - -The AppleScript command is a stopgap command to fill the place of exec - on the Mac. It is not a supported command, and will likely change - as we broaden it to allow communication with other OSA languages. -<H2>See Also:</H2> - - -</BODY> - -</HTML> diff --git a/mac/Background.doc b/mac/Background.doc deleted file mode 100644 index d23235a..0000000 --- a/mac/Background.doc +++ /dev/null @@ -1,92 +0,0 @@ -Notes about the Background Only application template -==================================================== - -RCS: @(#) $Id: Background.doc,v 1.2 1998/09/14 18:40:03 stanton Exp $ - -We have included sample code and project files for making a Background-Only - application (BOA) in Tcl. This could be used for server processes (like the -Tcl Web-Server). - -Files: ------- - -* BOA_TclShells.¼ - This is the project file. -* tclMacBOAAppInit.c - This is the AppInit file for the BOA App. -* tclMacBOAMain - This is a replacement for the Tcl_Main for BOA's. - -Caveat: -------- - -This is an unsupported addition to MacTcl. The main feature that will certainly -change is how we handle AppleEvents. Currently, all the AppleEvent handling is -done on the Tk side, which is not really right. Also, there is no way to -register your own AppleEvent handlers, which is obviously something that would be -useful in a BOA App. We will address these issues in Tcl8.1. If you need to -register your own AppleEvent Handlers in the meantime, be aware that your code -will probably break in Tcl8.1. - -I will also improve the basic code here based on feedback that I recieve. This -is to be considered a first cut only at writing a BOA in Tcl. - -Introduction: -------------- - -This project makes a double-clickable BOA application. It obviously needs -some Tcl code to get it started. It will look for this code first in a -'TEXT' resource in the application shell whose name is "bgScript.tcl". If -it does not find any such resource, it will look for a file called -bgScript.tcl in the application's folder. Otherwise it will quit with an -error. - -It creates three files in the application folder to store stdin, stdout & -stderr. They are imaginatively called temp.in, temp.out & temp.err. They -will be opened append, so you do not need to erase them after each use of -the BOA. - -The app does understand the "quit", and the "doScript" AppleEvents, so you can -kill it with the former, and instruct it with the latter. It also has an -aete, so you can target it with Apple's "Script Editor". - -For more information on Macintosh BOA's, see the Apple TechNote: 1070. - -Notifications: --------------- - -BOA's are not supposed to have direct contact with the outside world. They -are, however, allowed to go through the Notification Manager to post -alerts. To this end, I have added a Tcl command called "bgnotify" to the -shell, that simply posts a notification through the notification manager. - -To use it, say: - -bgnotify "Hi, there little buddy" - -It will make the system beep, and pop up an annoying message box with the -text of the first argument to the command. While the message is up, Tcl -is yielding processor time, but not processing any events. - -Errors: -------- - -Usually a Tcl background application will have some startup code, opening -up a server socket, or whatever, and at the end of this, will use the -vwait command to kick off the event loop. If an error occurs in the -startup code, it will kill the application, and a notification of the error -will be posted through the Notification Manager. - -If an error occurs in the event handling code after the -vwait, the error message will be written to the file temp.err. However, -if you would like to have these errors post a notification as well, just -define a proc called bgerror that takes one argument, the error message, -and passes that off to "bgnotify", thusly: - -proc bgerror {mssg} { - bgnotify "A background error has occured\n $mssg" -} - -Support: --------- - -If you have any questions, contact me at: - -jim.ingham@eng.sun.com diff --git a/mac/MW_TclAppleScriptHeader.pch b/mac/MW_TclAppleScriptHeader.pch deleted file mode 100644 index 84b09fc..0000000 --- a/mac/MW_TclAppleScriptHeader.pch +++ /dev/null @@ -1,47 +0,0 @@ -/* - * MW_TclAppleScriptHeader.pch -- - * - * This file is the source for a pre-compilied header that gets used - * for TclAppleScript. This make compilies go a bit - * faster. This file is only intended to be used in the MetroWerks - * CodeWarrior environment. It essentially acts as a place to set - * compiler flags. See MetroWerks documention for more details. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: MW_TclAppleScriptHeader.pch,v 1.4 1999/05/11 07:11:46 jingham Exp $ - */ - -/* - * To use the compilied header you need to set the "Prefix file" in - * the "C/C++ Language" preference panel to point to the created - * compilied header. The name of the header depends on the - * architecture we are compiling for (see the code below). For - * example, for a 68k app the prefix file should be: MW_TclHeader68K. - */ - -#if __POWERPC__ -#pragma precompile_target "MW_TclAppleScriptHeaderPPC" -#elif __CFM68K__ -#pragma precompile_target "MW_TclAppleScriptHeaderCFM68K" -#else -#pragma precompile_target "MW_TclAppleScriptHeader68K" -#endif - -#include "tclMacCommonPch.h" - -/* #define TCL_REGISTER_LIBRARY 1 */ -#define USE_TCL_STUBS - -/* - * Place any includes below that will are needed by the majority of the - * and is OK to be in any file in the system. The pragma's are used - * to control what functions are exported in the Tcl shared library. - */ - -#pragma export on -#pragma export off - diff --git a/mac/MW_TclHeader.pch b/mac/MW_TclHeader.pch deleted file mode 100644 index 5253291..0000000 --- a/mac/MW_TclHeader.pch +++ /dev/null @@ -1,49 +0,0 @@ -/* - * MW_TclHeader.pch -- - * - * This file is the source for a pre-compilied header that gets used - * for all files in the Tcl projects. This make compilies go a bit - * faster. This file is only intended to be used in the MetroWerks - * CodeWarrior environment. It essentially acts as a place to set - * compiler flags. See MetroWerks documention for more details. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: MW_TclHeader.pch,v 1.7 1999/05/11 07:11:48 jingham Exp $ - */ - -/* - * To use the compilied header you need to set the "Prefix file" in - * the "C/C++ Language" preference panel to point to the created - * compilied header. The name of the header depends on the - * architecture we are compiling for (see the code below). For - * example, for a 68k app the prefix file should be: MW_TclHeader68K. - */ -#if __POWERPC__ -#pragma precompile_target "MW_TclHeaderPPC" -#elif __CFM68K__ -#pragma precompile_target "MW_TclHeaderCFM68K" -#else -#pragma precompile_target "MW_TclHeader68K" -#endif - -#include "tclMacCommonPch.h" - -/* - * Place any includes below that will are needed by the majority of the - * and is OK to be in any file in the system. The pragma's are used - * to control what functions are exported in the Tcl shared library. - */ - -#pragma export on -#include "tcl.h" -#include "tclMac.h" -#include "tclInt.h" -#include "MoreFiles.h" -#include "MoreFilesExtras.h" - -#pragma export reset - diff --git a/mac/README b/mac/README deleted file mode 100644 index 84aa4b1..0000000 --- a/mac/README +++ /dev/null @@ -1,78 +0,0 @@ -Tcl 8.3 for Macintosh - -by Ray Johnson -Scriptics Corporation -rjohnson@scriptics.com -with major help from -Jim Ingham -Cygnus Solutions -jingham@cygnus.com - -RCS: @(#) $Id: README,v 1.9 1999/10/05 22:46:13 hobbs Exp $ - -1. Introduction ---------------- - -This is the README file for the Macintosh version of the Tcl -scripting language. The home page for the Macintosh releases is - http://www.scriptics.com/mac/ - -A summary of what's new in this release is at - http://www.scriptics.com/software/whatsnew83.html - -A summary of Macintosh-specific features is at - http://www.scriptics.com/mac/features.html - - -2. The Distribution -------------------- - -Macintosh Tcl is distributed in three different forms. This should -make it easier to only download what you need. Substitute <version> -with the version you wish to use. The packages are as follows: - -mactk<version>.sea.hqx - - This distribution is a "binary" only release. It contains an - installer program that will install a 68k, PowerPC, or Fat - version of the "Tcl Shell" and "Wish" applications. In addition, - it installs the Tcl & Tk libraries in the Extensions folder inside - your System Folder. - -mactcltk-full-<version>.sea.hqx - - This release contains the full release of Tcl and Tk for the - Macintosh plus the More Files packages which Macintosh Tcl and Tk - rely on. - -mactcl-source-<version>.sea.hqx - - This release contains the complete source for Tcl. In - addition, Metrowerks CodeWarrior libraries and project files - are included. However, you must already have the More Files - package to compile this code. - -The "html" subdirectory contains reference documentation in -in the HTML format. You may also find these pages at: - - http://www.scriptics.com/man/tcl<version>/contents.html - -3. Compiling Tcl ----------------- - -In order to compile Macintosh Tcl you must have the -following items: - - CodeWarrior Pro 2 or 3 - Mac Tcl (source) - More Files 1.4.3 - -The included project files should work fine. However, for -current release notes please check this page: - - http://www.scriptics.com/support/howto/compile.html#mac - -If you have comments or Bug reports send them to: -Jim Ingham -jingham@cygnus.com - diff --git a/mac/bugs.doc b/mac/bugs.doc deleted file mode 100644 index b8e7b96..0000000 --- a/mac/bugs.doc +++ /dev/null @@ -1,37 +0,0 @@ -Known bug list for Tcl 8.0 for Macintosh - -by Ray Johnson -Sun Microsystems Laboratories -rjohnson@eng.sun.com - -RCS: @(#) $Id: bugs.doc,v 1.3 1999/08/15 04:05:13 jingham Exp $ - -This was a new feature as of Tcl7.6b1 and as such I'll started with -a clean slate. I currently know of no reproducable bugs. I often -get vague reports - but nothing I've been able to confirm. Let -me know what bugs you find! - -The Macintosh version of Tcl passes most all tests in the Tcl -test suite. Slower Macs may fail some tests in event.test whose -timing constraints are too tight. If other tests fail please report -them. - -Ray - -Known bugs in the current release. - -* With the socket code you can't use the "localhost" host name. This - is actually a known bug in Apple's MacTcp stack. However, you can - use [info hostname] whereever you would have used "localhost" to - achive the same effect. - -* Most socket bugs have been fixed. We do have a couple of test cases - that will hang the Mac, however, and we are still working on them. - If you find additional test cases that show crashes please let us - know! - -* In Tcl 8.2, the new Regexp code seems to be more deeply recursive than -the older version in Tcl8.0. As a result, I have had to increase the Stack -size of Tcl to 1Meg. If you are not doing regexps with many subexpressions, -this is probably more stack than you will need. You can relink with the -stack set to 512K, and you will be fine for most purposes. diff --git a/mac/libmoto.doc b/mac/libmoto.doc deleted file mode 100644 index 2183651..0000000 --- a/mac/libmoto.doc +++ /dev/null @@ -1,39 +0,0 @@ -Notes about the use of libmoto ------------------------------- - -RCS: @(#) $Id: libmoto.doc,v 1.2 1998/09/14 18:40:04 stanton Exp $ - -First of all, libmoto is not required! If you don't have it, you -can simply remove the library reference from the project file and -everything should compile just fine. - -The libmoto library replaces certain functions in the MathLib and -ANSI libraries. Motorola has optimized the functions in the library -to run very fast on the PowerPC. As I said above, you don't need -this library, but it does make things faster. - -Obtaining Libmoto: - - For more information about Libmoto and how to doanload - it, visit the following URL: - - http://www.mot.com/SPS/PowerPC/library/fact_sheet/libmoto.html - - You will need to register for the library. However, the - library is free and you can use it in any commercial product - you might have. - -Installing Libmoto: - - Just follow the instructions provided by the Motorola - README file. You need to make sure that the Libmoto - library is before the ANSI and MathLib libraries in - link order. Also, you will get several warnings stateing - that certain functions have already been defined in - Libmoto. (These can safely be ignored.) - -Finally, you can thank Kate Stewart of Motorola for twisting my -arm at the Tcl/Tk Conference to provide some support for Libmoto. - -Ray Johnson - diff --git a/mac/morefiles.doc b/mac/morefiles.doc deleted file mode 100644 index 58f0929..0000000 --- a/mac/morefiles.doc +++ /dev/null @@ -1,74 +0,0 @@ -Notes about MoreFiles, dnr.c & other non-Tcl source files ---------------------------------------------------------- - -RCS: @(#) $Id: morefiles.doc,v 1.2 1998/09/14 18:40:04 stanton Exp $ - -The Macintosh distribution uses several source files that don't -actually ship with Tcl. This sometimes causes problems or confusion -to developers. This document should help clear up a few things. - -dnr.c ------ - -We have found a way to work around some bugs in dnr.c that -Apple has never fixed even though we sent in numerous bug reports. -The file tclMacDNR.c simply set's some #pragma's and the includes -the Apple dnr.c file. This should work the problems that many of -you have reported with dnr.c. - -More Files ----------- - -Macintosh Tcl/Tk also uses Jim Luther's very useful package called -More Files. More Files fixes many of the broken or underfunctional -parts of the file system. - -More Files can be found on the MetroWerks CD and Developer CD from -Apple. You can also down load the latest version from: - - ftp://members.aol.com/JumpLong/ - -The package can also be found at the home of Tcl/Tk for the mac: - - ftp://ftp.sunlabs.com/pub/tcl/mac/ - -I used to just link the More Files library in the Tcl projects. -However, this caused problems when libraries wern't matched correctly. -I'm now including the files in the Tcl project directly. This -solves the problem of missmatched libraries - but may not always -compile. - -If you get a compiliation error in MoreFiles you need to contact -Jim Luther. His email address: - - JumpLong@aol.com - -The version of More Files that we use with Tcl/Tk is 1.4.3. Early -version may work as well.. - -Unfortunantly, there is one bug in his library (in 1.4.3). The bug is -in the function FSpGetFullPath found in the file FullPath.c. After -the call to PBGetCatInfoSync you need to change the line: - - if ( result == noErr ) - - to: - - if ( (result == noErr) || (result == fnfErr) ) - - -The latest version of More Files is 1.4.6. Unfortunantly, this -version has a bug that keeps it from working with shared libraries -right out of the box. If you want to use 1.4.6 you can but you will -need to make the following fix: - - In the file "Opimization.h" in the More Files package you - need to remove the line "#pragma internal on". And in the - file "OptimazationEnd.h" you need to remove the line - "#pragma internal reset". - -Note: the version of MoreFile downloaded from the Sun Tcl/Tk site -will have the fix included. (If you want you can send email to -Jim Luther suggesting that he use Tcl for regression testing!) - -Ray Johnson diff --git a/mac/porting.notes b/mac/porting.notes deleted file mode 100644 index 5e71969..0000000 --- a/mac/porting.notes +++ /dev/null @@ -1,23 +0,0 @@ -Porting Notes -------------- - -RCS: @(#) $Id: porting.notes,v 1.2 1998/09/14 18:40:04 stanton Exp $ - -Currently, the Macintosh version Tcl only compilies with the -CodeWarrior C compilier from MetroWerks. It should be straight -forward to port the Tcl source to MPW. - -Tcl on the Mac no longer requires the use of GUSI. It should now -be easier to port Tcl/Tk to other compiliers such as Symantic C -and MPW C. - -If you attempt to port Tcl to other Macintosh compiliers please -let me know. I would be glad to help with advice and encouragement. -If your efforts are succesfull I wold also be interested in puting -those changes into the core distribution. Furthermore, please feel -free to send me any notes you might make about your porting -experience so I may include them in this file for others to reference. - -Ray Johnson -ray.johnson@eng.sun.com - diff --git a/mac/tclMac.h b/mac/tclMac.h deleted file mode 100644 index a051cc8..0000000 --- a/mac/tclMac.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * tclMac.h -- - * - * Declarations of Macintosh specific public variables and procedures. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMac.h,v 1.4 1999/03/10 05:52:51 stanton Exp $ - */ - -#ifndef _TCLMAC -#define _TCLMAC - -#ifndef _TCL -# include "tcl.h" -#endif -#include <Types.h> -#include <Files.h> -#include <Events.h> - -/* - * "export" is a MetroWerks specific pragma. It flags the linker that - * any symbols that are defined when this pragma is on will be exported - * to shared libraries that link with this library. - */ - -#pragma export on - -typedef int (*Tcl_MacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr)); - -#include "tclPlatDecls.h" - -#pragma export reset - -#endif /* _TCLMAC */ diff --git a/mac/tclMacAETE.r b/mac/tclMacAETE.r deleted file mode 100644 index be9dd11..0000000 --- a/mac/tclMacAETE.r +++ /dev/null @@ -1,58 +0,0 @@ -/* - * tclMacAETE.r -- - * - * This file creates the Apple Event Terminology resources - * for use Tcl and Tk. It is not used in the Simple Tcl shell - * since SIOUX does not support AppleEvents. An example of its - * use in Tcl is the TclBGOnly project. And it is used in all the - * Tk Shells. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacAETE.r,v 1.2 1998/09/14 18:40:04 stanton Exp $ - */ - -#define SystemSevenOrLater 1 - -#include <Types.r> -#include <SysTypes.r> -#include <AEUserTermTypes.r> - -/* - * The following resources defines the Apple Events that Tk can be - * sent from Apple Script. - */ - -resource 'aete' (0, "Wish Suite") { - 0x01, 0x00, english, roman, - { - "Required Suite", - "Events that every application should support", - 'reqd', 1, 1, - {}, - {}, - {}, - {}, - - "Wish Suite", "Events for the Wish application", 'WIsH', 1, 1, - { - "do script", "Execute a Tcl script", 'misc', 'dosc', - 'TEXT', "Result", replyOptional, singleItem, - notEnumerated, reserved, reserved, reserved, reserved, - reserved, reserved, reserved, reserved, reserved, - reserved, reserved, reserved, reserved, - 'TEXT', "Script to execute", directParamRequired, - singleItem, notEnumerated, changesState, reserved, - reserved, reserved, reserved, reserved, reserved, - reserved, reserved, reserved, reserved, reserved, - reserved, - {}, - }, - {}, - {}, - {}, - } -}; diff --git a/mac/tclMacAlloc.c b/mac/tclMacAlloc.c deleted file mode 100644 index c5daa8b..0000000 --- a/mac/tclMacAlloc.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * tclMacAlloc.c -- - * - * This is a very fast storage allocator. It allocates blocks of a - * small number of different sizes, and keeps free lists of each size. - * Blocks that don't exactly fit are passed up to the next larger size. - * Blocks over a certain size are directly allocated by calling NewPtr. - * - * Copyright (c) 1983 Regents of the University of California. - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson - *. - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacAlloc.c,v 1.4 1999/05/11 07:11:51 jingham Exp $ - */ - -#include "tclInt.h" -#include "tclMacInt.h" -#include <Memory.h> -#include <stdlib.h> -#include <string.h> - - -/* - * Flags that are used by ConfigureMemory to define how the allocator - * should work. They can be or'd together. - */ -#define MEMORY_ALL_SYS 1 /* All memory should come from the system -heap. */ - -/* - * Amount of space to leave in the application heap for the Toolbox to work. - */ - -#define TOOLBOX_SPACE (32 * 1024) - -static int memoryFlags = 0; -static Handle toolGuardHandle = NULL; - /* This handle must be around so that we don't - * have NewGWorld failures. This handle is - * purgeable. Before we allocate any blocks, - * we see if this handle is still around. - * If it is not, then we try to get it again. - * If we can get it, we lock it and try - * to do the normal allocation, unlocking on - * the way out. If we can't, we go to the - * system heap directly. */ - - -/* - * The following typedef and variable are used to keep track of memory - * blocks that are allocated directly from the System Heap. These chunks - * of memory must always be freed - even if we crash. - */ - -typedef struct listEl { - Handle memoryHandle; - struct listEl * next; -} ListEl; - -ListEl * systemMemory = NULL; -ListEl * appMemory = NULL; - -/* - * Prototypes for functions used only in this file. - */ - -static pascal void CleanUpExitProc _ANSI_ARGS_((void)); -void ConfigureMemory _ANSI_ARGS_((int flags)); -void FreeAllMemory _ANSI_ARGS_((void)); - -/* - *---------------------------------------------------------------------- - * - * TclpSysRealloc -- - * - * This function reallocates a chunk of system memory. If the - * chunk is already big enough to hold the new block, then no - * allocation happens. - * - * Results: - * Returns a pointer to the newly allocated block. - * - * Side effects: - * May copy the contents of the original block to the new block - * and deallocate the original block. - * - *---------------------------------------------------------------------- - */ - -VOID * -TclpSysRealloc( - VOID *oldPtr, /* Original block */ - unsigned int size) /* New size of block. */ -{ - Handle hand; - void *newPtr; - int maxsize; - - hand = * (Handle *) ((Ptr) oldPtr - sizeof(Handle)); - maxsize = GetHandleSize(hand) - sizeof(Handle); - if (maxsize < size) { - newPtr = TclpSysAlloc(size, 1); - memcpy(newPtr, oldPtr, maxsize); - TclpSysFree(oldPtr); - } else { - newPtr = oldPtr; - } - return newPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TclpSysAlloc -- - * - * Allocate a new block of memory free from the System. - * - * Results: - * Returns a pointer to a new block of memory. - * - * Side effects: - * May obtain memory from app or sys space. Info is added to - * overhead lists etc. - * - *---------------------------------------------------------------------- - */ - -VOID * -TclpSysAlloc( - long size, /* Size of block to allocate. */ - int isBin) /* Is this a bin allocation? */ -{ - Handle hand = NULL; - ListEl * newMemoryRecord; - - if (!(memoryFlags & MEMORY_ALL_SYS)) { - - /* - * If the guard handle has been purged, throw it away and try - * to allocate it again. - */ - - if ((toolGuardHandle != NULL) && (*toolGuardHandle == NULL)) { - DisposeHandle(toolGuardHandle); - toolGuardHandle = NULL; - } - - /* - * If we have never allocated the guard handle, or it was purged - * and thrown away, then try to allocate it again. - */ - - if (toolGuardHandle == NULL) { - toolGuardHandle = NewHandle(TOOLBOX_SPACE); - if (toolGuardHandle != NULL) { - HPurge(toolGuardHandle); - } - } - - /* - * If we got the handle, lock it and do our allocation. - */ - - if (toolGuardHandle != NULL) { - HLock(toolGuardHandle); - hand = NewHandle(size + sizeof(Handle)); - HUnlock(toolGuardHandle); - } - } - if (hand != NULL) { - newMemoryRecord = (ListEl *) NewPtr(sizeof(ListEl)); - if (newMemoryRecord == NULL) { - DisposeHandle(hand); - return NULL; - } - newMemoryRecord->memoryHandle = hand; - newMemoryRecord->next = appMemory; - appMemory = newMemoryRecord; - } else { - /* - * Ran out of memory in application space. Lets try to get - * more memory from system. Otherwise, we return NULL to - * denote failure. - */ - isBin = 0; - hand = NewHandleSys(size + sizeof(Handle)); - if (hand == NULL) { - return NULL; - } - if (systemMemory == NULL) { - /* - * This is the first time we've attempted to allocate memory - * directly from the system heap. We need to now install the - * exit handle to ensure the memory is cleaned up. - */ - TclMacInstallExitToShellPatch(CleanUpExitProc); - } - newMemoryRecord = (ListEl *) NewPtrSys(sizeof(ListEl)); - if (newMemoryRecord == NULL) { - DisposeHandle(hand); - return NULL; - } - newMemoryRecord->memoryHandle = hand; - newMemoryRecord->next = systemMemory; - systemMemory = newMemoryRecord; - } - if (isBin) { - HLockHi(hand); - } else { - HLock(hand); - } - (** (Handle **) hand) = hand; - - return (*hand + sizeof(Handle)); -} - -/* - *---------------------------------------------------------------------- - * - * TclpSysFree -- - * - * Free memory that we allocated back to the system. - * - * Results: - * None. - * - * Side effects: - * Memory is freed. - * - *---------------------------------------------------------------------- - */ - -void -TclpSysFree( - void * ptr) /* Free this system memory. */ -{ - Handle hand; - OSErr err; - - hand = * (Handle *) ((Ptr) ptr - sizeof(Handle)); - DisposeHandle(hand); - *hand = NULL; - err = MemError(); -} - -/* - *---------------------------------------------------------------------- - * - * CleanUpExitProc -- - * - * This procedure is invoked as an exit handler when ExitToShell - * is called. It removes any memory that was allocated directly - * from the system heap. This must be called when the application - * quits or the memory will never be freed. - * - * Results: - * None. - * - * Side effects: - * May free memory in the system heap. - * - *---------------------------------------------------------------------- - */ - -static pascal void -CleanUpExitProc() -{ - ListEl * memRecord; - - while (systemMemory != NULL) { - memRecord = systemMemory; - systemMemory = memRecord->next; - if (*(memRecord->memoryHandle) != NULL) { - DisposeHandle(memRecord->memoryHandle); - } - DisposePtr((void *) memRecord); - } -} - -/* - *---------------------------------------------------------------------- - * - * FreeAllMemory -- - * - * This procedure frees all memory blocks allocated by the memory - * sub-system. Make sure you don't have any code that references - * any malloced data! - * - * Results: - * None. - * - * Side effects: - * Frees all memory allocated by TclpAlloc. - * - *---------------------------------------------------------------------- - */ - -void -FreeAllMemory() -{ - ListEl * memRecord; - - while (systemMemory != NULL) { - memRecord = systemMemory; - systemMemory = memRecord->next; - if (*(memRecord->memoryHandle) != NULL) { - DisposeHandle(memRecord->memoryHandle); - } - DisposePtr((void *) memRecord); - } - while (appMemory != NULL) { - memRecord = appMemory; - appMemory = memRecord->next; - if (*(memRecord->memoryHandle) != NULL) { - DisposeHandle(memRecord->memoryHandle); - } - DisposePtr((void *) memRecord); - } -} - -/* - *---------------------------------------------------------------------- - * - * ConfigureMemory -- - * - * This procedure sets certain flags in this file that control - * how memory is allocated and managed. This call must be made - * before any call to TclpAlloc is made. - * - * Results: - * None. - * - * Side effects: - * Certain state will be changed. - * - *---------------------------------------------------------------------- - */ - -void -ConfigureMemory( - int flags) /* Flags that control memory alloc scheme. */ -{ - memoryFlags = flags; -} diff --git a/mac/tclMacAppInit.c b/mac/tclMacAppInit.c deleted file mode 100644 index c4e4746..0000000 --- a/mac/tclMacAppInit.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * tclMacAppInit.c -- - * - * Provides a version of the Tcl_AppInit procedure for the example shell. - * - * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacAppInit.c,v 1.5 1999/04/16 00:47:19 stanton Exp $ - */ - -#include "tcl.h" -#include "tclInt.h" -#include "tclPort.h" -#include "tclMac.h" -#include "tclMacInt.h" - -#if defined(THINK_C) -# include <console.h> -#elif defined(__MWERKS__) -# include <SIOUX.h> -short InstallConsole _ANSI_ARGS_((short fd)); -#endif - -#ifdef TCL_TEST -extern int Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -extern int Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); -extern int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -extern int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#endif /* TCL_TEST */ - -/* - * Forward declarations for procedures defined later in this file: - */ - -static int MacintoshInit _ANSI_ARGS_((void)); - -/* - *---------------------------------------------------------------------- - * - * main -- - * - * Main program for tclsh. This file can be used as a prototype - * for other applications using the Tcl library. - * - * Results: - * None. This procedure never returns (it exits the process when - * it's done. - * - * Side effects: - * This procedure initializes the Macintosh world and then - * calls Tcl_Main. Tcl_Main will never return except to exit. - * - *---------------------------------------------------------------------- - */ - -void -main( - int argc, /* Number of arguments. */ - char **argv) /* Array of argument strings. */ -{ - char *newArgv[2]; - - if (MacintoshInit() != TCL_OK) { - Tcl_Exit(1); - } - - argc = 1; - newArgv[0] = "tclsh"; - newArgv[1] = NULL; - Tcl_Main(argc, newArgv, Tcl_AppInit); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AppInit -- - * - * This procedure performs application-specific initialization. - * Most applications, especially those that incorporate additional - * packages, will have their own version of this procedure. - * - * Results: - * Returns a standard Tcl completion code, and leaves an error - * message in the interp's result if an error occurs. - * - * Side effects: - * Depends on the startup script. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_AppInit( - Tcl_Interp *interp) /* Interpreter for application. */ -{ - if (Tcl_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - -#ifdef TCL_TEST - if (Tcltest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, - (Tcl_PackageInitProc *) NULL); - if (TclObjTest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - if (Procbodytest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init, - Procbodytest_SafeInit); -#endif /* TCL_TEST */ - - /* - * Call the init procedures for included packages. Each call should - * look like this: - * - * if (Mod_Init(interp) == TCL_ERROR) { - * return TCL_ERROR; - * } - * - * where "Mod" is the name of the module. - */ - - /* - * Call Tcl_CreateCommand for application-specific commands, if - * they weren't already created by the init procedures called above. - * Each call would loo like this: - * - * Tcl_CreateCommand(interp, "tclName", CFuncCmd, NULL, NULL); - */ - - /* - * Specify a user-specific startup script to invoke if the application - * is run interactively. On the Mac we can specifiy either a TEXT resource - * which contains the script or the more UNIX like file location - * may also used. (I highly recommend using the resource method.) - */ - - Tcl_SetVar(interp, "tcl_rcRsrcName", "tclshrc", TCL_GLOBAL_ONLY); - /* Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); */ - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * MacintoshInit -- - * - * This procedure calls initalization routines to set up a simple - * console on a Macintosh. This is necessary as the Mac doesn't - * have a stdout & stderr by default. - * - * Results: - * Returns TCL_OK if everything went fine. If it didn't the - * application should probably fail. - * - * Side effects: - * Inits the appropiate console package. - * - *---------------------------------------------------------------------- - */ - -static int -MacintoshInit() -{ -#if GENERATING68K && !GENERATINGCFM - SetApplLimit(GetApplLimit() - (TCL_MAC_68K_STACK_GROWTH)); -#endif - MaxApplZone(); - -#if defined(THINK_C) - - /* Set options for Think C console package */ - /* The console package calls the Mac init calls */ - console_options.pause_atexit = 0; - console_options.title = "\pTcl Interpreter"; - -#elif defined(__MWERKS__) - - /* Set options for CodeWarrior SIOUX package */ - SIOUXSettings.autocloseonquit = true; - SIOUXSettings.showstatusline = true; - SIOUXSettings.asktosaveonclose = false; - InstallConsole(0); - SIOUXSetTitle("\pTcl Interpreter"); - -#elif defined(applec) - - /* Init packages used by MPW SIOW package */ - InitGraf((Ptr)&qd.thePort); - InitFonts(); - InitWindows(); - InitMenus(); - TEInit(); - InitDialogs(nil); - InitCursor(); - -#endif - - Tcl_MacSetEventProc((Tcl_MacConvertEventPtr) SIOUXHandleOneEvent); - - /* No problems with initialization */ - return TCL_OK; -} diff --git a/mac/tclMacApplication.r b/mac/tclMacApplication.r deleted file mode 100644 index f69b3b6..0000000 --- a/mac/tclMacApplication.r +++ /dev/null @@ -1,75 +0,0 @@ -/* - * tclMacApplication.r -- - * - * This file creates resources for use Tcl Shell application. - * It should be viewed as an example of how to create a new - * Tcl application using the shared Tcl libraries. - * - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacApplication.r,v 1.3 1999/08/16 00:09:09 jingham Exp $ - */ - -#include <Types.r> -#include <SysTypes.r> - -/* - * The folowing include and defines help construct - * the version string for Tcl. - */ - -#define RESOURCE_INCLUDED -#include "tcl.h" - -#if (TCL_RELEASE_LEVEL == 0) -# define RELEASE_LEVEL alpha -#elif (TCL_RELEASE_LEVEL == 1) -# define RELEASE_LEVEL beta -#elif (TCL_RELEASE_LEVEL == 2) -# define RELEASE_LEVEL final -#endif - -#if (TCL_RELEASE_LEVEL == 2) -# define MINOR_VERSION (TCL_MINOR_VERSION * 16) + TCL_RELEASE_SERIAL -#else -# define MINOR_VERSION TCL_MINOR_VERSION * 16 -#endif - -resource 'vers' (1) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - TCL_PATCH_LEVEL ", by Ray Johnson & Jim Ingham © Scriptics Inc" -}; - -resource 'vers' (2) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - "Tcl Shell " TCL_PATCH_LEVEL " © 1996-1997 Sun Microsystems, 1998-1999 Scriptics Inc" -}; - -#define TCL_APP_CREATOR 'Tcl ' - -type TCL_APP_CREATOR as 'STR '; -resource TCL_APP_CREATOR (0, purgeable) { - "Tcl Shell " TCL_PATCH_LEVEL " © 1996-1999" -}; - -/* - * The 'kind' resource works with a 'BNDL' in Macintosh Easy Open - * to affect the text the Finder displays in the "kind" column and - * file info dialog. This information will be applied to all files - * with the listed creator and type. - */ - -resource 'kind' (128, "Tcl kind", purgeable) { - TCL_APP_CREATOR, - 0, /* region = USA */ - { - 'APPL', "Tcl Shell", - } -}; diff --git a/mac/tclMacBOAAppInit.c b/mac/tclMacBOAAppInit.c deleted file mode 100644 index 4fc34e8..0000000 --- a/mac/tclMacBOAAppInit.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * tclMacBOAAppInit.c -- - * - * Provides a version of the Tcl_AppInit procedure for a - * Macintosh Background Only Application. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacBOAAppInit.c,v 1.3 1999/04/16 00:47:19 stanton Exp $ - */ - -#include "tcl.h" -#include "tclInt.h" -#include "tclPort.h" -#include "tclMac.h" -#include "tclMacInt.h" -#include <Fonts.h> -#include <Windows.h> -#include <Dialogs.h> -#include <Menus.h> -#include <Aliases.h> -#include <LowMem.h> - -#include <AppleEvents.h> -#include <SegLoad.h> -#include <ToolUtils.h> - -#if defined(THINK_C) -# include <console.h> -#elif defined(__MWERKS__) -# include <SIOUX.h> -short InstallConsole _ANSI_ARGS_((short fd)); -#endif - -void TkMacInitAppleEvents(Tcl_Interp *interp); -int HandleHighLevelEvents(EventRecord *eventPtr); - -#ifdef TCL_TEST -EXTERN int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -EXTERN int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#endif /* TCL_TEST */ - -/* - * Forward declarations for procedures defined later in this file: - */ - -static int MacintoshInit _ANSI_ARGS_((void)); - -/* - *---------------------------------------------------------------------- - * - * main -- - * - * Main program for tclsh. This file can be used as a prototype - * for other applications using the Tcl library. - * - * Results: - * None. This procedure never returns (it exits the process when - * it's done. - * - * Side effects: - * This procedure initializes the Macintosh world and then - * calls Tcl_Main. Tcl_Main will never return except to exit. - * - *---------------------------------------------------------------------- - */ - -void -main( - int argc, /* Number of arguments. */ - char **argv) /* Array of argument strings. */ -{ - char *newArgv[3]; - - if (MacintoshInit() != TCL_OK) { - Tcl_Exit(1); - } - - argc = 2; - newArgv[0] = "tclsh"; - newArgv[1] = "bgScript.tcl"; - newArgv[2] = NULL; - Tcl_Main(argc, newArgv, Tcl_AppInit); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AppInit -- - * - * This procedure performs application-specific initialization. - * Most applications, especially those that incorporate additional - * packages, will have their own version of this procedure. - * - * Results: - * Returns a standard Tcl completion code, and leaves an error - * message in the interp's result if an error occurs. - * - * Side effects: - * Depends on the startup script. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_AppInit( - Tcl_Interp *interp) /* Interpreter for application. */ -{ - Tcl_Channel tempChan; - - if (Tcl_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - -#ifdef TCL_TEST - if (Tcltest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, - (Tcl_PackageInitProc *) NULL); - if (TclObjTest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } -#endif /* TCL_TEST */ - - /* - * Call the init procedures for included packages. Each call should - * look like this: - * - * if (Mod_Init(interp) == TCL_ERROR) { - * return TCL_ERROR; - * } - * - * where "Mod" is the name of the module. - */ - - /* - * Call Tcl_CreateCommand for application-specific commands, if - * they weren't already created by the init procedures called above. - * Each call would loo like this: - * - * Tcl_CreateCommand(interp, "tclName", CFuncCmd, NULL, NULL); - */ - - /* - * Specify a user-specific startup script to invoke if the application - * is run interactively. On the Mac we can specifiy either a TEXT resource - * which contains the script or the more UNIX like file location - * may also used. (I highly recommend using the resource method.) - */ - - Tcl_SetVar(interp, "tcl_rcRsrcName", "tclshrc", TCL_GLOBAL_ONLY); - - /* Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); */ - - /* - * We have to support at least the quit Apple Event. - */ - - TkMacInitAppleEvents(interp); - - /* - * Open a file channel to put stderr, stdin, stdout... - */ - - tempChan = Tcl_OpenFileChannel(interp, ":temp.in", "a+", 0); - Tcl_SetStdChannel(tempChan,TCL_STDIN); - Tcl_RegisterChannel(interp, tempChan); - Tcl_SetChannelOption(NULL, tempChan, "-translation", "cr"); - Tcl_SetChannelOption(NULL, tempChan, "-buffering", "line"); - - tempChan = Tcl_OpenFileChannel(interp, ":temp.out", "a+", 0); - Tcl_SetStdChannel(tempChan,TCL_STDOUT); - Tcl_RegisterChannel(interp, tempChan); - Tcl_SetChannelOption(NULL, tempChan, "-translation", "cr"); - Tcl_SetChannelOption(NULL, tempChan, "-buffering", "line"); - - tempChan = Tcl_OpenFileChannel(interp, ":temp.err", "a+", 0); - Tcl_SetStdChannel(tempChan,TCL_STDERR); - Tcl_RegisterChannel(interp, tempChan); - Tcl_SetChannelOption(NULL, tempChan, "-translation", "cr"); - Tcl_SetChannelOption(NULL, tempChan, "-buffering", "none"); - - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * MacintoshInit -- - * - * This procedure calls initalization routines to set up a simple - * console on a Macintosh. This is necessary as the Mac doesn't - * have a stdout & stderr by default. - * - * Results: - * Returns TCL_OK if everything went fine. If it didn't the - * application should probably fail. - * - * Side effects: - * Inits the appropiate console package. - * - *---------------------------------------------------------------------- - */ - -static int -MacintoshInit() -{ - THz theZone = GetZone(); - SysEnvRec sys; - - - /* - * There is a bug in systems earlier that 7.5.5, where a second BOA will - * get a corrupted heap. This is the fix from TechNote 1070 - */ - - SysEnvirons(1, &sys); - - if (sys.systemVersion < 0x0755) - { - if ( LMGetHeapEnd() != theZone->bkLim) { - LMSetHeapEnd(theZone->bkLim); - } - } - -#if GENERATING68K && !GENERATINGCFM - SetApplLimit(GetApplLimit() - (TCL_MAC_68K_STACK_GROWTH)); -#endif - MaxApplZone(); - - InitGraf((Ptr)&qd.thePort); - - /* No problems with initialization */ - Tcl_MacSetEventProc(HandleHighLevelEvents); - - return TCL_OK; -} - -int -HandleHighLevelEvents( - EventRecord *eventPtr) -{ - int eventFound = false; - - if (eventPtr->what == kHighLevelEvent) { - AEProcessAppleEvent(eventPtr); - eventFound = true; - } else if (eventPtr->what == nullEvent) { - eventFound = true; - } - return eventFound; -} diff --git a/mac/tclMacBOAMain.c b/mac/tclMacBOAMain.c deleted file mode 100644 index d863e9c..0000000 --- a/mac/tclMacBOAMain.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * tclMacBGMain.c -- - * - * Main program for Macintosh Background Only Application shells. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacBOAMain.c,v 1.3 1999/04/16 00:47:19 stanton Exp $ - */ - -#include "tcl.h" -#include "tclInt.h" -#include "tclMacInt.h" -#include <Resources.h> -#include <Notification.h> -#include <Strings.h> - -/* - * This variable is used to get out of the modal loop of the - * notification manager. - */ - -int NotificationIsDone = 0; - -/* - * The following code ensures that tclLink.c is linked whenever - * Tcl is linked. Without this code there's no reference to the - * code in that file from anywhere in Tcl, so it may not be - * linked into the application. - */ - -EXTERN int Tcl_LinkVar(); -int (*tclDummyLinkVarPtr)() = Tcl_LinkVar; - -/* - * Declarations for various library procedures and variables (don't want - * to include tclPort.h here, because people might copy this file out of - * the Tcl source directory to make their own modified versions). - * Note: "exit" should really be declared here, but there's no way to - * declare it without causing conflicts with other definitions elsewher - * on some systems, so it's better just to leave it out. - */ - -extern int isatty _ANSI_ARGS_((int fd)); -extern char * strcpy _ANSI_ARGS_((char *dst, CONST char *src)); - -static Tcl_Interp *interp; /* Interpreter for application. */ - -#ifdef TCL_MEM_DEBUG -static char dumpFile[100]; /* Records where to dump memory allocation - * information. */ -static int quitFlag = 0; /* 1 means "checkmem" command was called, - * so the application should quit and dump - * memory allocation information. */ -#endif - -/* - * Forward references for procedures defined later in this file: - */ - -#ifdef TCL_MEM_DEBUG -static int CheckmemCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char *argv[])); -#endif -void TclMacDoNotification(char *mssg); -void TclMacNotificationResponse(NMRecPtr nmRec); -int Tcl_MacBGNotifyObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); - - -/* - *---------------------------------------------------------------------- - * - * Tcl_Main -- - * - * Main program for tclsh and most other Tcl-based applications. - * - * Results: - * None. This procedure never returns (it exits the process when - * it's done. - * - * Side effects: - * This procedure initializes the Tk world and then starts - * interpreting commands; almost anything could happen, depending - * on the script being interpreted. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_Main(argc, argv, appInitProc) - int argc; /* Number of arguments. */ - char **argv; /* Array of argument strings. */ - Tcl_AppInitProc *appInitProc; - /* Application-specific initialization - * procedure to call after most - * initialization but before starting to - * execute commands. */ -{ - Tcl_Obj *prompt1NamePtr = NULL; - Tcl_Obj *prompt2NamePtr = NULL; - Tcl_Obj *commandPtr = NULL; - char buffer[1000], *args, *fileName; - int code, tty; - int exitCode = 0; - - Tcl_FindExecutable(argv[0]); - interp = Tcl_CreateInterp(); -#ifdef TCL_MEM_DEBUG - Tcl_InitMemory(interp); - Tcl_CreateCommand(interp, "checkmem", CheckmemCmd, (ClientData) 0, - (Tcl_CmdDeleteProc *) NULL); -#endif - - /* - * Make command-line arguments available in the Tcl variables "argc" - * and "argv". If the first argument doesn't start with a "-" then - * strip it off and use it as the name of a script file to process. - */ - - fileName = NULL; - if ((argc > 1) && (argv[1][0] != '-')) { - fileName = argv[1]; - argc--; - argv++; - } - args = Tcl_Merge(argc-1, argv+1); - Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY); - ckfree(args); - TclFormatInt(buffer, argc-1); - Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "argv0", (fileName != NULL) ? fileName : argv[0], - TCL_GLOBAL_ONLY); - - /* - * Set the "tcl_interactive" variable. - */ - - tty = isatty(0); - Tcl_SetVar(interp, "tcl_interactive", - ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY); - - /* - * Invoke application-specific initialization. - */ - - if ((*appInitProc)(interp) != TCL_OK) { - Tcl_DString errStr; - - Tcl_DStringInit(&errStr); - Tcl_DStringAppend(&errStr, - "application-specific initialization failed: \n", -1); - Tcl_DStringAppend(&errStr, Tcl_GetStringResult(interp), -1); - Tcl_DStringAppend(&errStr, "\n", 1); - TclMacDoNotification(Tcl_DStringValue(&errStr)); - Tcl_DStringFree(&errStr); - goto done; - } - - /* - * Install the BGNotify command: - */ - - if ( Tcl_CreateObjCommand(interp, "bgnotify", Tcl_MacBGNotifyObjCmd, NULL, - (Tcl_CmdDeleteProc *) NULL) == NULL) { - goto done; - } - - /* - * If a script file was specified then just source that file - * and quit. In this Mac BG Application version, we will try the - * resource fork first, then the file system second... - */ - - if (fileName != NULL) { - Str255 resName; - Handle resource; - - strcpy((char *) resName + 1, fileName); - resName[0] = strlen(fileName); - resource = GetNamedResource('TEXT',resName); - if (resource != NULL) { - code = Tcl_MacEvalResource(interp, fileName, -1, NULL); - } else { - code = Tcl_EvalFile(interp, fileName); - } - - if (code != TCL_OK) { - Tcl_DString errStr; - - Tcl_DStringInit(&errStr); - Tcl_DStringAppend(&errStr, " Error sourcing resource or file: ", -1); - Tcl_DStringAppend(&errStr, fileName, -1); - Tcl_DStringAppend(&errStr, "\n\nError was: ", -1); - Tcl_DStringAppend(&errStr, Tcl_GetStringResult(interp), -1); - TclMacDoNotification(Tcl_DStringValue(&errStr)); - Tcl_DStringFree(&errStr); - } - goto done; - } - - - /* - * Rather than calling exit, invoke the "exit" command so that - * users can replace "exit" with some other command to do additional - * cleanup on exit. The Tcl_Eval call should never return. - */ - - done: - if (commandPtr != NULL) { - Tcl_DecrRefCount(commandPtr); - } - if (prompt1NamePtr != NULL) { - Tcl_DecrRefCount(prompt1NamePtr); - } - if (prompt2NamePtr != NULL) { - Tcl_DecrRefCount(prompt2NamePtr); - } - sprintf(buffer, "exit %d", exitCode); - Tcl_Eval(interp, buffer); -} - -/*---------------------------------------------------------------------- - * - * TclMacDoNotification -- - * - * This posts an error message using the Notification manager. - * - * Results: - * Post a Notification Manager dialog. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -void -TclMacDoNotification(mssg) - char *mssg; -{ - NMRec errorNot; - EventRecord *theEvent = NULL; - OSErr err; - char *ptr; - - errorNot.qType = nmType; - errorNot.nmMark = 0; - errorNot.nmIcon = 0; - errorNot.nmSound = (Handle) -1; - - for ( ptr = mssg; *ptr != '\0'; ptr++) { - if (*ptr == '\n') { - *ptr = '\r'; - } - } - - c2pstr(mssg); - errorNot.nmStr = (StringPtr) mssg; - - errorNot.nmResp = NewNMProc(TclMacNotificationResponse); - errorNot.nmRefCon = SetCurrentA5(); - - NotificationIsDone = 0; - - /* - * Cycle while waiting for the user to click on the - * notification box. Don't take any events off the event queue, - * since we want Tcl to do this but we want to block till the notification - * has been handled... - */ - - err = NMInstall(&errorNot); - if (err == noErr) { - while (!NotificationIsDone) { - WaitNextEvent(0, theEvent, 20, NULL); - } - NMRemove(&errorNot); - } - - p2cstr((unsigned char *) mssg); -} - -void -TclMacNotificationResponse(nmRec) - NMRecPtr nmRec; -{ - int curA5; - - curA5 = SetCurrentA5(); - SetA5(nmRec->nmRefCon); - - NotificationIsDone = 1; - - SetA5(curA5); - -} - -int -Tcl_MacBGNotifyObjCmd(clientData, interp, objc, objv) - ClientData clientData; - Tcl_Interp *interp; - int objc; - Tcl_Obj **objv; -{ - Tcl_Obj *resultPtr; - - resultPtr = Tcl_GetObjResult(interp); - - if ( objc != 2 ) { - Tcl_WrongNumArgs(interp, 1, objv, "message"); - return TCL_ERROR; - } - - TclMacDoNotification(Tcl_GetString(objv[1])); - return TCL_OK; - -} - - -/* - *---------------------------------------------------------------------- - * - * CheckmemCmd -- - * - * This is the command procedure for the "checkmem" command, which - * causes the application to exit after printing information about - * memory usage to the file passed to this command as its first - * argument. - * - * Results: - * Returns a standard Tcl completion code. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -#ifdef TCL_MEM_DEBUG - - /* ARGSUSED */ -static int -CheckmemCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Interpreter for evaluation. */ - int argc; /* Number of arguments. */ - char *argv[]; /* String values of arguments. */ -{ - extern char *tclMemDumpFileName; - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " fileName\"", (char *) NULL); - return TCL_ERROR; - } - strcpy(dumpFile, argv[1]); - tclMemDumpFileName = dumpFile; - quitFlag = 1; - return TCL_OK; -} -#endif diff --git a/mac/tclMacChan.c b/mac/tclMacChan.c deleted file mode 100644 index 2fbac8f..0000000 --- a/mac/tclMacChan.c +++ /dev/null @@ -1,1394 +0,0 @@ -/* - * tclMacChan.c - * - * Channel drivers for Macintosh channels for the - * console fds. - * - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacChan.c,v 1.6 1999/04/16 00:47:19 stanton Exp $ - */ - -#include "tclInt.h" -#include "tclPort.h" -#include "tclMacInt.h" -#include <Aliases.h> -#include <Errors.h> -#include <Files.h> -#include <Gestalt.h> -#include <Processes.h> -#include <Strings.h> -#include <FSpCompat.h> -#include <MoreFiles.h> -#include <MoreFilesExtras.h> - - -/* - * The following are flags returned by GetOpenMode. They - * are or'd together to determine how opening and handling - * a file should occur. - */ - -#define TCL_RDONLY (1<<0) -#define TCL_WRONLY (1<<1) -#define TCL_RDWR (1<<2) -#define TCL_CREAT (1<<3) -#define TCL_TRUNC (1<<4) -#define TCL_APPEND (1<<5) -#define TCL_ALWAYS_APPEND (1<<6) -#define TCL_EXCL (1<<7) -#define TCL_NOCTTY (1<<8) -#define TCL_NONBLOCK (1<<9) -#define TCL_RW_MODES (TCL_RDONLY|TCL_WRONLY|TCL_RDWR) - -/* - * This structure describes per-instance state of a - * macintosh file based channel. - */ - -typedef struct FileState { - short fileRef; /* Macintosh file reference number. */ - Tcl_Channel fileChan; /* Pointer to the channel for this file. */ - int watchMask; /* OR'ed set of flags indicating which events - * are being watched. */ - int appendMode; /* Flag to tell if in O_APPEND mode or not. */ - int volumeRef; /* Flag to tell if in O_APPEND mode or not. */ - int pending; /* 1 if message is pending on queue. */ - struct FileState *nextPtr; /* Pointer to next registered file. */ -} FileState; - -typedef struct ThreadSpecificData { - int initialized; /* True after the thread initializes */ - FileState *firstFilePtr; /* the head of the list of files managed - * that are being watched for file events. */ - Tcl_Channel stdinChannel; - Tcl_Channel stdoutChannel; /* Note - these seem unused */ - Tcl_Channel stderrChannel; -} ThreadSpecificData; - -static Tcl_ThreadDataKey dataKey; - -/* - * The following structure is what is added to the Tcl event queue when - * file events are generated. - */ - -typedef struct FileEvent { - Tcl_Event header; /* Information that is standard for - * all events. */ - FileState *infoPtr; /* Pointer to file info structure. Note - * that we still have to verify that the - * file exists before dereferencing this - * pointer. */ -} FileEvent; - - -/* - * Static routines for this file: - */ - -static int CommonGetHandle _ANSI_ARGS_((ClientData instanceData, - int direction, ClientData *handlePtr)); -static void CommonWatch _ANSI_ARGS_((ClientData instanceData, - int mask)); -static int FileBlockMode _ANSI_ARGS_((ClientData instanceData, - int mode)); -static void FileChannelExitHandler _ANSI_ARGS_(( - ClientData clientData)); -static void FileCheckProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static int FileClose _ANSI_ARGS_((ClientData instanceData, - Tcl_Interp *interp)); -static int FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr, - int flags)); -static ThreadSpecificData *FileInit _ANSI_ARGS_((void)); -static int FileInput _ANSI_ARGS_((ClientData instanceData, - char *buf, int toRead, int *errorCode)); -static int FileOutput _ANSI_ARGS_((ClientData instanceData, - char *buf, int toWrite, int *errorCode)); -static int FileSeek _ANSI_ARGS_((ClientData instanceData, - long offset, int mode, int *errorCode)); -static void FileSetupProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static int GetOpenMode _ANSI_ARGS_((Tcl_Interp *interp, - CONST char *string)); -static Tcl_Channel OpenFileChannel _ANSI_ARGS_((CONST char *fileName, - int mode, int permissions, int *errorCodePtr)); -static int StdIOBlockMode _ANSI_ARGS_((ClientData instanceData, - int mode)); -static int StdIOClose _ANSI_ARGS_((ClientData instanceData, - Tcl_Interp *interp)); -static int StdIOInput _ANSI_ARGS_((ClientData instanceData, - char *buf, int toRead, int *errorCode)); -static int StdIOOutput _ANSI_ARGS_((ClientData instanceData, - char *buf, int toWrite, int *errorCode)); -static int StdIOSeek _ANSI_ARGS_((ClientData instanceData, - long offset, int mode, int *errorCode)); -static int StdReady _ANSI_ARGS_((ClientData instanceData, - int mask)); - -/* - * This structure describes the channel type structure for file based IO: - */ - -static Tcl_ChannelType consoleChannelType = { - "file", /* Type name. */ - StdIOBlockMode, /* Set blocking/nonblocking mode.*/ - StdIOClose, /* Close proc. */ - StdIOInput, /* Input proc. */ - StdIOOutput, /* Output proc. */ - StdIOSeek, /* Seek proc. */ - NULL, /* Set option proc. */ - NULL, /* Get option proc. */ - CommonWatch, /* Initialize notifier. */ - CommonGetHandle /* Get OS handles out of channel. */ -}; - -/* - * This variable describes the channel type structure for file based IO. - */ - -static Tcl_ChannelType fileChannelType = { - "file", /* Type name. */ - FileBlockMode, /* Set blocking or - * non-blocking mode.*/ - FileClose, /* Close proc. */ - FileInput, /* Input proc. */ - FileOutput, /* Output proc. */ - FileSeek, /* Seek proc. */ - NULL, /* Set option proc. */ - NULL, /* Get option proc. */ - CommonWatch, /* Initialize notifier. */ - CommonGetHandle /* Get OS handles out of channel. */ -}; - - -/* - * Hack to allow Mac Tk to override the TclGetStdChannels function. - */ - -typedef void (*TclGetStdChannelsProc) _ANSI_ARGS_((Tcl_Channel *stdinPtr, - Tcl_Channel *stdoutPtr, Tcl_Channel *stderrPtr)); - -TclGetStdChannelsProc getStdChannelsProc = NULL; - - -/* - *---------------------------------------------------------------------- - * - * FileInit -- - * - * This function initializes the file channel event source. - * - * Results: - * None. - * - * Side effects: - * Creates a new event source. - * - *---------------------------------------------------------------------- - */ - -static ThreadSpecificData * -FileInit() -{ - ThreadSpecificData *tsdPtr = - (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey); - if (tsdPtr == NULL) { - tsdPtr = TCL_TSD_INIT(&dataKey); - tsdPtr->firstFilePtr = NULL; - Tcl_CreateEventSource(FileSetupProc, FileCheckProc, NULL); - Tcl_CreateThreadExitHandler(FileChannelExitHandler, NULL); - } - return tsdPtr; -} - -/* - *---------------------------------------------------------------------- - * - * FileChannelExitHandler -- - * - * This function is called to cleanup the channel driver before - * Tcl is unloaded. - * - * Results: - * None. - * - * Side effects: - * Destroys the communication window. - * - *---------------------------------------------------------------------- - */ - -static void -FileChannelExitHandler( - ClientData clientData) /* Old window proc */ -{ - Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * FileSetupProc -- - * - * This procedure is invoked before Tcl_DoOneEvent blocks waiting - * for an event. - * - * Results: - * None. - * - * Side effects: - * Adjusts the block time if needed. - * - *---------------------------------------------------------------------- - */ - -void -FileSetupProc( - ClientData data, /* Not used. */ - int flags) /* Event flags as passed to Tcl_DoOneEvent. */ -{ - FileState *infoPtr; - Tcl_Time blockTime = { 0, 0 }; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - if (!(flags & TCL_FILE_EVENTS)) { - return; - } - - /* - * Check to see if there is a ready file. If so, poll. - */ - - for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; - infoPtr = infoPtr->nextPtr) { - if (infoPtr->watchMask) { - Tcl_SetMaxBlockTime(&blockTime); - break; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * FileCheckProc -- - * - * This procedure is called by Tcl_DoOneEvent to check the file - * event source for events. - * - * Results: - * None. - * - * Side effects: - * May queue an event. - * - *---------------------------------------------------------------------- - */ - -static void -FileCheckProc( - ClientData data, /* Not used. */ - int flags) /* Event flags as passed to Tcl_DoOneEvent. */ -{ - FileEvent *evPtr; - FileState *infoPtr; - int sentMsg = 0; - Tcl_Time blockTime = { 0, 0 }; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - if (!(flags & TCL_FILE_EVENTS)) { - return; - } - - /* - * Queue events for any ready files that don't already have events - * queued (caused by persistent states that won't generate WinSock - * events). - */ - - for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; - infoPtr = infoPtr->nextPtr) { - if (infoPtr->watchMask && !infoPtr->pending) { - infoPtr->pending = 1; - evPtr = (FileEvent *) ckalloc(sizeof(FileEvent)); - evPtr->header.proc = FileEventProc; - evPtr->infoPtr = infoPtr; - Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); - } - } -} - -/*---------------------------------------------------------------------- - * - * FileEventProc -- - * - * This function is invoked by Tcl_ServiceEvent when a file event - * reaches the front of the event queue. This procedure invokes - * Tcl_NotifyChannel on the file. - * - * Results: - * Returns 1 if the event was handled, meaning it should be removed - * from the queue. Returns 0 if the event was not handled, meaning - * it should stay on the queue. The only time the event isn't - * handled is if the TCL_FILE_EVENTS flag bit isn't set. - * - * Side effects: - * Whatever the notifier callback does. - * - *---------------------------------------------------------------------- - */ - -static int -FileEventProc( - Tcl_Event *evPtr, /* Event to service. */ - int flags) /* Flags that indicate what events to - * handle, such as TCL_FILE_EVENTS. */ -{ - FileEvent *fileEvPtr = (FileEvent *)evPtr; - FileState *infoPtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - if (!(flags & TCL_FILE_EVENTS)) { - return 0; - } - - /* - * Search through the list of watched files for the one whose handle - * matches the event. We do this rather than simply dereferencing - * the handle in the event so that files can be deleted while the - * event is in the queue. - */ - - for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; - infoPtr = infoPtr->nextPtr) { - if (fileEvPtr->infoPtr == infoPtr) { - infoPtr->pending = 0; - Tcl_NotifyChannel(infoPtr->fileChan, infoPtr->watchMask); - break; - } - } - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * StdIOBlockMode -- - * - * Set blocking or non-blocking mode on channel. - * - * Results: - * 0 if successful, errno when failed. - * - * Side effects: - * Sets the device into blocking or non-blocking mode. - * - *---------------------------------------------------------------------- - */ - -static int -StdIOBlockMode( - ClientData instanceData, /* Unused. */ - int mode) /* The mode to set. */ -{ - /* - * Do not allow putting stdin, stdout or stderr into nonblocking mode. - */ - - if (mode == TCL_MODE_NONBLOCKING) { - return EFAULT; - } - - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * StdIOClose -- - * - * Closes the IO channel. - * - * Results: - * 0 if successful, the value of errno if failed. - * - * Side effects: - * Closes the physical channel - * - *---------------------------------------------------------------------- - */ - -static int -StdIOClose( - ClientData instanceData, /* Unused. */ - Tcl_Interp *interp) /* Unused. */ -{ - int fd, errorCode = 0; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - /* - * Invalidate the stdio cache if necessary. Note that we assume that - * the stdio file and channel pointers will become invalid at the same - * time. - * Do not close standard channels while in thread-exit. - */ - - fd = (int) ((FileState*)instanceData)->fileRef; - if (!TclInExit()) { - if (fd == 0) { - tsdPtr->stdinChannel = NULL; - } else if (fd == 1) { - tsdPtr->stdoutChannel = NULL; - } else if (fd == 2) { - tsdPtr->stderrChannel = NULL; - } else { - panic("recieved invalid std file"); - } - - if (close(fd) < 0) { - errorCode = errno; - } - } - return errorCode; -} - -/* - *---------------------------------------------------------------------- - * - * CommonGetHandle -- - * - * Called from Tcl_GetChannelHandle to retrieve OS handles from inside - * a file based channel. - * - * Results: - * The appropriate handle or NULL if not present. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -CommonGetHandle( - ClientData instanceData, /* The file state. */ - int direction, /* Which handle to retrieve? */ - ClientData *handlePtr) -{ - if ((direction == TCL_READABLE) || (direction == TCL_WRITABLE)) { - *handlePtr = (ClientData) ((FileState*)instanceData)->fileRef; - return TCL_OK; - } - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * StdIOInput -- - * - * Reads input from the IO channel into the buffer given. Returns - * count of how many bytes were actually read, and an error indication. - * - * Results: - * A count of how many bytes were read is returned and an error - * indication is returned in an output argument. - * - * Side effects: - * Reads input from the actual channel. - * - *---------------------------------------------------------------------- - */ - -int -StdIOInput( - ClientData instanceData, /* Unused. */ - char *buf, /* Where to store data read. */ - int bufSize, /* How much space is available - * in the buffer? */ - int *errorCode) /* Where to store error code. */ -{ - int fd; - int bytesRead; /* How many bytes were read? */ - - *errorCode = 0; - errno = 0; - fd = (int) ((FileState*)instanceData)->fileRef; - bytesRead = read(fd, buf, (size_t) bufSize); - if (bytesRead > -1) { - return bytesRead; - } - *errorCode = errno; - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * StdIOOutput-- - * - * Writes the given output on the IO channel. Returns count of how - * many characters were actually written, and an error indication. - * - * Results: - * A count of how many characters were written is returned and an - * error indication is returned in an output argument. - * - * Side effects: - * Writes output on the actual channel. - * - *---------------------------------------------------------------------- - */ - -static int -StdIOOutput( - ClientData instanceData, /* Unused. */ - char *buf, /* The data buffer. */ - int toWrite, /* How many bytes to write? */ - int *errorCode) /* Where to store error code. */ -{ - int written; - int fd; - - *errorCode = 0; - errno = 0; - fd = (int) ((FileState*)instanceData)->fileRef; - written = write(fd, buf, (size_t) toWrite); - if (written > -1) { - return written; - } - *errorCode = errno; - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * StdIOSeek -- - * - * Seeks on an IO channel. Returns the new position. - * - * Results: - * -1 if failed, the new position if successful. If failed, it - * also sets *errorCodePtr to the error code. - * - * Side effects: - * Moves the location at which the channel will be accessed in - * future operations. - * - *---------------------------------------------------------------------- - */ - -static int -StdIOSeek( - ClientData instanceData, /* Unused. */ - long offset, /* Offset to seek to. */ - int mode, /* Relative to where - * should we seek? */ - int *errorCodePtr) /* To store error code. */ -{ - int newLoc; - int fd; - - *errorCodePtr = 0; - fd = (int) ((FileState*)instanceData)->fileRef; - newLoc = lseek(fd, offset, mode); - if (newLoc > -1) { - return newLoc; - } - *errorCodePtr = errno; - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_PidObjCmd -- - * - * This procedure is invoked to process the "pid" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -int -Tcl_PidObjCmd(dummy, interp, objc, objv) - ClientData dummy; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST *objv; /* Argument strings. */ -{ - ProcessSerialNumber psn; - char buf[20]; - Tcl_Channel chan; - Tcl_Obj *resultPtr; - - if (objc > 2) { - Tcl_WrongNumArgs(interp, 1, objv, "?channelId?"); - return TCL_ERROR; - } - if (objc == 1) { - resultPtr = Tcl_GetObjResult(interp); - GetCurrentProcess(&psn); - sprintf(buf, "0x%08x%08x", psn.highLongOfPSN, psn.lowLongOfPSN); - Tcl_SetStringObj(resultPtr, buf, -1); - } else { - chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), - NULL); - if (chan == (Tcl_Channel) NULL) { - return TCL_ERROR; - } - /* - * We can't create pipelines on the Mac so - * this will always return an empty list. - */ - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TclpGetDefaultStdChannel -- - * - * Constructs a channel for the specified standard OS handle. - * - * Results: - * Returns the specified default standard channel, or NULL. - * - * Side effects: - * May cause the creation of a standard channel and the underlying - * file. - * - *---------------------------------------------------------------------- - */ - -Tcl_Channel -TclpGetDefaultStdChannel( - int type) /* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */ -{ - Tcl_Channel channel = NULL; - int fd = 0; /* Initializations needed to prevent */ - int mode = 0; /* compiler warning (used before set). */ - char *bufMode = NULL; - char channelName[16 + TCL_INTEGER_SPACE]; - int channelPermissions; - FileState *fileState; - - /* - * If the channels were not created yet, create them now and - * store them in the static variables. - */ - - switch (type) { - case TCL_STDIN: - fd = 0; - channelPermissions = TCL_READABLE; - bufMode = "line"; - break; - case TCL_STDOUT: - fd = 1; - channelPermissions = TCL_WRITABLE; - bufMode = "line"; - break; - case TCL_STDERR: - fd = 2; - channelPermissions = TCL_WRITABLE; - bufMode = "none"; - break; - default: - panic("TclGetDefaultStdChannel: Unexpected channel type"); - break; - } - - sprintf(channelName, "console%d", (int) fd); - fileState = (FileState *) ckalloc((unsigned) sizeof(FileState)); - channel = Tcl_CreateChannel(&consoleChannelType, channelName, - (ClientData) fileState, channelPermissions); - fileState->fileChan = channel; - fileState->fileRef = fd; - - /* - * Set up the normal channel options for stdio handles. - */ - - Tcl_SetChannelOption(NULL, channel, "-translation", "cr"); - Tcl_SetChannelOption(NULL, channel, "-buffering", bufMode); - - return channel; -} - -/* - *---------------------------------------------------------------------- - * - * TclpOpenFileChannel -- - * - * Open an File based channel on Unix systems. - * - * Results: - * The new channel or NULL. If NULL, the output argument - * errorCodePtr is set to a POSIX error. - * - * Side effects: - * May open the channel and may cause creation of a file on the - * file system. - * - *---------------------------------------------------------------------- - */ - -Tcl_Channel -TclpOpenFileChannel( - Tcl_Interp *interp, /* Interpreter for error reporting; - * can be NULL. */ - char *fileName, /* Name of file to open. */ - char *modeString, /* A list of POSIX open modes or - * a string such as "rw". */ - int permissions) /* If the open involves creating a - * file, with what modes to create - * it? */ -{ - Tcl_Channel chan; - int mode; - char *native; - Tcl_DString ds, buffer; - int errorCode; - - mode = GetOpenMode(interp, modeString); - if (mode == -1) { - return NULL; - } - - if (Tcl_TranslateFileName(interp, fileName, &buffer) == NULL) { - return NULL; - } - native = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer), - Tcl_DStringLength(&buffer), &ds); - chan = OpenFileChannel(native, mode, permissions, &errorCode); - Tcl_DStringFree(&ds); - Tcl_DStringFree(&buffer); - - if (chan == NULL) { - Tcl_SetErrno(errorCode); - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, "couldn't open \"", fileName, "\": ", - Tcl_PosixError(interp), (char *) NULL); - } - return NULL; - } - - return chan; -} - -/* - *---------------------------------------------------------------------- - * - * OpenFileChannel-- - * - * Opens a Macintosh file and creates a Tcl channel to control it. - * - * Results: - * A Tcl channel. - * - * Side effects: - * Will open a Macintosh file. - * - *---------------------------------------------------------------------- - */ - -static Tcl_Channel -OpenFileChannel( - CONST char *fileName, /* Name of file to open (native). */ - int mode, /* Mode for opening file. */ - int permissions, /* If the open involves creating a - * file, with what modes to create - * it? */ - int *errorCodePtr) /* Where to store error code. */ -{ - int channelPermissions; - Tcl_Channel chan; - char macPermision; - FSSpec fileSpec; - OSErr err; - short fileRef; - FileState *fileState; - char channelName[16 + TCL_INTEGER_SPACE]; - - /* - * Note we use fsRdWrShPerm instead of fsRdWrPerm which allows shared - * writes on a file. This isn't common on a mac but is common with - * Windows and UNIX and the feature is used by Tcl. - */ - - switch (mode & (TCL_RDONLY | TCL_WRONLY | TCL_RDWR)) { - case TCL_RDWR: - channelPermissions = (TCL_READABLE | TCL_WRITABLE); - macPermision = fsRdWrShPerm; - break; - case TCL_WRONLY: - /* - * Mac's fsRdPerm permission actually defaults to fsRdWrPerm because - * the Mac OS doesn't realy support write only access. We explicitly - * set the permission fsRdWrShPerm so that we can have shared write - * access. - */ - channelPermissions = TCL_WRITABLE; - macPermision = fsRdWrShPerm; - break; - case TCL_RDONLY: - default: - channelPermissions = TCL_READABLE; - macPermision = fsRdPerm; - break; - } - - err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec); - if ((err != noErr) && (err != fnfErr)) { - *errorCodePtr = errno = TclMacOSErrorToPosixError(err); - Tcl_SetErrno(errno); - return NULL; - } - - if ((err == fnfErr) && (mode & TCL_CREAT)) { - err = HCreate(fileSpec.vRefNum, fileSpec.parID, fileSpec.name, 'MPW ', 'TEXT'); - if (err != noErr) { - *errorCodePtr = errno = TclMacOSErrorToPosixError(err); - Tcl_SetErrno(errno); - return NULL; - } - } else if ((mode & TCL_CREAT) && (mode & TCL_EXCL)) { - *errorCodePtr = errno = EEXIST; - Tcl_SetErrno(errno); - return NULL; - } - - err = HOpenDF(fileSpec.vRefNum, fileSpec.parID, fileSpec.name, macPermision, &fileRef); - if (err != noErr) { - *errorCodePtr = errno = TclMacOSErrorToPosixError(err); - Tcl_SetErrno(errno); - return NULL; - } - - if (mode & TCL_TRUNC) { - SetEOF(fileRef, 0); - } - - sprintf(channelName, "file%d", (int) fileRef); - fileState = (FileState *) ckalloc((unsigned) sizeof(FileState)); - chan = Tcl_CreateChannel(&fileChannelType, channelName, - (ClientData) fileState, channelPermissions); - if (chan == (Tcl_Channel) NULL) { - *errorCodePtr = errno = EFAULT; - Tcl_SetErrno(errno); - FSClose(fileRef); - ckfree((char *) fileState); - return NULL; - } - - fileState->fileChan = chan; - fileState->volumeRef = fileSpec.vRefNum; - fileState->fileRef = fileRef; - fileState->pending = 0; - fileState->watchMask = 0; - if (mode & TCL_ALWAYS_APPEND) { - fileState->appendMode = true; - } else { - fileState->appendMode = false; - } - - if ((mode & TCL_ALWAYS_APPEND) || (mode & TCL_APPEND)) { - if (Tcl_Seek(chan, 0, SEEK_END) < 0) { - *errorCodePtr = errno = EFAULT; - Tcl_SetErrno(errno); - Tcl_Close(NULL, chan); - FSClose(fileRef); - ckfree((char *) fileState); - return NULL; - } - } - - return chan; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_MakeFileChannel -- - * - * Makes a Tcl_Channel from an existing OS level file handle. - * - * Results: - * The Tcl_Channel created around the preexisting OS level file handle. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Channel -Tcl_MakeFileChannel(handle, mode) - ClientData handle; /* OS level handle. */ - int mode; /* ORed combination of TCL_READABLE and - * TCL_WRITABLE to indicate file mode. */ -{ - /* - * Not implemented yet. - */ - - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * FileBlockMode -- - * - * Set blocking or non-blocking mode on channel. Macintosh files - * can never really be set to blocking or non-blocking modes. - * However, we don't generate an error - we just return success. - * - * Results: - * 0 if successful, errno when failed. - * - * Side effects: - * Sets the device into blocking or non-blocking mode. - * - *---------------------------------------------------------------------- - */ - -static int -FileBlockMode( - ClientData instanceData, /* Unused. */ - int mode) /* The mode to set. */ -{ - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * FileClose -- - * - * Closes the IO channel. - * - * Results: - * 0 if successful, the value of errno if failed. - * - * Side effects: - * Closes the physical channel - * - *---------------------------------------------------------------------- - */ - -static int -FileClose( - ClientData instanceData, /* Unused. */ - Tcl_Interp *interp) /* Unused. */ -{ - FileState *fileState = (FileState *) instanceData; - int errorCode = 0; - OSErr err; - - err = FSClose(fileState->fileRef); - FlushVol(NULL, fileState->volumeRef); - if (err != noErr) { - errorCode = errno = TclMacOSErrorToPosixError(err); - panic("error during file close"); - } - - ckfree((char *) fileState); - Tcl_SetErrno(errorCode); - return errorCode; -} - -/* - *---------------------------------------------------------------------- - * - * FileInput -- - * - * Reads input from the IO channel into the buffer given. Returns - * count of how many bytes were actually read, and an error indication. - * - * Results: - * A count of how many bytes were read is returned and an error - * indication is returned in an output argument. - * - * Side effects: - * Reads input from the actual channel. - * - *---------------------------------------------------------------------- - */ - -int -FileInput( - ClientData instanceData, /* Unused. */ - char *buffer, /* Where to store data read. */ - int bufSize, /* How much space is available - * in the buffer? */ - int *errorCodePtr) /* Where to store error code. */ -{ - FileState *fileState = (FileState *) instanceData; - OSErr err; - long length = bufSize; - - *errorCodePtr = 0; - errno = 0; - err = FSRead(fileState->fileRef, &length, buffer); - if ((err == noErr) || (err == eofErr)) { - return length; - } else { - switch (err) { - case ioErr: - *errorCodePtr = errno = EIO; - case afpAccessDenied: - *errorCodePtr = errno = EACCES; - default: - *errorCodePtr = errno = EINVAL; - } - return -1; - } - *errorCodePtr = errno; - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * FileOutput-- - * - * Writes the given output on the IO channel. Returns count of how - * many characters were actually written, and an error indication. - * - * Results: - * A count of how many characters were written is returned and an - * error indication is returned in an output argument. - * - * Side effects: - * Writes output on the actual channel. - * - *---------------------------------------------------------------------- - */ - -static int -FileOutput( - ClientData instanceData, /* Unused. */ - char *buffer, /* The data buffer. */ - int toWrite, /* How many bytes to write? */ - int *errorCodePtr) /* Where to store error code. */ -{ - FileState *fileState = (FileState *) instanceData; - long length = toWrite; - OSErr err; - - *errorCodePtr = 0; - errno = 0; - - if (fileState->appendMode == true) { - FileSeek(instanceData, 0, SEEK_END, errorCodePtr); - *errorCodePtr = 0; - } - - err = FSWrite(fileState->fileRef, &length, buffer); - if (err == noErr) { - err = FlushFile(fileState->fileRef); - } else { - *errorCodePtr = errno = TclMacOSErrorToPosixError(err); - return -1; - } - return length; -} - -/* - *---------------------------------------------------------------------- - * - * FileSeek -- - * - * Seeks on an IO channel. Returns the new position. - * - * Results: - * -1 if failed, the new position if successful. If failed, it - * also sets *errorCodePtr to the error code. - * - * Side effects: - * Moves the location at which the channel will be accessed in - * future operations. - * - *---------------------------------------------------------------------- - */ - -static int -FileSeek( - ClientData instanceData, /* Unused. */ - long offset, /* Offset to seek to. */ - int mode, /* Relative to where - * should we seek? */ - int *errorCodePtr) /* To store error code. */ -{ - FileState *fileState = (FileState *) instanceData; - IOParam pb; - OSErr err; - - *errorCodePtr = 0; - pb.ioCompletion = NULL; - pb.ioRefNum = fileState->fileRef; - if (mode == SEEK_SET) { - pb.ioPosMode = fsFromStart; - } else if (mode == SEEK_END) { - pb.ioPosMode = fsFromLEOF; - } else if (mode == SEEK_CUR) { - err = PBGetFPosSync((ParmBlkPtr) &pb); - if (pb.ioResult == noErr) { - if (offset == 0) { - return pb.ioPosOffset; - } - offset += pb.ioPosOffset; - } - pb.ioPosMode = fsFromStart; - } - pb.ioPosOffset = offset; - err = PBSetFPosSync((ParmBlkPtr) &pb); - if (pb.ioResult == noErr){ - return pb.ioPosOffset; - } else if (pb.ioResult == eofErr) { - long currentEOF, newEOF; - long buffer, i, length; - - err = PBGetEOFSync((ParmBlkPtr) &pb); - currentEOF = (long) pb.ioMisc; - if (mode == SEEK_SET) { - newEOF = offset; - } else if (mode == SEEK_END) { - newEOF = offset + currentEOF; - } else if (mode == SEEK_CUR) { - err = PBGetFPosSync((ParmBlkPtr) &pb); - newEOF = offset + pb.ioPosOffset; - } - - /* - * Write 0's to the new EOF. - */ - pb.ioPosOffset = 0; - pb.ioPosMode = fsFromLEOF; - err = PBGetFPosSync((ParmBlkPtr) &pb); - length = 1; - buffer = 0; - for (i = 0; i < (newEOF - currentEOF); i++) { - err = FSWrite(fileState->fileRef, &length, &buffer); - } - err = PBGetFPosSync((ParmBlkPtr) &pb); - if (pb.ioResult == noErr){ - return pb.ioPosOffset; - } - } - *errorCodePtr = errno = TclMacOSErrorToPosixError(err); - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * CommonWatch -- - * - * Initialize the notifier to watch handles from this channel. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -CommonWatch( - ClientData instanceData, /* The file state. */ - int mask) /* Events of interest; an OR-ed - * combination of TCL_READABLE, - * TCL_WRITABLE and TCL_EXCEPTION. */ -{ - FileState **nextPtrPtr, *ptr; - FileState *infoPtr = (FileState *) instanceData; - int oldMask = infoPtr->watchMask; - ThreadSpecificData *tsdPtr; - - tsdPtr = FileInit(); - - infoPtr->watchMask = mask; - if (infoPtr->watchMask) { - if (!oldMask) { - infoPtr->nextPtr = tsdPtr->firstFilePtr; - tsdPtr->firstFilePtr = infoPtr; - } - } else { - if (oldMask) { - /* - * Remove the file from the list of watched files. - */ - - for (nextPtrPtr = &(tsdPtr->firstFilePtr), ptr = *nextPtrPtr; - ptr != NULL; - nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) { - if (infoPtr == ptr) { - *nextPtrPtr = ptr->nextPtr; - break; - } - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * GetOpenMode -- - * - * Description: - * Computes a POSIX mode mask from a given string and also sets - * a flag to indicate whether the caller should seek to EOF during - * opening of the file. - * - * Results: - * On success, returns mode to pass to "open". If an error occurs, the - * returns -1 and if interp is not NULL, sets the interp's result to an - * error message. - * - * Side effects: - * Sets the integer referenced by seekFlagPtr to 1 if the caller - * should seek to EOF during opening the file. - * - * Special note: - * This code is based on a prototype implementation contributed - * by Mark Diekhans. - * - *---------------------------------------------------------------------- - */ - -static int -GetOpenMode( - Tcl_Interp *interp, /* Interpreter to use for error - * reporting - may be NULL. */ - CONST char *string) /* Mode string, e.g. "r+" or - * "RDONLY CREAT". */ -{ - int mode, modeArgc, c, i, gotRW; - char **modeArgv, *flag; - - /* - * Check for the simpler fopen-like access modes (e.g. "r"). They - * are distinguished from the POSIX access modes by the presence - * of a lower-case first letter. - */ - - mode = 0; - /* - * Guard against international characters before using byte oriented - * routines. - */ - - if (!(string[0] & 0x80) - && islower(UCHAR(string[0]))) { /* INTL: ISO only. */ - switch (string[0]) { - case 'r': - mode = TCL_RDONLY; - break; - case 'w': - mode = TCL_WRONLY|TCL_CREAT|TCL_TRUNC; - break; - case 'a': - mode = TCL_WRONLY|TCL_CREAT|TCL_APPEND; - break; - default: - error: - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, - "illegal access mode \"", string, "\"", - (char *) NULL); - } - return -1; - } - if (string[1] == '+') { - mode &= ~(TCL_RDONLY|TCL_WRONLY); - mode |= TCL_RDWR; - if (string[2] != 0) { - goto error; - } - } else if (string[1] != 0) { - goto error; - } - return mode; - } - - /* - * The access modes are specified using a list of POSIX modes - * such as TCL_CREAT. - */ - - if (Tcl_SplitList(interp, string, &modeArgc, &modeArgv) != TCL_OK) { - if (interp != (Tcl_Interp *) NULL) { - Tcl_AddErrorInfo(interp, - "\n while processing open access modes \""); - Tcl_AddErrorInfo(interp, string); - Tcl_AddErrorInfo(interp, "\""); - } - return -1; - } - - gotRW = 0; - for (i = 0; i < modeArgc; i++) { - flag = modeArgv[i]; - c = flag[0]; - if ((c == 'R') && (strcmp(flag, "RDONLY") == 0)) { - mode = (mode & ~TCL_RW_MODES) | TCL_RDONLY; - gotRW = 1; - } else if ((c == 'W') && (strcmp(flag, "WRONLY") == 0)) { - mode = (mode & ~TCL_RW_MODES) | TCL_WRONLY; - gotRW = 1; - } else if ((c == 'R') && (strcmp(flag, "RDWR") == 0)) { - mode = (mode & ~TCL_RW_MODES) | TCL_RDWR; - gotRW = 1; - } else if ((c == 'A') && (strcmp(flag, "APPEND") == 0)) { - mode |= TCL_ALWAYS_APPEND; - } else if ((c == 'C') && (strcmp(flag, "CREAT") == 0)) { - mode |= TCL_CREAT; - } else if ((c == 'E') && (strcmp(flag, "EXCL") == 0)) { - mode |= TCL_EXCL; - } else if ((c == 'N') && (strcmp(flag, "NOCTTY") == 0)) { - mode |= TCL_NOCTTY; - } else if ((c == 'N') && (strcmp(flag, "NONBLOCK") == 0)) { - mode |= TCL_NONBLOCK; - } else if ((c == 'T') && (strcmp(flag, "TRUNC") == 0)) { - mode |= TCL_TRUNC; - } else { - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, "invalid access mode \"", flag, - "\": must be RDONLY, WRONLY, RDWR, APPEND, CREAT", - " EXCL, NOCTTY, NONBLOCK, or TRUNC", (char *) NULL); - } - ckfree((char *) modeArgv); - return -1; - } - } - ckfree((char *) modeArgv); - if (!gotRW) { - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, "access mode must include either", - " RDONLY, WRONLY, or RDWR", (char *) NULL); - } - return -1; - } - return mode; -} diff --git a/mac/tclMacCommonPch.h b/mac/tclMacCommonPch.h deleted file mode 100755 index b06a494..0000000 --- a/mac/tclMacCommonPch.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * tclMacCommonPch.h -- - * - * Macintosh Tcl must be compiled with certain compiler options to - * ensure that it will work correctly. The following pragmas are - * used to ensure that those options are set correctly. An error - * will occur at compile time if they are not set correctly. - * - * 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: tclMacCommonPch.h,v 1.2 1998/11/11 07:46:04 jingham Exp $ - */ - -#if !__option(enumsalwaysint) -#error Tcl requires the Metrowerks setting "Enums always ints". -#endif - - -#if !defined(__POWERPC__) -#if !__option(far_data) -#error Tcl requires the Metrowerks setting "Far data". -#endif -#endif - - -#if !defined(__POWERPC__) -#if !__option(fourbyteints) -#error Tcl requires the Metrowerks setting "4 byte ints". -#endif -#endif - - -#if !defined(__POWERPC__) -#if !__option(IEEEdoubles) -#error Tcl requires the Metrowerks setting "8 byte doubles". -#endif -#endif - - -/* -* The define is used most everywhere to tell Tcl (or any Tcl -* extensions) that we are compiling for the Macintosh platform. -*/ - - -#define MAC_TCL - - -/* -* The following defines control the behavior of the Macintosh -* Universial Headers. -*/ - - -#define SystemSevenOrLater 1 -#define STRICT_CONTROLS 1 -#define STRICT_WINDOWS 1 - - -/* -* Define the following symbol if you want -* comprehensive debugging turned on. -*/ - - -/* #define TCL_DEBUG */ - - -#ifdef TCL_DEBUG -# define TCL_MEM_DEBUG -# define TCL_TEST -#endif - - - -/* -* For a while, we will continue to use the old routine names, so that -* people with older versions of CodeWarrior will still be able to compile -* the source (albeit they will have to update the project files themselves). -* -* At some point, we will convert over to the new routine names. -*/ - - -#define OLDROUTINENAMES 1 diff --git a/mac/tclMacDNR.c b/mac/tclMacDNR.c deleted file mode 100644 index fa7058b..0000000 --- a/mac/tclMacDNR.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * tclMacDNR.c - * - * This file actually just includes the file "dnr.c" provided by - * Apple Computer and redistributed by MetroWerks (and other compiler - * vendors.) Unfortunantly, despite various bug reports, dnr.c uses - * C++ style comments and will not compile under the "ANSI Strict" - * mode that the rest of Tcl compiles under. Furthermore, the Apple - * license prohibits me from redistributing a corrected version of - * dnr.c. This file uses a pragma to turn off the Strict ANSI option - * and then includes the dnr.c file. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacDNR.c,v 1.2 1998/09/14 18:40:04 stanton Exp $ - */ - -#pragma ANSI_strict off -#include <dnr.c> -#pragma ANSI_strict reset diff --git a/mac/tclMacEnv.c b/mac/tclMacEnv.c deleted file mode 100644 index 8f6b58f..0000000 --- a/mac/tclMacEnv.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * tclMacEnv.c -- - * - * Implements the "environment" on a Macintosh. - * - * Copyright (c) 1995-1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacEnv.c,v 1.2 1998/09/14 18:40:04 stanton Exp $ - */ - -#include <Gestalt.h> -#include <Folders.h> -#include <TextUtils.h> -#include <Resources.h> -#include <string.h> - -#include "tcl.h" -#include "tclInt.h" -#include "tclMacInt.h" -#include "tclPort.h" - -#define kMaxEnvStringSize 255 -#define kMaxEnvVarSize 100 -#define kLoginnameTag "LOGIN=" -#define kUsernameTag "USER=" -#define kDefaultDirTag "HOME=" - -/* - * The following specifies a text file where additional environment variables - * can be set. The file must reside in the preferences folder. If the file - * doesn't exist NO error will occur. Commet out the difinition if you do - * NOT want to use an environment variables file. - */ -#define kPrefsFile "Tcl Environment Variables" - -/* - * The following specifies the Name of a 'STR#' resource in the application - * where additional environment variables may be set. If the resource doesn't - * exist no errors will occur. Commet it out if you don't want it. - */ -#define REZ_ENV "\pTcl Environment Variables" - -/* Globals */ -char **environ = NULL; - -/* - * Declarations for local procedures defined in this file: - */ -static char ** RezRCVariables _ANSI_ARGS_((void)); -static char ** FileRCVariables _ANSI_ARGS_((void)); -static char ** PathVariables _ANSI_ARGS_((void)); -static char ** SystemVariables _ANSI_ARGS_((void)); -static char * MakeFolderEnvVar _ANSI_ARGS_((char * prefixTag, - long whichFolder)); -static char * GetUserName _ANSI_ARGS_((void)); - -/* - *---------------------------------------------------------------------- - * - * RezRCVariables -- - * - * Creates environment variables from the applications resource fork. - * The function looks for the 'STR#' resource with the name defined - * in the #define REZ_ENV. If the define is not defined this code - * will not be included. If the resource doesn't exist or no strings - * reside in the resource nothing will happen. - * - * Results: - * ptr to value on success, NULL if error. - * - * Side effects: - * Memory is allocated and returned to the caller. - * - *---------------------------------------------------------------------- - */ - -#ifdef REZ_ENV -static char ** -RezRCVariables() -{ - Handle envStrs = NULL; - char** rezEnv = NULL; - short int numStrs; - - envStrs = GetNamedResource('STR#', REZ_ENV); - if (envStrs == NULL) return NULL; - numStrs = *((short *) (*envStrs)); - - rezEnv = (char **) ckalloc((numStrs + 1) * sizeof(char *)); - - if (envStrs != NULL) { - ResType theType; - Str255 theName; - short theID, index = 1; - int i = 0; - char* string; - - GetResInfo(envStrs, &theID, &theType, theName); - for(;;) { - GetIndString(theName, theID, index++); - if (theName[0] == '\0') break; - string = (char *) ckalloc(theName[0] + 2); - strncpy(string, (char *) theName + 1, theName[0]); - string[theName[0]] = '\0'; - rezEnv[i++] = string; - } - ReleaseResource(envStrs); - - rezEnv[i] = NULL; - return rezEnv; - } - - return NULL; -} -#endif - -/* - *---------------------------------------------------------------------- - * - * FileRCVariables -- - * - * Creates environment variables from a file in the system preferences - * folder. The function looks for a file in the preferences folder - * a name defined in the #define kPrefsFile. If the define is not - * defined this code will not be included. If the resource doesn't exist or - * no strings reside in the resource nothing will happen. - * - * Results: - * ptr to value on success, NULL if error. - * - * Side effects: - * Memory is allocated and returned to the caller. - * - *---------------------------------------------------------------------- - */ - -#ifdef kPrefsFile -static char ** -FileRCVariables() -{ - char *prefsFolder = NULL; - char *tempPtr = NULL; - char **fileEnv = NULL; - FILE *thePrefsFile = NULL; - int i; - FSSpec prefDir; - OSErr err; - Handle theString = NULL; - Tcl_Channel chan; - int size; - Tcl_DString lineRead; - - err = FSpFindFolder(kOnSystemDisk, kPreferencesFolderType, - kDontCreateFolder, &prefDir); - if (err != noErr) { - return NULL; - } - err = FSpPathFromLocation(&prefDir, &size, &theString); - if (err != noErr) { - return NULL; - } - (void) Munger(theString, size, NULL, 0, kPrefsFile, strlen(kPrefsFile)); - - HLock(theString); - chan = Tcl_OpenFileChannel(NULL, *theString, "r", 0); - HUnlock(theString); - DisposeHandle(theString); - if (chan == NULL) { - return NULL; - } - - /* - * We found a env file. Let start parsing it. - */ - fileEnv = (char **) ckalloc((kMaxEnvVarSize + 1) * sizeof(char *)); - - i = 0; - Tcl_DStringInit(&lineRead); - while (Tcl_Gets(chan, &lineRead) != -1) { - /* - * First strip off new line char - */ - if (lineRead.string[lineRead.length-1] == '\n') { - lineRead.string[lineRead.length-1] = '\0'; - } - if (lineRead.string[0] == '\0' || lineRead.string[0] == '#') { - /* - * skip empty lines or commented lines - */ - Tcl_DStringSetLength(&lineRead, 0); - continue; - } - - tempPtr = (char *) ckalloc(lineRead.length + 1); - strcpy(tempPtr, lineRead.string); - fileEnv[i++] = tempPtr; - Tcl_DStringSetLength(&lineRead, 0); - } - - fileEnv[i] = NULL; - Tcl_Close(NULL, chan); - Tcl_DStringFree(&lineRead); - - return fileEnv; -} -#endif - -/* - *---------------------------------------------------------------------- - * - * MakeFolderEnvVar -- - * - * This function creates "environment" variable by taking a prefix and - * appending a folder path to a directory. The directory is specified - * by a integer value acceptable by the FindFolder function. - * - * Results: - * The function returns an *allocated* string. If the folder doesn't - * exist the return string is still allocated and just contains the - * given prefix. - * - * Side effects: - * Memory is allocated and returned to the caller. - * - *---------------------------------------------------------------------- - */ - -static char * -MakeFolderEnvVar( - char * prefixTag, /* Prefix added before result. */ - long whichFolder) /* Constant for FSpFindFolder. */ -{ - char * thePath = NULL; - char * result = NULL; - OSErr theErr = noErr; - Handle theString = NULL; - FSSpec theFolder; - int size; - Tcl_DString pathStr; - Tcl_DString tagPathStr; - - Tcl_DStringInit(&pathStr); - theErr = FSpFindFolder(kOnSystemDisk, whichFolder, - kDontCreateFolder, &theFolder); - if (theErr == noErr) { - theErr = FSpPathFromLocation(&theFolder, &size, &theString); - - HLock(theString); - tclPlatform = TCL_PLATFORM_MAC; - Tcl_DStringAppend(&pathStr, *theString, -1); - HUnlock(theString); - DisposeHandle(theString); - - Tcl_DStringInit(&tagPathStr); - Tcl_DStringAppend(&tagPathStr, prefixTag, strlen(prefixTag)); - Tcl_DStringAppend(&tagPathStr, pathStr.string, pathStr.length); - Tcl_DStringFree(&pathStr); - - /* - * Make sure the path ends with a ':' - */ - if (tagPathStr.string[tagPathStr.length - 1] != ':') { - Tcl_DStringAppend(&tagPathStr, ":", 1); - } - - /* - * Don't free tagPathStr - rather make sure it's allocated - * and return it as the result. - */ - if (tagPathStr.string == tagPathStr.staticSpace) { - result = (char *) ckalloc(tagPathStr.length + 1); - strcpy(result, tagPathStr.string); - } else { - result = tagPathStr.string; - } - } else { - result = (char *) ckalloc(strlen(prefixTag) + 1); - strcpy(result, prefixTag); - } - - return result; -} - -/* - *---------------------------------------------------------------------- - * - * PathVariables -- - * - * Creates environment variables from the system call FSpFindFolder. - * The function generates environment variables for many of the - * commonly used paths on the Macintosh. - * - * Results: - * ptr to value on success, NULL if error. - * - * Side effects: - * Memory is allocated and returned to the caller. - * - *---------------------------------------------------------------------- - */ - -static char ** -PathVariables() -{ - int i = 0; - char **sysEnv; - char *thePath = NULL; - - sysEnv = (char **) ckalloc((12) * sizeof(char *)); - - sysEnv[i++] = MakeFolderEnvVar("PREF_FOLDER=", kPreferencesFolderType); - sysEnv[i++] = MakeFolderEnvVar("SYS_FOLDER=", kSystemFolderType); - sysEnv[i++] = MakeFolderEnvVar("TEMP=", kTemporaryFolderType); - sysEnv[i++] = MakeFolderEnvVar("APPLE_M_FOLDER=", kAppleMenuFolderType); - sysEnv[i++] = MakeFolderEnvVar("CP_FOLDER=", kControlPanelFolderType); - sysEnv[i++] = MakeFolderEnvVar("DESK_FOLDER=", kDesktopFolderType); - sysEnv[i++] = MakeFolderEnvVar("EXT_FOLDER=", kExtensionFolderType); - sysEnv[i++] = MakeFolderEnvVar("PRINT_MON_FOLDER=", - kPrintMonitorDocsFolderType); - sysEnv[i++] = MakeFolderEnvVar("SHARED_TRASH_FOLDER=", - kWhereToEmptyTrashFolderType); - sysEnv[i++] = MakeFolderEnvVar("TRASH_FOLDER=", kTrashFolderType); - sysEnv[i++] = MakeFolderEnvVar("START_UP_FOLDER=", kStartupFolderType); - sysEnv[i++] = NULL; - - return sysEnv; -} - -/* - *---------------------------------------------------------------------- - * - * SystemVariables -- - * - * Creates environment variables from various Mac system calls. - * - * Results: - * ptr to value on success, NULL if error. - * - * Side effects: - * Memory is allocated and returned to the caller. - * - *---------------------------------------------------------------------- - */ - -static char ** -SystemVariables() -{ - int i = 0; - char ** sysEnv; - char * thePath = NULL; - Handle theString = NULL; - FSSpec currentDir; - int size; - - sysEnv = (char **) ckalloc((4) * sizeof(char *)); - - /* - * Get user name from chooser. It will be assigned to both - * the USER and LOGIN environment variables. - */ - thePath = GetUserName(); - if (thePath != NULL) { - sysEnv[i] = (char *) ckalloc(strlen(kLoginnameTag) + strlen(thePath) + 1); - strcpy(sysEnv[i], kLoginnameTag); - strcpy(sysEnv[i]+strlen(kLoginnameTag), thePath); - i++; - sysEnv[i] = (char *) ckalloc(strlen(kUsernameTag) + strlen(thePath) + 1); - strcpy(sysEnv[i], kUsernameTag); - strcpy(sysEnv[i]+strlen(kUsernameTag), thePath); - i++; - } - - /* - * Get 'home' directory - */ -#ifdef kDefaultDirTag - FSpGetDefaultDir(¤tDir); - FSpPathFromLocation(¤tDir, &size, &theString); - HLock(theString); - sysEnv[i] = (char *) ckalloc(strlen(kDefaultDirTag) + size + 4); - strcpy(sysEnv[i], kDefaultDirTag); - strncpy(sysEnv[i]+strlen(kDefaultDirTag) , *theString, size); - if (sysEnv[i][strlen(kDefaultDirTag) + size - 1] != ':') { - sysEnv[i][strlen(kDefaultDirTag) + size] = ':'; - sysEnv[i][strlen(kDefaultDirTag) + size + 1] = '\0'; - } else { - sysEnv[i][strlen(kDefaultDirTag) + size] = '\0'; - } - HUnlock(theString); - DisposeHandle(theString); - i++; -#endif - - sysEnv[i++] = NULL; - return sysEnv; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacCreateEnv -- - * - * This function allocates and populates the global "environ" - * variable. Entries are in traditional Unix format but variables - * are, hopefully, a bit more relevant for the Macintosh. - * - * Results: - * The number of elements in the newly created environ array. - * - * Side effects: - * Memory is allocated and pointed too by the environ variable. - * - *---------------------------------------------------------------------- - */ - -int -TclMacCreateEnv() -{ - char ** sysEnv = NULL; - char ** pathEnv = NULL; - char ** fileEnv = NULL; - char ** rezEnv = NULL; - int count = 0; - int i, j; - - sysEnv = SystemVariables(); - if (sysEnv != NULL) { - for (i = 0; sysEnv[i] != NULL; count++, i++) { - /* Empty Loop */ - } - } - - pathEnv = PathVariables(); - if (pathEnv != NULL) { - for (i = 0; pathEnv[i] != NULL; count++, i++) { - /* Empty Loop */ - } - } - -#ifdef kPrefsFile - fileEnv = FileRCVariables(); - if (fileEnv != NULL) { - for (i = 0; fileEnv[i] != NULL; count++, i++) { - /* Empty Loop */ - } - } -#endif - -#ifdef REZ_ENV - rezEnv = RezRCVariables(); - if (rezEnv != NULL) { - for (i = 0; rezEnv[i] != NULL; count++, i++) { - /* Empty Loop */ - } - } -#endif - - /* - * Create environ variable - */ - environ = (char **) ckalloc((count + 1) * sizeof(char *)); - j = 0; - - if (sysEnv != NULL) { - for (i = 0; sysEnv[i] != NULL;) - environ[j++] = sysEnv[i++]; - ckfree((char *) sysEnv); - } - - if (pathEnv != NULL) { - for (i = 0; pathEnv[i] != NULL;) - environ[j++] = pathEnv[i++]; - ckfree((char *) pathEnv); - } - -#ifdef kPrefsFile - if (fileEnv != NULL) { - for (i = 0; fileEnv[i] != NULL;) - environ[j++] = fileEnv[i++]; - ckfree((char *) fileEnv); - } -#endif - -#ifdef REZ_ENV - if (rezEnv != NULL) { - for (i = 0; rezEnv[i] != NULL;) - environ[j++] = rezEnv[i++]; - ckfree((char *) rezEnv); - } -#endif - - environ[j] = NULL; - return j; -} - -/* - *---------------------------------------------------------------------- - * - * GetUserName -- - * - * Get the user login name. - * - * Results: - * ptr to static string, NULL if error. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static char * -GetUserName() -{ - static char buf[33]; - short refnum; - Handle h; - - refnum = CurResFile(); - UseResFile(0); - h = GetResource('STR ', -16096); - UseResFile(refnum); - if (h == NULL) { - return NULL; - } - - HLock(h); - strncpy(buf, (*h)+1, **h); - buf[**h] = '\0'; - HUnlock(h); - ReleaseResource(h); - return(buf[0] ? buf : NULL); -} diff --git a/mac/tclMacExit.c b/mac/tclMacExit.c deleted file mode 100644 index 347ff4e..0000000 --- a/mac/tclMacExit.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * tclMacExit.c -- - * - * This file contains routines that deal with cleaning up various state - * when Tcl/Tk applications quit. Unfortunantly, not all state is cleaned - * up by the process when an application quites or crashes. Also you - * need to do different things depending on wether you are running as - * 68k code, PowerPC, or a code resource. The Exit handler code was - * adapted from code posted on alt.sources.mac by Dave Nebinger. - * - * Copyright (c) 1995 Dave Nebinger. - * Copyright (c) 1995-1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacExit.c,v 1.4 1999/04/16 00:47:19 stanton Exp $ - */ - -#include "tclInt.h" -#include "tclMacInt.h" -#include <SegLoad.h> -#include <Traps.h> -#include <Processes.h> - -/* - * Various typedefs and defines needed to patch ExitToShell. - */ - -enum { - uppExitToShellProcInfo = kPascalStackBased -}; - -#if GENERATINGCFM -typedef UniversalProcPtr ExitToShellUPP; - -#define CallExitToShellProc(userRoutine) \ - CallUniversalProc((UniversalProcPtr)(userRoutine),uppExitToShellProcInfo) -#define NewExitToShellProc(userRoutine) \ - (ExitToShellUPP)NewRoutineDescriptor((ProcPtr)(userRoutine), \ - uppExitToShellProcInfo, GetCurrentArchitecture()) - -#else -typedef ExitToShellProcPtr ExitToShellUPP; - -#define CallExitToShellProc(userRoutine) \ - (*(userRoutine))() -#define NewExitToShellProc(userRoutine) \ - (ExitToShellUPP)(userRoutine) -#endif - -#define DisposeExitToShellProc(userRoutine) \ - DisposeRoutineDescriptor(userRoutine) - -#if defined(powerc)||defined(__powerc) -#pragma options align=mac68k -#endif -struct ExitToShellUPPList{ - struct ExitToShellUPPList* nextProc; - ExitToShellUPP userProc; -}; -#if defined(powerc)||defined(__powerc) -#pragma options align=reset -#endif - -typedef struct ExitToShellDataStruct ExitToShellDataRec,* ExitToShellDataPtr,** ExitToShellDataHdl; - -typedef struct ExitToShellUPPList ExitToShellUPPList,* ExitToShellUPPListPtr,** ExitToShellUPPHdl; - -#if defined(powerc)||defined(__powerc) -#pragma options align=mac68k -#endif -struct ExitToShellDataStruct{ - unsigned long a5; - ExitToShellUPPList* userProcs; - ExitToShellUPP oldProc; -}; -#if defined(powerc)||defined(__powerc) -#pragma options align=reset -#endif - -/* - * Static globals used within this file. - */ -static ExitToShellDataPtr gExitToShellData = (ExitToShellDataPtr) NULL; - - -/* - *---------------------------------------------------------------------- - * - * TclPlatformExit -- - * - * This procedure implements the Macintosh specific exit routine. - * We explicitly callthe ExitHandler function to do various clean - * up. - * - * Results: - * None. - * - * Side effects: - * We exit the process. - * - *---------------------------------------------------------------------- - */ - -void -TclpExit( - int status) /* Ignored. */ -{ - TclMacExitHandler(); - -/* - * If we are using the Metrowerks Standard Library, then we will call its exit so that it - * will get a chance to clean up temp files, and so forth. It always calls the standard - * ExitToShell, so the Tcl handlers will also get called. - * - * If you have another exit, make sure that it does not patch ExitToShell, and does - * call it. If so, it will probably work as well. - * - */ - -#ifdef __MSL__ - exit(status); -#else - ExitToShell(); -#endif - -} - -/* - *---------------------------------------------------------------------- - * - * TclMacExitHandler -- - * - * This procedure is invoked after Tcl at the last possible moment - * to clean up any state Tcl has left around that may cause other - * applications to crash. For example, this function can be used - * as the termination routine for CFM applications. - * - * Results: - * None. - * - * Side effects: - * Various cleanup occurs. - * - *---------------------------------------------------------------------- - */ - -void -TclMacExitHandler() -{ - ExitToShellUPPListPtr curProc; - - /* - * Loop through all installed Exit handlers - * and call them. Always make sure we are in - * a clean state in case we are recursivly called. - */ - if ((gExitToShellData) != NULL && (gExitToShellData->userProcs != NULL)){ - - /* - * Call the installed exit to shell routines. - */ - curProc = gExitToShellData->userProcs; - do { - gExitToShellData->userProcs = curProc->nextProc; - CallExitToShellProc(curProc->userProc); - DisposeExitToShellProc(curProc->userProc); - DisposePtr((Ptr) curProc); - curProc = gExitToShellData->userProcs; - } while (curProc != (ExitToShellUPPListPtr) NULL); - } - - return; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacInstallExitToShellPatch -- - * - * This procedure installs a way to clean up state at the latest - * possible moment before we exit. These are things that must - * be cleaned up or the system will crash. The exact way in which - * this is implemented depends on the architecture in which we are - * running. For 68k applications we patch the ExitToShell call. - * For PowerPC applications we just create a list of procs to call. - * The function ExitHandler should be installed in the Code - * Fragments terminiation routine. - * - * Results: - * None. - * - * Side effects: - * Installs the new routine. - * - *---------------------------------------------------------------------- - */ - -OSErr -TclMacInstallExitToShellPatch( - ExitToShellProcPtr newProc) /* Function pointer. */ -{ - ExitToShellUPP exitHandler; - ExitToShellUPPListPtr listPtr; - - if (gExitToShellData == (ExitToShellDataPtr) NULL){ - TclMacInitExitToShell(true); - } - - /* - * Add the passed in function pointer to the list of functions - * to be called when ExitToShell is called. - */ - exitHandler = NewExitToShellProc(newProc); - listPtr = (ExitToShellUPPListPtr) NewPtrClear(sizeof(ExitToShellUPPList)); - listPtr->userProc = exitHandler; - listPtr->nextProc = gExitToShellData->userProcs; - gExitToShellData->userProcs = listPtr; - - return noErr; -} - -/* - *---------------------------------------------------------------------- - * - * ExitToShellPatchRoutine -- - * - * This procedure is invoked when someone calls ExitToShell for - * this application. This function performs some last miniute - * clean up and then calls the real ExitToShell routine. - * - * Results: - * None. - * - * Side effects: - * Various cleanup occurs. - * - *---------------------------------------------------------------------- - */ - -static pascal void -ExitToShellPatchRoutine() -{ - ExitToShellUPP oldETS; - long oldA5; - - /* - * Set up our A5 world. This allows us to have - * access to our global variables in the 68k world. - */ - oldA5 = SetCurrentA5(); - SetA5(gExitToShellData->a5); - - /* - * Call the function that invokes all - * of the handlers. - */ - TclMacExitHandler(); - - /* - * Call the origional ExitToShell routine. - */ - oldETS = gExitToShellData->oldProc; - DisposePtr((Ptr) gExitToShellData); - SetA5(oldA5); - CallExitToShellProc(oldETS); - return; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacInitExitToShell -- - * - * This procedure initializes the ExitToShell clean up machanism. - * Generally, this is handled automatically when users make a call - * to InstallExitToShellPatch. However, it can be called - * explicitly at startup time to turn off the patching mechanism. - * This can be used by code resources which could be removed from - * the application before ExitToShell is called. - * - * Note, if we are running from CFM code we never install the - * patch. Instead, the function ExitHandler should be installed - * as the terminiation routine for the code fragment. - * - * Results: - * None. - * - * Side effects: - * Creates global state. - * - *---------------------------------------------------------------------- - */ - -void -TclMacInitExitToShell( - int usePatch) /* True if on 68k. */ -{ - if (gExitToShellData == (ExitToShellDataPtr) NULL){ -#if GENERATINGCFM - gExitToShellData = (ExitToShellDataPtr) - NewPtr(sizeof(ExitToShellDataRec)); - gExitToShellData->a5 = SetCurrentA5(); - gExitToShellData->userProcs = (ExitToShellUPPList*) NULL; -#else - ExitToShellUPP oldExitToShell, newExitToShellPatch; - short exitToShellTrap; - - /* - * Initialize patch mechanism. - */ - - gExitToShellData = (ExitToShellDataPtr) NewPtr(sizeof(ExitToShellDataRec)); - gExitToShellData->a5 = SetCurrentA5(); - gExitToShellData->userProcs = (ExitToShellUPPList*) NULL; - - /* - * Save state needed to call origional ExitToShell routine. Install - * the new ExitToShell code in it's place. - */ - if (usePatch) { - exitToShellTrap = _ExitToShell & 0x3ff; - newExitToShellPatch = NewExitToShellProc(ExitToShellPatchRoutine); - oldExitToShell = (ExitToShellUPP) - NGetTrapAddress(exitToShellTrap, ToolTrap); - NSetTrapAddress((UniversalProcPtr) newExitToShellPatch, - exitToShellTrap, ToolTrap); - gExitToShellData->oldProc = oldExitToShell; - } -#endif - } -} diff --git a/mac/tclMacFCmd.c b/mac/tclMacFCmd.c deleted file mode 100644 index a83011d..0000000 --- a/mac/tclMacFCmd.c +++ /dev/null @@ -1,1551 +0,0 @@ -/* - * tclMacFCmd.c -- - * - * Implements the Macintosh specific portions of the file manipulation - * subcommands of the "file" command. - * - * Copyright (c) 1996-1998 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacFCmd.c,v 1.7 1999/10/15 04:47:03 jingham Exp $ - */ - -#include "tclInt.h" -#include "tclMac.h" -#include "tclMacInt.h" -#include "tclPort.h" -#include <FSpCompat.h> -#include <MoreFilesExtras.h> -#include <Strings.h> -#include <Errors.h> -#include <FileCopy.h> -#include <DirectoryCopy.h> -#include <Script.h> -#include <string.h> -#include <Finder.h> - -/* - * Callback for the file attributes code. - */ - -static int GetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp, - int objIndex, CONST char *fileName, - Tcl_Obj **attributePtrPtr)); -static int GetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp, - int objIndex, CONST char *fileName, - Tcl_Obj **readOnlyPtrPtr)); -static int SetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp, - int objIndex, CONST char *fileName, - Tcl_Obj *attributePtr)); -static int SetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp, - int objIndex, CONST char *fileName, - Tcl_Obj *readOnlyPtr)); - -/* - * These are indeces into the tclpFileAttrsStrings table below. - */ - -#define MAC_CREATOR_ATTRIBUTE 0 -#define MAC_HIDDEN_ATTRIBUTE 1 -#define MAC_READONLY_ATTRIBUTE 2 -#define MAC_TYPE_ATTRIBUTE 3 - -/* - * Global variables for the file attributes code. - */ - -char *tclpFileAttrStrings[] = {"-creator", "-hidden", "-readonly", - "-type", (char *) NULL}; -CONST TclFileAttrProcs tclpFileAttrProcs[] = { - {GetFileFinderAttributes, SetFileFinderAttributes}, - {GetFileFinderAttributes, SetFileFinderAttributes}, - {GetFileReadOnly, SetFileReadOnly}, - {GetFileFinderAttributes, SetFileFinderAttributes}}; - - -/* - * Prototypes for procedure only used in this file - */ - -static pascal Boolean CopyErrHandler _ANSI_ARGS_((OSErr error, - short failedOperation, - short srcVRefNum, long srcDirID, - ConstStr255Param srcName, short dstVRefNum, - long dstDirID,ConstStr255Param dstName)); -static int DoCopyDirectory _ANSI_ARGS_((CONST char *src, - CONST char *dst, Tcl_DString *errorPtr)); -static int DoCopyFile _ANSI_ARGS_((CONST char *src, - CONST char *dst)); -static int DoCreateDirectory _ANSI_ARGS_((CONST char *path)); -static int DoDeleteFile _ANSI_ARGS_((CONST char *path)); -static int DoRemoveDirectory _ANSI_ARGS_((CONST char *path, - int recursive, Tcl_DString *errorPtr)); -static int DoRenameFile _ANSI_ARGS_((CONST char *src, - CONST char *dst)); -OSErr FSpGetFLockCompat _ANSI_ARGS_((const FSSpec *specPtr, - Boolean *lockedPtr)); -static OSErr GenerateUniqueName _ANSI_ARGS_((short vRefNum, - long dirID1, long dirID2, Str31 uniqueName)); -static OSErr GetFileSpecs _ANSI_ARGS_((CONST char *path, - FSSpec *pathSpecPtr, FSSpec *dirSpecPtr, - Boolean *pathExistsPtr, - Boolean *pathIsDirectoryPtr)); -static OSErr MoveRename _ANSI_ARGS_((const FSSpec *srcSpecPtr, - const FSSpec *dstSpecPtr, StringPtr copyName)); -static int Pstrequal _ANSI_ARGS_((ConstStr255Param stringA, - ConstStr255Param stringB)); - -/* - *--------------------------------------------------------------------------- - * - * TclpRenameFile, DoRenameFile -- - * - * Changes the name of an existing file or directory, from src to dst. - * If src and dst refer to the same file or directory, does nothing - * and returns success. Otherwise if dst already exists, it will be - * deleted and replaced by src subject to the following conditions: - * If src is a directory, dst may be an empty directory. - * If src is a file, dst may be a file. - * In any other situation where dst already exists, the rename will - * fail. - * - * Results: - * If the directory was successfully created, returns TCL_OK. - * Otherwise the return value is TCL_ERROR and errno is set to - * indicate the error. Some possible values for errno are: - * - * EACCES: src or dst parent directory can't be read and/or written. - * EEXIST: dst is a non-empty directory. - * EINVAL: src is a root directory or dst is a subdirectory of src. - * EISDIR: dst is a directory, but src is not. - * ENOENT: src doesn't exist. src or dst is "". - * ENOTDIR: src is a directory, but dst is not. - * EXDEV: src and dst are on different filesystems. - * - * Side effects: - * The implementation of rename may allow cross-filesystem renames, - * but the caller should be prepared to emulate it with copy and - * delete if errno is EXDEV. - * - *--------------------------------------------------------------------------- - */ - -int -TclpRenameFile( - CONST char *src, /* Pathname of file or dir to be renamed - * (UTF-8). */ - CONST char *dst) /* New pathname of file or directory - * (UTF-8). */ -{ - int result; - Tcl_DString srcString, dstString; - - Tcl_UtfToExternalDString(NULL, src, -1, &srcString); - Tcl_UtfToExternalDString(NULL, dst, -1, &dstString); - result = DoRenameFile(Tcl_DStringValue(&srcString), - Tcl_DStringValue(&dstString)); - Tcl_DStringFree(&srcString); - Tcl_DStringFree(&dstString); - return result; -} - -static int -DoRenameFile( - CONST char *src, /* Pathname of file or dir to be renamed - * (native). */ - CONST char *dst) /* New pathname of file or directory - * (native). */ -{ - FSSpec srcFileSpec, dstFileSpec, dstDirSpec; - OSErr err; - long srcID, dummy; - Boolean srcIsDirectory, dstIsDirectory, dstExists, dstLocked; - - err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); - if (err == noErr) { - FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory); - } - if (err == noErr) { - err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, - &dstIsDirectory); - } - if (err == noErr) { - if (dstExists == 0) { - err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); - goto end; - } - err = FSpGetFLockCompat(&dstFileSpec, &dstLocked); - if (dstLocked) { - FSpRstFLockCompat(&dstFileSpec); - } - } - if (err == noErr) { - if (srcIsDirectory) { - if (dstIsDirectory) { - /* - * The following call will remove an empty directory. If it - * fails, it's because it wasn't empty. - */ - - if (DoRemoveDirectory(dst, 0, NULL) != TCL_OK) { - return TCL_ERROR; - } - - /* - * Now that that empty directory is gone, we can try - * renaming src. If that fails, we'll put this empty - * directory back, for completeness. - */ - - err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); - if (err != noErr) { - FSpDirCreateCompat(&dstFileSpec, smSystemScript, &dummy); - if (dstLocked) { - FSpSetFLockCompat(&dstFileSpec); - } - } - } else { - errno = ENOTDIR; - return TCL_ERROR; - } - } else { - if (dstIsDirectory) { - errno = EISDIR; - return TCL_ERROR; - } else { - /* - * Overwrite existing file by: - * - * 1. Rename existing file to temp name. - * 2. Rename old file to new name. - * 3. If success, delete temp file. If failure, - * put temp file back to old name. - */ - - Str31 tmpName; - FSSpec tmpFileSpec; - - err = GenerateUniqueName(dstFileSpec.vRefNum, - dstFileSpec.parID, dstFileSpec.parID, tmpName); - if (err == noErr) { - err = FSpRenameCompat(&dstFileSpec, tmpName); - } - if (err == noErr) { - err = FSMakeFSSpecCompat(dstFileSpec.vRefNum, - dstFileSpec.parID, tmpName, &tmpFileSpec); - } - if (err == noErr) { - err = MoveRename(&srcFileSpec, &dstDirSpec, - dstFileSpec.name); - } - if (err == noErr) { - FSpDeleteCompat(&tmpFileSpec); - } else { - FSpDeleteCompat(&dstFileSpec); - FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); - if (dstLocked) { - FSpSetFLockCompat(&dstFileSpec); - } - } - } - } - } - - end: - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *-------------------------------------------------------------------------- - * - * MoveRename -- - * - * Helper function for TclpRenameFile. Renames a file or directory - * into the same directory or another directory. The target name - * must not already exist in the destination directory. - * - * Don't use FSpMoveRenameCompat because it doesn't work with - * directories or with locked files. - * - * Results: - * Returns a mac error indicating the cause of the failure. - * - * Side effects: - * Creates a temp file in the target directory to handle a rename - * between directories. - * - *-------------------------------------------------------------------------- - */ - -static OSErr -MoveRename( - const FSSpec *srcFileSpecPtr, /* Source object. */ - const FSSpec *dstDirSpecPtr, /* Destination directory. */ - StringPtr copyName) /* New name for object in destination - * directory. */ -{ - OSErr err; - long srcID, dstID; - Boolean srcIsDir, dstIsDir; - Str31 tmpName; - FSSpec dstFileSpec, srcDirSpec, tmpSrcFileSpec, tmpDstFileSpec; - Boolean locked; - - if (srcFileSpecPtr->parID == 1) { - /* - * Trying to rename a volume. - */ - - return badMovErr; - } - if (srcFileSpecPtr->vRefNum != dstDirSpecPtr->vRefNum) { - /* - * Renaming across volumes. - */ - - return diffVolErr; - } - err = FSpGetFLockCompat(srcFileSpecPtr, &locked); - if (locked) { - FSpRstFLockCompat(srcFileSpecPtr); - } - if (err == noErr) { - err = FSpGetDirectoryID(dstDirSpecPtr, &dstID, &dstIsDir); - } - if (err == noErr) { - if (srcFileSpecPtr->parID == dstID) { - /* - * Renaming object within directory. - */ - - err = FSpRenameCompat(srcFileSpecPtr, copyName); - goto done; - } - if (Pstrequal(srcFileSpecPtr->name, copyName)) { - /* - * Moving object to another directory (under same name). - */ - - err = FSpCatMoveCompat(srcFileSpecPtr, dstDirSpecPtr); - goto done; - } - err = FSpGetDirectoryID(srcFileSpecPtr, &srcID, &srcIsDir); - } - if (err == noErr) { - /* - * Fullblown: rename source object to temp name, move temp to - * dest directory, and rename temp to target. - */ - - err = GenerateUniqueName(srcFileSpecPtr->vRefNum, - srcFileSpecPtr->parID, dstID, tmpName); - FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, - tmpName, &tmpSrcFileSpec); - FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, dstID, tmpName, - &tmpDstFileSpec); - } - if (err == noErr) { - err = FSpRenameCompat(srcFileSpecPtr, tmpName); - } - if (err == noErr) { - err = FSpCatMoveCompat(&tmpSrcFileSpec, dstDirSpecPtr); - if (err == noErr) { - err = FSpRenameCompat(&tmpDstFileSpec, copyName); - if (err == noErr) { - goto done; - } - FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, - NULL, &srcDirSpec); - FSpCatMoveCompat(&tmpDstFileSpec, &srcDirSpec); - } - FSpRenameCompat(&tmpSrcFileSpec, srcFileSpecPtr->name); - } - - done: - if (locked != false) { - if (err == noErr) { - FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, - dstID, copyName, &dstFileSpec); - FSpSetFLockCompat(&dstFileSpec); - } else { - FSpSetFLockCompat(srcFileSpecPtr); - } - } - return err; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpCopyFile, DoCopyFile -- - * - * Copy a single file (not a directory). If dst already exists and - * is not a directory, it is removed. - * - * Results: - * If the file was successfully copied, returns TCL_OK. Otherwise - * the return value is TCL_ERROR and errno is set to indicate the - * error. Some possible values for errno are: - * - * EACCES: src or dst parent directory can't be read and/or written. - * EISDIR: src or dst is a directory. - * ENOENT: src doesn't exist. src or dst is "". - * - * Side effects: - * This procedure will also copy symbolic links, block, and - * character devices, and fifos. For symbolic links, the links - * themselves will be copied and not what they point to. For the - * other special file types, the directory entry will be copied and - * not the contents of the device that it refers to. - * - *--------------------------------------------------------------------------- - */ - -int -TclpCopyFile( - CONST char *src, /* Pathname of file to be copied (UTF-8). */ - CONST char *dst) /* Pathname of file to copy to (UTF-8). */ -{ - int result; - Tcl_DString srcString, dstString; - - Tcl_UtfToExternalDString(NULL, src, -1, &srcString); - Tcl_UtfToExternalDString(NULL, dst, -1, &dstString); - result = DoCopyFile(Tcl_DStringValue(&srcString), - Tcl_DStringValue(&dstString)); - Tcl_DStringFree(&srcString); - Tcl_DStringFree(&dstString); - return result; -} - -static int -DoCopyFile( - CONST char *src, /* Pathname of file to be copied (native). */ - CONST char *dst) /* Pathname of file to copy to (native). */ -{ - OSErr err, dstErr; - Boolean dstExists, dstIsDirectory, dstLocked; - FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpFileSpec; - Str31 tmpName; - - err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); - if (err == noErr) { - err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, - &dstIsDirectory); - } - if (dstExists) { - if (dstIsDirectory) { - errno = EISDIR; - return TCL_ERROR; - } - err = FSpGetFLockCompat(&dstFileSpec, &dstLocked); - if (dstLocked) { - FSpRstFLockCompat(&dstFileSpec); - } - - /* - * Backup dest file. - */ - - dstErr = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, - dstFileSpec.parID, tmpName); - if (dstErr == noErr) { - dstErr = FSpRenameCompat(&dstFileSpec, tmpName); - } - } - if (err == noErr) { - err = FSpFileCopy(&srcFileSpec, &dstDirSpec, - (StringPtr) dstFileSpec.name, NULL, 0, true); - } - if ((dstExists != false) && (dstErr == noErr)) { - FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, - tmpName, &tmpFileSpec); - if (err == noErr) { - /* - * Delete backup file. - */ - - FSpDeleteCompat(&tmpFileSpec); - } else { - - /* - * Restore backup file. - */ - - FSpDeleteCompat(&dstFileSpec); - FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); - if (dstLocked) { - FSpSetFLockCompat(&dstFileSpec); - } - } - } - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpDeleteFile, DoDeleteFile -- - * - * Removes a single file (not a directory). - * - * Results: - * If the file was successfully deleted, returns TCL_OK. Otherwise - * the return value is TCL_ERROR and errno is set to indicate the - * error. Some possible values for errno are: - * - * EACCES: a parent directory can't be read and/or written. - * EISDIR: path is a directory. - * ENOENT: path doesn't exist or is "". - * - * Side effects: - * The file is deleted, even if it is read-only. - * - *--------------------------------------------------------------------------- - */ - -int -TclpDeleteFile( - CONST char *path) /* Pathname of file to be removed (UTF-8). */ -{ - int result; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, path, -1, &pathString); - result = DoDeleteFile(Tcl_DStringValue(&pathString)); - Tcl_DStringFree(&pathString); - return result; -} - -static int -DoDeleteFile( - CONST char *path) /* Pathname of file to be removed (native). */ -{ - OSErr err; - FSSpec fileSpec; - Boolean isDirectory; - long dirID; - - err = FSpLocationFromPath(strlen(path), path, &fileSpec); - if (err == noErr) { - /* - * Since FSpDeleteCompat will delete an empty directory, make sure - * that this isn't a directory first. - */ - - FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); - if (isDirectory == true) { - errno = EISDIR; - return TCL_ERROR; - } - } - err = FSpDeleteCompat(&fileSpec); - if (err == fLckdErr) { - FSpRstFLockCompat(&fileSpec); - err = FSpDeleteCompat(&fileSpec); - if (err != noErr) { - FSpSetFLockCompat(&fileSpec); - } - } - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpCreateDirectory, DoCreateDirectory -- - * - * Creates the specified directory. All parent directories of the - * specified directory must already exist. The directory is - * automatically created with permissions so that user can access - * the new directory and create new files or subdirectories in it. - * - * Results: - * If the directory was successfully created, returns TCL_OK. - * Otherwise the return value is TCL_ERROR and errno is set to - * indicate the error. Some possible values for errno are: - * - * EACCES: a parent directory can't be read and/or written. - * EEXIST: path already exists. - * ENOENT: a parent directory doesn't exist. - * - * Side effects: - * A directory is created with the current umask, except that - * permission for u+rwx will always be added. - * - *--------------------------------------------------------------------------- - */ - -int -TclpCreateDirectory( - CONST char *path) /* Pathname of directory to create (UTF-8). */ -{ - int result; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, path, -1, &pathString); - result = DoCreateDirectory(Tcl_DStringValue(&pathString)); - Tcl_DStringFree(&pathString); - return result; -} - -static int -DoCreateDirectory( - CONST char *path) /* Pathname of directory to create (native). */ -{ - OSErr err; - FSSpec dirSpec; - long outDirID; - - err = FSpLocationFromPath(strlen(path), path, &dirSpec); - if (err == noErr) { - err = dupFNErr; /* EEXIST. */ - } else if (err == fnfErr) { - err = FSpDirCreateCompat(&dirSpec, smSystemScript, &outDirID); - } - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpCopyDirectory, DoCopyDirectory -- - * - * Recursively copies a directory. The target directory dst must - * not already exist. Note that this function does not merge two - * directory hierarchies, even if the target directory is an an - * empty directory. - * - * Results: - * If the directory was successfully copied, returns TCL_OK. - * Otherwise the return value is TCL_ERROR, errno is set to indicate - * the error, and the pathname of the file that caused the error - * is stored in errorPtr. See TclpCreateDirectory and TclpCopyFile - * for a description of possible values for errno. - * - * Side effects: - * An exact copy of the directory hierarchy src will be created - * with the name dst. If an error occurs, the error will - * be returned immediately, and remaining files will not be - * processed. - * - *--------------------------------------------------------------------------- - */ - -int -TclpCopyDirectory( - CONST char *src, /* Pathname of directory to be copied - * (UTF-8). */ - CONST char *dst, /* Pathname of target directory (UTF-8). */ - Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free - * DString filled with UTF-8 name of file - * causing error. */ -{ - int result; - Tcl_DString srcString, dstString; - - Tcl_UtfToExternalDString(NULL, src, -1, &srcString); - Tcl_UtfToExternalDString(NULL, dst, -1, &dstString); - result = DoCopyDirectory(Tcl_DStringValue(&srcString), - Tcl_DStringValue(&dstString), errorPtr); - Tcl_DStringFree(&srcString); - Tcl_DStringFree(&dstString); - return result; -} - -static int -DoCopyDirectory( - CONST char *src, /* Pathname of directory to be copied - * (UTF-8). */ - CONST char *dst, /* Pathname of target directory (UTF-8). */ - Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free - * DString filled with UTF-8 name of file - * causing error. */ -{ - OSErr err, saveErr; - long srcID, tmpDirID; - FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpDirSpec, tmpFileSpec; - Boolean srcIsDirectory, srcLocked; - Boolean dstIsDirectory, dstExists; - Str31 tmpName; - - err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); - if (err == noErr) { - err = FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory); - } - if (err == noErr) { - if (srcIsDirectory == false) { - err = afpObjectTypeErr; /* ENOTDIR. */ - } - } - if (err == noErr) { - err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, - &dstIsDirectory); - } - if (dstExists) { - if (dstIsDirectory == false) { - err = afpObjectTypeErr; /* ENOTDIR. */ - } else { - err = dupFNErr; /* EEXIST. */ - } - } - if (err != noErr) { - goto done; - } - if ((srcFileSpec.vRefNum == dstFileSpec.vRefNum) && - (srcFileSpec.parID == dstFileSpec.parID) && - (Pstrequal(srcFileSpec.name, dstFileSpec.name) != 0)) { - /* - * Copying on top of self. No-op. - */ - - goto done; - } - - /* - * This algorthm will work making a copy of the source directory in - * the current directory with a new name, in a new directory with the - * same name, and in a new directory with a new name: - * - * 1. Make dstDir/tmpDir. - * 2. Copy srcDir/src to dstDir/tmpDir/src - * 3. Rename dstDir/tmpDir/src to dstDir/tmpDir/dst (if necessary). - * 4. CatMove dstDir/tmpDir/dst to dstDir/dst. - * 5. Remove dstDir/tmpDir. - */ - - err = FSpGetFLockCompat(&srcFileSpec, &srcLocked); - if (srcLocked) { - FSpRstFLockCompat(&srcFileSpec); - } - if (err == noErr) { - err = GenerateUniqueName(dstFileSpec.vRefNum, dstFileSpec.parID, - dstFileSpec.parID, tmpName); - } - if (err == noErr) { - FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, - tmpName, &tmpDirSpec); - err = FSpDirCreateCompat(&tmpDirSpec, smSystemScript, &tmpDirID); - } - if (err == noErr) { - err = FSpDirectoryCopy(&srcFileSpec, &tmpDirSpec, NULL, 0, true, - CopyErrHandler); - } - - /* - * Even if the Copy failed, Rename/Move whatever did get copied to the - * appropriate final destination, if possible. - */ - - saveErr = err; - err = noErr; - if (Pstrequal(srcFileSpec.name, dstFileSpec.name) == 0) { - err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, - srcFileSpec.name, &tmpFileSpec); - if (err == noErr) { - err = FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); - } - } - if (err == noErr) { - err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, - dstFileSpec.name, &tmpFileSpec); - } - if (err == noErr) { - err = FSpCatMoveCompat(&tmpFileSpec, &dstDirSpec); - } - if (err == noErr) { - if (srcLocked) { - FSpSetFLockCompat(&dstFileSpec); - } - } - - FSpDeleteCompat(&tmpDirSpec); - - if (saveErr != noErr) { - err = saveErr; - } - - done: - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - if (errorPtr != NULL) { - Tcl_ExternalToUtfDString(NULL, dst, -1, errorPtr); - } - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * CopyErrHandler -- - * - * This procedure is called from the MoreFiles procedure - * FSpDirectoryCopy whenever an error occurs. - * - * Results: - * False if the condition should not be considered an error, true - * otherwise. - * - * Side effects: - * Since FSpDirectoryCopy() is called only after removing any - * existing target directories, there shouldn't be any errors. - * - *---------------------------------------------------------------------- - */ - -static pascal Boolean -CopyErrHandler( - OSErr error, /* Error that occured */ - short failedOperation, /* operation that caused the error */ - short srcVRefNum, /* volume ref number of source */ - long srcDirID, /* directory id of source */ - ConstStr255Param srcName, /* name of source */ - short dstVRefNum, /* volume ref number of dst */ - long dstDirID, /* directory id of dst */ - ConstStr255Param dstName) /* name of dst directory */ -{ - return true; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpRemoveDirectory, DoRemoveDirectory -- - * - * Removes directory (and its contents, if the recursive flag is set). - * - * Results: - * If the directory was successfully removed, returns TCL_OK. - * Otherwise the return value is TCL_ERROR, errno is set to indicate - * the error, and the pathname of the file that caused the error - * is stored in errorPtr. Some possible values for errno are: - * - * EACCES: path directory can't be read and/or written. - * EEXIST: path is a non-empty directory. - * EINVAL: path is a root directory. - * ENOENT: path doesn't exist or is "". - * ENOTDIR: path is not a directory. - * - * Side effects: - * Directory removed. If an error occurs, the error will be returned - * immediately, and remaining files will not be deleted. - * - *--------------------------------------------------------------------------- - */ - -int -TclpRemoveDirectory( - CONST char *path, /* Pathname of directory to be removed - * (UTF-8). */ - int recursive, /* If non-zero, removes directories that - * are nonempty. Otherwise, will only remove - * empty directories. */ - Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free - * DString filled with UTF-8 name of file - * causing error. */ -{ - int result; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, path, -1, &pathString); - result = DoRemoveDirectory(Tcl_DStringValue(&pathString), recursive, - errorPtr); - Tcl_DStringFree(&pathString); - - return result; -} - -static int -DoRemoveDirectory( - CONST char *path, /* Pathname of directory to be removed - * (native). */ - int recursive, /* If non-zero, removes directories that - * are nonempty. Otherwise, will only remove - * empty directories. */ - Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free - * DString filled with UTF-8 name of file - * causing error. */ -{ - OSErr err; - FSSpec fileSpec; - long dirID; - int locked; - Boolean isDirectory; - CInfoPBRec pb; - Str255 fileName; - - - locked = 0; - err = FSpLocationFromPath(strlen(path), path, &fileSpec); - if (err != noErr) { - goto done; - } - - /* - * Since FSpDeleteCompat will delete a file, make sure this isn't - * a file first. - */ - - isDirectory = 1; - FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); - if (isDirectory == 0) { - errno = ENOTDIR; - return TCL_ERROR; - } - - err = FSpDeleteCompat(&fileSpec); - if (err == fLckdErr) { - locked = 1; - FSpRstFLockCompat(&fileSpec); - err = FSpDeleteCompat(&fileSpec); - } - if (err == noErr) { - return TCL_OK; - } - if (err != fBsyErr) { - goto done; - } - - if (recursive == 0) { - /* - * fBsyErr means one of three things: file busy, directory not empty, - * or working directory control block open. Determine if directory - * is empty. If directory is not empty, return EEXIST. - */ - - pb.hFileInfo.ioVRefNum = fileSpec.vRefNum; - pb.hFileInfo.ioDirID = dirID; - pb.hFileInfo.ioNamePtr = (StringPtr) fileName; - pb.hFileInfo.ioFDirIndex = 1; - if (PBGetCatInfoSync(&pb) == noErr) { - err = dupFNErr; /* EEXIST */ - goto done; - } - } - - /* - * DeleteDirectory removes a directory and all its contents, including - * any locked files. There is no interface to get the name of the - * file that caused the error, if an error occurs deleting this tree, - * unless we rewrite DeleteDirectory ourselves. - */ - - err = DeleteDirectory(fileSpec.vRefNum, dirID, NULL); - - done: - if (err != noErr) { - if (errorPtr != NULL) { - Tcl_UtfToExternalDString(NULL, path, -1, errorPtr); - } - if (locked) { - FSpSetFLockCompat(&fileSpec); - } - errno = TclMacOSErrorToPosixError(err); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *--------------------------------------------------------------------------- - * - * GenerateUniqueName -- - * - * Generate a filename that is not in either of the two specified - * directories (on the same volume). - * - * Results: - * Standard macintosh error. On success, uniqueName is filled with - * the name of the temporary file. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -static OSErr -GenerateUniqueName( - short vRefNum, /* Volume on which the following directories - * are located. */ - long dirID1, /* ID of first directory. */ - long dirID2, /* ID of second directory. May be the same - * as the first. */ - Str31 uniqueName) /* Filled with filename for a file that is - * not located in either of the above two - * directories. */ -{ - OSErr err; - long i; - CInfoPBRec pb; - static unsigned char hexStr[16] = "0123456789ABCDEF"; - static long startSeed = 248923489; - - pb.hFileInfo.ioVRefNum = vRefNum; - pb.hFileInfo.ioFDirIndex = 0; - pb.hFileInfo.ioNamePtr = uniqueName; - - while (1) { - startSeed++; - pb.hFileInfo.ioNamePtr[0] = 8; - for (i = 1; i <= 8; i++) { - pb.hFileInfo.ioNamePtr[i] = hexStr[((startSeed >> ((8-i)*4)) & 0xf)]; - } - pb.hFileInfo.ioDirID = dirID1; - err = PBGetCatInfoSync(&pb); - if (err == fnfErr) { - if (dirID1 != dirID2) { - pb.hFileInfo.ioDirID = dirID2; - err = PBGetCatInfoSync(&pb); - } - if (err == fnfErr) { - return noErr; - } - } - if (err == noErr) { - continue; - } - return err; - } -} - -/* - *--------------------------------------------------------------------------- - * - * GetFileSpecs -- - * - * Gets FSSpecs for the specified path and its parent directory. - * - * Results: - * The return value is noErr if there was no error getting FSSpecs, - * otherwise it is an error describing the problem. Fills buffers - * with information, as above. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -static OSErr -GetFileSpecs( - CONST char *path, /* The path to query. */ - FSSpec *pathSpecPtr, /* Filled with information about path. */ - FSSpec *dirSpecPtr, /* Filled with information about path's - * parent directory. */ - Boolean *pathExistsPtr, /* Set to true if path actually exists, - * false if it doesn't or there was an - * error reading the specified path. */ - Boolean *pathIsDirectoryPtr)/* Set to true if path is itself a directory, - * otherwise false. */ -{ - char *dirName; - OSErr err; - int argc; - char **argv; - long d; - Tcl_DString buffer; - - *pathExistsPtr = false; - *pathIsDirectoryPtr = false; - - Tcl_DStringInit(&buffer); - Tcl_SplitPath(path, &argc, &argv); - if (argc == 1) { - dirName = ":"; - } else { - dirName = Tcl_JoinPath(argc - 1, argv, &buffer); - } - err = FSpLocationFromPath(strlen(dirName), dirName, dirSpecPtr); - Tcl_DStringFree(&buffer); - ckfree((char *) argv); - - if (err == noErr) { - err = FSpLocationFromPath(strlen(path), path, pathSpecPtr); - if (err == noErr) { - *pathExistsPtr = true; - err = FSpGetDirectoryID(pathSpecPtr, &d, pathIsDirectoryPtr); - } else if (err == fnfErr) { - err = noErr; - } - } - return err; -} - -/* - *------------------------------------------------------------------------- - * - * FSpGetFLockCompat -- - * - * Determines if there exists a software lock on the specified - * file. The software lock could prevent the file from being - * renamed or moved. - * - * Results: - * Standard macintosh error code. - * - * Side effects: - * None. - * - * - *------------------------------------------------------------------------- - */ - -OSErr -FSpGetFLockCompat( - const FSSpec *specPtr, /* File to query. */ - Boolean *lockedPtr) /* Set to true if file is locked, false - * if it isn't or there was an error reading - * specified file. */ -{ - CInfoPBRec pb; - OSErr err; - - pb.hFileInfo.ioVRefNum = specPtr->vRefNum; - pb.hFileInfo.ioDirID = specPtr->parID; - pb.hFileInfo.ioNamePtr = (StringPtr) specPtr->name; - pb.hFileInfo.ioFDirIndex = 0; - - err = PBGetCatInfoSync(&pb); - if ((err == noErr) && (pb.hFileInfo.ioFlAttrib & 0x01)) { - *lockedPtr = true; - } else { - *lockedPtr = false; - } - return err; -} - -/* - *---------------------------------------------------------------------- - * - * Pstrequal -- - * - * Pascal string compare. - * - * Results: - * Returns 1 if strings equal, 0 otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -Pstrequal ( - ConstStr255Param stringA, /* Pascal string A */ - ConstStr255Param stringB) /* Pascal string B */ -{ - int i, len; - - len = *stringA; - for (i = 0; i <= len; i++) { - if (*stringA++ != *stringB++) { - return 0; - } - } - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * GetFileFinderAttributes -- - * - * Returns a Tcl_Obj containing the value of a file attribute - * which is part of the FInfo record. Which attribute is controlled - * by objIndex. - * - * Results: - * Returns a standard TCL error. If the return value is TCL_OK, - * the new creator or file type object is put into attributePtrPtr. - * The object will have ref count 0. If there is an error, - * attributePtrPtr is not touched. - * - * Side effects: - * A new object is allocated if the file is valid. - * - *---------------------------------------------------------------------- - */ - -static int -GetFileFinderAttributes( - Tcl_Interp *interp, /* The interp to report errors with. */ - int objIndex, /* The index of the attribute option. */ - CONST char *fileName, /* The name of the file (UTF-8). */ - Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ -{ - OSErr err; - FSSpec fileSpec; - FInfo finfo; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, fileName, -1, &pathString); - err = FSpLocationFromPath(Tcl_DStringLength(&pathString), - Tcl_DStringValue(&pathString), &fileSpec); - Tcl_DStringFree(&pathString); - - if (err == noErr) { - err = FSpGetFInfo(&fileSpec, &finfo); - } - - if (err == noErr) { - switch (objIndex) { - case MAC_CREATOR_ATTRIBUTE: - *attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdCreator); - break; - case MAC_HIDDEN_ATTRIBUTE: - *attributePtrPtr = Tcl_NewBooleanObj(finfo.fdFlags - & kIsInvisible); - break; - case MAC_TYPE_ATTRIBUTE: - *attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdType); - break; - } - } else if (err == fnfErr) { - long dirID; - Boolean isDirectory = 0; - - err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); - if ((err == noErr) && isDirectory) { - if (objIndex == MAC_HIDDEN_ATTRIBUTE) { - *attributePtrPtr = Tcl_NewBooleanObj(0); - } else { - *attributePtrPtr = Tcl_NewOSTypeObj('Fldr'); - } - } - } - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "could not read \"", fileName, "\": ", - Tcl_PosixError(interp), (char *) NULL); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * GetFileReadOnly -- - * - * Returns a Tcl_Obj containing a Boolean value indicating whether - * or not the file is read-only. The object will have ref count 0. - * This procedure just checks the Finder attributes; it does not - * check AppleShare sharing attributes. - * - * Results: - * Returns a standard TCL error. If the return value is TCL_OK, - * the new creator type object is put into readOnlyPtrPtr. - * If there is an error, readOnlyPtrPtr is not touched. - * - * Side effects: - * A new object is allocated if the file is valid. - * - *---------------------------------------------------------------------- - */ - -static int -GetFileReadOnly( - Tcl_Interp *interp, /* The interp to report errors with. */ - int objIndex, /* The index of the attribute. */ - CONST char *fileName, /* The name of the file (UTF-8). */ - Tcl_Obj **readOnlyPtrPtr) /* A pointer to return the object with. */ -{ - OSErr err; - FSSpec fileSpec; - CInfoPBRec paramBlock; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, fileName, -1, &pathString); - err = FSpLocationFromPath(Tcl_DStringLength(&pathString), - Tcl_DStringValue(&pathString), &fileSpec); - Tcl_DStringFree(&pathString); - - if (err == noErr) { - if (err == noErr) { - paramBlock.hFileInfo.ioCompletion = NULL; - paramBlock.hFileInfo.ioNamePtr = fileSpec.name; - paramBlock.hFileInfo.ioVRefNum = fileSpec.vRefNum; - paramBlock.hFileInfo.ioFDirIndex = 0; - paramBlock.hFileInfo.ioDirID = fileSpec.parID; - err = PBGetCatInfo(¶mBlock, 0); - if (err == noErr) { - - /* - * For some unknown reason, the Mac does not give - * symbols for the bits in the ioFlAttrib field. - * 1 -> locked. - */ - - *readOnlyPtrPtr = Tcl_NewBooleanObj( - paramBlock.hFileInfo.ioFlAttrib & 1); - } - } - } - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "could not read \"", fileName, "\": ", - Tcl_PosixError(interp), (char *) NULL); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * SetFileFinderAttributes -- - * - * Sets the file to the creator or file type given by attributePtr. - * objIndex determines whether the creator or file type is set. - * - * Results: - * Returns a standard TCL error. - * - * Side effects: - * The file's attribute is set. - * - *---------------------------------------------------------------------- - */ - -static int -SetFileFinderAttributes( - Tcl_Interp *interp, /* The interp to report errors with. */ - int objIndex, /* The index of the attribute. */ - CONST char *fileName, /* The name of the file (UTF-8). */ - Tcl_Obj *attributePtr) /* The command line object. */ -{ - OSErr err; - FSSpec fileSpec; - FInfo finfo; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, fileName, -1, &pathString); - err = FSpLocationFromPath(Tcl_DStringLength(&pathString), - Tcl_DStringValue(&pathString), &fileSpec); - Tcl_DStringFree(&pathString); - - if (err == noErr) { - err = FSpGetFInfo(&fileSpec, &finfo); - } - - if (err == noErr) { - switch (objIndex) { - case MAC_CREATOR_ATTRIBUTE: - if (Tcl_GetOSTypeFromObj(interp, attributePtr, - &finfo.fdCreator) != TCL_OK) { - return TCL_ERROR; - } - break; - case MAC_HIDDEN_ATTRIBUTE: { - int hidden; - - if (Tcl_GetBooleanFromObj(interp, attributePtr, &hidden) - != TCL_OK) { - return TCL_ERROR; - } - if (hidden) { - finfo.fdFlags |= kIsInvisible; - } else { - finfo.fdFlags &= ~kIsInvisible; - } - break; - } - case MAC_TYPE_ATTRIBUTE: - if (Tcl_GetOSTypeFromObj(interp, attributePtr, - &finfo.fdType) != TCL_OK) { - return TCL_ERROR; - } - break; - } - err = FSpSetFInfo(&fileSpec, &finfo); - } else if (err == fnfErr) { - long dirID; - Boolean isDirectory = 0; - - err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); - if ((err == noErr) && isDirectory) { - Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); - Tcl_AppendStringsToObj(resultPtr, "cannot set ", - tclpFileAttrStrings[objIndex], ": \"", - fileName, "\" is a directory", (char *) NULL); - return TCL_ERROR; - } - } - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "could not read \"", fileName, "\": ", - Tcl_PosixError(interp), (char *) NULL); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * SetFileReadOnly -- - * - * Sets the file to be read-only according to the Boolean value - * given by hiddenPtr. - * - * Results: - * Returns a standard TCL error. - * - * Side effects: - * The file's attribute is set. - * - *---------------------------------------------------------------------- - */ - -static int -SetFileReadOnly( - Tcl_Interp *interp, /* The interp to report errors with. */ - int objIndex, /* The index of the attribute. */ - CONST char *fileName, /* The name of the file (UTF-8). */ - Tcl_Obj *readOnlyPtr) /* The command line object. */ -{ - OSErr err; - FSSpec fileSpec; - HParamBlockRec paramBlock; - int hidden; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, fileName, -1, &pathString); - err = FSpLocationFromPath(Tcl_DStringLength(&pathString), - Tcl_DStringValue(&pathString), &fileSpec); - Tcl_DStringFree(&pathString); - - if (err == noErr) { - if (Tcl_GetBooleanFromObj(interp, readOnlyPtr, &hidden) != TCL_OK) { - return TCL_ERROR; - } - - paramBlock.fileParam.ioCompletion = NULL; - paramBlock.fileParam.ioNamePtr = fileSpec.name; - paramBlock.fileParam.ioVRefNum = fileSpec.vRefNum; - paramBlock.fileParam.ioDirID = fileSpec.parID; - if (hidden) { - err = PBHSetFLock(¶mBlock, 0); - } else { - err = PBHRstFLock(¶mBlock, 0); - } - } - - if (err == fnfErr) { - long dirID; - Boolean isDirectory = 0; - err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); - if ((err == noErr) && isDirectory) { - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "cannot set a directory to read-only when File Sharing is turned off", - (char *) NULL); - return TCL_ERROR; - } else { - err = fnfErr; - } - } - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "could not read \"", fileName, "\": ", - Tcl_PosixError(interp), (char *) NULL); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpListVolumes -- - * - * Lists the currently mounted volumes - * - * Results: - * A standard Tcl result. Will always be TCL_OK, since there is no way - * that this command can fail. Also, the interpreter's result is set to - * the list of volumes. - * - * Side effects: - * None - * - *--------------------------------------------------------------------------- - */ -int -TclpListVolumes( - Tcl_Interp *interp) /* Interpreter to which to pass the volume list */ -{ - HParamBlockRec pb; - Str255 name; - OSErr theError = noErr; - Tcl_Obj *resultPtr, *elemPtr; - short volIndex = 1; - Tcl_DString dstr; - - resultPtr = Tcl_NewObj(); - - /* - * We use two facts: - * 1) The Mac volumes are enumerated by the ioVolIndex parameter of - * the HParamBlockRec. They run through the integers contiguously, - * starting at 1. - * 2) PBHGetVInfoSync returns an error when you ask for a volume index - * that does not exist. - * - */ - - while ( 1 ) { - pb.volumeParam.ioNamePtr = (StringPtr) &name; - pb.volumeParam.ioVolIndex = volIndex; - - theError = PBHGetVInfoSync(&pb); - - if ( theError != noErr ) { - break; - } - - Tcl_ExternalToUtfDString(NULL, (char *) &name[1], name[0], &dstr); - elemPtr = Tcl_NewStringObj(Tcl_DStringValue(&dstr), - Tcl_DStringLength(&dstr)); - Tcl_AppendToObj(elemPtr, ":", 1); - Tcl_ListObjAppendElement(interp, resultPtr, elemPtr); - - Tcl_DStringFree(&dstr); - - volIndex++; - } - - Tcl_SetObjResult(interp, resultPtr); - return TCL_OK; -} - diff --git a/mac/tclMacFile.c b/mac/tclMacFile.c deleted file mode 100644 index b3175d9..0000000 --- a/mac/tclMacFile.c +++ /dev/null @@ -1,921 +0,0 @@ -/* - * tclMacFile.c -- - * - * This file implements the channel drivers for Macintosh - * files. It also comtains Macintosh version of other Tcl - * functions that deal with the file system. - * - * Copyright (c) 1995-1998 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacFile.c,v 1.8 1999/08/10 04:21:35 jingham Exp $ - */ - -/* - * Note: This code eventually needs to support async I/O. In doing this - * we will need to keep track of all current async I/O. If exit to shell - * is called - we shouldn't exit until all asyc I/O completes. - */ - -#include "tclInt.h" -#include "tclPort.h" -#include "tclMacInt.h" -#include <Aliases.h> -#include <Errors.h> -#include <Processes.h> -#include <Strings.h> -#include <Types.h> -#include <MoreFiles.h> -#include <MoreFilesExtras.h> -#include <FSpCompat.h> - -/* - * Static variables used by the TclpStat function. - */ -static int initialized = false; -static long gmt_offset; -TCL_DECLARE_MUTEX(gmtMutex) - - -/* - *---------------------------------------------------------------------- - * - * TclpFindExecutable -- - * - * This procedure computes the absolute path name of the current - * application, given its argv[0] value. However, this - * implementation doesn't need the argv[0] value. NULL - * may be passed in its place. - * - * Results: - * None. - * - * Side effects: - * The variable tclExecutableName gets filled in with the file - * name for the application, if we figured it out. If we couldn't - * figure it out, Tcl_FindExecutable is set to NULL. - * - *---------------------------------------------------------------------- - */ - -char * -TclpFindExecutable( - CONST char *argv0) /* The value of the application's argv[0]. */ -{ - ProcessSerialNumber psn; - ProcessInfoRec info; - Str63 appName; - FSSpec fileSpec; - int pathLength; - Handle pathName = NULL; - OSErr err; - Tcl_DString ds; - - TclInitSubsystems(argv0); - - GetCurrentProcess(&psn); - info.processInfoLength = sizeof(ProcessInfoRec); - info.processName = appName; - info.processAppSpec = &fileSpec; - GetProcessInformation(&psn, &info); - - if (tclExecutableName != NULL) { - ckfree(tclExecutableName); - tclExecutableName = NULL; - } - - err = FSpPathFromLocation(&fileSpec, &pathLength, &pathName); - HLock(pathName); - Tcl_ExternalToUtfDString(NULL, *pathName, pathLength, &ds); - HUnlock(pathName); - DisposeHandle(pathName); - - tclExecutableName = (char *) ckalloc((unsigned) - (Tcl_DStringLength(&ds) + 1)); - strcpy(tclExecutableName, Tcl_DStringValue(&ds)); - Tcl_DStringFree(&ds); - return tclExecutableName; -} - -/* - *---------------------------------------------------------------------- - * - * TclpMatchFiles -- - * - * This routine is used by the globbing code to search a - * directory for all files which match a given pattern. - * - * Results: - * If the tail argument is NULL, then the matching files are - * added to the the interp's result. Otherwise, TclDoGlob is called - * recursively for each matching subdirectory. The return value - * is a standard Tcl result indicating whether an error occurred - * in globbing. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- */ - -int -TclpMatchFiles( - Tcl_Interp *interp, /* Interpreter to receive results. */ - char *separators, /* Directory separators to pass to TclDoGlob. */ - Tcl_DString *dirPtr, /* Contains path to directory to search. */ - char *pattern, /* Pattern to match against. */ - char *tail) /* Pointer to end of pattern. Tail must - * point to a location in pattern and must - * not be static.*/ -{ - char *patternEnd = tail; - char savedChar; - int result = TCL_OK; - int baseLength = Tcl_DStringLength(dirPtr); - CInfoPBRec pb; - OSErr err; - FSSpec dirSpec; - Boolean isDirectory; - long dirID; - short itemIndex; - Str255 fileName; - Tcl_DString fileString; - - /* - * Make sure that the directory part of the name really is a - * directory. - */ - - Tcl_UtfToExternalDString(NULL, dirPtr->string, dirPtr->length, &fileString); - - FSpLocationFromPath(fileString.length, fileString.string, &dirSpec); - Tcl_DStringFree(&fileString); - - err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory); - if ((err != noErr) || !isDirectory) { - return TCL_OK; - } - - /* - * Now open the directory for reading and iterate over the contents. - */ - - pb.hFileInfo.ioVRefNum = dirSpec.vRefNum; - pb.hFileInfo.ioDirID = dirID; - pb.hFileInfo.ioNamePtr = (StringPtr) fileName; - pb.hFileInfo.ioFDirIndex = itemIndex = 1; - - /* - * Clean up the end of the pattern and the tail pointer. Leave - * the tail pointing to the first character after the path separator - * following the pattern, or NULL. Also, ensure that the pattern - * is null-terminated. - */ - - if (*tail == '\\') { - tail++; - } - if (*tail == '\0') { - tail = NULL; - } else { - tail++; - } - savedChar = *patternEnd; - *patternEnd = '\0'; - - while (1) { - pb.hFileInfo.ioFDirIndex = itemIndex; - pb.hFileInfo.ioDirID = dirID; - err = PBGetCatInfoSync(&pb); - if (err != noErr) { - break; - } - - /* - * Now check to see if the file matches. If there are more - * characters to be processed, then ensure matching files are - * directories before calling TclDoGlob. Otherwise, just add - * the file to the result. - */ - - Tcl_ExternalToUtfDString(NULL, (char *) fileName + 1, fileName[0], - &fileString); - if (Tcl_StringMatch(Tcl_DStringValue(&fileString), pattern)) { - Tcl_DStringSetLength(dirPtr, baseLength); - Tcl_DStringAppend(dirPtr, Tcl_DStringValue(&fileString), -1); - if (tail == NULL) { - if ((dirPtr->length > 1) && - (strchr(dirPtr->string+1, ':') == NULL)) { - Tcl_AppendElement(interp, dirPtr->string+1); - } else { - Tcl_AppendElement(interp, dirPtr->string); - } - } else if ((pb.hFileInfo.ioFlAttrib & ioDirMask) != 0) { - Tcl_DStringAppend(dirPtr, ":", 1); - result = TclDoGlob(interp, separators, dirPtr, tail); - if (result != TCL_OK) { - Tcl_DStringFree(&fileString); - break; - } - } - } - Tcl_DStringFree(&fileString); - - itemIndex++; - } - *patternEnd = savedChar; - - return result; -} - -/* - *---------------------------------------------------------------------- - * - * TclpAccess -- - * - * This function replaces the library version of access(). - * - * Results: - * See access documentation. - * - * Side effects: - * See access documentation. - * - *---------------------------------------------------------------------- - */ - -int -TclpAccess( - CONST char *path, /* Path of file to access (UTF-8). */ - int mode) /* Permission setting. */ -{ - HFileInfo fpb; - HVolumeParam vpb; - OSErr err; - FSSpec fileSpec; - Boolean isDirectory; - long dirID; - Tcl_DString ds; - char *native; - int full_mode = 0; - - native = Tcl_UtfToExternalDString(NULL, path, -1, &ds); - err = FSpLocationFromPath(Tcl_DStringLength(&ds), native, &fileSpec); - Tcl_DStringFree(&ds); - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return -1; - } - - /* - * Fill the fpb & vpb struct up with info about file or directory. - */ - FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); - vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum; - vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name; - if (isDirectory) { - fpb.ioDirID = fileSpec.parID; - } else { - fpb.ioDirID = dirID; - } - - fpb.ioFDirIndex = 0; - err = PBGetCatInfoSync((CInfoPBPtr)&fpb); - if (err == noErr) { - vpb.ioVolIndex = 0; - err = PBHGetVInfoSync((HParmBlkPtr)&vpb); - if (err == noErr) { - /* - * Use the Volume Info & File Info to determine - * access information. If we have got this far - * we know the directory is searchable or the file - * exists. (We have F_OK) - */ - - /* - * Check to see if the volume is hardware or - * software locked. If so we arn't W_OK. - */ - if (mode & W_OK) { - if ((vpb.ioVAtrb & 0x0080) || (vpb.ioVAtrb & 0x8000)) { - errno = EROFS; - return -1; - } - if (fpb.ioFlAttrib & 0x01) { - errno = EACCES; - return -1; - } - } - - /* - * Directories are always searchable and executable. But only - * files of type 'APPL' are executable. - */ - if (!(fpb.ioFlAttrib & 0x10) && (mode & X_OK) - && (fpb.ioFlFndrInfo.fdType != 'APPL')) { - return -1; - } - } - } - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return -1; - } - - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * TclpChdir -- - * - * This function replaces the library version of chdir(). - * - * Results: - * See chdir() documentation. - * - * Side effects: - * See chdir() documentation. Also the cache maintained used by - * TclGetCwd() is deallocated and set to NULL. - * - *---------------------------------------------------------------------- - */ - -int -TclpChdir( - CONST char *dirName) /* Path to new working directory (UTF-8). */ -{ - FSSpec spec; - OSErr err; - Boolean isFolder; - long dirID; - Tcl_DString ds; - char *native; - - native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds); - err = FSpLocationFromPath(Tcl_DStringLength(&ds), native, &spec); - Tcl_DStringFree(&ds); - - if (err != noErr) { - errno = ENOENT; - return -1; - } - - err = FSpGetDirectoryID(&spec, &dirID, &isFolder); - if (err != noErr) { - errno = ENOENT; - return -1; - } - - if (isFolder != true) { - errno = ENOTDIR; - return -1; - } - - err = FSpSetDefaultDir(&spec); - if (err != noErr) { - switch (err) { - case afpAccessDenied: - errno = EACCES; - break; - default: - errno = ENOENT; - } - return -1; - } - - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * TclpGetCwd -- - * - * This function replaces the library version of getcwd(). - * - * Results: - * The result is a pointer to a string specifying the current - * directory, or NULL if the current directory could not be - * determined. If NULL is returned, an error message is left in the - * interp's result. Storage for the result string is allocated in - * bufferPtr; the caller must call Tcl_DStringFree() when the result - * is no longer needed. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -char * -TclpGetCwd( - Tcl_Interp *interp, /* If non-NULL, used for error reporting. */ - Tcl_DString *bufferPtr) /* Uninitialized or free DString filled - * with name of current directory. */ -{ - FSSpec theSpec; - int length; - Handle pathHandle = NULL; - - if (FSpGetDefaultDir(&theSpec) != noErr) { - if (interp != NULL) { - Tcl_SetResult(interp, "error getting working directory name", - TCL_STATIC); - } - return NULL; - } - if (FSpPathFromLocation(&theSpec, &length, &pathHandle) != noErr) { - if (interp != NULL) { - Tcl_SetResult(interp, "error getting working directory name", - TCL_STATIC); - } - return NULL; - } - HLock(pathHandle); - Tcl_ExternalToUtfDString(NULL, *pathHandle, length, bufferPtr); - HUnlock(pathHandle); - DisposeHandle(pathHandle); - - return Tcl_DStringValue(bufferPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TclpReadlink -- - * - * This function replaces the library version of readlink(). - * - * Results: - * The result is a pointer to a string specifying the contents - * of the symbolic link given by 'path', or NULL if the symbolic - * link could not be read. Storage for the result string is - * allocated in bufferPtr; the caller must call Tcl_DStringFree() - * when the result is no longer needed. - * - * Side effects: - * See readlink() documentation. - * - *--------------------------------------------------------------------------- - */ - -char * -TclpReadlink( - CONST char *path, /* Path of file to readlink (UTF-8). */ - Tcl_DString *linkPtr) /* Uninitialized or free DString filled - * with contents of link (UTF-8). */ -{ - HFileInfo fpb; - OSErr err; - FSSpec fileSpec; - Boolean isDirectory; - Boolean wasAlias; - long dirID; - char fileName[257]; - char *end; - Handle theString = NULL; - int pathSize; - Tcl_DString ds; - char *native; - - native = Tcl_UtfToExternalDString(NULL, path, -1, &ds); - - /* - * Remove ending colons if they exist. - */ - - while ((strlen(native) != 0) && (path[strlen(native) - 1] == ':')) { - native[strlen(native) - 1] = NULL; - } - - if (strchr(native, ':') == NULL) { - strcpy(fileName + 1, native); - native = NULL; - } else { - end = strrchr(native, ':') + 1; - strcpy(fileName + 1, end); - *end = NULL; - } - fileName[0] = (char) strlen(fileName + 1); - - /* - * Create the file spec for the directory of the file - * we want to look at. - */ - - if (native != NULL) { - err = FSpLocationFromPath(strlen(native), native, &fileSpec); - if (err != noErr) { - Tcl_DStringFree(&ds); - errno = EINVAL; - return NULL; - } - } else { - FSMakeFSSpecCompat(0, 0, NULL, &fileSpec); - } - Tcl_DStringFree(&ds); - - /* - * Fill the fpb struct up with info about file or directory. - */ - - FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); - fpb.ioVRefNum = fileSpec.vRefNum; - fpb.ioDirID = dirID; - fpb.ioNamePtr = (StringPtr) fileName; - - fpb.ioFDirIndex = 0; - err = PBGetCatInfoSync((CInfoPBPtr)&fpb); - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return NULL; - } else { - if (fpb.ioFlAttrib & 0x10) { - errno = EINVAL; - return NULL; - } else { - if (fpb.ioFlFndrInfo.fdFlags & 0x8000) { - /* - * The file is a link! - */ - } else { - errno = EINVAL; - return NULL; - } - } - } - - /* - * If we are here it's really a link - now find out - * where it points to. - */ - err = FSMakeFSSpecCompat(fileSpec.vRefNum, dirID, (StringPtr) fileName, - &fileSpec); - if (err == noErr) { - err = ResolveAliasFile(&fileSpec, true, &isDirectory, &wasAlias); - } - if ((err == fnfErr) || wasAlias) { - err = FSpPathFromLocation(&fileSpec, &pathSize, &theString); - if (err != noErr) { - DisposeHandle(theString); - errno = ENAMETOOLONG; - return NULL; - } - } else { - errno = EINVAL; - return NULL; - } - - Tcl_ExternalToUtfDString(NULL, *theString, pathSize, linkPtr); - DisposeHandle(theString); - - return Tcl_DStringValue(linkPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TclpLstat -- - * - * This function replaces the library version of lstat(). - * - * Results: - * See stat() documentation. - * - * Side effects: - * See stat() documentation. - * - *---------------------------------------------------------------------- - */ - -int -TclpLstat( - CONST char *path, /* Path of file to stat (in UTF-8). */ - struct stat *bufPtr) /* Filled with results of stat call. */ -{ - /* - * FIXME: Emulate TclpLstat - */ - - return TclpStat(path, bufPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TclpStat -- - * - * This function replaces the library version of stat(). - * - * Results: - * See stat() documentation. - * - * Side effects: - * See stat() documentation. - * - *---------------------------------------------------------------------- - */ - -int -TclpStat( - CONST char *path, /* Path of file to stat (in UTF-8). */ - struct stat *bufPtr) /* Filled with results of stat call. */ -{ - HFileInfo fpb; - HVolumeParam vpb; - OSErr err; - FSSpec fileSpec; - Boolean isDirectory; - long dirID; - Tcl_DString ds; - - path = Tcl_UtfToExternalDString(NULL, path, -1, &ds); - err = FSpLocationFromPath(Tcl_DStringLength(&ds), path, &fileSpec); - Tcl_DStringFree(&ds); - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return -1; - } - - /* - * Fill the fpb & vpb struct up with info about file or directory. - */ - - FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); - vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum; - vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name; - if (isDirectory) { - fpb.ioDirID = fileSpec.parID; - } else { - fpb.ioDirID = dirID; - } - - fpb.ioFDirIndex = 0; - err = PBGetCatInfoSync((CInfoPBPtr)&fpb); - if (err == noErr) { - vpb.ioVolIndex = 0; - err = PBHGetVInfoSync((HParmBlkPtr)&vpb); - if (err == noErr && bufPtr != NULL) { - /* - * Files are always readable by everyone. - */ - - bufPtr->st_mode = S_IRUSR | S_IRGRP | S_IROTH; - - /* - * Use the Volume Info & File Info to fill out stat buf. - */ - if (fpb.ioFlAttrib & 0x10) { - bufPtr->st_mode |= S_IFDIR; - bufPtr->st_nlink = 2; - } else { - bufPtr->st_nlink = 1; - if (fpb.ioFlFndrInfo.fdFlags & 0x8000) { - bufPtr->st_mode |= S_IFLNK; - } else { - bufPtr->st_mode |= S_IFREG; - } - } - if ((fpb.ioFlAttrib & 0x10) || (fpb.ioFlFndrInfo.fdType == 'APPL')) { - /* - * Directories and applications are executable by everyone. - */ - - bufPtr->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; - } - if ((fpb.ioFlAttrib & 0x01) == 0){ - /* - * If not locked, then everyone has write acces. - */ - - bufPtr->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; - } - bufPtr->st_ino = fpb.ioDirID; - bufPtr->st_dev = fpb.ioVRefNum; - bufPtr->st_uid = -1; - bufPtr->st_gid = -1; - bufPtr->st_rdev = 0; - bufPtr->st_size = fpb.ioFlLgLen; - bufPtr->st_blksize = vpb.ioVAlBlkSiz; - bufPtr->st_blocks = (bufPtr->st_size + bufPtr->st_blksize - 1) - / bufPtr->st_blksize; - - /* - * The times returned by the Mac file system are in the - * local time zone. We convert them to GMT so that the - * epoch starts from GMT. This is also consistant with - * what is returned from "clock seconds". - */ - - Tcl_MutexLock(&gmtMutex); - if (initialized == false) { - MachineLocation loc; - - ReadLocation(&loc); - gmt_offset = loc.u.gmtDelta & 0x00ffffff; - if (gmt_offset & 0x00800000) { - gmt_offset = gmt_offset | 0xff000000; - } - initialized = true; - } - Tcl_MutexUnlock(&gmtMutex); - - bufPtr->st_atime = bufPtr->st_mtime = fpb.ioFlMdDat - gmt_offset; - bufPtr->st_ctime = fpb.ioFlCrDat - gmt_offset; - } - } - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - } - - return (err == noErr ? 0 : -1); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_WaitPid -- - * - * Fakes a call to wait pid. - * - * Results: - * Always returns -1. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Pid -Tcl_WaitPid( - Tcl_Pid pid, - int *statPtr, - int options) -{ - return (Tcl_Pid) -1; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacFOpenHack -- - * - * This function replaces fopen. It supports paths with alises. - * Note, remember to undefine the fopen macro! - * - * Results: - * See fopen documentation. - * - * Side effects: - * See fopen documentation. - * - *---------------------------------------------------------------------- - */ - -#undef fopen -FILE * -TclMacFOpenHack( - CONST char *path, - CONST char *mode) -{ - OSErr err; - FSSpec fileSpec; - Handle pathString = NULL; - int size; - FILE * f; - - err = FSpLocationFromPath(strlen(path), (char *) path, &fileSpec); - if ((err != noErr) && (err != fnfErr)) { - return NULL; - } - err = FSpPathFromLocation(&fileSpec, &size, &pathString); - if ((err != noErr) && (err != fnfErr)) { - return NULL; - } - - HLock(pathString); - f = fopen(*pathString, mode); - HUnlock(pathString); - DisposeHandle(pathString); - return f; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpGetUserHome -- - * - * This function takes the specified user name and finds their - * home directory. - * - * Results: - * The result is a pointer to a string specifying the user's home - * directory, or NULL if the user's home directory could not be - * determined. Storage for the result string is allocated in - * bufferPtr; the caller must call Tcl_DStringFree() when the result - * is no longer needed. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -char * -TclpGetUserHome(name, bufferPtr) - CONST char *name; /* User name for desired home directory. */ - Tcl_DString *bufferPtr; /* Uninitialized or free DString filled - * with name of user's home directory. */ -{ - return NULL; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacOSErrorToPosixError -- - * - * Given a Macintosh OSErr return the appropiate POSIX error. - * - * Results: - * A Posix error. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclMacOSErrorToPosixError( - int error) /* A Macintosh error. */ -{ - switch (error) { - case noErr: - return 0; - case bdNamErr: - return ENAMETOOLONG; - case afpObjectTypeErr: - return ENOTDIR; - case fnfErr: - case dirNFErr: - return ENOENT; - case dupFNErr: - return EEXIST; - case dirFulErr: - case dskFulErr: - return ENOSPC; - case fBsyErr: - return EBUSY; - case tmfoErr: - return ENFILE; - case fLckdErr: - case permErr: - case afpAccessDenied: - return EACCES; - case wPrErr: - case vLckdErr: - return EROFS; - case badMovErr: - return EINVAL; - case diffVolErr: - return EXDEV; - default: - return EINVAL; - } -} -int -TclMacChmod( - char *path, - int mode) -{ - HParamBlockRec hpb; - OSErr err; - - c2pstr(path); - hpb.fileParam.ioNamePtr = (unsigned char *) path; - hpb.fileParam.ioVRefNum = 0; - hpb.fileParam.ioDirID = 0; - - if (mode & 0200) { - err = PBHRstFLockSync(&hpb); - } else { - err = PBHSetFLockSync(&hpb); - } - p2cstr((unsigned char *) path); - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - return -1; - } - - return 0; -}
\ No newline at end of file diff --git a/mac/tclMacInit.c b/mac/tclMacInit.c deleted file mode 100644 index 53ab851..0000000 --- a/mac/tclMacInit.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * tclMacInit.c -- - * - * Contains the Mac-specific interpreter initialization functions. - * - * Copyright (c) 1995-1998 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacInit.c,v 1.4 1999/05/11 07:12:16 jingham Exp $ - */ - -#include <AppleEvents.h> -#include <AEDataModel.h> -#include <AEObjects.h> -#include <AEPackObject.h> -#include <AERegistry.h> -#include <Files.h> -#include <Folders.h> -#include <Gestalt.h> -#include <TextUtils.h> -#include <Resources.h> -#include <Strings.h> -#include "tclInt.h" -#include "tclMacInt.h" -#include "tclPort.h" - -/* - * The following string is the startup script executed in new - * interpreters. It looks on the library path and in the resource fork for - * a script "init.tcl" that is compatible with this version of Tcl. The - * init.tcl script does all of the real work of initialization. - */ - -static char initCmd[] = "\ -proc sourcePath {file} {\n\ - set dirs {}\n\ - foreach i $::auto_path {\n\ - set init [file join $i $file.tcl]\n\ - if {[catch {uplevel #0 [list source $init]}] == 0} {\n\ - return\n\ - }\n\ - }\n\ - if {[catch {uplevel #0 [list source -rsrc $file]}] == 0} {\n\ - return\n\ - }\n\ - rename sourcePath {}\n\ - set msg \"can't find $file resource or a usable $file.tcl file\n\"\n\ - append msg \"in the following directories:\n\"\n\ - append msg \" $::auto_path\n\"\n\ - append msg \" perhaps you need to install Tcl or set your \n\"\n\ - append msg \"TCL_LIBRARY environment variable?\"\n\ - error $msg\n\ -}\n\ -if {[info exists env(EXT_FOLDER)]} {\n\ - lappend tcl_pkgPath [file join $env(EXT_FOLDER) {:Tool Command Language}]\n\ -}\n\ -if {[info exists tcl_pkgPath] == 0} {\n\ - set tcl_pkgPath {no extension folder}\n\ -}\n\ -sourcePath Init\n\ -sourcePath Auto\n\ -sourcePath Package\n\ -sourcePath History\n\ -sourcePath Word\n\ -rename sourcePath {}"; - -/* - * The following structures are used to map the script/language codes of a - * font to the name that should be passed to Tcl_GetEncoding() to obtain - * the encoding for that font. The set of numeric constants is fixed and - * defined by Apple. - */ - -typedef struct Map { - int numKey; - char *strKey; -} Map; - -static Map scriptMap[] = { - {smRoman, "macRoman"}, - {smJapanese, "macJapan"}, - {smTradChinese, "macChinese"}, - {smKorean, "macKorean"}, - {smArabic, "macArabic"}, - {smHebrew, "macHebrew"}, - {smGreek, "macGreek"}, - {smCyrillic, "macCyrillic"}, - {smRSymbol, "macRSymbol"}, - {smDevanagari, "macDevanagari"}, - {smGurmukhi, "macGurmukhi"}, - {smGujarati, "macGujarati"}, - {smOriya, "macOriya"}, - {smBengali, "macBengali"}, - {smTamil, "macTamil"}, - {smTelugu, "macTelugu"}, - {smKannada, "macKannada"}, - {smMalayalam, "macMalayalam"}, - {smSinhalese, "macSinhalese"}, - {smBurmese, "macBurmese"}, - {smKhmer, "macKhmer"}, - {smThai, "macThailand"}, - {smLaotian, "macLaos"}, - {smGeorgian, "macGeorgia"}, - {smArmenian, "macArmenia"}, - {smSimpChinese, "macSimpChinese"}, - {smTibetan, "macTIbet"}, - {smMongolian, "macMongolia"}, - {smGeez, "macEthiopia"}, - {smEastEurRoman, "macCentEuro"}, - {smVietnamese, "macVietnam"}, - {smExtArabic, "macSindhi"}, - {NULL, NULL} -}; - -static Map romanMap[] = { - {langCroatian, "macCroatian"}, - {langSlovenian, "macCroatian"}, - {langIcelandic, "macIceland"}, - {langRomanian, "macRomania"}, - {langTurkish, "macTurkish"}, - {langGreek, "macGreek"}, - {NULL, NULL} -}; - -static Map cyrillicMap[] = { - {langUkrainian, "macUkraine"}, - {langBulgarian, "macBulgaria"}, - {NULL, NULL} -}; - -static int GetFinderFont(int *finderID); - - -/* - *---------------------------------------------------------------------- - * - * GetFinderFont -- - * - * Gets the "views" font of the Macintosh Finder - * - * Results: - * Standard Tcl result, and sets finderID to the font family - * id for the current finder font. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -static int -GetFinderFont(int *finderID) -{ - OSErr err = noErr; - OSType finderPrefs, viewFont = 'vfnt'; - DescType returnType; - Size returnSize; - long result, sys8Mask = 0x0800; - static AppleEvent outgoingAevt = {typeNull, NULL}; - AppleEvent returnAevt; - AEAddressDesc fndrAddress; - AEDesc nullContainer = {typeNull, NULL}, - tempDesc = {typeNull, NULL}, - tempDesc2 = {typeNull, NULL}, - finalDesc = {typeNull, NULL}; - const OSType finderSignature = 'MACS'; - - - if (outgoingAevt.descriptorType == typeNull) { - if ((Gestalt(gestaltSystemVersion, &result) != noErr) - || (result >= sys8Mask)) { - finderPrefs = 'pfrp'; - } else { - finderPrefs = 'pvwp'; - } - - AECreateDesc(typeApplSignature, &finderSignature, - sizeof(finderSignature), &fndrAddress); - - err = AECreateAppleEvent(kAECoreSuite, kAEGetData, &fndrAddress, - kAutoGenerateReturnID, kAnyTransactionID, &outgoingAevt); - - AEDisposeDesc(&fndrAddress); - - /* - * The structure is: - * the property view font ('vfnt') - * of the property view preferences ('pvwp') - * of the Null Container (i.e. the Finder itself). - */ - - AECreateDesc(typeType, &finderPrefs, sizeof(finderPrefs), &tempDesc); - err = CreateObjSpecifier(typeType, &nullContainer, formPropertyID, - &tempDesc, true, &tempDesc2); - AECreateDesc(typeType, &viewFont, sizeof(viewFont), &tempDesc); - err = CreateObjSpecifier(typeType, &tempDesc2, formPropertyID, - &tempDesc, true, &finalDesc); - - AEPutKeyDesc(&outgoingAevt, keyDirectObject, &finalDesc); - AEDisposeDesc(&finalDesc); - } - - err = AESend(&outgoingAevt, &returnAevt, kAEWaitReply, kAEHighPriority, - kAEDefaultTimeout, NULL, NULL); - if (err == noErr) { - err = AEGetKeyPtr(&returnAevt, keyDirectObject, typeInteger, - &returnType, (void *) finderID, sizeof(int), &returnSize); - if (err == noErr) { - return TCL_OK; - } - } - return TCL_ERROR; -} - -/* - *--------------------------------------------------------------------------- - * - * TclMacGetFontEncoding -- - * - * Determine the encoding of the specified font. The encoding - * can be used to convert bytes from UTF-8 into the encoding of - * that font. - * - * Results: - * The return value is a string that specifies the font's encoding - * and that can be passed to Tcl_GetEncoding() to construct the - * encoding. If the font's encoding could not be identified, NULL - * is returned. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -char * -TclMacGetFontEncoding( - int fontId) -{ - int script, lang; - char *name; - Map *mapPtr; - - script = FontToScript(fontId); - lang = GetScriptVariable(script, smScriptLang); - name = NULL; - if (script == smRoman) { - for (mapPtr = romanMap; mapPtr->strKey != NULL; mapPtr++) { - if (mapPtr->numKey == lang) { - name = mapPtr->strKey; - break; - } - } - } else if (script == smCyrillic) { - for (mapPtr = cyrillicMap; mapPtr->strKey != NULL; mapPtr++) { - if (mapPtr->numKey == lang) { - name = mapPtr->strKey; - break; - } - } - } - if (name == NULL) { - for (mapPtr = scriptMap; mapPtr->strKey != NULL; mapPtr++) { - if (mapPtr->numKey == script) { - name = mapPtr->strKey; - break; - } - } - } - return name; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpInitPlatform -- - * - * Initialize all the platform-dependant things like signals and - * floating-point error handling. - * - * Called at process initialization time. - * - * Results: - * None. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -void -TclpInitPlatform() -{ - tclPlatform = TCL_PLATFORM_MAC; -} - -/* - *--------------------------------------------------------------------------- - * - * TclpInitLibraryPath -- - * - * Initialize the library path at startup. We have a minor - * metacircular problem that we don't know the encoding of the - * operating system but we may need to talk to operating system - * to find the library directories so that we know how to talk to - * the operating system. - * - * We do not know the encoding of the operating system. - * We do know that the encoding is some multibyte encoding. - * In that multibyte encoding, the characters 0..127 are equivalent - * to ascii. - * - * So although we don't know the encoding, it's safe: - * to look for the last colon character in a path in the encoding. - * to append an ascii string to a path. - * to pass those strings back to the operating system. - * - * But any strings that we remembered before we knew the encoding of - * the operating system must be translated to UTF-8 once we know the - * encoding so that the rest of Tcl can use those strings. - * - * This call sets the library path to strings in the unknown native - * encoding. TclpSetInitialEncodings() will translate the library - * path from the native encoding to UTF-8 as soon as it determines - * what the native encoding actually is. - * - * Called at process initialization time. - * - * Results: - * None. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -void -TclpInitLibraryPath(argv0) - CONST char *argv0; /* Name of executable from argv[0] to main(). - * Not used because we can determine the name - * by querying the module handle. */ -{ - Tcl_Obj *objPtr, *pathPtr; - char *str; - Tcl_DString ds; - - TclMacCreateEnv(); - - pathPtr = Tcl_NewObj(); - - str = TclGetEnv("TCL_LIBRARY", &ds); - if ((str != NULL) && (str[0] != '\0')) { - /* - * If TCL_LIBRARY is set, search there. - */ - - objPtr = Tcl_NewStringObj(str, -1); - Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); - Tcl_DStringFree(&ds); - } - - objPtr = TclGetLibraryPath(); - if (objPtr != NULL) { - Tcl_ListObjAppendList(NULL, pathPtr, objPtr); - } - - /* - * lappend path [file join $env(EXT_FOLDER) \ - * ":Tool Command Language:tcl[info version]" - */ - - str = TclGetEnv("EXT_FOLDER", &ds); - if ((str != NULL) && (str[0] != '\0')) { - objPtr = Tcl_NewStringObj(str, -1); - if (str[strlen(str) - 1] != ':') { - Tcl_AppendToObj(objPtr, ":", 1); - } - Tcl_AppendToObj(objPtr, "Tool Command Language:tcl" TCL_VERSION, -1); - Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); - Tcl_DStringFree(&ds); - } - TclSetLibraryPath(pathPtr); -} - -/* - *--------------------------------------------------------------------------- - * - * TclpSetInitialEncodings -- - * - * Based on the locale, determine the encoding of the operating - * system and the default encoding for newly opened files. - * - * Called at process initialization time. - * - * Results: - * None. - * - * Side effects: - * The Tcl library path is converted from native encoding to UTF-8. - * - *--------------------------------------------------------------------------- - */ - -void -TclpSetInitialEncodings() -{ - CONST char *encoding; - Tcl_Obj *pathPtr; - int fontId; - - fontId = 0; - GetFinderFont(&fontId); - encoding = TclMacGetFontEncoding(fontId); - if (encoding == NULL) { - encoding = "macRoman"; - } - - Tcl_SetSystemEncoding(NULL, encoding); - - /* - * Until the system encoding was actually set, the library path was - * actually in the native multi-byte encoding, and not really UTF-8 - * as advertised. We cheated as follows: - * - * 1. It was safe to allow the Tcl_SetSystemEncoding() call to - * append the ASCII chars that make up the encoding's filename to - * the names (in the native encoding) of directories in the library - * path, since all Unix multi-byte encodings have ASCII in the - * beginning. - * - * 2. To open the encoding file, the native bytes in the file name - * were passed to the OS, without translating from UTF-8 to native, - * because the name was already in the native encoding. - * - * Now that the system encoding was actually successfully set, - * translate all the names in the library path to UTF-8. That way, - * next time we search the library path, we'll translate the names - * from UTF-8 to the system encoding which will be the native - * encoding. - */ - - pathPtr = TclGetLibraryPath(); - if (pathPtr != NULL) { - int i, objc; - Tcl_Obj **objv; - - objc = 0; - Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv); - for (i = 0; i < objc; i++) { - int length; - char *string; - Tcl_DString ds; - - string = Tcl_GetStringFromObj(objv[i], &length); - Tcl_ExternalToUtfDString(NULL, string, length, &ds); - Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); - } - } - - /* - * Keep the iso8859-1 encoding preloaded. The IO package uses it for - * gets on a binary channel. - */ - - Tcl_GetEncoding(NULL, "iso8859-1"); -} - -/* - *--------------------------------------------------------------------------- - * - * TclpSetVariables -- - * - * Performs platform-specific interpreter initialization related to - * the tcl_library and tcl_platform variables, and other platform- - * specific things. - * - * Results: - * None. - * - * Side effects: - * Sets "tcl_library" and "tcl_platform" Tcl variables. - * - *---------------------------------------------------------------------- - */ - -void -TclpSetVariables(interp) - Tcl_Interp *interp; -{ - long int gestaltResult; - int minor, major, objc; - Tcl_Obj **objv; - char versStr[2 * TCL_INTEGER_SPACE]; - char *str; - Tcl_Obj *pathPtr; - Tcl_DString ds; - - str = "no library"; - pathPtr = TclGetLibraryPath(); - if (pathPtr != NULL) { - objc = 0; - Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv); - if (objc > 0) { - str = Tcl_GetStringFromObj(objv[0], NULL); - } - } - Tcl_SetVar(interp, "tcl_library", str, TCL_GLOBAL_ONLY); - - if (pathPtr != NULL) { - Tcl_SetVar2Ex(interp, "tcl_pkgPath", NULL, pathPtr, TCL_GLOBAL_ONLY); - } - - Tcl_SetVar2(interp, "tcl_platform", "platform", "macintosh", - TCL_GLOBAL_ONLY); - Tcl_SetVar2(interp, "tcl_platform", "os", "MacOS", TCL_GLOBAL_ONLY); - Gestalt(gestaltSystemVersion, &gestaltResult); - major = (gestaltResult & 0x0000FF00) >> 8; - minor = (gestaltResult & 0x000000F0) >> 4; - sprintf(versStr, "%d.%d", major, minor); - Tcl_SetVar2(interp, "tcl_platform", "osVersion", versStr, TCL_GLOBAL_ONLY); -#if GENERATINGPOWERPC - Tcl_SetVar2(interp, "tcl_platform", "machine", "ppc", TCL_GLOBAL_ONLY); -#else - Tcl_SetVar2(interp, "tcl_platform", "machine", "68k", TCL_GLOBAL_ONLY); -#endif - - /* - * Copy USER or LOGIN environment variable into tcl_platform(user) - * These are set by SystemVariables in tclMacEnv.c - */ - - Tcl_DStringInit(&ds); - str = TclGetEnv("USER", &ds); - if (str == NULL) { - str = TclGetEnv("LOGIN", &ds); - if (str == NULL) { - str = ""; - } - } - Tcl_SetVar2(interp, "tcl_platform", "user", str, TCL_GLOBAL_ONLY); - Tcl_DStringFree(&ds); -} - -/* - *---------------------------------------------------------------------- - * - * TclpCheckStackSpace -- - * - * On a 68K Mac, we can detect if we are about to blow the stack. - * Called before an evaluation can happen when nesting depth is - * checked. - * - * Results: - * 1 if there is enough stack space to continue; 0 if not. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclpCheckStackSpace() -{ - return StackSpace() > TCL_MAC_STACK_THRESHOLD; -} - -/* - *---------------------------------------------------------------------- - * - * TclpFindVariable -- - * - * Locate the entry in environ for a given name. On Unix and Macthis - * routine is case sensitive, on Windows this matches mixed case. - * - * Results: - * The return value is the index in environ of an entry with the - * name "name", or -1 if there is no such entry. The integer at - * *lengthPtr is filled in with the length of name (if a matching - * entry is found) or the length of the environ array (if no matching - * entry is found). - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclpFindVariable(name, lengthPtr) - CONST char *name; /* Name of desired environment variable - * (native). */ - int *lengthPtr; /* Used to return length of name (for - * successful searches) or number of non-NULL - * entries in environ (for unsuccessful - * searches). */ -{ - int i, result = -1; - register CONST char *env, *p1, *p2; - Tcl_DString envString; - - Tcl_DStringInit(&envString); - for (i = 0, env = environ[i]; env != NULL; i++, env = environ[i]) { - p1 = Tcl_ExternalToUtfDString(NULL, env, -1, &envString); - p2 = name; - - for (; *p2 == *p1; p1++, p2++) { - /* NULL loop body. */ - } - if ((*p1 == '=') && (*p2 == '\0')) { - *lengthPtr = p2 - name; - result = i; - goto done; - } - - Tcl_DStringFree(&envString); - } - - *lengthPtr = i; - - done: - Tcl_DStringFree(&envString); - return result; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_Init -- - * - * This procedure is typically invoked by Tcl_AppInit procedures - * to perform additional initialization for a Tcl interpreter, - * such as sourcing the "init.tcl" script. - * - * Results: - * Returns a standard Tcl completion code and sets the interp's result - * if there is an error. - * - * Side effects: - * Depends on what's in the init.tcl script. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_Init( - Tcl_Interp *interp) /* Interpreter to initialize. */ -{ - Tcl_Obj *pathPtr; - - /* - * For Macintosh applications the Init function may be contained in - * the application resources. If it exists we use it - otherwise we - * look in the tcl_library directory. Ditto for the history command. - */ - - pathPtr = TclGetLibraryPath(); - if (pathPtr == NULL) { - pathPtr = Tcl_NewObj(); - } - Tcl_SetVar2Ex(interp, "auto_path", NULL, pathPtr, TCL_GLOBAL_ONLY); - return Tcl_Eval(interp, initCmd); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_SourceRCFile -- - * - * This procedure is typically invoked by Tcl_Main or Tk_Main - * procedure to source an application specific rc file into the - * interpreter at startup time. This will either source a file - * in the "tcl_rcFileName" variable or a TEXT resource in the - * "tcl_rcRsrcName" variable. - * - * Results: - * None. - * - * Side effects: - * Depends on what's in the rc script. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_SourceRCFile( - Tcl_Interp *interp) /* Interpreter to source rc file into. */ -{ - Tcl_DString temp; - char *fileName; - Tcl_Channel errChannel; - Handle h; - - fileName = Tcl_GetVar(interp, "tcl_rcFileName", TCL_GLOBAL_ONLY); - - if (fileName != NULL) { - Tcl_Channel c; - char *fullName; - - Tcl_DStringInit(&temp); - fullName = Tcl_TranslateFileName(interp, fileName, &temp); - if (fullName == NULL) { - /* - * Couldn't translate the file name (e.g. it referred to a - * bogus user or there was no HOME environment variable). - * Just do nothing. - */ - } else { - - /* - * Test for the existence of the rc file before trying to read it. - */ - - c = Tcl_OpenFileChannel(NULL, fullName, "r", 0); - if (c != (Tcl_Channel) NULL) { - Tcl_Close(NULL, c); - if (Tcl_EvalFile(interp, fullName) != TCL_OK) { - errChannel = Tcl_GetStdChannel(TCL_STDERR); - if (errChannel) { - Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); - Tcl_WriteChars(errChannel, "\n", 1); - } - } - } - } - Tcl_DStringFree(&temp); - } - - fileName = Tcl_GetVar(interp, "tcl_rcRsrcName", TCL_GLOBAL_ONLY); - - if (fileName != NULL) { - c2pstr(fileName); - h = GetNamedResource('TEXT', (StringPtr) fileName); - p2cstr((StringPtr) fileName); - if (h != NULL) { - if (Tcl_MacEvalResource(interp, fileName, 0, NULL) != TCL_OK) { - errChannel = Tcl_GetStdChannel(TCL_STDERR); - if (errChannel) { - Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); - Tcl_WriteChars(errChannel, "\n", 1); - } - } - Tcl_ResetResult(interp); - ReleaseResource(h); - } - } -} diff --git a/mac/tclMacInt.h b/mac/tclMacInt.h deleted file mode 100644 index 77d274c..0000000 --- a/mac/tclMacInt.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * tclMacInt.h -- - * - * Declarations of Macintosh specific shared variables and procedures. - * - * Copyright (c) 1996-1998 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacInt.h,v 1.6 1999/08/16 00:09:18 jingham Exp $ - */ - -#ifndef _TCLMACINT -#define _TCLMACINT - -#ifndef _TCL -# include "tcl.h" -#endif -#ifndef _TCLMAC -# include "tclMac.h" -#endif - -#include <Events.h> -#include <Files.h> - -#pragma export on - -/* - * Defines to control stack behavior. - * - * The Tcl8.2 regexp code is highly recursive for patterns with many - * subexpressions. So we have to increase the stack space to accomodate. - * 512 K is good enough for ordinary work, but you need 768 to pass the Tcl - * regexp testsuite. - * - * For the PPC, you need to set the stack space in the Project file. - * - */ - -#ifdef TCL_TEST -# define TCL_MAC_68K_STACK_GROWTH (768*1024) -#else -# define TCL_MAC_68K_STACK_GROWTH (512*1024) -#endif - -#define TCL_MAC_STACK_THRESHOLD 16384 - -/* - * This flag is passed to TclMacRegisterResourceFork - * by a file (usually a library) whose resource fork - * should not be closed by the resource command. - */ - -#define TCL_RESOURCE_DONT_CLOSE 2 - -/* - * Typedefs used by Macintosh parts of Tcl. - */ - -/* - * Prototypes of Mac only internal functions. - */ - -EXTERN char * TclMacGetFontEncoding _ANSI_ARGS_((int fontId)); -EXTERN int TclMacHaveThreads(void); - -#include "tclPort.h" -#include "tclPlatDecls.h" -#include "tclIntPlatDecls.h" - -#pragma export reset - -#endif /* _TCLMACINT */ diff --git a/mac/tclMacInterupt.c b/mac/tclMacInterupt.c deleted file mode 100644 index 7f37d2f..0000000 --- a/mac/tclMacInterupt.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * tclMacInterupt.c -- - * - * This file contains routines that deal with the Macintosh's low level - * time manager. This code provides a better resolution timer than what - * can be provided by WaitNextEvent. - * - * Copyright (c) 1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacInterupt.c,v 1.2 1998/09/14 18:40:05 stanton Exp $ - */ - -#include "tclInt.h" -#include "tclMacInt.h" -#include <LowMem.h> -#include <Processes.h> -#include <Timer.h> - -/* - * Data structure for timer tasks. - */ -typedef struct TMInfo { - TMTask tmTask; - ProcessSerialNumber psn; - Point lastPoint; - Point newPoint; - long currentA5; - long ourA5; - int installed; -} TMInfo; - -/* - * Globals used within this file. - */ - -static TimerUPP sleepTimerProc = NULL; -static int interuptsInited = false; -static ProcessSerialNumber applicationPSN; -#define MAX_TIMER_ARRAY_SIZE 16 -static TMInfo timerInfoArray[MAX_TIMER_ARRAY_SIZE]; -static int topTimerElement = 0; - -/* - * Prototypes for procedures that are referenced only in this file: - */ - -#if !GENERATINGCFM -static TMInfo * GetTMInfo(void) ONEWORDINLINE(0x2E89); /* MOVE.L A1,(SP) */ -#endif -static void SleepTimerProc _ANSI_ARGS_((void)); -static pascal void CleanUpExitProc _ANSI_ARGS_((void)); -static void InitInteruptSystem _ANSI_ARGS_((void)); - -/* - *---------------------------------------------------------------------- - * - * InitInteruptSystem -- - * - * Does various initialization for the functions used in this - * file. Sets up Universial Pricedure Pointers, installs a trap - * patch for ExitToShell, etc. - * - * Results: - * None. - * - * Side effects: - * Various initialization. - * - *---------------------------------------------------------------------- - */ - -void -InitInteruptSystem() -{ - int i; - - sleepTimerProc = NewTimerProc(SleepTimerProc); - GetCurrentProcess(&applicationPSN); - for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) { - timerInfoArray[i].installed = false; - } - - /* - * Install the ExitToShell patch. We use this patch instead - * of the Tcl exit mechanism because we need to ensure that - * these routines are cleaned up even if we crash or are forced - * to quit. There are some circumstances when the Tcl exit - * handlers may not fire. - */ - - TclMacInstallExitToShellPatch(CleanUpExitProc); - interuptsInited = true; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacStartTimer -- - * - * Install a Time Manager task to wake our process up in the - * future. The process should get a NULL event after ms - * milliseconds. - * - * Results: - * None. - * - * Side effects: - * Schedules our process to wake up. - * - *---------------------------------------------------------------------- - */ - -void * -TclMacStartTimer( - long ms) /* Milliseconds. */ -{ - TMInfo *timerInfoPtr; - - if (!interuptsInited) { - InitInteruptSystem(); - } - - /* - * Obtain a pointer for the timer. We only allocate up - * to MAX_TIMER_ARRAY_SIZE timers. If we are past that - * max we return NULL. - */ - if (topTimerElement < MAX_TIMER_ARRAY_SIZE) { - timerInfoPtr = &timerInfoArray[topTimerElement]; - topTimerElement++; - } else { - return NULL; - } - - /* - * Install timer to wake process in ms milliseconds. - */ - timerInfoPtr->tmTask.tmAddr = sleepTimerProc; - timerInfoPtr->tmTask.tmWakeUp = 0; - timerInfoPtr->tmTask.tmReserved = 0; - timerInfoPtr->psn = applicationPSN; - timerInfoPtr->installed = true; - - InsTime((QElemPtr) timerInfoPtr); - PrimeTime((QElemPtr) timerInfoPtr, (long) ms); - - return (void *) timerInfoPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacRemoveTimer -- - * - * Remove the timer event from the Time Manager. - * - * Results: - * None. - * - * Side effects: - * A scheduled timer would be removed. - * - *---------------------------------------------------------------------- - */ - -void -TclMacRemoveTimer( - void * timerToken) /* Token got from start timer. */ -{ - TMInfo *timerInfoPtr = (TMInfo *) timerToken; - - if (timerInfoPtr == NULL) { - return; - } - - RmvTime((QElemPtr) timerInfoPtr); - timerInfoPtr->installed = false; - topTimerElement--; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacTimerExpired -- - * - * Check to see if the installed timer has expired. - * - * Results: - * True if timer has expired, false otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclMacTimerExpired( - void * timerToken) /* Our token again. */ -{ - TMInfo *timerInfoPtr = (TMInfo *) timerToken; - - if ((timerInfoPtr == NULL) || - !(timerInfoPtr->tmTask.qType & kTMTaskActive)) { - return true; - } else { - return false; - } -} - -/* - *---------------------------------------------------------------------- - * - * SleepTimerProc -- - * - * Time proc is called by the is a callback routine placed in the - * system by Tcl_Sleep. The routine is called at interupt time - * and threrfor can not move or allocate memory. This call will - * schedule our process to wake up the next time the process gets - * around to consider running it. - * - * Results: - * None. - * - * Side effects: - * Schedules our process to wake up. - * - *---------------------------------------------------------------------- - */ - -static void -SleepTimerProc() -{ - /* - * In CFM code we can access our code directly. In 68k code that - * isn't based on CFM we must do a glorious hack. The function - * GetTMInfo is an inline assembler call that moves the pointer - * at A1 to the top of the stack. The Time Manager keeps the TMTask - * info record there before calling this call back. In order for - * this to work the infoPtr argument must be the *last* item on the - * stack. If we "piggyback" our data to the TMTask info record we - * can get access to the information we need. While this is really - * ugly - it's the way Apple recomends it be done - go figure... - */ - -#if GENERATINGCFM - WakeUpProcess(&applicationPSN); -#else - TMInfo * infoPtr; - - infoPtr = GetTMInfo(); - WakeUpProcess(&infoPtr->psn); -#endif -} - -/* - *---------------------------------------------------------------------- - * - * CleanUpExitProc -- - * - * This procedure is invoked as an exit handler when ExitToShell - * is called. It removes the system level timer handler if it - * is installed. This must be called or the Mac OS will more than - * likely crash. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static pascal void -CleanUpExitProc() -{ - int i; - - for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) { - if (timerInfoArray[i].installed) { - RmvTime((QElemPtr) &timerInfoArray[i]); - timerInfoArray[i].installed = false; - } - } -} diff --git a/mac/tclMacLibrary.c b/mac/tclMacLibrary.c deleted file mode 100644 index 99fdf72..0000000 --- a/mac/tclMacLibrary.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * tclMacLibrary.c -- - * - * This file should be included in Tcl extensions that want to - * automatically open their resource forks when the code is linked. - * These routines should not be exported but should be compiled - * locally by each fragment. Many thanks to Jay Lieske - * <lieske@princeton.edu> who provide an initial version of this - * file. - * - * Copyright (c) 1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacLibrary.c,v 1.3 1999/08/15 04:03:52 jingham Exp $ - */ - -/* - * Here is another place that we are using the old routine names... - */ - -#define OLDROUTINENAMES 1 - -#include <CodeFragments.h> -#include <Errors.h> -#include <Resources.h> -#include <Strings.h> -#include "tclMacInt.h" - -/* - * These function are not currently defined in any header file. The - * only place they should be used is in the Initialization and - * Termination entry points for a code fragment. The prototypes - * are included here to avoid compile errors. - */ - -OSErr TclMacInitializeFragment _ANSI_ARGS_(( - struct CFragInitBlock* initBlkPtr)); -void TclMacTerminateFragment _ANSI_ARGS_((void)); - -/* - * Static functions in this file. - */ - -static OSErr OpenLibraryResource _ANSI_ARGS_(( - struct CFragInitBlock* initBlkPtr)); -static void CloseLibraryResource _ANSI_ARGS_((void)); - -/* - * The refnum of the opened resource fork. - */ -static short ourResFile = kResFileNotOpened; - -/* - * This is the resource token for the our resource file. - * It stores the name we registered with the resource facility. - * We only need to use this if we are actually registering ourselves. - */ - -#ifdef TCL_REGISTER_LIBRARY -static Tcl_Obj *ourResToken; -#endif - -/* - *---------------------------------------------------------------------- - * - * TclMacInitializeFragment -- - * - * Called by MacOS CFM when the shared library is loaded. All this - * function really does is give Tcl a chance to open and register - * the resource fork of the library. - * - * Results: - * MacOS error code if loading should be canceled. - * - * Side effects: - * Opens the resource fork of the shared library file. - * - *---------------------------------------------------------------------- - */ - -OSErr -TclMacInitializeFragment( - struct CFragInitBlock* initBlkPtr) /* Pointer to our library. */ -{ - OSErr err = noErr; - -#ifdef __MWERKS__ - { - extern OSErr __initialize( CFragInitBlock* initBlkPtr); - err = __initialize((CFragInitBlock *) initBlkPtr); - } -#endif - if (err == noErr) - err = OpenLibraryResource( initBlkPtr); - return err; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacTerminateFragment -- - * - * Called by MacOS CFM when the shared library is unloaded. - * - * Results: - * None. - * - * Side effects: - * The resource fork of the code fragment is closed. - * - *---------------------------------------------------------------------- - */ - -void -TclMacTerminateFragment() -{ - CloseLibraryResource(); - -#ifdef __MWERKS__ - { - extern void __terminate(void); - __terminate(); - } -#endif -} - -/* - *---------------------------------------------------------------------- - * - * OpenLibraryResource -- - * - * This routine can be called by a MacOS fragment's initialiation - * function to open the resource fork of the file. - * Call it with the same data passed to the initialization function. - * If the fragment loading should fail if the resource fork can't - * be opened, then the initialization function can pass on this - * return value. - * - * If you #define TCL_REGISTER_RESOURCE before compiling this resource, - * then your library will register its open resource fork with the - * resource command. - * - * Results: - * It returns noErr on success and a MacOS error code on failure. - * - * Side effects: - * The resource fork of the code fragment is opened read-only and - * is installed at the head of the resource chain. - * - *---------------------------------------------------------------------- - */ - -static OSErr -OpenLibraryResource( - struct CFragInitBlock* initBlkPtr) -{ - /* - * The 3.0 version of the Universal headers changed CFragInitBlock - * to an opaque pointer type. CFragSystem7InitBlock is now the - * real pointer. - */ - -#if !defined(UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0300) - struct CFragInitBlock *realInitBlkPtr = initBlkPtr; -#else - CFragSystem7InitBlock *realInitBlkPtr = (CFragSystem7InitBlock *) initBlkPtr; -#endif - FSSpec* fileSpec = NULL; - OSErr err = noErr; - - - if (realInitBlkPtr->fragLocator.where == kOnDiskFlat) { - fileSpec = realInitBlkPtr->fragLocator.u.onDisk.fileSpec; - } else if (realInitBlkPtr->fragLocator.where == kOnDiskSegmented) { - fileSpec = realInitBlkPtr->fragLocator.u.inSegs.fileSpec; - } else { - err = resFNotFound; - } - - /* - * Open the resource fork for this library in read-only mode. - * This will make it the current res file, ahead of the - * application's own resources. - */ - - if (fileSpec != NULL) { - ourResFile = FSpOpenResFile(fileSpec, fsRdPerm); - if (ourResFile == kResFileNotOpened) { - err = ResError(); - } else { -#ifdef TCL_REGISTER_LIBRARY - ourResToken = Tcl_NewObj(); - Tcl_IncrRefCount(ourResToken); - p2cstr(realInitBlkPtr->libName); - Tcl_SetStringObj(ourResToken, (char *) realInitBlkPtr->libName, -1); - c2pstr((char *) realInitBlkPtr->libName); - TclMacRegisterResourceFork(ourResFile, ourResToken, - TCL_RESOURCE_DONT_CLOSE); -#endif - SetResFileAttrs(ourResFile, mapReadOnly); - } - } - - return err; -} - -/* - *---------------------------------------------------------------------- - * - * CloseLibraryResource -- - * - * This routine should be called by a MacOS fragment's termination - * function to close the resource fork of the file - * that was opened with OpenLibraryResource. - * - * Results: - * None. - * - * Side effects: - * The resource fork of the code fragment is closed. - * - *---------------------------------------------------------------------- - */ - -static void -CloseLibraryResource() -{ - if (ourResFile != kResFileNotOpened) { -#ifdef TCL_REGISTER_LIBRARY - int length; - TclMacUnRegisterResourceFork( - Tcl_GetStringFromObj(ourResToken, &length), - NULL); - Tcl_DecrRefCount(ourResToken); -#endif - CloseResFile(ourResFile); - ourResFile = kResFileNotOpened; - } -} diff --git a/mac/tclMacLibrary.r b/mac/tclMacLibrary.r deleted file mode 100644 index c526f17..0000000 --- a/mac/tclMacLibrary.r +++ /dev/null @@ -1,221 +0,0 @@ -/* - * tclMacLibrary.r -- - * - * This file creates resources used by the Tcl shared library. - * Many thanks go to "Jay Lieske, Jr." <lieske@princeton.edu> who - * wrote the initial version of this file. - * - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacLibrary.r,v 1.4 1999/08/16 00:09:22 jingham Exp $ - */ - -#include <Types.r> -#include <SysTypes.r> - -/* - * The folowing include and defines help construct - * the version string for Tcl. - */ - -#define RESOURCE_INCLUDED -#include "tcl.h" - -#if (TCL_RELEASE_LEVEL == 0) -# define RELEASE_LEVEL alpha -#elif (TCL_RELEASE_LEVEL == 1) -# define RELEASE_LEVEL beta -#elif (TCL_RELEASE_LEVEL == 2) -# define RELEASE_LEVEL final -#endif - -#if (TCL_RELEASE_LEVEL == 2) -# define MINOR_VERSION (TCL_MINOR_VERSION * 16) + TCL_RELEASE_SERIAL -#else -# define MINOR_VERSION TCL_MINOR_VERSION * 16 -#endif - -resource 'vers' (1) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - TCL_PATCH_LEVEL ", by Ray Johnson & Jim Ingham © Scriptics Inc." -}; - -resource 'vers' (2) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - "Tcl Library " TCL_PATCH_LEVEL " © 1996-1997 Sun Microsystems, 1998-1999 Scriptics Inc." -}; - -/* - * Currently the creator for all Tcl/Tk libraries and extensions - * should be 'TclL'. This will allow those extension and libraries - * to use the common icon for Tcl extensions. However, this signature - * still needs to be approved by the signature police at Apple and may - * change. - */ -#define TCL_CREATOR 'TclL' -#define TCL_LIBRARY_RESOURCES 2000 - -/* - * The 'BNDL' resource is the primary link between a file's - * creator/type and its icon. This resource acts for all Tcl shared - * libraries; other libraries will not need one and ought to use - * custom icons rather than new file types for a different appearance. - */ - -resource 'BNDL' (TCL_LIBRARY_RESOURCES, "Tcl bundle", purgeable) -{ - TCL_CREATOR, - 0, - { /* array TypeArray: 2 elements */ - /* [1] */ - 'FREF', - { /* array IDArray: 1 elements */ - /* [1] */ - 0, TCL_LIBRARY_RESOURCES - }, - /* [2] */ - 'ICN#', - { /* array IDArray: 1 elements */ - /* [1] */ - 0, TCL_LIBRARY_RESOURCES - } - } -}; - -resource 'FREF' (TCL_LIBRARY_RESOURCES, purgeable) -{ - 'shlb', 0, "" -}; - -type TCL_CREATOR as 'STR '; -resource TCL_CREATOR (0, purgeable) { - "Tcl Library " TCL_PATCH_LEVEL " © 1996-1999" -}; - -/* - * The 'kind' resource works with a 'BNDL' in Macintosh Easy Open - * to affect the text the Finder displays in the "kind" column and - * file info dialog. This information will be applied to all files - * with the listed creator and type. - */ - -resource 'kind' (TCL_LIBRARY_RESOURCES, "Tcl kind", purgeable) { - TCL_CREATOR, - 0, /* region = USA */ - { - 'shlb', "Tcl Library" - } -}; - - -/* - * The -16397 string will be displayed by Finder when a user - * tries to open the shared library. The string should - * give the user a little detail about the library's capabilities - * and enough information to install the library in the correct location. - * A similar string should be placed in all shared libraries. - */ -resource 'STR ' (-16397, purgeable) { - "Tcl Library\n\n" - "This is the core library needed to run Tool Command Language programs. " - "To work properly, it should be placed in the ÔTool Command LanguageÕ folder " - "within the Extensions folder." -}; - -/* - * The mechanisim below loads Tcl source into the resource fork of the - * application. The example below creates a TEXT resource named - * "Init" from the file "init.tcl". This allows applications to use - * Tcl to define the behavior of the application without having to - * require some predetermined file structure - all needed Tcl "files" - * are located within the application. To source a file for the - * resource fork the source command has been modified to support - * sourcing from resources. In the below case "source -rsrc {Init}" - * will load the TEXT resource named "Init". - */ - -#include "tclMacTclCode.r" - -/* - * The following are icons for the shared library. - */ - -data 'icl4' (2000, "Tcl Shared Library", purgeable) { - $"0FFF FFFF FFFF FFFF FFFF FFFF FFFF 0000" - $"F000 0000 0000 0000 0000 0000 000C F000" - $"F0CC CFFF CCCC CCC6 66CC CCCC CCCC F000" - $"F0CC CFFF FFFF FF66 F6CC CCCC CCCC F000" - $"F0CC CFFF 2000 0D66 6CCC CCCC CCCC F000" - $"F0CC CFFF 0202 056F 6E5C CCCC CCCC F000" - $"F0CC CFFF 2020 C666 F66F CCCC CCCC F000" - $"F0CC CFFF 0200 B66F 666B FCCC CCCC F000" - $"F0FC CFFF B020 55F6 6F52 BFCC CCCC F000" - $"FF0F 0CCC FB02 5665 66D0 2FCC CCCC F0F0" - $"F00F 0CCC CFB0 BF55 F6CF FFCC CCCC FFCF" - $"000F 0CCC CCFB 06C9 66CC CCCC CCCC F0CF" - $"000F 0CCC CCCF 56C6 6CCC CCCC CCCC CCCF" - $"000F 0CCC CCCC 6FC6 FCCC CCCC CCCC CCCF" - $"000F 0CCC CCCC 65C5 65CC CCCC CCCC CCCF" - $"000F 0CCC CCCC 55D6 57CC CCCC CCCC CCCF" - $"000F 0CCC CCCC 65CF 6CCC CCCC CCCC CCCF" - $"000F 0CCC CCCC 5AC6 6CFF CCCC CCCC CCCF" - $"000F 0CCC CCCC 65C5 6CF0 FCCC CCCC CCCF" - $"000F 0CCC CCCC CECF CCF0 0FCC CCCC CCCF" - $"000F 0CCC CCCC C5C6 CCCF 20FC CCCC FCCF" - $"F00F 0CCC CCCF FFD5 CCCC F20F CCCC FFCF" - $"FF0F 0CCC CCCF 20CF CCCC F020 FCCC F0F0" - $"F0F0 CCCC CCCF B2C2 FFFF 0002 0FFC F000" - $"F00C CCCC CCCC FBC0 2000 0020 2FFC F000" - $"F0CC CCCC CCCC CFCB 0202 0202 0FFC F000" - $"F0CC CCCC CCCC CCCF B020 2020 2FFC F000" - $"F0CC CCCC CCCC CCDC FBBB BBBB BFFC F000" - $"F0CC CCCC CCCC CCCC CFFF FFFF FFFC F000" - $"F0CC CCCC CCCC CCCC CCCC CCCC CFFC F000" - $"FCCC CCCC CCCC CCCC CCCC CCCC CCCC F000" - $"0FFF FFFF FFFF FFFF FFFF FFFF FFFF 0000" -}; - -data 'ICN#' (2000, "Tcl Shared Library", purgeable) { - $"7FFF FFF0 8000 0008 8701 C008 87FF C008" - $"8703 8008 8707 E008 8707 F008 870F F808" - $"A78F EC08 D0CF C40A 906F DC0D 1035 C009" - $"101D 8001 100D 8001 100D C001 100D C001" - $"100D 8001 100D B001 100D A801 1005 2401" - $"1005 1209 901D 090D D011 088A A018 F068" - $"800C 0068 8005 0068 8001 8068 8000 FFE8" - $"8000 7FE8 8000 0068 8000 0008 7FFF FFF0" - $"7FFF FFF0 FFFF FFF8 FFFF FFF8 FFFF FFF8" - $"FFFF FFF8 FFFF FFF8 FFFF FFF8 FFFF FFF8" - $"FFFF FFF8 DFFF FFFA 9FFF FFFF 1FFF FFFF" - $"1FFF FFFF 1FFF FFFF 1FFF FFFF 1FFF FFFF" - $"1FFF FFFF 1FFF FFFF 1FFF FFFF 1FFF FFFF" - $"1FFF FFFF 9FFF FFFF DFFF FFFA FFFF FFF8" - $"FFFF FFF8 FFFF FFF8 FFFF FFF8 FFFF FFF8" - $"FFFF FFF8 FFFF FFF8 FFFF FFF8 7FFF FFF0" -}; - -data 'ics#' (2000, "Tcl Shared Library", purgeable) { - $"FFFE B582 BB82 B3C2 BFA2 43C3 4381 4381" - $"4381 4763 4392 856E 838E 81AE 811E FFFE" - $"FFFE FFFE FFFE FFFE FFFE FFFF 7FFF 7FFF" - $"7FFF 7FFF 7FFF FFFE FFFE FFFE FFFE FFFE" -}; - -data 'ics4' (2000, "Tcl Shared Library", purgeable) { - $"FFFF FFFF FFFF FFF0 FCFF DED5 6CCC CCF0" - $"FCFF C0D6 ECCC CCF0 FCFF 2056 65DC CCF0" - $"FDFE D256 6DAC CCFF FFCC DDDE 5DDC CCEF" - $"0FCC CD67 5CCC CCCF 0FCC CC5D 6CCC CCCF" - $"0FCC CC5D 5CCC CCCF 0FCC CCD5 5CCC CCCF" - $"FFCC CFFD CCFF CCFF FCCC CF2D DF20 FCFC" - $"FCCC CCFD D202 FEF0 FCCC CC0D 2020 FEF0" - $"FCCC CCCD FBBB FEF0 FFFF FFFF FFFF FFE0" -}; - diff --git a/mac/tclMacLoad.c b/mac/tclMacLoad.c deleted file mode 100644 index daf87ca..0000000 --- a/mac/tclMacLoad.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * tclMacLoad.c -- - * - * This procedure provides a version of the TclLoadFile for use - * on the Macintosh. This procedure will only work with systems - * that use the Code Fragment Manager. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacLoad.c,v 1.4 1999/10/15 04:47:12 jingham Exp $ - */ - -#include <CodeFragments.h> -#include <Errors.h> -#include <Resources.h> -#include <Strings.h> -#include <FSpCompat.h> - -/* - * Seems that the 3.0.1 Universal headers leave this define out. So we - * define it here... - */ - -#ifndef fragNoErr - #define fragNoErr noErr -#endif - -#include "tclPort.h" -#include "tclInt.h" -#include "tclMacInt.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; - -/* - *---------------------------------------------------------------------- - * - * TclLoadFile -- - * - * This procedure is called to carry out dynamic loading of binary - * code for the Macintosh. This implementation is based on the - * Code Fragment Manager & will not work on other systems. - * - * Results: - * The result is TCL_ERROR, and an error message is left in - * the interp's result. - * - * Side effects: - * New binary code is loaded. - * - *---------------------------------------------------------------------- - */ - -int -TclpLoadFile( - Tcl_Interp *interp, /* Used for error reporting. */ - char *fileName, /* Name of the file containing the desired - * code. */ - char *sym1, char *sym2, /* Names of two procedures to look up in - * the file's symbol table. */ - Tcl_PackageInitProc **proc1Ptr, - Tcl_PackageInitProc **proc2Ptr, - /* Where to return the addresses corresponding - * to sym1 and sym2. */ - ClientData *clientDataPtr) /* Filled with token for dynamically loaded - * file which will be passed back to - * TclpUnloadFile() to unload the file. */ -{ - CFragConnectionID connID; - Ptr dummy; - OSErr err; - CFragSymbolClass symClass; - FSSpec fileSpec; - short fragFileRef, saveFileRef; - Handle fragResource; - UInt32 offset = 0; - UInt32 length = kCFragGoesToEOF; - char packageName[255]; - Str255 errName; - Tcl_DString ds; - char *native; - - /* - * First thing we must do is infer the package name from the sym1 - * variable. This is kind of dumb since the caller actually knows - * this value, it just doesn't give it to us. - */ - strcpy(packageName, sym1); - Tcl_UtfToLower(packageName); - *(Tcl_UtfAtIndex(packageName, Tcl_NumUtfChars(packageName, -1) - 5)) = 0; - - native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); - err = FSpLocationFromPath(strlen(native), native, &fileSpec); - Tcl_DStringFree(&ds); - - if (err != noErr) { - Tcl_SetResult(interp, "could not locate shared library", TCL_STATIC); - return TCL_ERROR; - } - - /* - * See if this fragment has a 'cfrg' resource. It will tell us where - * to look for the fragment in the file. If it doesn't exist we will - * assume we have a ppc frag using the whole data fork. If it does - * exist we find the frag that matches the one we are looking for and - * get the offset and size from the resource. - */ - - saveFileRef = CurResFile(); - SetResLoad(false); - fragFileRef = FSpOpenResFile(&fileSpec, fsRdPerm); - SetResLoad(true); - if (fragFileRef != -1) { - UseResFile(fragFileRef); - fragResource = Get1Resource(kCFragResourceType, kCFragResourceID); - 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, - kLoadCFrag, &connID, &dummy, errName); - if (err != fragNoErr) { - p2cstr(errName); - Tcl_AppendResult(interp, "couldn't load file \"", fileName, - "\": ", errName, (char *) NULL); - return TCL_ERROR; - } - - c2pstr(sym1); - err = FindSymbol(connID, (StringPtr) sym1, (Ptr *) proc1Ptr, &symClass); - p2cstr((StringPtr) sym1); - if (err != fragNoErr || symClass == kDataCFragSymbol) { - Tcl_SetResult(interp, - "could not find Initialization routine in library", - TCL_STATIC); - return TCL_ERROR; - } - - c2pstr(sym2); - err = FindSymbol(connID, (StringPtr) sym2, (Ptr *) proc2Ptr, &symClass); - p2cstr((StringPtr) sym2); - if (err != fragNoErr || symClass == kDataCFragSymbol) { - *proc2Ptr = NULL; - } - - *clientDataPtr = (ClientData) connID; - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TclpUnloadFile -- - * - * Unloads a dynamically loaded binary code file from memory. - * Code pointers in the formerly loaded file are no longer valid - * after calling this function. - * - * Results: - * None. - * - * Side effects: - * Does nothing. Can anything be done? - * - *---------------------------------------------------------------------- - */ - -void -TclpUnloadFile(clientData) - ClientData clientData; /* ClientData returned by a previous call - * to TclpLoadFile(). The clientData is - * a token that represents the loaded - * file. */ -{ -} - -/* - *---------------------------------------------------------------------- - * - * TclGuessPackageName -- - * - * If the "load" command is invoked without providing a package - * name, this procedure is invoked to try to figure it out. - * - * Results: - * Always returns 0 to indicate that we couldn't figure out a - * package name; generic code will then try to guess the package - * from the file name. A return value of 1 would have meant that - * we figured out the package name and put it in bufPtr. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclGuessPackageName( - 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. */ -{ - return 0; -} diff --git a/mac/tclMacMSLPrefix.h b/mac/tclMacMSLPrefix.h deleted file mode 100644 index 1d11099..0000000 --- a/mac/tclMacMSLPrefix.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * tclMacMSLPrefix.h -- - * - * A wrapper for the MSL ansi_prefix.mac.h file. This just turns export on - * after including the MSL prefix file, so we can export symbols from the MSL - * and through the Tcl shared libraries - * - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacMSLPrefix.h,v 1.2 1998/09/14 18:40:05 stanton Exp $ - */ - -#include <ansi_prefix.mac.h> -/* - * "export" is a MetroWerks specific pragma. It flags the linker that - * any symbols that are defined when this pragma is on will be exported - * to shared libraries that link with this library. - */ - -#pragma export on diff --git a/mac/tclMacMath.h b/mac/tclMacMath.h deleted file mode 100644 index 14af9a8..0000000 --- a/mac/tclMacMath.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * tclMacMath.h -- - * - * This file is necessary because of Metrowerks CodeWarrior Pro 1 - * on the Macintosh. With 8-byte doubles turned on, the definitions of - * sin, cos, acos, etc., are screwed up. They are fine as long as - * they are used as function calls, but if the function pointers - * are passed around and used, they will crash hard on the 68K. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacMath.h,v 1.2 1998/09/14 18:40:05 stanton Exp $ - */ - -#ifndef _TCLMACMATH -#define _TCLMACMATH - -#include <math.h> - -#if defined(__MWERKS__) && !defined(__POWERPC__) -#if __option(IEEEdoubles) - -# ifdef cos -# undef cos -# define cos cosd -# endif - -# ifdef sin -# undef sin -# define sin sind -# endif - -# ifdef tan -# undef tan -# define tan tand -# endif - -# ifdef acos -# undef acos -# define acos acosd -# endif - -# ifdef asin -# undef asin -# define asin asind -# endif - -# ifdef atan -# undef atan -# define atan atand -# endif - -# ifdef cosh -# undef cosh -# define cosh coshd -# endif - -# ifdef sinh -# undef sinh -# define sinh sinhd -# endif - -# ifdef tanh -# undef tanh -# define tanh tanhd -# endif - -# ifdef exp -# undef exp -# define exp expd -# endif - -# ifdef ldexp -# undef ldexp -# define ldexp ldexpd -# endif - -# ifdef log -# undef log -# define log logd -# endif - -# ifdef log10 -# undef log10 -# define log10 log10d -# endif - -# ifdef fabs -# undef fabs -# define fabs fabsd -# endif - -# ifdef sqrt -# undef sqrt -# define sqrt sqrtd -# endif - -# ifdef fmod -# undef fmod -# define fmod fmodd -# endif - -# ifdef atan2 -# undef atan2 -# define atan2 atan2d -# endif - -# ifdef frexp -# undef frexp -# define frexp frexpd -# endif - -# ifdef modf -# undef modf -# define modf modfd -# endif - -# ifdef pow -# undef pow -# define pow powd -# endif - -# ifdef ceil -# undef ceil -# define ceil ceild -# endif - -# ifdef floor -# undef floor -# define floor floord -# endif -#endif -#endif - -#if (defined(THINK_C) || defined(__MWERKS__)) -#pragma export on -double hypotd(double x, double y); -#define hypot hypotd -#pragma export reset -#endif - -#endif /* _TCLMACMATH */ diff --git a/mac/tclMacNotify.c b/mac/tclMacNotify.c deleted file mode 100644 index 93820ba..0000000 --- a/mac/tclMacNotify.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * tclMacNotify.c -- - * - * This file contains Macintosh-specific procedures for the notifier, - * which is the lowest-level part of the Tcl event loop. This file - * works together with ../generic/tclNotify.c. - * - * The Mac notifier only polls for system and OS events, so it is process - * wide, rather than thread specific. However, this means that the convert - * event proc will have to arbitrate which events go to which threads. - * - * Copyright (c) 1995-1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacNotify.c,v 1.6 1999/08/10 04:21:40 jingham Exp $ - */ - -#include "tclInt.h" -#include "tclPort.h" -#include "tclMac.h" -#include "tclMacInt.h" -#include <signal.h> -#include <Events.h> -#include <LowMem.h> -#include <Processes.h> -#include <Timer.h> -#include <Threads.h> - - -/* - * This is necessary to work around a bug in Apple's Universal header files - * for the CFM68K libraries. - */ - -#ifdef __CFM68K__ -#undef GetEventQueue -extern pascal QHdrPtr GetEventQueue(void) - THREEWORDINLINE(0x2EBC, 0x0000, 0x014A); -#pragma import list GetEventQueue -#define GetEvQHdr() GetEventQueue() -#endif - -/* - * Need this for replacing Tcl_SetTimer and Tcl_WaitForEvent defined - * in THIS file with ones defined in the stub table. - */ - -extern TclStubs tclStubs; - -/* - * The follwing static indicates whether this module has been initialized. - */ - -static int initialized = 0; - -/* - * The following structure contains the state information for the - * notifier module. - */ - -static struct { - int timerActive; /* 1 if timer is running. */ - Tcl_Time timer; /* Time when next timer event is expected. */ - int flags; /* OR'ed set of flags defined below. */ - Point lastMousePosition; /* Last known mouse location. */ - RgnHandle utilityRgn; /* Region used as the mouse region for - * WaitNextEvent and the update region when - * checking for events. */ - Tcl_MacConvertEventPtr eventProcPtr; - /* This pointer holds the address of the - * function that will handle all incoming - * Macintosh events. */ -} notifier; - -/* - * The following defines are used in the flags field of the notifier struct. - */ - -#define NOTIFY_IDLE (1<<1) /* Tcl_ServiceIdle should be called. */ -#define NOTIFY_TIMER (1<<2) /* Tcl_ServiceTimer should be called. */ - -/* - * Prototypes for procedures that are referenced only in this file: - */ - -static int HandleMacEvents _ANSI_ARGS_((void)); -static void InitNotifier _ANSI_ARGS_((void)); -static void NotifierExitHandler _ANSI_ARGS_(( - ClientData clientData)); - -/* - *---------------------------------------------------------------------- - * - * Tcl_InitNotifier -- - * - * Initializes the platform specific notifier state. There is no thread - * specific platform notifier on the Mac, so this really doesn't do - * anything. However, we need to return the ThreadID, since the generic - * notifier hands this back to us in AlertThread. - * - * Results: - * Returns the threadID for this thread. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -ClientData -Tcl_InitNotifier() -{ - -#ifdef TCL_THREADS - ThreadID curThread; - if (TclMacHaveThreads()) { - GetCurrentThread(&curThread); - return (ClientData) curThread; - } else { - return NULL; - } -#else - return NULL; -#endif - -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_FinalizeNotifier -- - * - * This function is called to cleanup the notifier state before - * a thread is terminated. There is no platform thread specific - * notifier, so this does nothing. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_FinalizeNotifier(clientData) - ClientData clientData; /* Pointer to notifier data. */ -{ - /* Nothing to do on the Mac */ -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AlertNotifier -- - * - * Wake up the specified notifier from any thread. This routine - * is called by the platform independent notifier code whenever - * the Tcl_ThreadAlert routine is called. This routine is - * guaranteed not to be called on a given notifier after - * Tcl_FinalizeNotifier is called for that notifier. - * - * Results: - * None. - * - * Side effects: - * Calls YieldToThread from this thread. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_AlertNotifier(clientData) - ClientData clientData; /* Pointer to thread data. */ -{ - -#ifdef TCL_THREADS - if (TclMacHaveThreads()) { - YieldToThread((ThreadID) clientData); - } -#endif - -} - -/* - *---------------------------------------------------------------------- - * - * InitNotifier -- - * - * Initializes the notifier structure. Note - this function is never - * used. - * - * Results: - * None. - * - * Side effects: - * Creates a new exit handler. - * - *---------------------------------------------------------------------- - */ - -static void -InitNotifier(void) -{ - initialized = 1; - memset(¬ifier, 0, sizeof(notifier)); - Tcl_CreateExitHandler(NotifierExitHandler, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * NotifierExitHandler -- - * - * This function is called to cleanup the notifier state before - * Tcl is unloaded. This function is never used, since InitNotifier - * isn't either. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -NotifierExitHandler( - ClientData clientData) /* Not used. */ -{ - initialized = 0; -} - -/* - *---------------------------------------------------------------------- - * - * HandleMacEvents -- - * - * This function checks for events from the Macintosh event queue. - * - * Results: - * Returns 1 if event found, 0 otherwise. - * - * Side effects: - * Pulls events off of the Mac event queue and then calls - * convertEventProc. - * - *---------------------------------------------------------------------- - */ - -static int -HandleMacEvents(void) -{ - EventRecord theEvent; - int eventFound = 0, needsUpdate = 0; - Point currentMouse; - WindowRef windowRef; - Rect mouseRect; - - /* - * Check for mouse moved events. These events aren't placed on the - * system event queue unless we call WaitNextEvent. - */ - - GetGlobalMouse(¤tMouse); - if ((notifier.eventProcPtr != NULL) && - !EqualPt(currentMouse, notifier.lastMousePosition)) { - notifier.lastMousePosition = currentMouse; - theEvent.what = nullEvent; - if ((*notifier.eventProcPtr)(&theEvent) == true) { - eventFound = 1; - } - } - - /* - * Check for update events. Since update events aren't generated - * until we call GetNextEvent, we may need to force a call to - * GetNextEvent, even if the queue is empty. - */ - - for (windowRef = FrontWindow(); windowRef != NULL; - windowRef = GetNextWindow(windowRef)) { - GetWindowUpdateRgn(windowRef, notifier.utilityRgn); - if (!EmptyRgn(notifier.utilityRgn)) { - needsUpdate = 1; - break; - } - } - - /* - * Process events from the OS event queue. - */ - - while (needsUpdate || (GetEvQHdr()->qHead != NULL)) { - GetGlobalMouse(¤tMouse); - SetRect(&mouseRect, currentMouse.h, currentMouse.v, - currentMouse.h + 1, currentMouse.v + 1); - RectRgn(notifier.utilityRgn, &mouseRect); - - WaitNextEvent(everyEvent, &theEvent, 5, notifier.utilityRgn); - needsUpdate = 0; - if ((notifier.eventProcPtr != NULL) - && ((*notifier.eventProcPtr)(&theEvent) == true)) { - eventFound = 1; - } - } - - return eventFound; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_SetTimer -- - * - * This procedure sets the current notifier timer value. The - * notifier will ensure that Tcl_ServiceAll() is called after - * the specified interval, even if no events have occurred. - * - * Results: - * None. - * - * Side effects: - * Replaces any previous timer. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_SetTimer( - Tcl_Time *timePtr) /* New value for interval timer. */ -{ - /* - * Allow the notifier to be hooked. This may not make sense - * on the Mac, but mirrors the UNIX hook. - */ - - if (tclStubs.tcl_SetTimer != Tcl_SetTimer) { - tclStubs.tcl_SetTimer(timePtr); - return; - } - - if (!timePtr) { - notifier.timerActive = 0; - } else { - /* - * Compute when the timer should fire. - */ - - TclpGetTime(¬ifier.timer); - notifier.timer.sec += timePtr->sec; - notifier.timer.usec += timePtr->usec; - if (notifier.timer.usec >= 1000000) { - notifier.timer.usec -= 1000000; - notifier.timer.sec += 1; - } - notifier.timerActive = 1; - } -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_ServiceModeHook -- - * - * This function is invoked whenever the service mode changes. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_ServiceModeHook(mode) - int mode; /* Either TCL_SERVICE_ALL, or - * TCL_SERVICE_NONE. */ -{ -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_WaitForEvent -- - * - * This function is called by Tcl_DoOneEvent to wait for new - * events on the message queue. If the block time is 0, then - * Tcl_WaitForEvent just polls the event queue without blocking. - * - * Results: - * Always returns 0. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_WaitForEvent( - Tcl_Time *timePtr) /* Maximum block time. */ -{ - int found; - EventRecord macEvent; - long sleepTime = 5; - long ms; - Point currentMouse; - void * timerToken; - Rect mouseRect; - - /* - * Allow the notifier to be hooked. This may not make - * sense on the Mac, but mirrors the UNIX hook. - */ - - if (tclStubs.tcl_WaitForEvent != Tcl_WaitForEvent) { - return tclStubs.tcl_WaitForEvent(timePtr); - } - - /* - * Compute the next timeout value. - */ - - if (!timePtr) { - ms = INT_MAX; - } else { - ms = (timePtr->sec * 1000) + (timePtr->usec / 1000); - } - timerToken = TclMacStartTimer((long) ms); - - /* - * Poll the Mac event sources. This loop repeats until something - * happens: a timeout, a socket event, mouse motion, or some other - * window event. Note that we don't call WaitNextEvent if another - * event is found to avoid context switches. This effectively gives - * events coming in via WaitNextEvent a slightly lower priority. - */ - - found = 0; - if (notifier.utilityRgn == NULL) { - notifier.utilityRgn = NewRgn(); - } - - while (!found) { - /* - * Check for generated and queued events. - */ - - if (HandleMacEvents()) { - found = 1; - } - - /* - * Check for time out. - */ - - if (!found && TclMacTimerExpired(timerToken)) { - found = 1; - } - - /* - * Check for window events. We may receive a NULL event for - * various reasons. 1) the timer has expired, 2) a mouse moved - * event is occuring or 3) the os is giving us time for idle - * events. Note that we aren't sharing the processor very - * well here. We really ought to do a better job of calling - * WaitNextEvent for time slicing purposes. - */ - - if (!found) { - /* - * Set up mouse region so we will wake if the mouse is moved. - * We do this by defining the smallest possible region around - * the current mouse position. - */ - - GetGlobalMouse(¤tMouse); - SetRect(&mouseRect, currentMouse.h, currentMouse.v, - currentMouse.h + 1, currentMouse.v + 1); - RectRgn(notifier.utilityRgn, &mouseRect); - - WaitNextEvent(everyEvent, &macEvent, sleepTime, - notifier.utilityRgn); - - if (notifier.eventProcPtr != NULL) { - if ((*notifier.eventProcPtr)(&macEvent) == true) { - found = 1; - } - } - } - } - TclMacRemoveTimer(timerToken); - - /* - * Yield time to nay other thread at this point. If we find that the - * apps thrash too switching between threads, we can put a timer here, - * and only yield when the timer fires. - */ - - if (TclMacHaveThreads()) { - YieldToAnyThread(); - } - - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_Sleep -- - * - * Delay execution for the specified number of milliseconds. This - * is not a very good call to make. It will block the system - - * you will not even be able to switch applications. - * - * Results: - * None. - * - * Side effects: - * Time passes. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_Sleep( - int ms) /* Number of milliseconds to sleep. */ -{ - EventRecord dummy; - void *timerToken; - - if (ms <= 0) { - return; - } - - timerToken = TclMacStartTimer((long) ms); - while (1) { - WaitNextEvent(0, &dummy, (ms / 16.66) + 1, NULL); - if (TclMacHaveThreads()) { - YieldToAnyThread(); - } - if (TclMacTimerExpired(timerToken)) { - break; - } - } - TclMacRemoveTimer(timerToken); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_MacSetEventProc -- - * - * This function sets the event handling procedure for the - * application. This function will be passed all incoming Mac - * events. This function usually controls the console or some - * other entity like Tk. - * - * Results: - * None. - * - * Side effects: - * Changes the event handling function. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_MacSetEventProc( - Tcl_MacConvertEventPtr procPtr) -{ - notifier.eventProcPtr = procPtr; -} diff --git a/mac/tclMacOSA.c b/mac/tclMacOSA.c deleted file mode 100644 index 72dcccf..0000000 --- a/mac/tclMacOSA.c +++ /dev/null @@ -1,2945 +0,0 @@ -/* - * tclMacOSA.c -- - * - * This contains the initialization routines, and the implementation of - * the OSA and Component commands. These commands allow you to connect - * with the AppleScript or any other OSA component to compile and execute - * scripts. - * - * Copyright (c) 1996 Lucent Technologies and Jim Ingham - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "License Terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacOSA.c,v 1.5 1999/08/15 04:04:06 jingham Exp $ - */ - -#define MAC_TCL - -#include <Aliases.h> -#include <string.h> -#include <AppleEvents.h> -#include <AppleScript.h> -#include <OSA.h> -#include <OSAGeneric.h> -#include <Script.h> - -#include <FullPath.h> -#include <components.h> - -#include <resources.h> -#include <FSpCompat.h> -/* - * The following two Includes are from the More Files package. - */ -#include <MoreFiles.h> -#include <FullPath.h> - -#include "tcl.h" -#include "tclInt.h" - -/* - * I need this only for the call to FspGetFullPath, - * I'm really not poking my nose where it does not belong! - */ -#include "tclMacInt.h" - -/* - * Data structures used by the OSA code. - */ -typedef struct tclOSAScript { - OSAID scriptID; - OSType languageID; - long modeFlags; -} tclOSAScript; - -typedef struct tclOSAContext { - OSAID contextID; -} tclOSAContext; - -typedef struct tclOSAComponent { - char *theName; - ComponentInstance theComponent; /* The OSA Component represented */ - long componentFlags; - OSType languageID; - char *languageName; - Tcl_HashTable contextTable; /* Hash Table linking the context names & ID's */ - Tcl_HashTable scriptTable; - Tcl_Interp *theInterp; - OSAActiveUPP defActiveProc; - long defRefCon; -} tclOSAComponent; - -/* - * Prototypes for static procedures. - */ - -static pascal OSErr TclOSAActiveProc _ANSI_ARGS_((long refCon)); -static int TclOSACompileCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSADecompileCmd _ANSI_ARGS_((Tcl_Interp * Interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSADeleteCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSAExecuteCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSAInfoCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSALoadCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSARunCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSAStoreCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, char - **argv)); -static void GetRawDataFromDescriptor _ANSI_ARGS_((AEDesc *theDesc, - Ptr destPtr, Size destMaxSize, Size *actSize)); -static OSErr GetCStringFromDescriptor _ANSI_ARGS_(( - AEDesc *sourceDesc, char *resultStr, - Size resultMaxSize,Size *resultSize)); -static int Tcl_OSAComponentCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -static void getSortedHashKeys _ANSI_ARGS_((Tcl_HashTable *theTable, - char *pattern, Tcl_DString *theResult)); -static int ASCIICompareProc _ANSI_ARGS_((const void *first, - const void *second)); -static int Tcl_OSACmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -static void tclOSAClose _ANSI_ARGS_((ClientData clientData)); -static void tclOSACloseAll _ANSI_ARGS_((ClientData clientData)); -static tclOSAComponent *tclOSAMakeNewComponent _ANSI_ARGS_((Tcl_Interp *interp, - char *cmdName, char *languageName, - OSType scriptSubtype, long componentFlags)); -static int prepareScriptData _ANSI_ARGS_((int argc, char **argv, - Tcl_DString *scrptData ,AEDesc *scrptDesc)); -static void tclOSAResultFromID _ANSI_ARGS_((Tcl_Interp *interp, - ComponentInstance theComponent, OSAID resultID)); -static void tclOSAASError _ANSI_ARGS_((Tcl_Interp * interp, - ComponentInstance theComponent, char *scriptSource)); -static int tclOSAGetContextID _ANSI_ARGS_((tclOSAComponent *theComponent, - char *contextName, OSAID *theContext)); -static void tclOSAAddContext _ANSI_ARGS_((tclOSAComponent *theComponent, - char *contextName, const OSAID theContext)); -static int tclOSAMakeContext _ANSI_ARGS_((tclOSAComponent *theComponent, - char *contextName, OSAID *theContext)); -static int tclOSADeleteContext _ANSI_ARGS_((tclOSAComponent *theComponent, - char *contextName)); -static int tclOSALoad _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *theComponent, char *resourceName, - int resourceNumber, char *fileName,OSAID *resultID)); -static int tclOSAStore _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *theComponent, char *resourceName, - int resourceNumber, char *fileName,char *scriptName)); -static int tclOSAAddScript _ANSI_ARGS_((tclOSAComponent *theComponent, - char *scriptName, long modeFlags, OSAID scriptID)); -static int tclOSAGetScriptID _ANSI_ARGS_((tclOSAComponent *theComponent, - char *scriptName, OSAID *scriptID)); -static tclOSAScript * tclOSAGetScript _ANSI_ARGS_((tclOSAComponent *theComponent, - char *scriptName)); -static int tclOSADeleteScript _ANSI_ARGS_((tclOSAComponent *theComponent, - char *scriptName,char *errMsg)); - -/* - * "export" is a MetroWerks specific pragma. It flags the linker that - * any symbols that are defined when this pragma is on will be exported - * to shared libraries that link with this library. - */ - - -#pragma export on -int Tclapplescript_Init( Tcl_Interp *interp ); -#pragma export reset - -/* - *---------------------------------------------------------------------- - * - * Tclapplescript_Init -- - * - * Initializes the the OSA command which opens connections to - * OSA components, creates the AppleScript command, which opens an - * instance of the AppleScript component,and constructs the table of - * available languages. - * - * Results: - * A standard Tcl result. - * - * Side Effects: - * Opens one connection to the AppleScript component, if - * available. Also builds up a table of available OSA languages, - * and creates the OSA command. - * - *---------------------------------------------------------------------- - */ - -int -Tclapplescript_Init( - Tcl_Interp *interp) /* Tcl interpreter. */ -{ - char *errMsg = NULL; - OSErr myErr = noErr; - Boolean gotAppleScript = false; - Boolean GotOneOSALanguage = false; - ComponentDescription compDescr = { - kOSAComponentType, - (OSType) 0, - (OSType) 0, - (long) 0, - (long) 0 - }, *foundComp; - Component curComponent = (Component) 0; - ComponentInstance curOpenComponent; - Tcl_HashTable *ComponentTable; - Tcl_HashTable *LanguagesTable; - Tcl_HashEntry *hashEntry; - int newPtr; - AEDesc componentName = { typeNull, NULL }; - char nameStr[32]; - Size nameLen; - long appleScriptFlags; - - /* - * Perform the required stubs magic... - */ - - if (!Tcl_InitStubs(interp, "8.2", 0)) { - return TCL_ERROR; - } - - /* - * Here We Will Get The Available Osa Languages, Since They Can Only Be - * Registered At Startup... If You Dynamically Load Components, This - * Will Fail, But This Is Not A Common Thing To Do. - */ - - LanguagesTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); - - if (LanguagesTable == NULL) { - panic("Memory Error Allocating Languages Hash Table"); - } - - Tcl_SetAssocData(interp, "OSAScript_LangTable", NULL, LanguagesTable); - Tcl_InitHashTable(LanguagesTable, TCL_STRING_KEYS); - - - while ((curComponent = FindNextComponent(curComponent, &compDescr)) != 0) { - int nbytes = sizeof(ComponentDescription); - foundComp = (ComponentDescription *) - ckalloc(sizeof(ComponentDescription)); - myErr = GetComponentInfo(curComponent, foundComp, NULL, NULL, NULL); - if (foundComp->componentSubType == - kOSAGenericScriptingComponentSubtype) { - /* Skip the generic component */ - ckfree((char *) foundComp); - } else { - GotOneOSALanguage = true; - - /* - * This is gross: looks like I have to open the component just - * to get its name!!! GetComponentInfo is supposed to return - * the name, but AppleScript always returns an empty string. - */ - - curOpenComponent = OpenComponent(curComponent); - if (curOpenComponent == NULL) { - Tcl_AppendResult(interp,"Error opening component", - (char *) NULL); - return TCL_ERROR; - } - - myErr = OSAScriptingComponentName(curOpenComponent,&componentName); - if (myErr == noErr) { - myErr = GetCStringFromDescriptor(&componentName, - nameStr, 31, &nameLen); - AEDisposeDesc(&componentName); - } - CloseComponent(curOpenComponent); - - if (myErr == noErr) { - hashEntry = Tcl_CreateHashEntry(LanguagesTable, - nameStr, &newPtr); - Tcl_SetHashValue(hashEntry, (ClientData) foundComp); - } else { - Tcl_AppendResult(interp,"Error getting componentName.", - (char *) NULL); - return TCL_ERROR; - } - - /* - * Make sure AppleScript is loaded, otherwise we will - * not bother to make the AppleScript command. - */ - if (foundComp->componentSubType == kAppleScriptSubtype) { - appleScriptFlags = foundComp->componentFlags; - gotAppleScript = true; - } - } - } - - /* - * Create the OSA command. - */ - - if (!GotOneOSALanguage) { - Tcl_AppendResult(interp,"Could not find any OSA languages", - (char *) NULL); - return TCL_ERROR; - } - - /* - * Create the Component Assoc Data & put it in the interpreter. - */ - - ComponentTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); - - if (ComponentTable == NULL) { - panic("Memory Error Allocating Hash Table"); - } - - Tcl_SetAssocData(interp, "OSAScript_CompTable", NULL, ComponentTable); - - Tcl_InitHashTable(ComponentTable, TCL_STRING_KEYS); - - /* - * The OSA command is not currently supported. - Tcl_CreateCommand(interp, "OSA", Tcl_OSACmd, (ClientData) NULL, - (Tcl_CmdDeleteProc *) NULL); - */ - - /* - * Open up one AppleScript component, with a default context - * and tie it to the AppleScript command. - * If the user just wants single-threaded AppleScript execution - * this should be enough. - * - */ - - if (gotAppleScript) { - if (tclOSAMakeNewComponent(interp, "AppleScript", - "AppleScript English", kAppleScriptSubtype, - appleScriptFlags) == NULL ) { - return TCL_ERROR; - } - } - - return Tcl_PkgProvide(interp, "OSAConnect", "1.0"); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_OSACmd -- - * - * This is the command that provides the interface to the OSA - * component manager. The subcommands are: close: close a component, - * info: get info on components open, and open: get a new connection - * with the Scripting Component - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Depends on the subcommand, see the user documentation - * for more details. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_OSACmd( - ClientData clientData, - Tcl_Interp *interp, - int argc, - char **argv) -{ - static unsigned short componentCmdIndex = 0; - char autoName[32]; - char c; - int length; - Tcl_HashTable *ComponentTable = NULL; - - - if (argc == 1) { - Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", - argv[0], " option\"", (char *) NULL); - return TCL_ERROR; - } - - c = *argv[1]; - length = strlen(argv[1]); - - /* - * Query out the Component Table, since most of these commands use it... - */ - - ComponentTable = (Tcl_HashTable *) Tcl_GetAssocData(interp, - "OSAScript_CompTable", (Tcl_InterpDeleteProc **) NULL); - - if (ComponentTable == NULL) { - Tcl_AppendResult(interp, "Error, could not get the Component Table", - " from the Associated data.", (char *) NULL); - return TCL_ERROR; - } - - if (c == 'c' && strncmp(argv[1],"close",length) == 0) { - Tcl_HashEntry *hashEntry; - if (argc != 3) { - Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", - argv[0], " ",argv[1], " componentName\"", - (char *) NULL); - return TCL_ERROR; - } - - if ((hashEntry = Tcl_FindHashEntry(ComponentTable,argv[2])) == NULL) { - Tcl_AppendResult(interp, "Component \"", argv[2], "\" not found", - (char *) NULL); - return TCL_ERROR; - } else { - Tcl_DeleteCommand(interp,argv[2]); - return TCL_OK; - } - } else if (c == 'o' && strncmp(argv[1],"open",length) == 0) { - /* - * Default language is AppleScript. - */ - OSType scriptSubtype = kAppleScriptSubtype; - char *languageName = "AppleScript English"; - char *errMsg = NULL; - ComponentDescription *theCD; - - argv += 2; - argc -= 2; - - while (argc > 0 ) { - if (*argv[0] == '-') { - c = *(argv[0] + 1); - if (c == 'l' && strcmp(argv[0] + 1, "language") == 0) { - if (argc == 1) { - Tcl_AppendResult(interp, - "Error - no language provided for the -language switch", - (char *) NULL); - return TCL_ERROR; - } else { - Tcl_HashEntry *hashEntry; - Tcl_HashSearch search; - Boolean gotIt = false; - Tcl_HashTable *LanguagesTable; - - /* - * Look up the language in the languages table - * Do a simple strstr match, so AppleScript - * will match "AppleScript English"... - */ - - LanguagesTable = Tcl_GetAssocData(interp, - "OSAScript_LangTable", - (Tcl_InterpDeleteProc **) NULL); - - for (hashEntry = - Tcl_FirstHashEntry(LanguagesTable, &search); - hashEntry != NULL; - hashEntry = Tcl_NextHashEntry(&search)) { - languageName = Tcl_GetHashKey(LanguagesTable, - hashEntry); - if (strstr(languageName,argv[1]) != NULL) { - theCD = (ComponentDescription *) - Tcl_GetHashValue(hashEntry); - gotIt = true; - break; - } - } - if (!gotIt) { - Tcl_AppendResult(interp, - "Error, could not find the language \"", - argv[1], - "\" in the list of known languages.", - (char *) NULL); - return TCL_ERROR; - } - } - } - argc -= 2; - argv += 2; - } else { - Tcl_AppendResult(interp, "Expected a flag, but got ", - argv[0], (char *) NULL); - return TCL_ERROR; - } - } - - sprintf(autoName, "OSAComponent%-d", componentCmdIndex++); - if (tclOSAMakeNewComponent(interp, autoName, languageName, - theCD->componentSubType, theCD->componentFlags) == NULL ) { - return TCL_ERROR; - } else { - Tcl_SetResult(interp,autoName,TCL_VOLATILE); - return TCL_OK; - } - - } else if (c == 'i' && strncmp(argv[1],"info",length) == 0) { - if (argc == 2) { - Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", - argv[0], " ", argv[1], " what\"", - (char *) NULL); - return TCL_ERROR; - } - - c = *argv[2]; - length = strlen(argv[2]); - - if (c == 'c' && strncmp(argv[2], "components", length) == 0) { - Tcl_DString theResult; - - Tcl_DStringInit(&theResult); - - if (argc == 3) { - getSortedHashKeys(ComponentTable,(char *) NULL, &theResult); - } else if (argc == 4) { - getSortedHashKeys(ComponentTable, argv[3], &theResult); - } else { - Tcl_AppendResult(interp, "Error: wrong # of arguments", - ", should be \"", argv[0], " ", argv[1], " ", - argv[2], " ?pattern?\".", (char *) NULL); - return TCL_ERROR; - } - Tcl_DStringResult(interp, &theResult); - return TCL_OK; - } else if (c == 'l' && strncmp(argv[2],"languages",length) == 0) { - Tcl_DString theResult; - Tcl_HashTable *LanguagesTable; - - Tcl_DStringInit(&theResult); - LanguagesTable = Tcl_GetAssocData(interp, - "OSAScript_LangTable", (Tcl_InterpDeleteProc **) NULL); - - if (argc == 3) { - getSortedHashKeys(LanguagesTable, (char *) NULL, &theResult); - } else if (argc == 4) { - getSortedHashKeys(LanguagesTable, argv[3], &theResult); - } else { - Tcl_AppendResult(interp, "Error: wrong # of arguments", - ", should be \"", argv[0], " ", argv[1], " ", - argv[2], " ?pattern?\".", (char *) NULL); - return TCL_ERROR; - } - Tcl_DStringResult(interp,&theResult); - return TCL_OK; - } else { - Tcl_AppendResult(interp, "Unknown option: ", argv[2], - " for OSA info, should be one of", - " \"components\" or \"languages\"", - (char *) NULL); - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "Unknown option: ", argv[1], - ", should be one of \"open\", \"close\" or \"info\".", - (char *) NULL); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_OSAComponentCmd -- - * - * This is the command that provides the interface with an OSA - * component. The sub commands are: - * - compile ? -context context? scriptData - * compiles the script data, returns the ScriptID - * - decompile ? -context context? scriptData - * decompiles the script data, source code - * - execute ?-context context? scriptData - * compiles and runs script data - * - info what: get component info - * - load ?-flags values? fileName - * loads & compiles script data from fileName - * - run scriptId ?options? - * executes the compiled script - * - * Results: - * A standard Tcl result - * - * Side Effects: - * Depends on the subcommand, see the user documentation - * for more details. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_OSAComponentCmd( - ClientData clientData, - Tcl_Interp *interp, - int argc, - char **argv) -{ - int length; - char c; - - tclOSAComponent *OSAComponent = (tclOSAComponent *) clientData; - - if (argc == 1) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option ?arg ...?\"", - (char *) NULL); - return TCL_ERROR; - } - - c = *argv[1]; - length = strlen(argv[1]); - if (c == 'c' && strncmp(argv[1], "compile", length) == 0) { - return TclOSACompileCmd(interp, OSAComponent, argc, argv); - } else if (c == 'l' && strncmp(argv[1], "load", length) == 0) { - return tclOSALoadCmd(interp, OSAComponent, argc, argv); - } else if (c == 'e' && strncmp(argv[1], "execute", length) == 0) { - return tclOSAExecuteCmd(interp, OSAComponent, argc, argv); - } else if (c == 'i' && strncmp(argv[1], "info", length) == 0) { - return tclOSAInfoCmd(interp, OSAComponent, argc, argv); - } else if (c == 'd' && strncmp(argv[1], "decompile", length) == 0) { - return tclOSADecompileCmd(interp, OSAComponent, argc, argv); - } else if (c == 'd' && strncmp(argv[1], "delete", length) == 0) { - return tclOSADeleteCmd(interp, OSAComponent, argc, argv); - } else if (c == 'r' && strncmp(argv[1], "run", length) == 0) { - return tclOSARunCmd(interp, OSAComponent, argc, argv); - } else if (c == 's' && strncmp(argv[1], "store", length) == 0) { - return tclOSAStoreCmd(interp, OSAComponent, argc, argv); - } else { - Tcl_AppendResult(interp,"bad option \"", argv[1], - "\": should be compile, decompile, delete, ", - "execute, info, load, run or store", - (char *) NULL); - return TCL_ERROR; - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TclOSACompileCmd -- - * - * This is the compile subcommand for the component command. - * - * Results: - * A standard Tcl result - * - * Side Effects: - * Compiles the script data either into a script or a script - * context. Adds the script to the component's script or context - * table. Sets interp's result to the name of the new script or - * context. - * - *---------------------------------------------------------------------- - */ - -static int -TclOSACompileCmd( - Tcl_Interp *interp, - tclOSAComponent *OSAComponent, - int argc, - char **argv) -{ - int tclError = TCL_OK; - int augment = 1; - int makeContext = 0; - char c; - char autoName[16]; - char buffer[32]; - char *resultName; - Boolean makeNewContext = false; - Tcl_DString scrptData; - AEDesc scrptDesc = { typeNull, NULL }; - long modeFlags = kOSAModeCanInteract; - OSAID resultID = kOSANullScript; - OSAID contextID = kOSANullScript; - OSAID parentID = kOSANullScript; - OSAError osaErr = noErr; - - if (!(OSAComponent->componentFlags && kOSASupportsCompiling)) { - Tcl_AppendResult(interp, - "OSA component does not support compiling", - (char *) NULL); - return TCL_ERROR; - } - - /* - * This signals that we should make up a name, which is the - * default behavior: - */ - - autoName[0] = '\0'; - resultName = NULL; - - if (argc == 2) { - numArgs: - Tcl_AppendResult(interp, - "wrong # args: should be \"", argv[0], " ", argv[1], - " ?options? code\"",(char *) NULL); - return TCL_ERROR; - } - - argv += 2; - argc -= 2; - - /* - * Do the argument parsing. - */ - - while (argc > 0) { - - if (*argv[0] == '-') { - c = *(argv[0] + 1); - - /* - * "--" is the only switch that has no value, stops processing - */ - - if (c == '-' && *(argv[0] + 2) == '\0') { - argv += 1; - argc--; - break; - } - - /* - * So we can check here a switch with no value. - */ - - if (argc == 1) { - Tcl_AppendResult(interp, - "no value given for switch: ", - argv[0], (char *) NULL); - return TCL_ERROR; - } - - if (c == 'c' && strcmp(argv[0] + 1, "context") == 0) { - if (Tcl_GetBoolean(interp, argv[1], &makeContext) != TCL_OK) { - return TCL_ERROR; - } - } else if (c == 'a' && strcmp(argv[0] + 1, "augment") == 0) { - /* - * Augment the current context which implies making a context. - */ - - if (Tcl_GetBoolean(interp, argv[1], &augment) != TCL_OK) { - return TCL_ERROR; - } - makeContext = 1; - } else if (c == 'n' && strcmp(argv[0] + 1, "name") == 0) { - resultName = argv[1]; - } else if (c == 'p' && strcmp(argv[0] + 1,"parent") == 0) { - /* - * Since this implies we are compiling into a context, - * set makeContext here - */ - if (tclOSAGetContextID(OSAComponent, - argv[1], &parentID) != TCL_OK) { - Tcl_AppendResult(interp, "context not found \"", - argv[1], "\"", (char *) NULL); - return TCL_ERROR; - } - makeContext = 1; - } else { - Tcl_AppendResult(interp, "bad option \"", argv[0], - "\": should be -augment, -context, -name or -parent", - (char *) NULL); - return TCL_ERROR; - } - argv += 2; - argc -= 2; - - } else { - break; - } - } - - /* - * Make sure we have some data left... - */ - if (argc == 0) { - goto numArgs; - } - - /* - * Now if we are making a context, see if it is a new one... - * There are three options here: - * 1) There was no name provided, so we autoName it - * 2) There was a name, then check and see if it already exists - * a) If yes, then makeNewContext is false - * b) Otherwise we are making a new context - */ - - if (makeContext) { - modeFlags |= kOSAModeCompileIntoContext; - if (resultName == NULL) { - /* - * Auto name the new context. - */ - resultName = autoName; - resultID = kOSANullScript; - makeNewContext = true; - } else if (tclOSAGetContextID(OSAComponent, - resultName, &resultID) == TCL_OK) { - makeNewContext = false; - } else { - makeNewContext = true; - resultID = kOSANullScript; - } - - /* - * Deal with the augment now... - */ - if (augment && !makeNewContext) { - modeFlags |= kOSAModeAugmentContext; - } - } - - /* - * Ok, now we have the options, so we can compile the script data. - */ - - if (prepareScriptData(argc, argv, &scrptData, &scrptDesc) == TCL_ERROR) { - Tcl_DStringResult(interp, &scrptData); - AEDisposeDesc(&scrptDesc); - return TCL_ERROR; - } - - /* - * If we want to use a parent context, we have to make the context - * by hand. Note, parentID is only specified when you make a new context. - */ - - if (parentID != kOSANullScript && makeNewContext) { - AEDesc contextDesc = { typeNull, NULL }; - - osaErr = OSAMakeContext(OSAComponent->theComponent, - &contextDesc, parentID, &resultID); - modeFlags |= kOSAModeAugmentContext; - } - - osaErr = OSACompile(OSAComponent->theComponent, &scrptDesc, - modeFlags, &resultID); - if (osaErr == noErr) { - - if (makeContext) { - /* - * For the compiled context to be active, you need to run - * the code that is in the context. - */ - OSAID activateID; - - osaErr = OSAExecute(OSAComponent->theComponent, resultID, - resultID, kOSAModeCanInteract, &activateID); - OSADispose(OSAComponent->theComponent, activateID); - - if (osaErr == noErr) { - if (makeNewContext) { - /* - * If we have compiled into a context, - * this is added to the context table - */ - - tclOSAAddContext(OSAComponent, resultName, resultID); - } - - Tcl_SetResult(interp, resultName, TCL_VOLATILE); - tclError = TCL_OK; - } - } else { - /* - * For a script, we return the script name. - */ - tclOSAAddScript(OSAComponent, resultName, modeFlags, resultID); - Tcl_SetResult(interp, resultName, TCL_VOLATILE); - tclError = TCL_OK; - } - } - - /* - * This catches the error either from the original compile, - * or from the execute in case makeContext == true - */ - - if (osaErr == errOSAScriptError) { - OSADispose(OSAComponent->theComponent, resultID); - tclOSAASError(interp, OSAComponent->theComponent, - Tcl_DStringValue(&scrptData)); - tclError = TCL_ERROR; - } else if (osaErr != noErr) { - sprintf(buffer, "Error #%-6d compiling script", osaErr); - Tcl_AppendResult(interp, buffer, (char *) NULL); - tclError = TCL_ERROR; - } - - Tcl_DStringFree(&scrptData); - AEDisposeDesc(&scrptDesc); - - return tclError; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSADecompileCmd -- - * - * This implements the Decompile subcommand of the component command - * - * Results: - * A standard Tcl result. - * - * Side Effects: - * Decompiles the script, and sets interp's result to the - * decompiled script data. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSADecompileCmd( - Tcl_Interp * interp, - tclOSAComponent *OSAComponent, - int argc, - char **argv) -{ - AEDesc resultingSourceData = { typeChar, NULL }; - OSAID scriptID; - Boolean isContext; - long result; - OSErr sysErr = noErr; - - if (argc == 2) { - Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", - argv[0], " ",argv[1], " scriptName \"", (char *) NULL ); - return TCL_ERROR; - } - - if (!(OSAComponent->componentFlags && kOSASupportsGetSource)) { - Tcl_AppendResult(interp, - "Error, this component does not support get source", - (char *) NULL); - return TCL_ERROR; - } - - if (tclOSAGetScriptID(OSAComponent, argv[2], &scriptID) == TCL_OK) { - isContext = false; - } else if (tclOSAGetContextID(OSAComponent, argv[2], &scriptID) - == TCL_OK ) { - isContext = true; - } else { - Tcl_AppendResult(interp, "Could not find script \"", - argv[2], "\"", (char *) NULL); - return TCL_ERROR; - } - - OSAGetScriptInfo(OSAComponent->theComponent, scriptID, - kOSACanGetSource, &result); - - sysErr = OSAGetSource(OSAComponent->theComponent, - scriptID, typeChar, &resultingSourceData); - - if (sysErr == noErr) { - Tcl_DString theResult; - Tcl_DStringInit(&theResult); - - Tcl_DStringAppend(&theResult, *resultingSourceData.dataHandle, - GetHandleSize(resultingSourceData.dataHandle)); - Tcl_DStringResult(interp, &theResult); - AEDisposeDesc(&resultingSourceData); - return TCL_OK; - } else { - Tcl_AppendResult(interp, "Error getting source data", (char *) NULL); - AEDisposeDesc(&resultingSourceData); - return TCL_ERROR; - } -} - -/* - *---------------------------------------------------------------------- - * - * tclOSADeleteCmd -- - * - * This implements the Delete subcommand of the Component command. - * - * Results: - * A standard Tcl result. - * - * Side Effects: - * Deletes a script from the script list of the given component. - * Removes all references to the script, and frees the memory - * associated with it. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSADeleteCmd( - Tcl_Interp *interp, - tclOSAComponent *OSAComponent, - int argc, - char **argv) -{ - char c,*errMsg = NULL; - int length; - - if (argc < 4) { - Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", - argv[0], " ", argv[1], " what scriptName", (char *) NULL); - return TCL_ERROR; - } - - c = *argv[2]; - length = strlen(argv[2]); - if (c == 'c' && strncmp(argv[2], "context", length) == 0) { - if (strcmp(argv[3], "global") == 0) { - Tcl_AppendResult(interp, "You cannot delete the global context", - (char *) NULL); - return TCL_ERROR; - } else if (tclOSADeleteContext(OSAComponent, argv[3]) != TCL_OK) { - Tcl_AppendResult(interp, "Error deleting script \"", argv[2], - "\": ", errMsg, (char *) NULL); - ckfree(errMsg); - return TCL_ERROR; - } - } else if (c == 's' && strncmp(argv[2], "script", length) == 0) { - if (tclOSADeleteScript(OSAComponent, argv[3], errMsg) != TCL_OK) { - Tcl_AppendResult(interp, "Error deleting script \"", argv[3], - "\": ", errMsg, (char *) NULL); - ckfree(errMsg); - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp,"Unknown value ", argv[2], - " should be one of ", - "\"context\" or \"script\".", - (char *) NULL ); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAExecuteCmd -- - * - * This implements the execute subcommand of the component command. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Executes the given script data, and sets interp's result to - * the OSA component's return value. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSAExecuteCmd( - Tcl_Interp *interp, - tclOSAComponent *OSAComponent, - int argc, - char **argv) -{ - int tclError = TCL_OK, resID = 128; - char c,buffer[32], - *contextName = NULL,*scriptName = NULL, *resName = NULL; - Boolean makeNewContext = false,makeContext = false; - AEDesc scrptDesc = { typeNull, NULL }; - long modeFlags = kOSAModeCanInteract; - OSAID resultID = kOSANullScript, - contextID = kOSANullScript, - parentID = kOSANullScript; - Tcl_DString scrptData; - OSAError osaErr = noErr; - OSErr sysErr = noErr; - - if (argc == 2) { - Tcl_AppendResult(interp, - "Error, no script data for \"", argv[0], - " run\"", (char *) NULL); - return TCL_ERROR; - } - - argv += 2; - argc -= 2; - - /* - * Set the context to the global context by default. - * Then parse the argument list for switches - */ - tclOSAGetContextID(OSAComponent, "global", &contextID); - - while (argc > 0) { - - if (*argv[0] == '-') { - c = *(argv[0] + 1); - - /* - * "--" is the only switch that has no value. - */ - - if (c == '-' && *(argv[0] + 2) == '\0') { - argv += 1; - argc--; - break; - } - - /* - * So we can check here for a switch with no value. - */ - - if (argc == 1) { - Tcl_AppendResult(interp, - "Error, no value given for switch ", - argv[0], (char *) NULL); - return TCL_ERROR; - } - - if (c == 'c' && strcmp(argv[0] + 1, "context") == 0) { - if (tclOSAGetContextID(OSAComponent, - argv[1], &contextID) == TCL_OK) { - } else { - Tcl_AppendResult(interp, "Script context \"", - argv[1], "\" not found", (char *) NULL); - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "Error, invalid switch ", argv[0], - " should be \"-context\"", (char *) NULL); - return TCL_ERROR; - } - - argv += 2; - argc -= 2; - } else { - break; - } - } - - if (argc == 0) { - Tcl_AppendResult(interp, "Error, no script data", (char *) NULL); - return TCL_ERROR; - } - - if (prepareScriptData(argc, argv, &scrptData, &scrptDesc) == TCL_ERROR) { - Tcl_DStringResult(interp, &scrptData); - AEDisposeDesc(&scrptDesc); - return TCL_ERROR; - } - /* - * Now try to compile and run, but check to make sure the - * component supports the one shot deal - */ - if (OSAComponent->componentFlags && kOSASupportsConvenience) { - osaErr = OSACompileExecute(OSAComponent->theComponent, - &scrptDesc, contextID, modeFlags, &resultID); - } else { - /* - * If not, we have to do this ourselves - */ - if (OSAComponent->componentFlags && kOSASupportsCompiling) { - OSAID compiledID = kOSANullScript; - osaErr = OSACompile(OSAComponent->theComponent, &scrptDesc, - modeFlags, &compiledID); - if (osaErr == noErr) { - osaErr = OSAExecute(OSAComponent->theComponent, compiledID, - contextID, modeFlags, &resultID); - } - OSADispose(OSAComponent->theComponent, compiledID); - } else { - /* - * The scripting component had better be able to load text data... - */ - OSAID loadedID = kOSANullScript; - - scrptDesc.descriptorType = OSAComponent->languageID; - osaErr = OSALoad(OSAComponent->theComponent, &scrptDesc, - modeFlags, &loadedID); - if (osaErr == noErr) { - OSAExecute(OSAComponent->theComponent, loadedID, - contextID, modeFlags, &resultID); - } - OSADispose(OSAComponent->theComponent, loadedID); - } - } - if (osaErr == errOSAScriptError) { - tclOSAASError(interp, OSAComponent->theComponent, - Tcl_DStringValue(&scrptData)); - tclError = TCL_ERROR; - } else if (osaErr != noErr) { - sprintf(buffer, "Error #%-6d compiling script", osaErr); - Tcl_AppendResult(interp, buffer, (char *) NULL); - tclError = TCL_ERROR; - } else { - tclOSAResultFromID(interp, OSAComponent->theComponent, resultID); - osaErr = OSADispose(OSAComponent->theComponent, resultID); - tclError = TCL_OK; - } - - Tcl_DStringFree(&scrptData); - AEDisposeDesc(&scrptDesc); - - return tclError; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAInfoCmd -- - * - * This implements the Info subcommand of the component command - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Info on scripts and contexts. See the user documentation for details. - * - *---------------------------------------------------------------------- - */ -static int -tclOSAInfoCmd( - Tcl_Interp *interp, - tclOSAComponent *OSAComponent, - int argc, - char **argv) -{ - char c; - int length; - Tcl_DString theResult; - - if (argc == 2) { - Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", - argv[0], " ", argv[1], " what \"", (char *) NULL ); - return TCL_ERROR; - } - - c = *argv[2]; - length = strlen(argv[2]); - if (c == 's' && strncmp(argv[2], "scripts", length) == 0) { - Tcl_DStringInit(&theResult); - if (argc == 3) { - getSortedHashKeys(&OSAComponent->scriptTable, (char *) NULL, - &theResult); - } else if (argc == 4) { - getSortedHashKeys(&OSAComponent->scriptTable, argv[3], &theResult); - } else { - Tcl_AppendResult(interp, "Error: wrong # of arguments,", - " should be \"", argv[0], " ", argv[1], " ", - argv[2], " ?pattern?", (char *) NULL); - return TCL_ERROR; - } - Tcl_DStringResult(interp, &theResult); - return TCL_OK; - } else if (c == 'c' && strncmp(argv[2], "contexts", length) == 0) { - Tcl_DStringInit(&theResult); - if (argc == 3) { - getSortedHashKeys(&OSAComponent->contextTable, (char *) NULL, - &theResult); - } else if (argc == 4) { - getSortedHashKeys(&OSAComponent->contextTable, - argv[3], &theResult); - } else { - Tcl_AppendResult(interp, "Error: wrong # of arguments for ,", - " should be \"", argv[0], " ", argv[1], " ", - argv[2], " ?pattern?", (char *) NULL); - return TCL_ERROR; - } - Tcl_DStringResult(interp, &theResult); - return TCL_OK; - } else if (c == 'l' && strncmp(argv[2], "language", length) == 0) { - Tcl_SetResult(interp, OSAComponent->languageName, TCL_STATIC); - return TCL_OK; - } else { - Tcl_AppendResult(interp, "Unknown argument \"", argv[2], - "\" for \"", argv[0], " info \", should be one of ", - "\"scripts\" \"language\", or \"contexts\"", - (char *) NULL); - return TCL_ERROR; - } -} - -/* - *---------------------------------------------------------------------- - * - * tclOSALoadCmd -- - * - * This is the load subcommand for the Component Command - * - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Loads script data from the given file, creates a new context - * for it, and sets interp's result to the name of the new context. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSALoadCmd( - Tcl_Interp *interp, - tclOSAComponent *OSAComponent, - int argc, - char **argv) -{ - int tclError = TCL_OK, resID = 128; - char c, autoName[24], - *contextName = NULL, *scriptName = NULL, *resName = NULL; - Boolean makeNewContext = false, makeContext = false; - AEDesc scrptDesc = { typeNull, NULL }; - long modeFlags = kOSAModeCanInteract; - OSAID resultID = kOSANullScript, - contextID = kOSANullScript, - parentID = kOSANullScript; - OSAError osaErr = noErr; - OSErr sysErr = noErr; - long scptInfo; - - autoName[0] = '\0'; - scriptName = autoName; - contextName = autoName; - - if (argc == 2) { - Tcl_AppendResult(interp, - "Error, no data for \"", argv[0], " ", argv[1], - "\"", (char *) NULL); - return TCL_ERROR; - } - - argv += 2; - argc -= 2; - - /* - * Do the argument parsing. - */ - - while (argc > 0) { - - if (*argv[0] == '-') { - c = *(argv[0] + 1); - - /* - * "--" is the only switch that has no value. - */ - - if (c == '-' && *(argv[0] + 2) == '\0') { - argv += 1; - argc--; - break; - } - - /* - * So we can check here a switch with no value. - */ - - if (argc == 1) { - Tcl_AppendResult(interp, "Error, no value given for switch ", - argv[0], (char *) NULL); - return TCL_ERROR; - } - - if (c == 'r' && strcmp(argv[0] + 1, "rsrcname") == 0) { - resName = argv[1]; - } else if (c == 'r' && strcmp(argv[0] + 1, "rsrcid") == 0) { - if (Tcl_GetInt(interp, argv[1], &resID) != TCL_OK) { - Tcl_AppendResult(interp, - "Error getting resource ID", (char *) NULL); - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "Error, invalid switch ", argv[0], - " should be \"--\", \"-rsrcname\" or \"-rsrcid\"", - (char *) NULL); - return TCL_ERROR; - } - - argv += 2; - argc -= 2; - } else { - break; - } - } - /* - * Ok, now we have the options, so we can load the resource, - */ - if (argc == 0) { - Tcl_AppendResult(interp, "Error, no filename given", (char *) NULL); - return TCL_ERROR; - } - - if (tclOSALoad(interp, OSAComponent, resName, resID, - argv[0], &resultID) != TCL_OK) { - Tcl_AppendResult(interp, "Error in load command", (char *) NULL); - return TCL_ERROR; - } - - /* - * Now find out whether we have a script, or a script context. - */ - - OSAGetScriptInfo(OSAComponent->theComponent, resultID, - kOSAScriptIsTypeScriptContext, &scptInfo); - - if (scptInfo) { - autoName[0] = '\0'; - tclOSAAddContext(OSAComponent, autoName, resultID); - - Tcl_SetResult(interp, autoName, TCL_VOLATILE); - } else { - /* - * For a script, we return the script name - */ - autoName[0] = '\0'; - tclOSAAddScript(OSAComponent, autoName, kOSAModeCanInteract, resultID); - Tcl_SetResult(interp, autoName, TCL_VOLATILE); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSARunCmd -- - * - * This implements the run subcommand of the component command - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Runs the given compiled script, and returns the OSA - * component's result. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSARunCmd( - Tcl_Interp *interp, - tclOSAComponent *OSAComponent, - int argc, - char **argv) -{ - int tclError = TCL_OK, - resID = 128; - char c, *contextName = NULL, - *scriptName = NULL, - *resName = NULL; - AEDesc scrptDesc = { typeNull, NULL }; - long modeFlags = kOSAModeCanInteract; - OSAID resultID = kOSANullScript, - contextID = kOSANullScript, - parentID = kOSANullScript; - OSAError osaErr = noErr; - OSErr sysErr = noErr; - char *componentName = argv[0]; - OSAID scriptID; - - if (argc == 2) { - Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", - argv[0], " ", argv[1], " scriptName", (char *) NULL); - return TCL_ERROR; - } - - /* - * Set the context to the global context for this component, - * as a default - */ - if (tclOSAGetContextID(OSAComponent, "global", &contextID) != TCL_OK) { - Tcl_AppendResult(interp, - "Could not find the global context for component ", - OSAComponent->theName, (char *) NULL ); - return TCL_ERROR; - } - - /* - * Now parse the argument list for switches - */ - argv += 2; - argc -= 2; - - while (argc > 0) { - if (*argv[0] == '-') { - c = *(argv[0] + 1); - /* - * "--" is the only switch that has no value - */ - if (c == '-' && *(argv[0] + 2) == '\0') { - argv += 1; - argc--; - break; - } - - /* - * So we can check here for a switch with no value. - */ - if (argc == 1) { - Tcl_AppendResult(interp, "Error, no value given for switch ", - argv[0], (char *) NULL); - return TCL_ERROR; - } - - if (c == 'c' && strcmp(argv[0] + 1, "context") == 0) { - if (argc == 1) { - Tcl_AppendResult(interp, - "Error - no context provided for the -context switch", - (char *) NULL); - return TCL_ERROR; - } else if (tclOSAGetContextID(OSAComponent, - argv[1], &contextID) == TCL_OK) { - } else { - Tcl_AppendResult(interp, "Script context \"", argv[1], - "\" not found", (char *) NULL); - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "Error, invalid switch ", argv[0], - " for ", componentName, - " should be \"-context\"", (char *) NULL); - return TCL_ERROR; - } - argv += 2; - argc -= 2; - } else { - break; - } - } - - if (tclOSAGetScriptID(OSAComponent, argv[0], &scriptID) != TCL_OK) { - if (tclOSAGetContextID(OSAComponent, argv[0], &scriptID) != TCL_OK) { - Tcl_AppendResult(interp, "Could not find script \"", - argv[2], "\"", (char *) NULL); - return TCL_ERROR; - } - } - - sysErr = OSAExecute(OSAComponent->theComponent, - scriptID, contextID, modeFlags, &resultID); - - if (sysErr == errOSAScriptError) { - tclOSAASError(interp, OSAComponent->theComponent, (char *) NULL); - tclError = TCL_ERROR; - } else if (sysErr != noErr) { - char buffer[32]; - sprintf(buffer, "Error #%6.6d encountered in run", sysErr); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - tclError = TCL_ERROR; - } else { - tclOSAResultFromID(interp, OSAComponent->theComponent, resultID ); - } - OSADispose(OSAComponent->theComponent, resultID); - - return tclError; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAStoreCmd -- - * - * This implements the store subcommand of the component command - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Runs the given compiled script, and returns the OSA - * component's result. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSAStoreCmd( - Tcl_Interp *interp, - tclOSAComponent *OSAComponent, - int argc, - char **argv) -{ - int tclError = TCL_OK, resID = 128; - char c, *contextName = NULL, *scriptName = NULL, *resName = NULL; - Boolean makeNewContext = false, makeContext = false; - AEDesc scrptDesc = { typeNull, NULL }; - long modeFlags = kOSAModeCanInteract; - OSAID resultID = kOSANullScript, - contextID = kOSANullScript, - parentID = kOSANullScript; - OSAError osaErr = noErr; - OSErr sysErr = noErr; - - if (argc == 2) { - Tcl_AppendResult(interp, "Error, no data for \"", argv[0], - " ",argv[1], "\"", (char *) NULL); - return TCL_ERROR; - } - - argv += 2; - argc -= 2; - - /* - * Do the argument parsing - */ - - while (argc > 0) { - if (*argv[0] == '-') { - c = *(argv[0] + 1); - - /* - * "--" is the only switch that has no value - */ - if (c == '-' && *(argv[0] + 2) == '\0') { - argv += 1; - argc--; - break; - } - - /* - * So we can check here a switch with no value. - */ - if (argc == 1) { - Tcl_AppendResult(interp, - "Error, no value given for switch ", - argv[0], (char *) NULL); - return TCL_ERROR; - } - - if (c == 'r' && strcmp(argv[0] + 1, "rsrcname") == 0) { - resName = argv[1]; - } else if (c == 'r' && strcmp(argv[0] + 1, "rsrcid") == 0) { - if (Tcl_GetInt(interp, argv[1], &resID) != TCL_OK) { - Tcl_AppendResult(interp, - "Error getting resource ID", (char *) NULL); - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "Error, invalid switch ", argv[0], - " should be \"--\", \"-rsrcname\" or \"-rsrcid\"", - (char *) NULL); - return TCL_ERROR; - } - - argv += 2; - argc -= 2; - } else { - break; - } - } - /* - * Ok, now we have the options, so we can load the resource, - */ - if (argc != 2) { - Tcl_AppendResult(interp, "Error, wrong # of arguments, should be ", - argv[0], " ", argv[1], "?option flag? scriptName fileName", - (char *) NULL); - return TCL_ERROR; - } - - if (tclOSAStore(interp, OSAComponent, resName, resID, - argv[0], argv[1]) != TCL_OK) { - Tcl_AppendResult(interp, "Error in load command", (char *) NULL); - return TCL_ERROR; - } else { - Tcl_ResetResult(interp); - tclError = TCL_OK; - } - - return tclError; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAMakeNewComponent -- - * - * Makes a command cmdName to represent a new connection to the - * OSA component with componentSubType scriptSubtype. - * - * Results: - * Returns the tclOSAComponent structure for the connection. - * - * Side Effects: - * Adds a new element to the component table. If there is an - * error, then the result of the Tcl interpreter interp is set - * to an appropriate error message. - * - *---------------------------------------------------------------------- - */ - -tclOSAComponent * -tclOSAMakeNewComponent( - Tcl_Interp *interp, - char *cmdName, - char *languageName, - OSType scriptSubtype, - long componentFlags) -{ - char buffer[32]; - AEDesc resultingName = {typeNull, NULL}; - AEDesc nullDesc = {typeNull, NULL }; - OSAID globalContext; - char global[] = "global"; - int nbytes; - ComponentDescription requestedComponent = { - kOSAComponentType, - (OSType) 0, - (OSType) 0, - (long int) 0, - (long int) 0 - }; - Tcl_HashTable *ComponentTable; - Component foundComponent = NULL; - OSAActiveUPP myActiveProcUPP; - - tclOSAComponent *newComponent; - Tcl_HashEntry *hashEntry; - int newPtr; - - requestedComponent.componentSubType = scriptSubtype; - nbytes = sizeof(tclOSAComponent); - newComponent = (tclOSAComponent *) ckalloc(sizeof(tclOSAComponent)); - if (newComponent == NULL) { - goto CleanUp; - } - - foundComponent = FindNextComponent(0, &requestedComponent); - if (foundComponent == 0) { - Tcl_AppendResult(interp, - "Could not find component of requested type", (char *) NULL); - goto CleanUp; - } - - newComponent->theComponent = OpenComponent(foundComponent); - - if (newComponent->theComponent == NULL) { - Tcl_AppendResult(interp, - "Could not open component of the requested type", - (char *) NULL); - goto CleanUp; - } - - newComponent->languageName = (char *) ckalloc(strlen(languageName) + 1); - strcpy(newComponent->languageName,languageName); - - newComponent->componentFlags = componentFlags; - - newComponent->theInterp = interp; - - Tcl_InitHashTable(&newComponent->contextTable, TCL_STRING_KEYS); - Tcl_InitHashTable(&newComponent->scriptTable, TCL_STRING_KEYS); - - if (tclOSAMakeContext(newComponent, global, &globalContext) != TCL_OK) { - sprintf(buffer, "%-6.6d", globalContext); - Tcl_AppendResult(interp, "Error ", buffer, " making ", global, - " context.", (char *) NULL); - goto CleanUp; - } - - newComponent->languageID = scriptSubtype; - - newComponent->theName = (char *) ckalloc(strlen(cmdName) + 1 ); - strcpy(newComponent->theName, cmdName); - - Tcl_CreateCommand(interp, newComponent->theName, Tcl_OSAComponentCmd, - (ClientData) newComponent, tclOSAClose); - - /* - * Register the new component with the component table - */ - - ComponentTable = (Tcl_HashTable *) Tcl_GetAssocData(interp, - "OSAScript_CompTable", (Tcl_InterpDeleteProc **) NULL); - - if (ComponentTable == NULL) { - Tcl_AppendResult(interp, "Error, could not get the Component Table", - " from the Associated data.", (char *) NULL); - return (tclOSAComponent *) NULL; - } - - hashEntry = Tcl_CreateHashEntry(ComponentTable, - newComponent->theName, &newPtr); - Tcl_SetHashValue(hashEntry, (ClientData) newComponent); - - /* - * Set the active proc to call Tcl_DoOneEvent() while idle - */ - if (OSAGetActiveProc(newComponent->theComponent, - &newComponent->defActiveProc, &newComponent->defRefCon) != noErr ) { - /* TODO -- clean up here... */ - } - - myActiveProcUPP = NewOSAActiveProc(TclOSAActiveProc); - OSASetActiveProc(newComponent->theComponent, - myActiveProcUPP, (long) newComponent); - return newComponent; - - CleanUp: - - ckfree((char *) newComponent); - return (tclOSAComponent *) NULL; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAClose -- - * - * This procedure closes the connection to an OSA component, and - * deletes all the script and context data associated with it. - * It is the command deletion callback for the component's command. - * - * Results: - * None - * - * Side effects: - * Closes the connection, and releases all the script data. - * - *---------------------------------------------------------------------- - */ - -void -tclOSAClose( - ClientData clientData) -{ - tclOSAComponent *theComponent = (tclOSAComponent *) clientData; - Tcl_HashEntry *hashEntry; - Tcl_HashSearch search; - tclOSAScript *theScript; - Tcl_HashTable *ComponentTable; - - /* - * Delete the context and script tables - * the memory for the language name, and - * the hash entry. - */ - - for (hashEntry = Tcl_FirstHashEntry(&theComponent->scriptTable, &search); - hashEntry != NULL; - hashEntry = Tcl_NextHashEntry(&search)) { - - theScript = (tclOSAScript *) Tcl_GetHashValue(hashEntry); - OSADispose(theComponent->theComponent, theScript->scriptID); - ckfree((char *) theScript); - Tcl_DeleteHashEntry(hashEntry); - } - - for (hashEntry = Tcl_FirstHashEntry(&theComponent->contextTable, &search); - hashEntry != NULL; - hashEntry = Tcl_NextHashEntry(&search)) { - - Tcl_DeleteHashEntry(hashEntry); - } - - ckfree(theComponent->languageName); - ckfree(theComponent->theName); - - /* - * Finally close the component - */ - - CloseComponent(theComponent->theComponent); - - ComponentTable = (Tcl_HashTable *) - Tcl_GetAssocData(theComponent->theInterp, - "OSAScript_CompTable", (Tcl_InterpDeleteProc **) NULL); - - if (ComponentTable == NULL) { - panic("Error, could not get the Component Table from the Associated data."); - } - - hashEntry = Tcl_FindHashEntry(ComponentTable, theComponent->theName); - if (hashEntry != NULL) { - Tcl_DeleteHashEntry(hashEntry); - } - - ckfree((char *) theComponent); -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAGetContextID -- - * - * This returns the context ID, given the component name. - * - * Results: - * A context ID - * - * Side effects: - * None - * - *---------------------------------------------------------------------- - */ - -static int -tclOSAGetContextID( - tclOSAComponent *theComponent, - char *contextName, - OSAID *theContext) -{ - Tcl_HashEntry *hashEntry; - tclOSAContext *contextStruct; - - if ((hashEntry = Tcl_FindHashEntry(&theComponent->contextTable, - contextName)) == NULL ) { - return TCL_ERROR; - } else { - contextStruct = (tclOSAContext *) Tcl_GetHashValue(hashEntry); - *theContext = contextStruct->contextID; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAAddContext -- - * - * This adds the context ID, with the name contextName. If the - * name is passed in as a NULL string, space is malloc'ed for the - * string and a new name is made up, if the string is empty, you - * must have allocated enough space ( 24 characters is fine) for - * the name, which is made up and passed out. - * - * Results: - * Nothing - * - * Side effects: - * Adds the script context to the component's context table. - * - *---------------------------------------------------------------------- - */ - -static void -tclOSAAddContext( - tclOSAComponent *theComponent, - char *contextName, - const OSAID theContext) -{ - static unsigned short contextIndex = 0; - tclOSAContext *contextStruct; - Tcl_HashEntry *hashEntry; - int newPtr; - - if (contextName == NULL) { - contextName = ckalloc(16 + TCL_INTEGER_SPACE); - sprintf(contextName, "OSAContext%d", contextIndex++); - } else if (*contextName == '\0') { - sprintf(contextName, "OSAContext%d", contextIndex++); - } - - hashEntry = Tcl_CreateHashEntry(&theComponent->contextTable, - contextName, &newPtr); - - contextStruct = (tclOSAContext *) ckalloc(sizeof(tclOSAContext)); - contextStruct->contextID = theContext; - Tcl_SetHashValue(hashEntry,(ClientData) contextStruct); -} - -/* - *---------------------------------------------------------------------- - * - * tclOSADeleteContext -- - * - * This deletes the context struct, with the name contextName. - * - * Results: - * A normal Tcl result - * - * Side effects: - * Removes the script context to the component's context table, - * and deletes the data associated with it. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSADeleteContext( - tclOSAComponent *theComponent, - char *contextName) -{ - Tcl_HashEntry *hashEntry; - tclOSAContext *contextStruct; - - hashEntry = Tcl_FindHashEntry(&theComponent->contextTable, contextName); - if (hashEntry == NULL) { - return TCL_ERROR; - } - /* - * Dispose of the script context data - */ - contextStruct = (tclOSAContext *) Tcl_GetHashValue(hashEntry); - OSADispose(theComponent->theComponent,contextStruct->contextID); - /* - * Then the hash entry - */ - ckfree((char *) contextStruct); - Tcl_DeleteHashEntry(hashEntry); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAMakeContext -- - * - * This makes the context with name contextName, and returns the ID. - * - * Results: - * A standard Tcl result - * - * Side effects: - * Makes a new context, adds it to the context table, and returns - * the new contextID in the variable theContext. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSAMakeContext( - tclOSAComponent *theComponent, - char *contextName, - OSAID *theContext) -{ - AEDesc contextNameDesc = {typeNull, NULL}; - OSAError osaErr = noErr; - - AECreateDesc(typeChar, contextName, strlen(contextName), &contextNameDesc); - osaErr = OSAMakeContext(theComponent->theComponent, &contextNameDesc, - kOSANullScript, theContext); - - AEDisposeDesc(&contextNameDesc); - - if (osaErr == noErr) { - tclOSAAddContext(theComponent, contextName, *theContext); - } else { - *theContext = (OSAID) osaErr; - return TCL_ERROR; - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAStore -- - * - * This stores a script resource from the file named in fileName. - * - * Most of this routine is caged from the Tcl Source, from the - * Tcl_MacSourceCmd routine. This is good, since it ensures this - * follows the same convention for looking up files as Tcl. - * - * Returns - * A standard Tcl result. - * - * Side Effects: - * The given script data is stored in the file fileName. - * - *---------------------------------------------------------------------- - */ - -int -tclOSAStore( - Tcl_Interp *interp, - tclOSAComponent *theComponent, - char *resourceName, - int resourceNumber, - char *scriptName, - char *fileName) -{ - Handle resHandle; - Str255 rezName; - int result = TCL_OK; - short saveRef, fileRef = -1; - char idStr[16 + TCL_INTEGER_SPACE]; - FSSpec fileSpec; - Tcl_DString buffer; - char *nativeName; - OSErr myErr = noErr; - OSAID scriptID; - Size scriptSize; - AEDesc scriptData; - - /* - * First extract the script data - */ - - if (tclOSAGetScriptID(theComponent, scriptName, &scriptID) != TCL_OK ) { - if (tclOSAGetContextID(theComponent, scriptName, &scriptID) - != TCL_OK) { - Tcl_AppendResult(interp, "Error getting script ", - scriptName, (char *) NULL); - return TCL_ERROR; - } - } - - myErr = OSAStore(theComponent->theComponent, scriptID, - typeOSAGenericStorage, kOSAModeNull, &scriptData); - if (myErr != noErr) { - sprintf(idStr, "%d", myErr); - Tcl_AppendResult(interp, "Error #", idStr, - " storing script ", scriptName, (char *) NULL); - return TCL_ERROR; - } - - /* - * Now try to open the output file - */ - - saveRef = CurResFile(); - - if (fileName != NULL) { - OSErr err; - - Tcl_DStringInit(&buffer); - nativeName = Tcl_TranslateFileName(interp, fileName, &buffer); - if (nativeName == NULL) { - return TCL_ERROR; - } - err = FSpLocationFromPath(strlen(nativeName), nativeName, &fileSpec); - - Tcl_DStringFree(&buffer); - if ((err != noErr) && (err != fnfErr)) { - Tcl_AppendResult(interp, - "Error getting a location for the file: \"", - fileName, "\".", NULL); - return TCL_ERROR; - } - - FSpCreateResFileCompat(&fileSpec, - 'WiSH', 'osas', smSystemScript); - myErr = ResError(); - - if ((myErr != noErr) && (myErr != dupFNErr)) { - sprintf(idStr, "%d", myErr); - Tcl_AppendResult(interp, "Error #", idStr, - " creating new resource file ", fileName, (char *) NULL); - result = TCL_ERROR; - goto rezEvalCleanUp; - } - - fileRef = FSpOpenResFileCompat(&fileSpec, fsRdWrPerm); - if (fileRef == -1) { - Tcl_AppendResult(interp, "Error reading the file: \"", - fileName, "\".", NULL); - result = TCL_ERROR; - goto rezEvalCleanUp; - } - UseResFile(fileRef); - } else { - /* - * The default behavior will search through all open resource files. - * This may not be the behavior you desire. If you want the behavior - * of this call to *only* search the application resource fork, you - * must call UseResFile at this point to set it to the application - * file. This means you must have already obtained the application's - * fileRef when the application started up. - */ - } - - /* - * Load the resource by name - */ - if (resourceName != NULL) { - strcpy((char *) rezName + 1, resourceName); - rezName[0] = strlen(resourceName); - resHandle = Get1NamedResource('scpt', rezName); - myErr = ResError(); - if (resHandle == NULL) { - /* - * These signify either the resource or the resource - * type were not found - */ - if (myErr == resNotFound || myErr == noErr) { - short uniqueID; - while ((uniqueID = Unique1ID('scpt') ) < 128) {} - AddResource(scriptData.dataHandle, 'scpt', uniqueID, rezName); - WriteResource(resHandle); - result = TCL_OK; - goto rezEvalCleanUp; - } else { - /* - * This means there was some other error, for now - * I just bag out. - */ - sprintf(idStr, "%d", myErr); - Tcl_AppendResult(interp, "Error #", idStr, - " opening scpt resource named ", resourceName, - " in file ", fileName, (char *) NULL); - result = TCL_ERROR; - goto rezEvalCleanUp; - } - } - /* - * Or ID - */ - } else { - resHandle = Get1Resource('scpt', resourceNumber); - rezName[0] = 0; - rezName[1] = '\0'; - myErr = ResError(); - if (resHandle == NULL) { - /* - * These signify either the resource or the resource - * type were not found - */ - if (myErr == resNotFound || myErr == noErr) { - AddResource(scriptData.dataHandle, 'scpt', - resourceNumber, rezName); - WriteResource(resHandle); - result = TCL_OK; - goto rezEvalCleanUp; - } else { - /* - * This means there was some other error, for now - * I just bag out */ - sprintf(idStr, "%d", myErr); - Tcl_AppendResult(interp, "Error #", idStr, - " opening scpt resource named ", resourceName, - " in file ", fileName,(char *) NULL); - result = TCL_ERROR; - goto rezEvalCleanUp; - } - } - } - - /* - * We get to here if the resource exists - * we just copy into it... - */ - - scriptSize = GetHandleSize(scriptData.dataHandle); - SetHandleSize(resHandle, scriptSize); - HLock(scriptData.dataHandle); - HLock(resHandle); - BlockMove(*scriptData.dataHandle, *resHandle,scriptSize); - HUnlock(scriptData.dataHandle); - HUnlock(resHandle); - ChangedResource(resHandle); - WriteResource(resHandle); - result = TCL_OK; - goto rezEvalCleanUp; - - rezEvalError: - sprintf(idStr, "ID=%d", resourceNumber); - Tcl_AppendResult(interp, "The resource \"", - (resourceName != NULL ? resourceName : idStr), - "\" could not be loaded from ", - (fileName != NULL ? fileName : "application"), - ".", NULL); - - rezEvalCleanUp: - if (fileRef != -1) { - CloseResFile(fileRef); - } - - UseResFile(saveRef); - - return result; -} - -/*---------------------------------------------------------------------- - * - * tclOSALoad -- - * - * This loads a script resource from the file named in fileName. - * Most of this routine is caged from the Tcl Source, from the - * Tcl_MacSourceCmd routine. This is good, since it ensures this - * follows the same convention for looking up files as Tcl. - * - * Returns - * A standard Tcl result. - * - * Side Effects: - * A new script element is created from the data in the file. - * The script ID is passed out in the variable resultID. - * - *---------------------------------------------------------------------- - */ - -int -tclOSALoad( - Tcl_Interp *interp, - tclOSAComponent *theComponent, - char *resourceName, - int resourceNumber, - char *fileName, - OSAID *resultID) -{ - Handle sourceData; - Str255 rezName; - int result = TCL_OK; - short saveRef, fileRef = -1; - char idStr[16 + TCL_INTEGER_SPACE]; - FSSpec fileSpec; - Tcl_DString buffer; - char *nativeName; - - saveRef = CurResFile(); - - if (fileName != NULL) { - OSErr err; - - Tcl_DStringInit(&buffer); - nativeName = Tcl_TranslateFileName(interp, fileName, &buffer); - if (nativeName == NULL) { - return TCL_ERROR; - } - err = FSpLocationFromPath(strlen(nativeName), nativeName, &fileSpec); - Tcl_DStringFree(&buffer); - if (err != noErr) { - Tcl_AppendResult(interp, "Error finding the file: \"", - fileName, "\".", NULL); - return TCL_ERROR; - } - - fileRef = FSpOpenResFileCompat(&fileSpec, fsRdPerm); - if (fileRef == -1) { - Tcl_AppendResult(interp, "Error reading the file: \"", - fileName, "\".", NULL); - return TCL_ERROR; - } - UseResFile(fileRef); - } else { - /* - * The default behavior will search through all open resource files. - * This may not be the behavior you desire. If you want the behavior - * of this call to *only* search the application resource fork, you - * must call UseResFile at this point to set it to the application - * file. This means you must have already obtained the application's - * fileRef when the application started up. - */ - } - - /* - * Load the resource by name or ID - */ - if (resourceName != NULL) { - strcpy((char *) rezName + 1, resourceName); - rezName[0] = strlen(resourceName); - sourceData = GetNamedResource('scpt', rezName); - } else { - sourceData = GetResource('scpt', (short) resourceNumber); - } - - if (sourceData == NULL) { - result = TCL_ERROR; - } else { - AEDesc scriptDesc; - OSAError osaErr; - - scriptDesc.descriptorType = typeOSAGenericStorage; - scriptDesc.dataHandle = sourceData; - - osaErr = OSALoad(theComponent->theComponent, &scriptDesc, - kOSAModeNull, resultID); - - ReleaseResource(sourceData); - - if (osaErr != noErr) { - result = TCL_ERROR; - goto rezEvalError; - } - - goto rezEvalCleanUp; - } - - rezEvalError: - sprintf(idStr, "ID=%d", resourceNumber); - Tcl_AppendResult(interp, "The resource \"", - (resourceName != NULL ? resourceName : idStr), - "\" could not be loaded from ", - (fileName != NULL ? fileName : "application"), - ".", NULL); - - rezEvalCleanUp: - if (fileRef != -1) { - CloseResFile(fileRef); - } - - UseResFile(saveRef); - - return result; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAGetScriptID -- - * - * This returns the context ID, gibven the component name. - * - * Results: - * A standard Tcl result - * - * Side effects: - * Passes out the script ID in the variable scriptID. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSAGetScriptID( - tclOSAComponent *theComponent, - char *scriptName, - OSAID *scriptID) -{ - tclOSAScript *theScript; - - theScript = tclOSAGetScript(theComponent, scriptName); - if (theScript == NULL) { - return TCL_ERROR; - } - - *scriptID = theScript->scriptID; - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAAddScript -- - * - * This adds a script to theComponent's script table, with the - * given name & ID. - * - * Results: - * A standard Tcl result - * - * Side effects: - * Adds an element to the component's script table. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSAAddScript( - tclOSAComponent *theComponent, - char *scriptName, - long modeFlags, - OSAID scriptID) -{ - Tcl_HashEntry *hashEntry; - int newPtr; - static int scriptIndex = 0; - tclOSAScript *theScript; - - if (*scriptName == '\0') { - sprintf(scriptName, "OSAScript%d", scriptIndex++); - } - - hashEntry = Tcl_CreateHashEntry(&theComponent->scriptTable, - scriptName, &newPtr); - if (newPtr == 0) { - theScript = (tclOSAScript *) Tcl_GetHashValue(hashEntry); - OSADispose(theComponent->theComponent, theScript->scriptID); - } else { - theScript = (tclOSAScript *) ckalloc(sizeof(tclOSAScript)); - if (theScript == NULL) { - return TCL_ERROR; - } - } - - theScript->scriptID = scriptID; - theScript->languageID = theComponent->languageID; - theScript->modeFlags = modeFlags; - - Tcl_SetHashValue(hashEntry,(ClientData) theScript); - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAGetScriptID -- - * - * This returns the script structure, given the component and script name. - * - * Results: - * A pointer to the script structure. - * - * Side effects: - * None - * - *---------------------------------------------------------------------- - */ - -static tclOSAScript * -tclOSAGetScript( - tclOSAComponent *theComponent, - char *scriptName) -{ - Tcl_HashEntry *hashEntry; - - hashEntry = Tcl_FindHashEntry(&theComponent->scriptTable, scriptName); - if (hashEntry == NULL) { - return NULL; - } - - return (tclOSAScript *) Tcl_GetHashValue(hashEntry); -} - -/* - *---------------------------------------------------------------------- - * - * tclOSADeleteScript -- - * - * This deletes the script given by scriptName. - * - * Results: - * A standard Tcl result - * - * Side effects: - * Deletes the script from the script table, and frees up the - * resources associated with it. If there is an error, then - * space for the error message is malloc'ed, and passed out in - * the variable errMsg. - * - *---------------------------------------------------------------------- - */ - -static int -tclOSADeleteScript( - tclOSAComponent *theComponent, - char *scriptName, - char *errMsg) -{ - Tcl_HashEntry *hashEntry; - tclOSAScript *scriptPtr; - - hashEntry = Tcl_FindHashEntry(&theComponent->scriptTable, scriptName); - if (hashEntry == NULL) { - errMsg = ckalloc(17); - strcpy(errMsg,"Script not found"); - return TCL_ERROR; - } - - scriptPtr = (tclOSAScript *) Tcl_GetHashValue(hashEntry); - OSADispose(theComponent->theComponent, scriptPtr->scriptID); - ckfree((char *) scriptPtr); - Tcl_DeleteHashEntry(hashEntry); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TclOSAActiveProc -- - * - * This is passed to each component. It is run periodically - * during script compilation and script execution. It in turn - * calls Tcl_DoOneEvent to process the event queue. We also call - * the default Active proc which will let the user cancel the script - * by hitting Command-. - * - * Results: - * A standard MacOS system error - * - * Side effects: - * Any Tcl code may run while calling Tcl_DoOneEvent. - * - *---------------------------------------------------------------------- - */ - -static pascal OSErr -TclOSAActiveProc( - long refCon) -{ - tclOSAComponent *theComponent = (tclOSAComponent *) refCon; - - Tcl_DoOneEvent(TCL_DONT_WAIT); - CallOSAActiveProc(theComponent->defActiveProc, theComponent->defRefCon); - - return noErr; -} - -/* - *---------------------------------------------------------------------- - * - * ASCIICompareProc -- - * - * Trivial ascii compare for use with qsort. - * - * Results: - * strcmp of the two input strings - * - * Side effects: - * None - * - *---------------------------------------------------------------------- - */ -static int -ASCIICompareProc(const void *first,const void *second) -{ - int order; - - char *firstString = *((char **) first); - char *secondString = *((char **) second); - - order = strcmp(firstString, secondString); - - return order; -} - -#define REALLOC_INCR 30 -/* - *---------------------------------------------------------------------- - * - * getSortedHashKeys -- - * - * returns an alphabetically sorted list of the keys of the hash - * theTable which match the string "pattern" in the DString - * theResult. pattern == NULL matches all. - * - * Results: - * None - * - * Side effects: - * ReInitializes the DString theResult, then copies the names of - * the matching keys into the string as list elements. - * - *---------------------------------------------------------------------- - */ - -static void -getSortedHashKeys( - Tcl_HashTable *theTable, - char *pattern, - Tcl_DString *theResult) -{ - Tcl_HashSearch search; - Tcl_HashEntry *hPtr; - Boolean compare = true; - char *keyPtr; - static char **resultArgv = NULL; - static int totSize = 0; - int totElem = 0, i; - - if (pattern == NULL || *pattern == '\0' || - (*pattern == '*' && *(pattern + 1) == '\0')) { - compare = false; - } - - for (hPtr = Tcl_FirstHashEntry(theTable,&search), totElem = 0; - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - - keyPtr = (char *) Tcl_GetHashKey(theTable, hPtr); - if (!compare || Tcl_StringMatch(keyPtr, pattern)) { - totElem++; - if (totElem >= totSize) { - totSize += REALLOC_INCR; - resultArgv = (char **) ckrealloc((char *) resultArgv, - totSize * sizeof(char *)); - } - resultArgv[totElem - 1] = keyPtr; - } - } - - Tcl_DStringInit(theResult); - if (totElem == 1) { - Tcl_DStringAppendElement(theResult, resultArgv[0]); - } else if (totElem > 1) { - qsort((VOID *) resultArgv, (size_t) totElem, sizeof (char *), - ASCIICompareProc); - - for (i = 0; i < totElem; i++) { - Tcl_DStringAppendElement(theResult, resultArgv[i]); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * prepareScriptData -- - * - * Massages the input data in the argv array, concating the - * elements, with a " " between each, and replacing \n with \r, - * and \\n with " ". Puts the result in the the DString scrptData, - * and copies the result to the AEdesc scrptDesc. - * - * Results: - * Standard Tcl result - * - * Side effects: - * Creates a new Handle (with AECreateDesc) for the script data. - * Stores the script in scrptData, or the error message if there - * is an error creating the descriptor. - * - *---------------------------------------------------------------------- - */ - -static int -prepareScriptData( - int argc, - char **argv, - Tcl_DString *scrptData, - AEDesc *scrptDesc) -{ - char * ptr; - int i; - char buffer[7]; - OSErr sysErr = noErr; - - Tcl_DStringInit(scrptData); - - for (i = 0; i < argc; i++) { - Tcl_DStringAppend(scrptData, argv[i], -1); - Tcl_DStringAppend(scrptData, " ", 1); - } - - /* - * First replace the \n's with \r's in the script argument - * Also replace "\\n" with " ". - */ - - for (ptr = scrptData->string; *ptr != '\0'; ptr++) { - if (*ptr == '\n') { - *ptr = '\r'; - } else if (*ptr == '\\') { - if (*(ptr + 1) == '\n') { - *ptr = ' '; - *(ptr + 1) = ' '; - } - } - } - - sysErr = AECreateDesc(typeChar, Tcl_DStringValue(scrptData), - Tcl_DStringLength(scrptData), scrptDesc); - - if (sysErr != noErr) { - sprintf(buffer, "%6d", sysErr); - Tcl_DStringFree(scrptData); - Tcl_DStringAppend(scrptData, "Error #", 7); - Tcl_DStringAppend(scrptData, buffer, -1); - Tcl_DStringAppend(scrptData, " creating Script Data Descriptor.", 33); - return TCL_ERROR; - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAResultFromID -- - * - * Gets a human readable version of the result from the script ID - * and returns it in the result of the interpreter interp - * - * Results: - * None - * - * Side effects: - * Sets the result of interp to the human readable version of resultID. - * - * - *---------------------------------------------------------------------- - */ - -void -tclOSAResultFromID( - Tcl_Interp *interp, - ComponentInstance theComponent, - OSAID resultID ) -{ - OSErr myErr = noErr; - AEDesc resultDesc; - Tcl_DString resultStr; - - Tcl_DStringInit(&resultStr); - - myErr = OSADisplay(theComponent, resultID, typeChar, - kOSAModeNull, &resultDesc); - Tcl_DStringAppend(&resultStr, (char *) *resultDesc.dataHandle, - GetHandleSize(resultDesc.dataHandle)); - Tcl_DStringResult(interp,&resultStr); -} - -/* - *---------------------------------------------------------------------- - * - * tclOSAASError -- - * - * Gets the error message from the AppleScript component, and adds - * it to interp's result. If the script data is known, will point - * out the offending bit of code. This MUST BE A NULL TERMINATED - * C-STRING, not a typeChar. - * - * Results: - * None - * - * Side effects: - * Sets the result of interp to error, plus the relevant portion - * of the script. - * - *---------------------------------------------------------------------- - */ - -void -tclOSAASError( - Tcl_Interp * interp, - ComponentInstance theComponent, - char *scriptData ) -{ - OSErr myErr = noErr; - AEDesc errResult,errLimits; - Tcl_DString errStr; - DescType returnType; - Size returnSize; - short srcStart,srcEnd; - char buffer[16]; - - Tcl_DStringInit(&errStr); - Tcl_DStringAppend(&errStr, "An AppleScript error was encountered.\n", -1); - - OSAScriptError(theComponent, kOSAErrorNumber, - typeShortInteger, &errResult); - - sprintf(buffer, "Error #%-6.6d\n", (short int) **errResult.dataHandle); - - AEDisposeDesc(&errResult); - - Tcl_DStringAppend(&errStr,buffer, 15); - - OSAScriptError(theComponent, kOSAErrorMessage, typeChar, &errResult); - Tcl_DStringAppend(&errStr, (char *) *errResult.dataHandle, - GetHandleSize(errResult.dataHandle)); - AEDisposeDesc(&errResult); - - if (scriptData != NULL) { - int lowerB, upperB; - - myErr = OSAScriptError(theComponent, kOSAErrorRange, - typeOSAErrorRange, &errResult); - - myErr = AECoerceDesc(&errResult, typeAERecord, &errLimits); - myErr = AEGetKeyPtr(&errLimits, keyOSASourceStart, - typeShortInteger, &returnType, &srcStart, - sizeof(short int), &returnSize); - myErr = AEGetKeyPtr(&errLimits, keyOSASourceEnd, typeShortInteger, - &returnType, &srcEnd, sizeof(short int), &returnSize); - AEDisposeDesc(&errResult); - AEDisposeDesc(&errLimits); - - Tcl_DStringAppend(&errStr, "\nThe offending bit of code was:\n\t", -1); - /* - * Get the full line on which the error occured: - */ - for (lowerB = srcStart; lowerB > 0; lowerB--) { - if (*(scriptData + lowerB ) == '\r') { - lowerB++; - break; - } - } - - for (upperB = srcEnd; *(scriptData + upperB) != '\0'; upperB++) { - if (*(scriptData + upperB) == '\r') { - break; - } - } - - Tcl_DStringAppend(&errStr, scriptData+lowerB, srcStart - lowerB); - Tcl_DStringAppend(&errStr, "_", 1); - Tcl_DStringAppend(&errStr, scriptData+srcStart, upperB - srcStart); - } - - Tcl_DStringResult(interp,&errStr); -} - -/* - *---------------------------------------------------------------------- - * - * GetRawDataFromDescriptor -- - * - * Get the data from a descriptor. - * - * Results: - * None - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetRawDataFromDescriptor( - AEDesc *theDesc, - Ptr destPtr, - Size destMaxSize, - Size *actSize) - { - Size copySize; - - if (theDesc->dataHandle) { - HLock((Handle)theDesc->dataHandle); - *actSize = GetHandleSize((Handle)theDesc->dataHandle); - copySize = *actSize < destMaxSize ? *actSize : destMaxSize; - BlockMove(*theDesc->dataHandle, destPtr, copySize); - HUnlock((Handle)theDesc->dataHandle); - } else { - *actSize = 0; - } - - } - -/* - *---------------------------------------------------------------------- - * - * GetRawDataFromDescriptor -- - * - * Get the data from a descriptor. Assume it's a C string. - * - * Results: - * None - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static OSErr -GetCStringFromDescriptor( - AEDesc *sourceDesc, - char *resultStr, - Size resultMaxSize, - Size *resultSize) -{ - OSErr err; - AEDesc resultDesc; - - resultDesc.dataHandle = nil; - - err = AECoerceDesc(sourceDesc, typeChar, &resultDesc); - - if (!err) { - GetRawDataFromDescriptor(&resultDesc, (Ptr) resultStr, - resultMaxSize - 1, resultSize); - resultStr[*resultSize] = 0; - } else { - err = errAECoercionFail; - } - - if (resultDesc.dataHandle) { - AEDisposeDesc(&resultDesc); - } - - return err; -} diff --git a/mac/tclMacOSA.exp b/mac/tclMacOSA.exp deleted file mode 100644 index 4cde512..0000000 --- a/mac/tclMacOSA.exp +++ /dev/null @@ -1 +0,0 @@ -Tclapplescript_Init diff --git a/mac/tclMacOSA.r b/mac/tclMacOSA.r deleted file mode 100644 index 7343764..0000000 --- a/mac/tclMacOSA.r +++ /dev/null @@ -1,76 +0,0 @@ -/* - * tkMacOSA.r -- - * - * This file creates resources used by the AppleScript package. - * - * Copyright (c) 1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacOSA.r,v 1.3 1999/08/16 00:09:26 jingham Exp $ - */ - -#include <Types.r> -#include <SysTypes.r> - -/* - * The folowing include and defines help construct - * the version string for Tcl. - */ - -#define SCRIPT_MAJOR_VERSION 1 /* Major number */ -#define SCRIPT_MINOR_VERSION 0 /* Minor number */ -#define SCRIPT_RELEASE_SERIAL 2 /* Really minor number! */ -#define RELEASE_LEVEL alpha /* alpha, beta, or final */ -#define SCRIPT_VERSION "1.0" -#define SCRIPT_PATCH_LEVEL "1.0a2" -#define FINAL 0 /* Change to 1 if final version. */ - -#if FINAL -# define MINOR_VERSION (SCRIPT_MINOR_VERSION * 16) + SCRIPT_RELEASE_SERIAL -#else -# define MINOR_VERSION SCRIPT_MINOR_VERSION * 16 -#endif - -#define RELEASE_CODE 0x00 - -resource 'vers' (1) { - SCRIPT_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - SCRIPT_PATCH_LEVEL, - SCRIPT_PATCH_LEVEL ", by Jim Ingham © Cygnus Solutions" -}; - -resource 'vers' (2) { - SCRIPT_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - SCRIPT_PATCH_LEVEL, - "Tclapplescript " SCRIPT_PATCH_LEVEL " © 1996-1999" -}; - -/* - * The -16397 string will be displayed by Finder when a user - * tries to open the shared library. The string should - * give the user a little detail about the library's capabilities - * and enough information to install the library in the correct location. - * A similar string should be placed in all shared libraries. - */ -resource 'STR ' (-16397, purgeable) { - "TclAppleScript Library\n\n" - "This library provides the ability to run AppleScript " - " commands from Tcl/Tk programs. To work properly, it " - "should be placed in the ÔTool Command LanguageÕ folder " - "within the Extensions folder." -}; - - -/* - * We now load the Tk library into the resource fork of the library. - */ - -data 'TEXT' (4000,"pkgIndex",purgeable, preload) { - "# Tcl package index file, version 1.0\n" - "package ifneeded Tclapplescript 1.0 [list tclPkgSetup $dir Tclapplescript 1.0 {{Tclapplescript" - ".shlb load AppleScript}}]\n" -}; diff --git a/mac/tclMacPanic.c b/mac/tclMacPanic.c deleted file mode 100644 index 081c856..0000000 --- a/mac/tclMacPanic.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * tclMacPanic.c -- - * - * Source code for the "panic" library procedure used in "Simple Shell"; - * other Mac applications will probably override this with a more robust - * application-specific panic procedure. - * - * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center - * Copyright (c) 1995-1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacPanic.c,v 1.2 1998/09/14 18:40:05 stanton Exp $ - */ - - -#include <Events.h> -#include <Controls.h> -#include <Windows.h> -#include <TextEdit.h> -#include <Fonts.h> -#include <Dialogs.h> -#include <Icons.h> -#include <Sound.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include "tclInt.h" - -/* - * constants for panic dialog - */ -#define PANICHEIGHT 150 /* Height of dialog */ -#define PANICWIDTH 350 /* Width of dialog */ -#define PANIC_BUTTON_RECT {125, 260, 145, 335} /* Rect for button. */ -#define PANIC_ICON_RECT {10, 20, 42, 52} /* Rect for icon. */ -#define PANIC_TEXT_RECT {10, 65, 140, 330} /* Rect for text. */ -#define ENTERCODE (0x03) -#define RETURNCODE (0x0D) - -/* - * The panicProc variable contains a pointer to an application - * specific panic procedure. - */ - -void (*panicProc) _ANSI_ARGS_(TCL_VARARGS(char *,format)) = NULL; - -/* - *---------------------------------------------------------------------- - * - * Tcl_SetPanicProc -- - * - * Replace the default panic behavior with the specified functiion. - * - * Results: - * None. - * - * Side effects: - * Sets the panicProc variable. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_SetPanicProc(proc) - void (*proc) _ANSI_ARGS_(TCL_VARARGS(char *,format)); -{ - panicProc = proc; -} - -/* - *---------------------------------------------------------------------- - * - * MacPanic -- - * - * Displays panic info.. - * - * Results: - * None. - * - * Side effects: - * Sets the panicProc variable. - * - *---------------------------------------------------------------------- - */ - -static void -MacPanic( - char *msg) /* Text to show in panic dialog. */ -{ - WindowRef macWinPtr, foundWinPtr; - Rect macRect; - Rect buttonRect = PANIC_BUTTON_RECT; - Rect iconRect = PANIC_ICON_RECT; - Rect textRect = PANIC_TEXT_RECT; - ControlHandle okButtonHandle; - EventRecord event; - Handle stopIconHandle; - int part; - Boolean done = false; - - - /* - * Put up an alert without using the Resource Manager (there may - * be no resources to load). Use the Window and Control Managers instead. - * We want the window centered on the main monitor. The following - * should be tested with multiple monitors. Look and see if there is a way - * not using qd.screenBits. - */ - - macRect.top = (qd.screenBits.bounds.top + qd.screenBits.bounds.bottom) - / 2 - (PANICHEIGHT / 2); - macRect.bottom = (qd.screenBits.bounds.top + qd.screenBits.bounds.bottom) - / 2 + (PANICHEIGHT / 2); - macRect.left = (qd.screenBits.bounds.left + qd.screenBits.bounds.right) - / 2 - (PANICWIDTH / 2); - macRect.right = (qd.screenBits.bounds.left + qd.screenBits.bounds.right) - / 2 + (PANICWIDTH / 2); - - macWinPtr = NewWindow(NULL, &macRect, "\p", true, dBoxProc, (WindowRef) -1, - false, 0); - if (macWinPtr == NULL) { - goto exitNow; - } - - okButtonHandle = NewControl(macWinPtr, &buttonRect, "\pOK", true, - 0, 0, 1, pushButProc, 0); - if (okButtonHandle == NULL) { - CloseWindow(macWinPtr); - goto exitNow; - } - - SelectWindow(macWinPtr); - SetCursor(&qd.arrow); - stopIconHandle = GetIcon(kStopIcon); - - while (!done) { - if (WaitNextEvent(mDownMask | keyDownMask | updateMask, - &event, 0, NULL)) { - switch(event.what) { - case mouseDown: - part = FindWindow(event.where, &foundWinPtr); - - if ((foundWinPtr != macWinPtr) || (part != inContent)) { - SysBeep(1); - } else { - SetPortWindowPort(macWinPtr); - GlobalToLocal(&event.where); - part = FindControl(event.where, macWinPtr, - &okButtonHandle); - - if ((inButton == part) && - (TrackControl(okButtonHandle, - event.where, NULL))) { - done = true; - } - } - break; - case keyDown: - switch (event.message & charCodeMask) { - case ENTERCODE: - case RETURNCODE: - HiliteControl(okButtonHandle, 1); - HiliteControl(okButtonHandle, 0); - done = true; - } - break; - case updateEvt: - SetPortWindowPort(macWinPtr); - TextFont(systemFont); - - BeginUpdate(macWinPtr); - if (stopIconHandle != NULL) { - PlotIcon(&iconRect, stopIconHandle); - } - TextBox(msg, strlen(msg), &textRect, teFlushDefault); - DrawControls(macWinPtr); - EndUpdate(macWinPtr); - } - } - } - - CloseWindow(macWinPtr); - - exitNow: -#ifdef TCL_DEBUG - Debugger(); -#else - abort(); -#endif -} - -/* - *---------------------------------------------------------------------- - * - * panic -- - * - * Print an error message and kill the process. - * - * Results: - * None. - * - * Side effects: - * The process dies, entering the debugger if possible. - * - *---------------------------------------------------------------------- - */ - -#pragma ignore_oldstyle on -void -panic(char * format, ...) -{ - va_list varg; - char errorText[256]; - - if (panicProc != NULL) { - va_start(varg, format); - - (void) (*panicProc)(format, varg); - - va_end(varg); - } else { - va_start(varg, format); - - vsprintf(errorText, format, varg); - - va_end(varg); - - MacPanic(errorText); - } - -} -#pragma ignore_oldstyle reset diff --git a/mac/tclMacPort.h b/mac/tclMacPort.h deleted file mode 100644 index 31ffcb0..0000000 --- a/mac/tclMacPort.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - * tclMacPort.h -- - * - * This header file handles porting issues that occur because of - * differences between the Mac and Unix. It should be the only - * file that contains #ifdefs to handle different flavors of OS. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacPort.h,v 1.9 1999/05/11 07:12:45 jingham Exp $ - */ - - -#ifndef _MACPORT -#define _MACPORT - -#ifndef _TCLINT -# include "tclInt.h" -#endif - -/* - *--------------------------------------------------------------------------- - * The following sets of #includes and #ifdefs are required to get Tcl to - * compile on the macintosh. - *--------------------------------------------------------------------------- - */ - -#include "tclErrno.h" -#include <float.h> - -#ifdef THINK_C - /* - * The Symantic C code has not been tested - * and probably will not work. - */ -# include <pascal.h> -# include <posix.h> -# include <string.h> -# include <fcntl.h> -# include <pwd.h> -# include <sys/param.h> -# include <sys/types.h> -# include <sys/stat.h> -# include <unistd.h> -#elif defined(__MWERKS__) -# include <time.h> -# include <unistd.h> - -/* - * The following definitions are usually found if fcntl.h. - * However, MetroWerks has screwed that file up a couple of times - * and all we need are the defines. - */ - -# define O_RDWR 0x0 /* open the file in read/write mode */ -# define O_RDONLY 0x1 /* open the file in read only mode */ -# define O_WRONLY 0x2 /* open the file in write only mode */ -# define O_APPEND 0x0100 /* open the file in append mode */ -# define O_CREAT 0x0200 /* create the file if it doesn't exist */ -# define O_EXCL 0x0400 /* if the file exists don't create it again */ -# define O_TRUNC 0x0800 /* truncate the file after opening it */ - -/* - * MetroWerks stat.h file is rather weak. The defines - * after the include are needed to fill in the missing - * defines. - */ - -# include <stat.h> -# ifndef S_IFIFO -# define S_IFIFO 0x0100 -# endif -# ifndef S_IFBLK -# define S_IFBLK 0x0600 -# endif -# ifndef S_ISLNK -# define S_ISLNK(m) (((m)&(S_IFMT)) == (S_IFLNK)) -# endif -# ifndef S_ISSOCK -# define S_ISSOCK(m) (((m)&(S_IFMT)) == (S_IFSOCK)) -# endif -# ifndef S_IRWXU -# define S_IRWXU 00007 /* read, write, execute: owner */ -# define S_IRUSR 00004 /* read permission: owner */ -# define S_IWUSR 00002 /* write permission: owner */ -# define S_IXUSR 00001 /* execute permission: owner */ -# define S_IRWXG 00007 /* read, write, execute: group */ -# define S_IRGRP 00004 /* read permission: group */ -# define S_IWGRP 00002 /* write permission: group */ -# define S_IXGRP 00001 /* execute permission: group */ -# define S_IRWXO 00007 /* read, write, execute: other */ -# define S_IROTH 00004 /* read permission: other */ -# define S_IWOTH 00002 /* write permission: other */ -# define S_IXOTH 00001 /* execute permission: other */ -# endif - -# define isatty(arg) 1 - -/* - * Defines used by access function. This function is provided - * by Mac Tcl as the function TclpAccess. - */ - -# define F_OK 0 /* test for existence of file */ -# define X_OK 0x01 /* test for execute or search permission */ -# define W_OK 0x02 /* test for write permission */ -# define R_OK 0x04 /* test for read permission */ - -#endif /* __MWERKS__ */ - -/* - * Many signals are not supported on the Mac and are thus not defined in - * <signal.h>. They are defined here so that Tcl will compile with less - * modification. - */ - -#ifndef SIGQUIT -#define SIGQUIT 300 -#endif - -#ifndef SIGPIPE -#define SIGPIPE 13 -#endif - -#ifndef SIGHUP -#define SIGHUP 100 -#endif - -/* - * waitpid doesn't work on a Mac - the following makes - * Tcl compile without errors. These would normally - * be defined in sys/wait.h on UNIX systems. - */ - -#define WAIT_STATUS_TYPE int -#define WNOHANG 1 -#define WIFSTOPPED(stat) (1) -#define WIFSIGNALED(stat) (1) -#define WIFEXITED(stat) (1) -#define WIFSTOPSIG(stat) (1) -#define WIFTERMSIG(stat) (1) -#define WIFEXITSTATUS(stat) (1) -#define WEXITSTATUS(stat) (1) -#define WTERMSIG(status) (1) -#define WSTOPSIG(status) (1) - -/* - * Make sure that MAXPATHLEN is defined. - */ - -#ifndef MAXPATHLEN -# ifdef PATH_MAX -# define MAXPATHLEN PATH_MAX -# else -# define MAXPATHLEN 2048 -# endif -#endif - -/* - * Define "NBBY" (number of bits per byte) if it's not already defined. - */ - -#ifndef NBBY -# define NBBY 8 -#endif - -/* - * These functions always return dummy values on Mac. - */ -#ifndef geteuid -# define geteuid() 1 -#endif -#ifndef getpid -# define getpid() -1 -#endif - -/* - * Variables provided by the C library. - */ - -extern char **environ; - -/* - *--------------------------------------------------------------------------- - * The following macros and declarations represent the interface between - * generic and mac-specific parts of Tcl. Some of the macros may override - * functions declared in tclInt.h. - *--------------------------------------------------------------------------- - */ - -/* - * The default platform eol translation on Mac is TCL_TRANSLATE_CR: - */ - -#define TCL_PLATFORM_TRANSLATION TCL_TRANSLATE_CR - -/* - * Declare dynamic loading extension macro. - */ - -#define TCL_SHLIB_EXT ".shlb" - -/* - * The following define is bogus and needs to be fixed. It claims that - * struct tm has the timezone string in it, which is not true. However, - * the code that works around this fact does not compile on the Mac, since - * it relies on the fact that time.h has a "timezone" variable, which the - * Metrowerks time.h does not have... - * - * The Mac timezone stuff never worked (clock format 0 -format %Z returns "Z") - * so this just keeps the status quo. The real answer is to not use the - * MSL strftime, and provide the needed compat functions... - * - */ - -#define HAVE_TM_ZONE - -/* - * The following macros have trivial definitions, allowing generic code to - * address platform-specific issues. - */ - -#define TclpAsyncMark(async) -#define TclpGetPid(pid) ((unsigned long) (pid)) -#define TclSetSystemEnv(a,b) -#define tzset() - -/* - * The following defines replace the Macintosh version of the POSIX - * functions "stat" and "access". The various compilier vendors - * don't implement this function well nor consistantly. - */ -/* int TclpStat(const char *path, struct stat *bufPtr); */ -int TclpLstat(const char *path, struct stat *bufPtr); - -char *TclpFindExecutable(const char *argv0); -int TclpFindVariable(CONST char *name, int *lengthPtr); - -#define fopen(path, mode) TclMacFOpenHack(path, mode) -#define readlink(fileName, buffer, size) TclMacReadlink(fileName, buffer, size) -#ifdef TCL_TEST -#define chmod(path, mode) TclMacChmod(path, mode) -#endif - -/* - * Prototypes needed for compatability - */ - -/* EXTERN int strncasecmp _ANSI_ARGS_((CONST char *s1, - CONST char *s2, size_t n)); */ - -/* - * These definitions force putenv & company to use the version - * supplied with Tcl. - */ -#ifndef putenv -# define unsetenv TclUnsetEnv -# define putenv Tcl_PutEnv -# define setenv TclSetEnv -void TclSetEnv(CONST char *name, CONST char *value); -/* int Tcl_PutEnv(CONST char *string); */ -void TclUnsetEnv(CONST char *name); -#endif - -/* - * Platform specific mutex definition used by memory allocators. - * These are all no-ops on the Macintosh, since the threads are - * all cooperative. - */ - -#ifdef TCL_THREADS -typedef int TclpMutex; -#define TclpMutexInit(a) -#define TclpMutexLock(a) -#define TclpMutexUnlock(a) -#else -typedef int TclpMutex; -#define TclpMutexInit(a) -#define TclpMutexLock(a) -#define TclpMutexUnlock(a) -#endif /* TCL_THREADS */ - -typedef pascal void (*ExitToShellProcPtr)(void); -#include "tclMac.h" -#include "tclMacInt.h" -/* #include "tclPlatDecls.h" - #include "tclIntPlatDecls.h" */ - -#endif /* _MACPORT */ diff --git a/mac/tclMacProjects.sea.hqx b/mac/tclMacProjects.sea.hqx deleted file mode 100644 index 099d8a5..0000000 --- a/mac/tclMacProjects.sea.hqx +++ /dev/null @@ -1 +0,0 @@ -(This file must be converted with BinHex 4.0)
:#R4ME$JZ-LjcC@%!39"36'&eFh3J!*!$MkS!!AkT8re6G(9QCNPd)#KM+6%j16F
Y-6Nj1#""E'&NC'PZ)&0jFh4PEA-X)%PZBbiX)'KdG(!k,bphN!-ZB@aKC'4TER0
jFbjMEfd[8h4eCQC*G#m0#KS!"4!!!)qU!*!$FJ!"!*!$FQ[r$D@P8Q9cCA*fC@5
PT3#PN!3"!!!f!%#cf1pfXpNG[3#3$3B2GJ#3!m`!"ImG!!#1hJ!&G'0X1#ib!!!
4G!#i!BS#U30L!q$rN!3&"rrirr$$6!!!J!#3"!)lMk@3"!%!!%!!!,2BmHLcf4f
f!*!$FJ!!'8d!N!0b!"$q2!!"$bJ!!"JGqrB!!!d!3Np"Ae4ME&0SC@aXFbl2J!!
!Pla069"b3eG*43%!N!q!!*!($[K'A@C[H5hm1MpAIYRTEGE4bNicZVdmQYR,ABp
6Z4k24RDFE,EA$-qpPEX1fZ[(cfSJfdRiiX6BC@F01L2EhLlY'r#H,(a4XK#qm-@
cH,ha)rXPqeLA#pQ%%hl,Hrlb(MPH[)YXXM#J!cMa[HAA@QCbAcRPRE(GNHdYC#'
$(H&er!"f`2J$RYN&9$b659U@jE-Xcb,,irZqj3Q%,+ZP'6kE29i29#eGQ5&l)*E
0*M,C8$5EZG51j`ZqCK6*EIT)Ab)eR,4Ap(Efaj-G+qh"NBdEl@aSh8JkRdMCY3"
pQC&Xh!leCfdl9h2Z'XRP-kR3@[Z+bc2CS6(rcRMFcZ9#d9KqdjKcIbbldFk(qZa
m2T(H11Dr+T'd3j(Bm2#ipiU44()Se,dPRif014HUUR1Xq5pE[MC%*&KYTmGp9bC
bX9c16JdQlHaiJ0A*c'!X'HSG4XmNhMJ4**a)Ejj`GD#ReP",ZjBX3@P5`bMq@'M
Y$[a+MrG%ekS)NUZj4@,ahVj3a%BVS"A6GV)@)4VYQZ`(qKlS"`CSp!1$623$AD2
GUrEk6I3*I$YcUBPUVV2I@'`Kh41(3+mHT!amp3"9m+[(+!0J28!9"1Xa4S'`(U%
-KJFU,S"BMq'#iMlr-K$X#e)$Jhf"""$fZ6[02pjmSd#j2d3",-G$D-#XZik"CMf
+#jclr"Xp-`kJq`*0pB`$T*1q8re8"Y4kJ$+S`J&ZIC[Xj"i`GCh,)1Sk9X(6p5f
$TZYB"8[AGa3NAFmb1)jA6N$4pAA"X1TAEZLUFkf4U`'NJDYZ6R1@Qf38j-CF#q"
@GY@JjVU-JCRVlB*Be@qbeZ1J93f`TpB1509mpY5r$%UZBaQ-*(*))8!iN61Y,(4
-IH)X4%r!hbZf9q12rDQ5eq([&pZ[i4m3fqrL(a6ECr&[%Y[Am1HZPI+[q-q50)q
!dL+f9d#C,EEe8&V&PS-b4fcESF`9fap#Q5Hf[iA5*VB(SFcA0LpV`4aT1a(+!V&
e39NSYNe3MK6E@k$mLYKBbk2%GM18Sm9f0j3AL1fl8&kSE6l'28CXCd)j9Qbr#Z8
iXIdkP"H*lASSai[YFe#`MeDf"k6[f',X(pD0YT1K[&KXB5JRL@d%bN[%YK2+5mA
f'5L-5G[AS5`5flp"@DaY!GEpC@*l&C3PBQ206K(E9LLRLZe'+1eLqb+8T@*Mcjf
QE8(L`X[&aVUF,VC980MMY-@K[&*Xl)Nca2CH+-[%GK-8pK&Yl1rPB[Y(+'GTQi+
A$V'aheK$fTMEf@+l%-SjBXY#)Bl4pRBSjiVYJe$1%pZI3HN8'rYQKGJHJN,FJ$3
6beD+MAhE,6EQb6V64SaF,6Efk"Ua-HmHX6([mm9f#j5eB[XU&2DiQ8@)IF3mBKd
aMKM#hLC@%YZ)DF3bBLeaQ2e(6#@Q%FZ)BF3ZBKDaLKK&E#)Q%DZ*aH`cpM$R%-i
IR$XiEh#qiFc!HB0c"ZF,CriKf($1iCc"qB*c"HF*cK(%8H)rj`A1#CbIL)2%*Q)
5XBMB31`KeK(,L$h%(')0mBSi59`MjK&cL$A%''),-B9B3J`KGK!cL+@#P5B"bFH
6@!Ce$JmR%r&B2T&*YfHYRR6HcPi5Lp[Ka+!9k3XlQcbXApTAKX2+"4(&Uje4NSR
"9#DIX5,BdG'ZdeTRjp5q$cPeG'"IXlcpp2EFTZ3JGcH)NSeP%hDZrE-5VGr1jG[
M0)jDHJF[e8E%`-BR%NZNA6XUdC01U(LEiE%Qh(fCRFlR#L%kZrZl8B"i*Th,*1h
fA(jNN!$1`m2aMk!-IDTF@bSee5Xc99Nk4JE%$`l&EGVbpY-NMP26N!"HEqC#,`d
jTFpCN3%XSD6@+NM4LYM&'NJ,Y3pPiVTE6Q@r`8Z9S+ZGeMd054I@8QGe4IAa3he
hkkl1V!lY'B*$L09CP0Yd+[*CE#'K8%pU1*20Kj!!Tl8LPNaQ-ZR3'MXjc*VUK5-
pBBc'FR%XrQM&+Xl5HcTVI9I[UP9Z$YMcZ@C*A4FPY%KAUT`i1bd5(5LERG6&++R
6@NU2CUHb6!ij,N,+L`&3h(b@GT(DSE5)(AhR89P,MkkL+q[RdC9cHFeF@iVA(Q"
8hLq-VR2GM@aY#cZqH5e9f0Q`ZP[9mLDe[$ee&pfejIEi3V[81f1[01#bZB"0#YA
JS&"0$`4P##@1p3'I#r%k!1&d8!&0aH*X1mcaJRP!23E"j[0plk2K6EXVQYkEFT[
DK(AQA)6cb%VH%#Hl)9"p#KI8"JGVhik0GYV1*Z,'0U$J4#'i%"c&K96-h)B*P")
Z""aFf'b#'aF+Z)$pJVH-#kDhFF(&KF*q3H(#&M`3-F,0NF!&2bH'$Mb5-m2Y*%Z
i%0#iS&llpBd-mj@Jb3dK5VJ`Zc![i,qK5fZC9#U6lV$5mH6)N!"Y9)1*%LkdMZk
TihJI'c1i63`PA*JMZ"$*C'dqq-iCirD4,IM'f!@-Ue)P(c'`L((Z,5afLrl'6(K
-Cc4U!1$qHMhqC(%b!q34LB5&!ffr90L"aL85$3XhfR0j$(3*ppVreA9GhlU*$(q
@4hrhq[lf3G))lTFbAG+%U$c)M$FPCDDP!hNX%5krjr-i@*!!RqBa@ICRmML3!-M
K21`Y"`Xb)bU2JfhIU!I*j&3HKkSa5USe9BpKX%XC![+)(kMXG&e*'ZRNm6J5r65
2BA)SrNpG#hNFfX'4VQaD9"i(ZXab+-m1#2R3TR1YFDEY%6$%(HL0*i9c6$DA264
pr$J2aGee5#V8Eq0#DMic3"i84D2hV%6a[b#6YJm%m83L832!MTH8N!!e%VUU('[
mf"'JY(YM2,dMf*q(-@"(d,[LI1(Ph5m94X*aLBBc"J$'1J2)cQ+b1jlH@66bH'T
RdFMMUCh&%hRmH'FaRBGjB@Fa8BrLcZ+T(F&%([qe)jM1`b!`fpXERqmcimG-2SP
%6mrN8iKQ#TM*94kCJh'HR-p8(RJ&rSXKMAfQmRLZDG8mAEc)B@q3!'Eca!E!8$'
C'J%Q![$h(Yck2&9AX`+5rdM)C9imI-IJ)XeiSe8`HV5*+[l8+T(86lQ"1Mi3Dmq
-2(Y1aVN3$H1HVHXja6iRc1GJ")m4)-Zbm2Ncff&HC'!$A[LYX@0$GRCm%eZ(QS!
(JSk5VN06k4Y%HRrH9B@1BNVq%+6TKPKEm0hR0!G2bS@XJ'+2+L5XXbidqeL&(!p
5r$[%Z$a2`$Q$JV6pcKN8T1GhcU$SaGmjJf)!IqF-#NiecKN8Pq%[Ce"B9q)[Ce"
Beq![Ce"BlmGIcU#`H(U$R%'K6UZ3!$-SV#rK,fG3@2IK,fG3@0r'AmkJX(k![ja
"i@&Gj!`+$fXKCe"i@&FjJm,$m`6N$!S26`f3!$-S2"`mj!`+$iGZ1B2#maY3j!`
+ccZJb"N8RRG$N6-S2$G!N6-S2*q#)QG3H,i!4FkJm(`CLUaE2IG,Vp(f25Kb"S@
ke8R1S2!bCcQ$`X[c$q3-#Lr2)T!!-bM8U4Gb"S@ATd$)'46HLk$)'46HLk()'44
H2YU3!'@8PkG*b"N8hQZKb"N8hJp"N6-S[$a63XkJm0i+4FkJm,)[j3`+lcHJb"N
8hZp!N6-SI+bPR%(KBhr+'43qpS1FGZ"MER)'KBpR*-JC&$i1rh)'KHqe815GUBq
V+cQ$`VF<a"iAXE&$Q$`[FH+()'KHqM8'4Um,%[j3`+hqHKb"N8[Pe3C,f[cY-
3H2Fp$%A@l,l(S-JC&(jLSUcarF3J1B2#crkA-bMml"mjJm,2I13-#[m&8'4*ifG
GCFRKMd'*L)dpbMLdFB)RhY,f,LLb&I,r(K6fZpP$L!qF1cK[X+FiAa#r18r8cjG
`cjC`jS#I#rXf*,-ZE4b6Q+qDF3K3#YKK,Ba0l%l9PDi6B3f$XpA-@Fpa)QkVRR8
MXA&9`aDF(1jKA32mjq%r&rmjq,IJ2a[r9[bEp!L(H9)R'm5IJi)IIi*XQp53!(d
4BN2K2kmij4F,X`"@'4!8B222aY,$PYQI'ldCFrA#AaSBZ0'EM(AFk&KT9VR4F8E
4jK#Y"MDqp")Zc$I@FD-IBGEM4PF[1ieXl,BQ2fjd[AFbVr'PPh""hi*8jNC[IfA
l+daYfiB5,L`SFU02FG`C6k9qL+&K43afh1K6-k(jJa[G`-*lDTVN+fhN8ESHG+S
HKcR@Tr-`6[#R(ZCBhjZ)fBf(eEc!M@ifC%CYA1KKrQ$I0l9Fk"(,'J$Q$e2JT4r
'LFXkM(iAFDJm$V([2pQ[+JqM"2Zq@BBEAC'NPXLa*lR4G4cK4[FFZIHBlm1#U''
pCTRpT`Y[-`'8mJPZG0qh9(RPE`33Ka[p#*FEA6G#*C)aJKZGDCCTd2GaSh2j4Hl
[qPRbj2iQ2c(R!h*fN`1EBkV$$NaHDh*fNl[D1BZH6ihB%jb4bB(YR%e2VQYQ6Jj
ZFRk6!jRF`H62*M8[BCUFh14(*UFj+BNGVRCb6C0MQTcJj#mRMcBj`FR26Dj[mSq
6JjLm`16#GXqaGmk[*a8`&eRN$bHh0@Q2bGG02QlbS*-MRCcTj#NRbDI$`diHCP*
rNU[Cj@JQM6!*NIm$"bH&I9(RJhCbCll-QcQl(0*Q!2%J)HFFrQHiS+Y1LJXDq34
FJZJa,ZMp(+YQQcX@+[lQVqX9e0$YPU,!CFiCTdKGATHM%HKaraGJ3TMd4ijcmCq
$Ib[q3I`j!c6M2`[r&[aRX`liqr$hiqmPTXZ@`-2+U4ja,fmSG48-UT6&1-k*$E8
fT+0[)SkE$fFGrd`FMJqUX`l&iC`9R)R$ZDKTTYk+&&SD"2Z5FMj[,XAK6$HVQ-p
H$RUiFpCVQFQEFq(XQ6LF)9YRiR$HR$-4a`h)1A6Z6"aLfEbC10`9Y-h%iA`rIcU
1Z9#%)Eiarh"HSMSprh#qJVT`HJlK$!Eeb*NiR(pk1BHSRFl%(-+C$fTMVT'p8'0
HiH`)Y6'[F,k%fTKA1)0#EF`VR&1K0ZB'cVP3'h-)Cf+SMEQ'mc28aT`NXlc"F9i
a%)KjrQ51iN%FXiV%j'DG"M+GL"bid2a,!m0"(!i"YB(Yq)fk6"j+BT)lL+20J(I
iK''RJd`P8X+&T[d(FI5Bh3lLU,aI-+NG[e'A2BH5Q1F1iTK62)KMLRE@H#SJB!*
EB0mQ1fPF1B6$%I2F34b+qmij-0)i*c8Q4c-36mb'$EPm,2XX*D)*3)42X-DjfU5
*J!`!AIjmL6'NBdr9[5@4Aa0,$bArHd[Ph,pXRK(-H!XdCh))64E#+Q34GS&PTYM
,%lP0$LHbjLXQ(TJ"f*%2LDI%cDNT*hr#kq-&PD['-J2-J,,`j+lHPGdRKdjHfGR
I#6ADdp8[KdNE8J6-FX5!"TFEiK"G'Ya`L)2I%ja[#-*TqCLC1$rL!S8AZI!DA(h
`)KGHJc-8ATb*ML8((fai)l+AJ`pHj-*VF2!K$VR`MT[*Qeai,jU*3pDH"UFIiMc
1KHIQSfk8RSP$,VapR(PZR-Hj3-f5"(UF,cL,F(iJjK0r(A`LU")AR6ZqLAd%C-@
RLEpc(r`[K$JCBP+#Q84mjP[NFHF`iK+a2mhMAR8Dih'R&PcAfpYIlS[9kbjblSR
`cZ,k`hN'dV5U*pc0b9(d1D*l4IH*2PIdHG645[0+'IRD)TPm*TY*a[#bDM!Ebel
"0#@JAh5h"2j@(-qK3b9XRVA4,%'#SMY9D4&pYQ5YNZ%B*hDP`qi[*4HB`rUZXh1
CN@aFCHI8F*C%G@VG9SSDR-fSaI)&*$09'F48GMD[k+hLlebBlcCN24qRFZ2j`0j
NTiF5Pi4i4!(l'8G5q$mK)'!81,,G-)'24"dL$Y'&L%1d)F+`+pLY%X02m#!f%"H
)#6*A1pLUkNGXeB2q6fj00l8rrZ!`S``'N!"LQQZHH6ccI1)rSqdAYGP9"pha9"(
FCB+KmLKjEB+A*ZV&bD,FTP1(Kq1&&bIZ"5l&ebEpTSAA*T9A-G8D5Ce#ShAL(5I
V$3Ye'PqEb2TPqP!@pdJ@Xm4a,1D1`eLU!Q"3qkUB$#@dX`Bq0P4`aarF)((B&q`
GeY(F)-3#p"UI-UJKrd6VYdlFGH%AGrr`0&r[[hL2#(qcYIN#AVBN0@hqHee+f$G
F-,*dUG@kY#8'3XcjYbeYZI($d[ZUeY3rIFpaIi)@[YhS8&qcPA!'J(K[KF)jJ,B
[3H&X3YXhS(#ZS1dl8)L9%"pR%-&-(c'F-`TYR!Nicp$'h$JEd-DjKV-,EF3acMU
d[4D+m"riH2FICacDYN"K60VH"S8c%@h[JF,jK,D23T&4c2FT+*aAD2Xm&-iYY1f
#)PHbq4k!)PHqq"k')YHUq4k$`RN'iLF!bc9DIXj#R0pSiqc%1BifcP#FjfKM2Tc
VD116#6Rbb-qk'J#ZK60dL&(ZmHH-F'p`KZbkPXQVKc2eH)Yj36r[1%[m1m6r9@)
r@qcRU!d$j`*Y2eIdm`5"1N9I)C[@,YP6VT3ihC,2+Y&ALrmDLGXMq[RLYeBHf)6
9Z'jXIl0KM+$Q-!&)Xl(QA"1ch"kMF+Ab&&'MqH0+C92,ID!'`,Xq'hR)pF6l#rZ
ckj+Rmc"1h"Pkq,VN[BQB!Hm905pFU6aebEVjiiCJ!mXPkp(`rjkR@UL(DI)LGZ2
%"HT'YX[494k(EJKqFMj6H4JPEJJf)GkT$L'[3kKmLV&If9i-VSI,,#XPlr80EA+
#()ZT4H2#+4SAA[Bk8di,'8VN4#&LeU*aiA6J`XGhlllKcddj,@3Q%3miR9UY9#j
IQEMR`-qr&Ak9(F2mMb%QrG+MIJX3VeRbd#GeDeN($KJR$pG[1rBj6KkZhc(-Zfd
iDepL"Hjm1`ZNrBiRGdbcmJXZq4jXmQEjH$klH+(f1q[lX-RXFcci9iik@[ZG5Hi
MHBQr$28*,Y6jr5BjS)5ciHcI"KA99GV['YD$A&@3!&j`fhLDG"kR-@rKk[[+(k-
%adSHQ+dFjVXSHEmN[dHik")UeLJjZ9UdhbG*[5V%T9(bil6Ur)iQ$`ejXHM(RFa
F(Hrhf31D%F1+JRI9%p4qEf8HQ[R#ZR!!bUZP6[r%f1*hA6'25hi!Qh"bh3f1(mq
p8VmliF$P-1142fT3qehj'MDmp$(l40FeZ)`m31J,jFGk5efrbYMN(+-IZFQNVX[
rMV'ehpI)fI2A1Yl(bH9$[M$)el%2mZKq$Hbk'`lN%S2F`hTp61Ga$RZ2['@3!&h
N"'VAIQXr!"Yj4#$hib@p9r)qRea%V!rNZX[CkUQmfTQ9hR1rjSqJE)8Ihi@9r!E
)AG3'[d6&Mpa#jkAb5HiZA6rb%)fNFY9ikmRV&NVPFj@meq19Lq"FX'F(-8clA8b
'C-'j([BdqH,SGh%4jel1AP@hGm-2f12JA!rRHr)83A,ELMMhf'IJ3'ihb"8I+Z,
F6[BUH`4b&6L0"1F#P`),0@fJC6di9-5jUlE$36%*@YDlb2FNq6d)MMA&B8BrmL*
T2!MfXaH)!r6V+q,"iUYKBer3Ed-4RajPlFK04cqm`A0`lYDh`)%mGC!!EHa6MA1
"pl,[j4RkYTX+H34AhJ'EF1cq!aiC1$Kh*6QKK'YZ'fGHMA2",R)eNIm1XThePET
Zii`KlaZfXpk#Fjri)'cNhk-IqelUfNEq,1)mj&[-5A$ZRIF6Ul6IYe&h"qFH*[i
*rpBp0aG`,M"b*@c#aE8,h'f#Fi(VdG-1,pG$i-B5R!Zmire`N!#Ghqqi1&ILGEM
kEdSi9r*EchR*`EQ5hmj[3RQpi&E*lcV@HlRJAmP["rIc$[k9r$k!HMMch-hX8H%
2'b!QDC`,I2G0X!QAf!i51'UF#lbCp4CHX3qrYB"cJ6F3+i9Ml"CJJ1"Fm!4JPF-
hpJLiZKbFqfF5P![hf)jlLr2FFF44i5'llG0&R2XN1Eq%Nq`DpUlJ`IemX#,mC1Z
*RB)(ph,H%UkbDcJM#KjFp!KX`PYf,E&Im'NaHFL%`qaDc$F1cMe!("8qXjfFL`6
RKYi*Qh#El5515KiR[3%fi6Rlh&e&R0Yb)acN9Gp1jL3i&qE-+E[qRCaMT+ihFED
3!&GhYc1fi2HCl&IK4EXGrH(8YBXeNYGqYa0("HHZCJm)ApSA-,Xl12F3epr#RID
Aa%l"ZDYCBq&4Zi1kc(0RF#B46V8lJ"r12"IQZ`Pj"r*AQ!N+1&HkB1&1cJS1cTA
mlR*aVZ6h&H,4fB*REMcfYi0REMc1,Xim9r,lGmbX`A!U[l'bjpMe3bJ,8TNmmbM
*ACKI29ZMi9cH#[c&,A#3!$FKpcf+HTq5'XiKRT[(PpNrLl![UIMG4kiqmA2P2Xj
[V5QmYaMeHq"k0QdU0[Tfj2m"!+@3"!%!!$d!!,2BpTqcf4ff!*!$c!!!,SF!N!0
b!!fk,!!!TZ!!!"6C#I%!!!d!6@&M9'0X)%e66#l2J!!!Pla069"b3eG*43%!N!q
!!*!($[LMRprPjbL[mlZ9GAEfGV61[-jSf901'q5PHCYjEAEE#GeVCYI+EjhXpGZ
dfbGCZ$Zb[*&phL,KLbDjII'[Xq2ej2D4I@4,EL(,'9q14jD"6rKbNN@bb5B,fGm
aXJc)*MZ6,'4r4aD[!GNA!mB##"K22HQ%DfqjXXX,J#em3RDk5#B,ZB9`XLm!XJ$
MGC)Q!"!qNFZP2FqVp6cr8Xplr,1Hpm&[HekpR0j@[mBA0l$@A'pb9la3518+XBj
#lTjNSM58kdDaYRLL+j'1YA9ZLh9dY$C[52B-p2FR#l%G!pP5+T-Fbqr-$435b9K
A)CNXMZ@f$K4,Z8cXYZ5q`9bKGcbp*C&)&SZaMRKTchKZ9lc3Rbc&1T1P8LVE2jk
q+C91aYVLqIa%mLd$UA4[E12H8L%qRMYdR8'$BqRAVVdY"J"X6QBR8MHNL[&L-CR
T55F,%rQEdlQHH$V@RTG*5EhY5)eYUHbp4c*$Y"QEST@Y+eE)V@6bFZRMKB0X!Dc
Xa#LdEQU6cXDb*0cH'@Y,bJ6)p'@6kE%#FNk1!DR9-5$re"K3imJBN!$CXA(6iE3
Mdb&R5c&cj"Th*0pfH'jN*%lJ'[Q6Z%EZF9`MI4,Ab$f1Dk3I`c@5*h&Yq$UIa6A
5Mq*DQ$Sjd'&qGD$$'Xm1G*KjD(,0&"h$YA,f"+kCl(&F)qX%VP(J++k&UG8a1)9
VBBdMBh!)eiE5MNc(*+k41iaV@MpQS'0EUZKDf9BG4KB5)M%jDc4fJjc#RaLl3mi
kM3h+189MMmKCVl%Rj@c3f*r*fDLaEmSj9G[%RkDabm3j5f0YiNcA@,mi-c6fdq,
-e0J[Lh1faRjIR&NDqk)iXcAf(A(Q",%DmZGUl#TajQQX5jcj'XZ+Fil'IPDF"4U
Mei8DHdUFFcAf*A(1dpLrLV-SL0A5ff+0A521%SfeLh1qaZMe!Sfp@fH0f+q,Xe4
MRaER3ShpM6JA"E%kjR1CaLi@Kj2B6H*FSV(Ea9QZXEhL#1pPBX`SXdEX)q*FVV(
2LE0#BemAjiSJ0S@j[9*Mj$4TE*-i+c9fPcM-&$&k[9TM$iZc5Q-I&iGCF&mBXmI
--@[-',2&,$1Vc"Bca5`akq!!FmY--e2-%M2%R$!cc!Sc`Q``%f!&@-"-KGJ(jS&
eB#[B#GD"F@"EL,hJ+"J,KS&YB"TB"Xk!A@!@@!9'J3eJXmlG$bhHNbZ8ZT0l8k@
QK"G2Th-*r'`aeGdR'fD4B#&9fS-[Zh+"+Mh&C,b3!##PCk#[,eRS6Z8NPNMN-TP
iYTI3RRLBP-X@FqNN`8bFcK,56#S46hFAN[dT53l65[[b5I&l8`9CES2Db8)KLmm
p""PK*+KTS[NF9p5AcX9,h4PKB,Vld`2**YQQ*8[Z-TkQUda2X933AS&3-K0ihAd
$f35e-kPL)QJ[,r9Ap49*bJYlh"e13b8BG*kACNTp%RK,8BC(r%*`lm9%2%YD-G@
IMDF*K'd(JD"0LC9bD912b)!TY+qBc,j9!R"6SD[AR-L@dKSVPZ)P$3eNCII[,3I
hKU&+kB&5-4XhrA4ZDGqj1r3$AS0V0Z'fC(CJ+0M"e5B,BAKA+YZE'a`D-I(Ec#$
X,+9-!i2P84p-#%YQVY9%c,81*S5mNL%hN@$#"i-*("bDSF&`DJD(TQ93Tf#[el+
pFdX-PU@R%#rX'bAm4RN5VlNjRdmm88jUNV+HR,%YQEc-U5Pj#pHAbmCZ6DEcAYZ
Z@-!lQ@Cf#IXLGj%f8H&F[)#6mADhYQrD&28Jc%i8K[5+ZNk2G'f)UijG`q'`E`e
Uhd3V[5RM*46A#0%N#48#ETLi('-UKkR*-5jbK(`FCK[(fG)a[R'8c"YPlb,HECa
S1mbX9@iij-iLXQbB(4ZQ`b+QFjcD2-aP9QBRBLZ9BR5h@XMr`8@%(!3m3mMr`Bq
%r"qF4mMr`Hq%r0pk182qEiZF)Im(hkEmRhHhR-VrH6NjPIrcINj1jIqmAp"l`$i
JTr*rhSIN92l2JmG5rXrlT*c+rhPr,+IbIpjIb+RmRrG91CArmlkPGi["&bVrjc-
$b[rjh)[bIcljb[rjF%6+rrQVa9(qcqIZPIrc0iUMr*qr64cPrhcQ32Nr(rj-q6q
r6acPrrb#cKUaqm44rXpR2T6rmpmMM[*r2YbHmRrqViLMr*rr8A'8rr0r@acPrhc
Q3rNrrr2L+2rRrk8ib[rjAa0(q6mIlPEj2rrliLMr9m--+rpA`f`SreG$cmT$'Fj
9qEqD'm9KASL"$@XdeLR1Y4TM*Ul6'"c`@ShPaEPHBh$2c4TlKcMV02BZFH#VLF&
"-Sr%(K@(hSNp,Jjm+6(QifD0`HqfD1a2a,P&BhmY6U['`)`0'[ZH1-bi@#fi"Lp
+$1cBV$&`i9D0-FrF16(QBD['k&-hcYShLJ0@%%Z+!ap1M1FGfcA'IF-R%`-$1M6
'[Ej"Bam6CiI'2L81md8-VKIm)AC!R*dDqiBip%lXhmAC&F6U`1lG'J-Vhk3aX!D
HQ4KcblX!BXc$R4UM6fDCf*[&!I1*[8@FESf"Cq35HdLFZ-EH,dk2aTi3*k'a6iM
6Ul'Ra@&'L$'[i#Fa-!cF)2D2iZc4'21D#Q+'fliRL$PNM,PLRTJMjSHj!D-8%`e
ZX"Z"Sqb'l)6XJQ!MHb$l(lJ",S!(l)$-faMR$4D"+@!*Zail(RJ#rS6m0cXGZ`6
l(0J)4V,2J@rJ(CJ0KV0MM2(Ki#Hi#8k$Q@!5Q!aQJVrXFq`Ui"6i"#k"4q!3q!0
fJchXGq!hqacB$JDacl((6I$mi#el&lXG1ehdRJ#F$Gm8X"Y&E`EB"GL*f)A!8RB
IGKjf(ABFGKYf'RBCh5@F""CZqqjiNhh!N!#"XYQpRfhFZrrJU$GGmRfc0p6*1PB
R-EqjN!185+pY@Y8X,dq8Rh'c'FKa8%cF@N%)[eNHa$MGi'$)3Pb3!(fK*X!&mik
TFb$28bI(cLJj4Ub##lA`K12[hCbV0[V!eF9LKNYbXYblZmDQ'+l4"6-'"KNeiTb
c4N8'BqB4Dq$+13UH9$+(5C1R@E0Nhi`Ti@,Hm,r@qNeL,4dGm[$+hlpl[`[J+ZR
RC!8rkT,(LrpRi82MfI*q3DC"0Zq13V*2j$6dp@#PpI(!'"U($k5I,HRdXHjZ86e
a2A$%"NLR"N*cl32rFa9$@!RqeXA%'RiY2U[qNI@0pFZ+-@q+X1*m#Z""hd-`(J&
*q-6H"6*BS8#!HmDQH,9c$NRC4!DD[,!Y13R-Vh60%c#HFlaS0I+!0m!b"maD0'p
jDrZ'MFYMbcHdG,@)fl'PY8Z9'e`TpX)M3fF-m4G30QB6,2-2Nq51ESbNc6#jrJp
SMBU0d"VP0A5SSQP19E598AUf)3QB$F(@39+JeYD"BDQcGEM!+EB1dJAeYJilGi1
Y`dEED1XJLc$9eN%kBCUYJlc#@EB1XJ[6E4eBX4Qf$V)0-fdGT"h1YR@3!(qBCHX
J$c(EeN%kBSkYJj6%A&X(ZBPjYJk5&20Y(@3VcV&eN!#a@'$V)('ad0C""Z0F@`F
TM20X(H3b&YNk5'SXYR@3!0YBBZXJbA'qVB-da`@f$[)G-9X(LBqPYJib)"ID1NL
&A'6V)#@bc0Ba%V'f$[)VPpJkN!!6bfdG*%iZYA@3!%'jc0C"+Z9b@iH(#bYX(H4
EVV"eN!"iZI*SRDJJ-M"0YJj5-5YY(H4NVV*eN!$)ZGV@35CRPDf$&-deYJjb0DY
Y(54YeYJkb0jFDqXJMA1GVB0mcPTE"iQGkfdGRL)ffcT)pDbcGC!!mlR"eN(bCrf
T1Xi(ie)L1DK3#JUZC%,Z1*)j2L0Vc)iD56'&%N`6-NZKa&)Neha'RKPmI&Q'+6,
QmfDPfYB(l*M(Z0E+L9Bhl'@pR!eb3Xa0PA1DR'I*LAc+$$PRbRQfR,2NR#hR($R
RbMP2c[PbRX2Hcdl2[XiZcTl0$Xeqc1l,AX[1bMl+VXNHbBl)rXGZapl'6XDqa5l
&RX31a(l$lX*H`Xl"2X'Z`"i!aS2IB$1i#kD#Pf!K1!H'+6lG+*I2R-8D2[5EqBK
'02%DVqldBrj&`GZa(a[UA5hj2$rli3$SSkeYQiVr2@HMJX+(VDeMQiS#rU52ADd
U1[MMHph4ZF-"m*LF2VSflZjUkKQRN!#(E9KKqDLC2P6DEp+'aCP2p((bfH+VICb
mN!"AqcKflIrGaiP'AZNMZIINK9JcIC`Fqp2h`FTRqRMq0NCdZ)rI4ek%UKd"I54
1h1bTHq9"DYK(&BPHl5-rm2Up$[Aa[(J+#ZHRc24aBXT%P6&356pK5+LIkR9FC[f
3!2AQ%LGQiibaaa5+KHHhMaIl+1j*Mcc,QjL2%EAi`eBX$6J#qX#DC%KH[eG80VI
RXLU`HY6mYVB1"i!i$eUHihVfBlEBqF%4("19IidMH+i2C`"(d(l,9K@NIXj'rf2
JX(9Xbjh'XM2hiIMJ,)lr5X"rF4DRqhL*XcMGadZFa3Yp[-KCR1V$[F"C(,f2-QI
a%NG`Y)mIF35RqR!)l2C*&FcqAh0ql16(N!$SYChma-p$Z!&fFY-([da`h-lXCkB
2N9emI8P6jAD[k5G$DrETmPmF(5R5k*jJ!"`9QkN6B#13!&m"1FRk[(5[EJ8Nrdp
ccdZF6`LB1hB'b'9L2'0dm3QBZp`3SS),&3(ciqqCR+FfqNYH,KCcbR&*aUD+PZH
K(d6lJEN(Y$jIlX8TS$Tc@0efY)CU3Nl+#NCeUV+#8CfUV'"8TbSV'0@TbJT'GDU
bJP'GUUaJ9+FU+aM9UFS+4R@UXS*4RDUXB&5R+LXBeDR+#NCeUV+#8CfUV'"8TbS
V'0@TbJT'GBaXNDeMT)eX(50rC1XBL54EamJSf6T'DXR@-A*-YSk4E,*eM+b6V@1
NRf`G)`pPkaJ*+9[(b%cC1ND+bYBaFP@fMT'dXR@-l*@YBk5aE"dMRfAV')NY@mI
)F0Nk4UV,eM&bAVD1NIbbGB`XQ+eMT-0X(5-[CZXB#6*EamL8f6T'bXc@-A*RYSk
44,0eM'bDV@1Ne@`G)lpQkaL*0P[(b,MC1NEUcGBaFR#fMT'-Xh@-V*bYBk6RE"h
cPf$1#lR!PmfY)LXiCXcacB'U[SRGT"*lNh2[beNMCkfFGA)+c5Dm%j`5I"&F%$`
2(!lm$0`,[!UF#A`)A)I-LTacjC`Rjh`jcj&c!6Xrqcbl1RXi1cEl-lXaHbml,IX
UZbKl*MXNqb'l(hXG1a[l',X@Ha3l%[X2Z`el#cX*q`Dl"(X#1`$i$RD$bf!ZH!T
@JS0Q(Yaf2d(L-[[eMKrqC%5`1r+hJ2SAM%&PmkZ2r-mJ@fAillh6RrcbNYmkH2!
Iq#Gi"jeYfV*Y)d+jkMHT[e,pUp5rfSR`DbJZY"mqH@#PX%,R6eqjdQ[FrXQ$b![
#(XR5-Z82G'JN[Z5I0(rD9UqM[EpacAePNHAM$ilG(b,,$KB"4GHNm1(T2LSr,hh
m2Pi4Dcl9Kh0#L2%9XHBMMEMG""hG#b,,EN1*aG1rqZ$qN!$aGVAmkN1mi!$B2eb
"[`cKR2K&"kIIVc@B2TkAm6icVkB2Ti5-0cmY0kqLrYAD*"FhqYYbcSLIPR2*rBC
Fm$U8(rNTB`&b`%**22QPlmVrp0r+[p+lfk`Pr%XpB`%Zh!BZ($ci'6H,Y+%laNE
HN!#E2@('%dkGqA'Vf$eb#Qdi4G4Tc$YHiK1'-NfRUKadUEl*6S-bR[G'ShIMHEX
dIlIQ[dRMYf[m$[fCe6XeITIkGqX@dkhqQr9&H6bi%Up(kb5dReleNjVIThAleGq
MH5QMaF1GSVj"EZf1p[DZk&TV0qrB'E*HrXb@lCeEBM`4k5R%#rXNCC@qS[I9Ve'
r9[dkpDHSAkpqJrU0kNp9IjVkCkNrAIdCkXp8rfceCkNr@rh`2ZDS2eIpDp5ITrj
mpFp4Ii(k#p8r9rhce&qNrQ,ePkKr[[SAU"p6IkRk&kTrNIV,e,pBr8[8Akhq'[@
[9ImkpGHUIlhkcHU[8rm'pGGAaV9QqXjXDQrP&mh$i9ZZrUAUAkEqjHU[82q+5M1
eMGRNB1H@pTfl*4K1m`[D#JF1(1#XR6(B%FD1RCi[5NQ0AUCB'QARTdTH,AQMliD
Q5jj2ARBNEdDPMpU[Pr2Q5ekppK(P,C+m'ZdMbPXLHA@cm[,EP9lp3`b3!()*5e'
"DJcbhS2kP'UE,1@ThRP"hPrGbG"ShZh5pfk6el!!G5R9ZPRq#FQE&p6lqAFa9d(
Hj[X&`"i)kLem"i-Ej&hjDEQ#KU$HRp+(kNSdI8kZB,(fm5"h%q4GpIILD(mIq#U
$T(RI&fGDN!$hq-m3#r+ZTTrT3Gi$[bFa&,V)3iPVCR!IV5KQ"9Z0Gl8SEIRe39l
K2JB[b&X&"APMN!$hKJp5@r0i14Id8Ira,dX-a5rbj"@&ra@GXrG*!Xp'a&DhXG[
S[EC,$'8`mMj@[YF[INTLU)@4piIPHrdAHZAHb*2j#1re`AG6@r1iJfH#[+pp')!
)mYEmUYc(`L$[D96'8"m6ZrChaIN0[DI(*BBLQGKe81p0`Ad[3iQ-AC!![)F!iD$
H-pq5"*6,a0EG`FKP5ZBGA)A$hLKjJQHP2+p++RQE*-qE*AQTdEalaIRR6#R0Di4
+hZCZF@+C8R'd[pYPRN-mHbG[je"4%l[qX6+HI32&01kF2$J4aE-(89"$E8hXEXN
2m5cc5`"PN!$A+rF@iYQ(UF8XL1dAl!RaE2@I5`*+EI6hG"R2hXIE199I'2a#'Fq
qmei!0-KV&[c6Z@pBq*6%8(NMlbY$Fpq`kM-53rQ02$"2jqmTCSLl*3qp)-@c&Y6
F8)J6ZqHGC6blNTkjFqVpaa#He4qJPP,Xke"idckfIPjLU[5fljY$H0D`(8a%F8l
XThJ$TAMff,p*$"8kXA["E*fE,p#E[R"DYl9mVaGr9'*J,r@%V`V[p4IK)e#`Slp
RK[#XBGh[J%P"h[d2Pr(Xlf6R-%ThBZrPMCMLfIIk@!b#[,GrYSaR@m!YGJfaK`A
A&-mDlZ*9%bTjh)Id0)4R&CfR!FNE`V0+hPZjJa$2SMc45KR#V5M[EmAjYZ*F*Hm
4QHHkeCP5rqJqGarldXa-VN4r&AY-lVYQImHfBNRQLEP(Si9kXJr8A*(*&k9He-H
Ml%DAbPiiQVFIl0'mb0lqAHBb)fmK4r)HrBJiIj5*MlalrAm!TC!%!3!!33!!XpM
lR,2C(3N!!"P0!!"%Q3#3!h)!%El[!!$c%!!!&DhH&`!!$3"8BfaKF("XCA0MFQP
`G#l2J!!!Pla069"b3eG*43%!N!q!!*!($[J'RFFZ"jB0c-%@[jrGp[0TMFbTfGP
hDqR#2%lBYCM(PMA$EhBVGlfm[Ai,peTdi5l(EhQH#imY[2-lFT[XFq&Z,mmZ`JI
,m9Z-,dF'Li11,!1b21%C@FLqMLq5,G`@[dbbR"(HNIf%pi3"(F#*lc`k+'rYmLc
cXTha4A,E*-Z6@`MN13$J#`!"F'Efb@`fE9P@b,)#Te[@8ipEeY04bjU)hpSH#!B
JkYHBlA!f*I,j9$C[ar2CbjeNX@4V4RPYbA3LPdXlK@3qP5ZfESZPfKH[GYUlYQj
em[E'VXjL+Z08R,4QZr**afl,1dkKiU#aUe$-CZa,R*eAC2-Gr6iDNNQR8,$MLH+
fIJGYLIa@TfLh1X9LUR0V[iqQ90UaQf%fk'&99bVGBDrC8F`RqKf8-UlMVIKBX2!
5QfLaeZNFY&qG+L3+"5I6RREbJdl@TV2YLE6GNN0YTDkX1SUP1VGAc9fiUK6Ir-B
ccd5k-MN84hm)fJ@`Vh1`EKUEQK&SaE3jN@aTYCXGP![+Yp0*9lc%iif(DiEfBc9
$*cqU'6UUeJc0ifZDKQbVp36lKN+QQZQ0cT@(bNe9dIC49"8[99J9$b1i+NkU`#S
H4T!!9C`-3kZiU'*VAq)Vi#T1KY$9Fe#&#Xr,%Dc`2&A!`V2[4`5h$SFKYY[(!-D
k2Jk#V0L1SUbi'B*Ccm(4iKN(@Xr6F2(d3ke[2&aC9E!9$e@dKI04U+@,+Xl5I!4
NkD'+X$3IJ9Gk'-C@fPH"Y6[(&95PKb&)GDfVN!$JZML#"kkE#KLia[h&VXTX'%2
,$JB!9$NiL*id()91qKM#6GIk5)@-)kEVCV"#qV'bC$PB1e@8T(Nh4%S8YX+F@+T
J@Z'iM$M2*86Ri3q+VJNrq&2e,XFI&Yh[i+m4hIhiDdAhHI`4d6f,Re`V3cX*`J6
4,B!`8A6[J(#Fk+k&-%PdYd1B,,V23CJLZLFK60@k)11T%peF#00%Gc'%idA(R%d
AhHp#1%&d$d-i8A4IK-$m82FY##GVABKqCiMZ!JLRL1j5#$0&pkX3CSRZBa"QLqk
c%1D)lQX3hU4eBHEX90'G"F%@h3B)EaCG!F*E4(FcK,H+lNmJ--r8-5E@+FZ3!$A
j0Y(4jM64VBF!hP[T-K$1%0hl),aGG!p!1&0dV&hQK,V[3MKEkfUCPhV408#B,lT
h36K(G&G$1&GdHb#F*cV@l[QLBqfbMJJ4a)i,4FGm%41S)pjF*,TY%"D+lMS)Ld4
h&i6&S[XV#%Y%pa5%T9SA*EiX%ahcXPadV,-9SZ0X`%V4[4m#Fd[GI4"@LHi[)$5
+lKN)Ul9Z!ZYiMHKB-m`EGDd3eSSZ"f'Gk+k(`(UNELm%BK4eM1m5dE%qBPTRB(Q
X!H)-FBpi4j`MPK&2LCI%0q)%mBai5b`QGK*AL@[%-q)BDj'i4E`L6K'I@2r%Dq)
aFB0i3C`J2K!AL%2%'H)#mB!i3*`LKK&cL%I%!q)!kjpechTRRE1q@GHXCq)FFB`
p$r'"'-6HKMd0HbMf51aTf-Z`Kh&l,2C,a%2f-ZaKf,Z`pf#[`Kk&[3Pl%[BLl0(
F(X`Jm!l3DjI8&lDPfkh&LhYXY98aQ9E-5N1piM)@eTqRlACB$A69UPb"%,HD@f0
fmbBKi'!J4!h0&'-ZPK)a25)FL2P%2Z88k[rBDJDc9[*V0b91[b#eC@(('FV9qXk
LNhph)XR!*#ADpFlkT0@mD3Y#mG+acNPd12RkA(+EPljNEqTYc3KDV6X,45F$NN3
bB5(k6m#95TUE&*9'b5$)P[V9XGMqc+T%T92YQ@`aLf*#j+h&V[Ck@1M5+T91,TF
X"dJPr8Jk$miD9#M4jaNJUe+rUa,TG$EEDDpcdMN,(&'I&am"%+Zp2T2,jSZf+Yh
iTQle*PZcFk+-*`T*m'$8JXlb2APa-#mPak)8ap4U6X[Dh0M59)T!fC8$8Nl,h*l
S2!j5'hL8@cI9fdIXpY#i[D4Y$dAE6FMZTjMlq0MRqFGZ4XiRCrG6X4ALe8Za6kV
f8ULpK+QJVNpdlUFe+b5Q9cmZ3HR6NGhN)c(,a5X&E@F6%`Pd!+Db*3eKS"&3!H!
j2YSBRTr,rj)VFEN*mLFZrd[1a18Hb(Zir#qj$jIr[3brbrq5ra,q9r(&`[pD(m%
[r+re+Ic#reVN#SArYEk!ArKIkj[iKIqe[SpIq0m!Z4,KI`2NMB6r$C!!pa(q0d$
Z4[MI!2-Nr'pJ#`6KI`0E)3Mr'qL#)2a[i"S)`[m'ES3Jr'rJ0UN4kKk#)2a[J&b
Nm,q"ab!)ra[i0`M#r`Cq#%(iAc@!,2a[N!"qKIm0NXF5rMG)[NVihb$j*Z&rJq5
JKIm0GN!3rMG)lPMihq!Z#-,r"RG$%2ihH!X%iAq$Gd)3rMIiKa#%r`eq"S,`[m&
()3Mr'h`#J[#r3HC9q&m&%F,rKPLh`[q'@!2#riBBTr#r)I*Y`[q'b*m*raXLIJM
r'pS13IMId!i)`[q'1#FJr'q)Z46q0h52B"4ec+A`[b(Q8[MId#-3K2m0I3@#m,m
KFUr#riBiYb$mEjL*&Iih6#`3rMI-QK6q0mbm#[mECZk%r`h6Pr#ri6J%iAr$j-f
&r`ec2N(ihr!9%-`Yr#pVJeM1HQHGqc`YDiMi6,`NCV0f@$-Z0d`-BLrLBSh,kl,
1L9A%(')0-BPp"c'Af-PHJ(M(qLAq%1rB3l"2)4DcTh'j@2Bda'6L,'ZI'-YHKAK
-,'A0%arB1lJFFKpR6#`Q6V!A)%i38pR,%$H*-qaaT+mSFGcXRpJI%92CNl(r%K`
h#Mbhfc2(2r3$LJa#9hAe2LVf5hUQKAe$,GUG-0`&T#8h`$dLacimL#'&#mBiB2"
`3IF,DKi+%e#,-iQNd3dM2&bS38GTS1XM`5m%&5lSDEV@VKaR!%eZ+1(K3SKm[Mm
)DQCp"kI$$5[2+-FpUmGCX2*b9l0,'3!ChB)`c6f-&CB4-U"9&2&6mMh"3Rh+$+1
40BRkE0I,Zq0@i$A%iaKd$HcDc"(PealM'I%3-!*%fIdQ5i9-![@NpmS8kVQXkN$
S"fakd(Mr-KmM61GL!(KEYK5+LEcKBF%KJ63`rH$fRCmmZ)mTRm6IX)dAZ5049rZ
KCG(DZ39E)iN+e)Zl"1-qN!"`8)mNqRmmMK[ER%R'6ah(dRmC+F!D-lA4SAp-rHM
Bi-'q`kdAR59hfB4ji4'(EHPb`Z1C0-@3!!aKP%!)2hGC+)a5P4(3DbFL(rpi(Ij
(2UP(lHepqlkc&*89(L2X)lSrI28"VY3k-M0!("YE0mS5L&IMD&ZcZDfq[Ep9G&r
hFUk"Tq,)Mm6,[9kM,er)*md!H68(l'lDN!$Y(*RK#$3hairNrHMMISEp'm2khQc
c"!Be0mGN+FR3keh@9RR0mCJX+hNYMNf0XJcPeEbfV,TBPZ!-[GkYFj8AMf80!"K
NX-$k)bMG[BE[F"aRbV+Ieq-B5FKraM'BpTr&F6L3!"ILF(D-*'6mU6K'bRiX(pb
%Sq,JZXUAib$akFBaA2N[a'%%k$P9(!@(5lGHH4hC**Ge[I+)dfD&(VKh*fEP&E$
id``3"empLZ6RHHA@+K9(GX62XIj-aB(4hCmhDD`c&FGV4D[kkEi9SAh2r-%!),A
p2PjN!)EL-!B`!)D"MKYR[,`HLk'KFaqXXKFlpl%iIYbjMmAaimlpD"crhVQ2aQ&
Hk0`(m[&5jci3adZGqfJF"S(1IF5(,'mqr,MCH66@rGZI$ccM"`-`L'J[-J"9C$3
T-!$(kPA&BC4J!+b)RN!b!)caQ#$'cG`eZqDCGfbQ96[5+TX$6GUJHa#Y0%%+Fc9
,0qk(KL'j-NUL2C!!)$dc&5ll-6F-`"RIRhPq"E"Hm%YZ)STjf9TCj*VFPZ@p&eF
QZ)b[EE[0lChU*!kcfJ)QEf&RT'H4keDRdmQRc'h,A0p`)#ciPFeD*MDdk&l`Uh#
K0@D'kaNmA($jKHCXhZ'"6NDf,U(m2&bSNGNqY3D[0((A2`ASlRJ6ZACJ"+rN%Rl
`@C&a2c5-M[XK[6kKl+Gr"JG@A$BhF6`HALach,JIAM-cDA3d%Aii9MSf`JJr[*K
QmVJIAPmcCG52NIQj&e[j5cMe+NIG8lJAlCN,RVV+51mS9EUTb)4F8P9jGA!NPdd
prpMIX(GKAm*if"Ha*f2raPj+pAXelTj8RAI9,V*$,0f68&d0D$apPFX#c5V22(G
23QPPFE8RR'AH@KGVQPcc1KD(GeKR04mj(+9T#)M$1,&f0TFl[1KY0+pQYr@ejS@
9mY@c"U,QT,-'3&mD!%j"-LpJkl(hK["KCE(KlUJRYG#iI+T6q*5KXljrp%VR"aN
$hY&6RI3c#Z`&d+Fk"D`j!`HKkjSi&(62P(#ilcJKfNhVUE&ckq8LBR2+3rT"5kl
[6"96L65Z"Qr+*lCQR%k$`M*d(AqENmqN1K2&r`PI0936p*AQ,IplfPETV+hA6h8
bS5fP"aD-(P(Q(dQQIikBE2kd!5%h!Dp(qqR4@%%3,aV,$$"VA8iiVE&PpCV6l00
@0l3e3)b[Efb6Sla0+Fm-YdaF,fM6bk&E8aN`*$CkGI[d`VDcFlQNLH#'ED29Uph
3mB$@"+$,I0V[$fShr**,f*Y-AQQV8(9fchMkHQMb``0!TT*RP,Z%@cdMlT@U0HU
X5"PTNcF-QH,(T$&IBC+EQ!!bb$jSe3DY`lqH#Y8HbEXB[aT9p)eQi$qjcfJDIV8
(T-E$PP2`Rp6Vb4h4FTY4,S,PSPFZBI8A`DV&d[Kj&BTK)1N)N!#arAI5iAUb(Y$
X5lVR558GRLEK+P&hlc45ZV'PTFh23fMYaNYG'MTBelUc8(3b)'VEmiPmbZ(qJ'M
6qYJDa"%315Kb515`b$@886R+(V+bKecM"4LDb8%)(Ge11p(CBEGZ5f0j5@1fJfY
V9!K-QFJ4N5H,l+DLeJXT2"NKYE3ff)9X9clT4c&"j10%RNLCECA)`6De&N1CK5C
I%4Hc*5)[&AQCb-YI1L@fG%BXUiH9`j5bFPJeV"LQP)PKXTJSTPl1MRAK38A,SPH
"q)[$@Gmd!M#9M+S(U$lhX'(QK1'!0A0J,VT-d"lX6FeQ4`ZE$bDKhIPQ%mMJH26
JXF,QPhd!H1Lr4JpI0JpXPRMKHIaEmEfe[l%h9h[Ye4G!b8Sq#rrCq1Yr%Sp#J*N
8CP'BV6ZKBAV"'U3AZ*KHj0UAk3AV[qJ&)V92,j!!Lr*$q[rdJMN$$I$)*F`ACZ-
F'8Fi9bL[ma3PCPRRLrd&BRqKk"H)rL*TK4H+h5+Kf"D,h4+4PiVG-VQVB,RL1p!
m54`VTFGZ%2dUmGXSmQUjf@#0a0%NIYBD2fD[Jd'e�%LCRN&3MBpaai6%L(fGC
akhCB0HXZ$daDX64J*A"8d*5[`8i1e*l`2H%SBpE#$9hc*pTC+cSh2RmLrCadUab
ea8U*J1k2QZ9QXV`MPH6BX6FS$%GY@8DiSlBL"[kMYVTjTf3fNdZJNc5e23mADXZ
Ab96h5TNr,T-aYGb%B!#mj@!X$VQBC5La2ldSCM31im4Y#5pF&0-IL"R`4JAc`Q8
beHZPc"phSaKBVTH+aeij5D+8$p2N&96'LDZMM'cA3UNiMYb0FU`r8h%B*Hj'-5(
H*Q@FffCCINBjA1!'5)KMPrE#LVYraLlCK480Marh`q9"dmIpF$I3#H0qZ*9bl(*
Iq1'@TK2(iq%@Td-AqITqZ#eUl#*Iq1'fUN-AqIVaF+RVSBYmI6rFR(35YXRUh2I
NmGFp2paLGI+!Rprm'9iB54m"F@Eh)G+FqVHX13pqkIYIhVI[krr2N!"64DD50dX
Zc0C2ii,pi*GqF+&PcA[+P&0#KT)h@hJ6r63Z")%,$I[frIjl6$NPC#Kjl#Ae4N[
)$rl$(("$Pie0&jVDAJ$lm#GCQ8+aGi*P-Zc#Zf$A1l-cE5pmdUkcafikr%8PMY$
AbhDc[$KmZe1p1(bl0p0IA5l[[0Z+I2Z2Q#"Y0fmKK+LbLkjM6U3IRXFajTRDlSa
[3#I%iVaI"09jREEEm9NBb'Ekq9m&rAL#Y[[SFc#3!10#9Y`%Z[J'EEFV!32bZ(J
AIJFTL1Kmr22e-*!!LmJAr"!TQ+hpA8@XPB-C&R&AX-3A3blGkmJAFArd4'dhPEl
deQ"Vd883*ZRirQ8TG14GDFFCTbRDlXmr3apLp`[)4kf1if0FpD1h!eZ,0d&BV[h
G4Gd8XEZP&%HdmAh364@lfa((2fUl$li6"Kbfa&Yk&B4fEEGR#3YHl,j5cZZ9Hk!
lAZbq9FTVj"RD6"Fle)HEel[ZTfpYYr&8#(qYiqKNEC`SGNmM(c1dhC)lB+!1NV#
Xfe&rePjYGbXj-(A5"0BMdhHpMZr,pd+RMN#`V$YZ49hUZ+1E@GqX4l`fc(h@@*Q
LQN(cb1aPGd2B"6[Z@I$XP[-1U6VBTAVX9R#f#RCTcJ,kG[4[CiU&h[JZ3p`ZRMe
(R&-V`4(ISM+Hl5(fULhKX'XSipR*R,q5DpIIL9UFmV$J)ZhQD,[mH58mLhcMRf$
`*Qfh!p2Y,TlYCUbX1mEhMM+HrIhI-QIDl[T(bhJfjGX%BQfhRI8YG6rr2ZMHSZh
5a%("XjZCSlH+(I&#k[jKjQ+ZYV[KAmYipTFE#0"Lpi-bRXhJR4G[dhDlLHmDck+
rr6Kd-JkcQhJ[FI`G"h,Pf[IGL-R&XaQ-6ql)ZT(fJQFVN@2Vl@*(,*Hm"Tk&6ZD
#E`4qZ(Mf(1Z'ZppTKhj&mKUpk8RSL1HdHkL-CeF4[f9(r!GqVBaRPc(QqGVZJam
Ui9RNL5p!*eF!h,5mK'I4UF5$Fm81H#*i&[RF%c"![DXk3jf8m-`E-RN2kmI&-pr
Z6Jr2I,Y239JTZ1AE%AIR#XjjGRIH!k%V8qL,ijBGb)IJh02N*-mAI+9r`EPTV"A
Ze+IG&5@FLhccFZM!CI)pK$kNlK&YGqqP-&LJl6jbAEP[QmZphZbEm2i-f1$Lh2Z
*2H`6m@llD!RRSR@-PE@-Y`GpMiYc0l((N!"eDFXq8-D$@Fp!apk(I31aA("ZaMA
3XFCTTiiHdABV@0[,a)lpLH$6Np```EV'Z`IpMiYc(fEZC,[m*pN250rf2ICba$I
L1ZfNEjYd,A6X#qK[FaRRhX[EZ@3EaVh%"F'j'fk!6QCNErr6FPirI"YdXUdL6eb
8[&k$RKMliV8rBT,Np96kN!!Y'IIHA-+jb&Hr#peDEAIIZdSi&hRfmc!JKZ2GrbX
PR)[q&V&)h@pL@AIcr!(Tfalp"(3mi`6[Lf@FLiECAmVmp'-hHMMR$3hGaAl'a6R
2EKPVbm8jcqlZhF4D`6-rMYrcm-chaal)lHFmZmH4MpTBTVLePmpiJ#1cdc2C)Z2
`hPl@rFTiV&"%AmZH3@DTRd5[&M`VNb[!Rar(JkcT1[!LR$Ifqe6@fqQ`kr0(RGM
jl`(@EPd'mmXpGRr!IZC[-SQH@Hcr!k@3"!%!!$m!!,2Bp9Ucf4ff!!!ZK`!!Eq8
!N!0b!!pI+!!"aSS!!#VT&I-!!!d!9'0X6'PLFQ&bD@9c,Xq!!!#A[%e08(*$9dP
&!3#3$i!!N!F'DjYYeVQ`Z[JYC1&N1C-XNPXh1El`A`KIM[+Hl-MaK5mR@FL1G[D
,p$LpcAijGS3[4ik&TiEI6$blp@h"IhbKY6aC1&R),H5@)`YIRLhfNPZ1,fr(Pj&
N-A),@GKbM1b1,(`CN!"Eb%*ZN5bF,#GC"V+GmHA-MZb,,**Eb#+jjIh),a5V9D$
eM*dYE$1b(#1h,ck3!!#6AmKi)3YCb%*Z)Em32,R94Rf'$T[CqmeYC$DaYh-ckla
p6T5ERc[Cj@EbJI[LZ4brjI8bCjhj$4`ZZT`4[T!!@b5hm)9h(Er&Yb1rb5Bmb@#
lH(kpN9[)m52(Pb2,K1GbC#%l!E!!!QipAGRkCCjeH0Cjd4CZ@B4I(lQ&,'3KR2!
(B!X!!CjdHU@p21ph1TdpRFl#[Cf&AhkUXh$ahCh1lEp*cS-,,eR!p8pp[TQH5)S
Lbi[ZHT'I5A[9,0H0F[D0HMqeNQd85A(Z`32Ta[MdkE6S(Kd2Ufb3!&j*EXl(45r
Y(Lr5Y,b5@$mZUhc3I90klK[bBR-hYklA5mZbZjj8@lZ*Qj2LG&TeMk99P3e2lqD
Zb[TTGc8CMDjP,KpRrFhZ`HfU5(B6dbrRhbZE1rH"0hA9jD[6iE@m&9QCP'8kf1L
RaEANeIem)qPhedEd`Zl(VKGBR`h2ANmc-**YNQP,pph(-q`CmEJ(5rUT#S2fAR[
[qZ99,T40D8akDmHkUbR2V0TUEpUrNYfd[[4[EdeHeeZ6I1bY+A$SV8PV1VMmbCa
$lkrbkXV"p4IEP$l@Y-AF"mjq#SaXFKD-E')HM'aZ&SaXBKk-E1j"-,+C@6!kr()
#4MEAJP%q,pZJqH4#JqB,5)2Qdd`cCT[N)"LeTDE"+*[UJj&0D3-MQfh"+*rApGD
(`5KIi0"E'c!Uj"akrb`BfF3X')&5Qh[pBeYNGe#MG(D"'k8cfmP41VR!MY+ClI3
SRGc'Mp+T"B,8pS!"3dSRjbP50V(!'l,CKiP$YN,!(,*jPLCNqU@0*q9bXd3TNjY
K5ZQF$UU86XpcT@cLN8I[BN[C#Zf2E[R5`D6f6LJ`TR4QMM+Yqc4+CE0cT#R)E'0
03A+10J@CEE`T5-i6Tb!eajcD(c"0RB,NJp`TPjJM&,RX3i`L9b&0+A*j'IjJqb9
2S!Uj!B1bZBC#"6RY(#T)2dLLFSP((Vf64Z8UY$pkKNMPNpSl)8HPJX`#PfUZaK[
26CTXJ3+MXXRYT-VQ&hL96@kR9MDrM9hCl!,"1[bU!FHbqAQDPFmYN!#1I)($[#0
I*+!Hq94,0,)0eFDkfY+ca#ZERZ&H0Uf$IYN+H3D@cch@$edm,&qNXamX'b[NGIC
*JC2Cj#cJb3dU*QLb2L[E9SE+,UjM2N5-a%BGQiY9rbIdfB501rCVf)4M9f16MYf
$66Rf&@b*BdpK5ahlHfbCVp`$"dZX#UIFXAUFRSkGKG2,X8YaHMYf-diIaql(kH[
Beh(k1IBd6Rr(AX)C8-HLVm!Ck0JdR%'1FHr"MR&[kK!$ZiFkGMh1--Gq(fHiBpr
!'H(BAlQ2L2dVcUJk&Y2p4cY@Je2Kf'UF-BjYaaRVf+rMM(2XGTcaMMf#-m'a*h%
Q1[BFcU3k&PII9MV'r5Fl0J0RLQ-EFDBkYJZ((L6ffcM9MMf!`eX4qe-FqS8Bpjl
Z'2IQAX!#1$,6-ITNPQ2cF@Bl"TE-FH`Li`ba6q$-FqahFDK*l'Xi#aal"UI@-AT
VB4e,U[mA1FBE,AEXI6K,(0Z0Xp5aUh#@1ABR6TeMi0Cbajl!!41)r4h1LMU@%Yk
YG)bHA18B2Ve-l&bF0BkeiM3iGKh1@XGiih@1m5pT[@0rLG2S''qmSBk9#,2S@@+
mFC0Me1@GLG((p"Ha+h'D(H100c[f--iCMRd2jdc(`-JYGDa81,[9-A$NrBl4!ap
`E"X11%N-M$cEX8rKR12B(q$3#m68rk[)+FGH`+'q1QAL&5f1JE2R1`D1J)I%H1-
,(0Z*Xm-aq!GaB[!!hTrBicJA1[BM((TIR4l#T`mk"KE$CBL"(I`A)mBllR(X!-j
Haql!!Dq)2BUccl%Ii(cBX4GapYHaFZ%p[8m-(*3C3,Rkra,(Z$1mKYJe1*FjpRX
ih*dB1234ajl(q@JGkkQhK#-3JfpFlKMiq$((k1FVkPMAJA[!1H!Di"RF!Lj$Im!
Yi"4J!&b(rS5h'%i"Pi"$`"hJ$(!&X!PZ!#H!!r!fi"$i!qk!0l`,Z!CZJ62J#lJ
#lS'*B"Mi"Vl3Mq!*1!*qJ"[J"6J"2S!0i#*m%ji*[i4A`LIK3H!eI")H#DiCIJY
AKFI#)q%2m%Ei)Rd,eX),iB2`3(S0R+*I`3B`!5`!!m!F-!8-S2ITH6!*[!*I`"j
kRjkReqPaHTZHTTITBASA6!1ck&pi$CJ%Mi'r`*IJ3r!AH!Ym"6i&4X+0i%h`&[J
+'!dr-A`%(J,r!(I!)IL@i)0UZ#fR'0QZ5C20Y&JFpEBk9Dr2j+kZhmplLce(klH
5i5biF[MS,,ELSD1cf+UP`@B69(1[G,"K@+A&H&60%hBh`CAEmq#'[-VHFQi@9T1
fhFdc01HpXl2JCXE'kH!C`fbl#9kFp@I"pARL9kNVc`epPq9*1Eh@mQc)m-k2eCp
0QQH[*b+h93pEGhJ@DPLCK4SIGXJIqf@#+lG(44eGN9615rI0bNI6S9pmjAED'dm
,C"U)lYQ3!%cIGhAUDQZ5FXX409'mD2TX$F20G(YYim`dUTTYRf-EThkQ*aV@CYG
N-QSLVGAX"TQ@D8`bpcf[dHTEf4j0&fe+LY,[eA6fY!2ldc)Y(TfQlCqf9P0HCY[
(+RH)#ULaF[SLp,9NCKlYc%3THr)LI3ZYdEUiQIFk"l+##D[UJ[TmT0HJD8bSHD3
ZE&(IV"VhHCb,e6L0e+G+Uf-Vd[*XPBp@6qYbk@4rZ+mb@UYLf%[+Y$I``aY39)N
lp@["cpU8PRPrqXJ+FBMcH5'$"UVKZ)r'J1hj*UpY+Zp+Yhdh9I@5[[ZmZ6H&@i9
V#N"Dh"NA&X#dDBfG$4*H@$K,0f%'HpCR3%',@QJr0peIj-T6MDEDTRNm'Z9&aHb
Dh1dmNP44J14(G[,e`M6S*4X0BX[)@`826-&L3cj8+GAZA'4h2dXhZc@ML2!m&I#
,##2q(89@aqJd24K[rD,*`,bPkYj0iViTB[[cp!b#5harTjpY$2)URrSD"66Fl8a
kUCkbN6lAI[2+p'H*'YRA(&KCQD6SMbQ59k-kY3pUL%m,EHphUD#69+aD9G8YH6k
6qNLRlVr@qU)QVi*5qZ0,8%TA9UQ0*haC99)q5H5I`8r6pjE(mc-UPT0lAjqGHQ$
c#bHjkGE+G"DApAr*+!kR[KM3*,[j,"-m6Hl[X2hUQ2e4P[fiNrrAS*V%GS6+UMJ
b%(ESPemZaR64N!"(qG")lq"r&5&6"CZ5XXIh$+,UFd5NrMd41EQdYVamq3lU&iB
0kqZUTmTI9lG2diNVBA0K#FU&L3DA)U`IFIlLkaE,V6jpVi26hAaq5UfacI5pqVX
5r"la%i,[0GN25[N25GN252N24`Fr''8r&"@q4H9r&18qkZ3qjYMr0)Ar-iIrb`3
[E2l$f2m[fImZq@q(pPYDi5IDiFpR`Aqcp"8&&rQHP)G3Gr*K0XQFNYNNr`6Z`Yk
0j6r2[9MQkX`cQ9NbEqHI"Rm,Q&IIJ'@'bAqF6f0[aGk(jCr-,9Mq!M$2[!PVCjV
-G%&irQ%`"c8cAHDpRm4HLf@@bPb9Q5KcAQDZc)'CJ6)6CHl*,25hX-aPQEFb3f8
qbam@jUV-C(m(+l0a29Iq12BhXFaTQF8bPrd-pMBXrfbBmhm@qcNXXr22BjRe-Tp
QMXh-fXbbQD0q!FZr$QD[c'9[a*Uj-$2Cil0PjV6-bCQY-f0RCX[mRENjFhEQm-c
FfqIdc1HCc61M0r0ijZE-j*QT-lGQhXhXQPNimh&QhXc%QCFc!cGcGHEJCRE1r*M
j160k1cY[Rr-cHfI@EqE4c*LC161(0R0RjYGQlXqmRKNdFhlQrFbZQ@dc*qF[`'q
d,+#IkJlpq8eea4hUr-Lhl&ce5KBk#j6`F0*lJr`%iZN8[j*I4kIeR14kRGX[cpJ
KZi9Mlf"1SVk`[ScmYq1q35QGUar"eUIESl-r$Yf[ljJrVl+KF[,M%ckCK(bRa$j
U*m0609fY(53prmjdXaf3!11R(1A'GR&K9rhp`pQ'$3%Za'YFF1YdMm[N'&a32$)
j`3A(6[Hi6%l!&a*-*$b[%T)rLbihP!Mi!K0ZK3[0+qe`R#(!KGcFL8qc,5eZM#(
!"CNleFjqqE[GH%1!#`RpH#[mpRDZ(VXM`Y&bR(*r%[6KYfhlRe`A5a[)hf+clY-
PGrJ8R`l+*r@Z6r%NbDGiYB!JN5cQirpEL,b88lHqcKS"lr'6@Z6`lZ%q,eI`@J&
ZQ6f(9`1`r+MYkSHUQp8!IY5Xj6e@dVeccMY99NR4mV#e@`0TDEdrIH2riQ8D+d'
,H*H6qXRNMP[HpSCpYpa9GMYlTB3PXfA#[rIKY4+TZS3$!&YF%)ePeP+lCdkLXqH
fbj[H$Kh3j&@fj#3ih[c@[eK`dZ5p+3iB@M6JRU@e!`I[kGjci)h(hiMEG'6TZ2H
&Ze*1X0bLX0E#pa+AGrbiA)lME["RK`!r(rbe)BQ8-fUF-K1YG(SkS$PIGae@R-@
L$M1cH06KdI5-j*8kV&0,4Kh@VD@L$M1+NUM$1VI5U-0DYl+SSb8jG0GK09aje'&
eA-qS`hUjAP'(&A5pS`kVl2T%(9EcpBdkV1rV&h9BmGFrkV!'F%$8B9AJ`+M$1X&
"8BH9Ji1M$QX*Kd3G9KB1M6UX0a`@G9Kr1$cUX"ja404KKH,)U-1Da9&4Ke@-Sk-
1kaSVSJiV(FG%(GBqMSdkV)BF&h9B(cNqkV"LFN,8B3hPa+M$Z'P5e''PC@A8BHA
Pj+M$@X`T8BHeQ91M$QX`Uk)1Uc+VS`lV0'ZL$LXhTd8GeR*1McUXlC`4G9MV162
UX2Tc9Y4K9HMXU-2Dd$P4Kh@LFk-1UdER44h@NFk21UbJA4"eq&aDHk11,FL+h)9
a(pES,SSkV0TG((9BTlXNkM#$AaTe@-Zl,1U`,VFZkV"'GhR8i309IG4K0Hf+U--
Dh*94Ka@qUk)1UheA4ah@jkk*1UcAEBJkV1"G'hAB6EXZkV$#Ghh8BEe[Bp4KcI#
'U-1UiBe4KaA)69'(9Fl[LcUXMGi8G9J2hGc8-HTj$Kk9c[VScA%I9NbI%A9BVAa
Qe'(pmTDS`aVQV5r@F3BGqSRj0Q$"A0UXjfC@h#jTaDlM2LPGK4NGmcGQDrqe9Yc
)IMNTmm@XrBEA`pRKifDY0abjAG++PE*b8VS+h!6H!DH!,m!&`(N`((aZPaKcr)"
cfp5!B*kb)"f`&m2'XHJC5Q*6@*ClPf,,X1M)B4%Z'QakBAYMqf$lB[YKqf-(B!G
L"f%(BiGJKf+(BBGM4f"(BNGK4f-VX'1`Bl(MX11a%l!6XC1`PGM*f#RBUGJUE$@
f"MX01adl!cX61`Xl'cX(1aFl$cXIZ`"ELef)AB4G,1i2ViHc`mIKf["S1$,m&fi
,Ei@6`MIKN["%1#$m$Zi',i0c`DIJ5[!J1!lm"@i#la"1mAiD$8bTf0RjjhrBC4*
V,3FSR3@ZQ9pqB*8K8f#3!2Rc$,kBMb9JKj%L"5BB+9+XYcGr2PRMEk4))3P!T%K
T53-L48T,!"!T8K&*0")T8T%,aPd1FSe%LP6N'H-`"mP4)N8UmQ(M-ZHIM-qFRaL
RH@VH3U4)HC-C[X6!C*%LTD94L43T6jJU8U3mBDC)NI+%K5*&bT0%!T%Lj8Q#J%L
4mL4*3+4)HC*')&+N2-Ni%#P5RL3EL"3T6a)34)U8*cP#)NA+8aq)&#P2I5"5T$c
*&")T8PTkPA`Yp$k))e+N2-Qr%LP5hLG`4)T89,dY8U5LkL@4)KA9qiS8UDMZ,&+
NSZ)G)N8U+NiK8U5LiJiL45SUEL"5T++53L"5T+,U#C%L&C8m"*%L&CAX!*%L&C@
X"C%L&G8DE*%L&C@d"C%L&C@d*9ND%j9X+*%L&CA-*C%L&C@m*T%L&C8-*C%L&CA
m*IR2UL9LL45TQ2"!T%M&e-mL45UQRT(P!$'pR8L4LZN1)N8U*QiN8U4L`J#4)K@
6Y!H4)KA6IKq4)K@6,!D4)K@6I!I4*4#6l!@4)KAl@4b4)KAl*4b4)K9l'NHN5-A
dhL*&+LBT6#*&+[BK(*%L&IXSMNL4LJ[64BT8A$JV8U6L`Mk4)K8A(JPrLk[R4BT
8A$dQ8U6LkLZ4)KAAfiN8UELN,)J8+5eV5k4)a5Ah3D4)a5AA3D4)a5A[3EK(A$d
Y8U6LHQrj"4dAcSN8UEM`AU4)aGAI)N9+bq!5+9*aBEa)N8U)!iJ8UB6`9k4)*B4
h)N8U)G`4+9)*pE0)N8VSh8@+P*E+*9+N%T*()9+NY&3ZN5+9N!!d-*%LPC!!"#T
CCCCi$ij)N8Tm!%IqhbH%3b*&5X[T%LP55A%UN5+9e2Z*&+QNq)$XL%S+Fd@+9&)
i*&+NNX)1N9Z49+q+e+5NqN'N5#AeeL,c)DNhN[dD58Qj3&S'-EJ)mM#))8Q$A')
2i5$[JKJi")i4!iH3!(C"l2Xi508J"Jq$ia"$RK9F6jf81#&p4!cX3AB'-AJ,q%!
-h%I+"M(k%Pj!$-a#jJ8a-!*j'm4i5l#8''r+'a,M$NMK))E%$U4b%1-YNFa"M,G
%KJDalq!J4i-BE`NR*BEm+lf@AmAq!`HC'ZU8L$H!fm6JRf!D-EJImM5)`E@i1c'
i$6e&$&i"eb-',L2lJaJiKI`2BZ!&h)FBliSN%',d'",4A%((25r'JZP)Y2k$hLD
e`L%RU5'hmYSK*m%MIPdkJEpScXQfr0VJ3NBk34BAd[,4h'[)%1##iC(ZZ4Aj`L-
GG&)Ve"CD4jh8LQ3MU5(3r1GF29CUTD2P11AN(1RMa*A881S&l%ElkRmIpm##GLI
$X[IiE0',($I3[LPRLT`&0jT)K42b3D`m%0qbAQHV9VLi$Nj1T)*KqCdk'Tda!j(
reC(bVS)5*A)M%&Gk5!@(Ik50Lb[UE4eP)Jp((GKYFC@pVD-9ZhEA#9I8fcUX4LZ
Z[,Ge@*Y@A'9[kfMeX0ee`KAeYJkVf)SVlfdGeV399pRE1La2++kbYh9BleCFC@r
VX2UYZ-VHeQ%YA('9[Dh$QV2L+RYEKh8qa9AfYNkiSYl@#9I8fcVKLRTE*ea4EqZ
%+qTYRA"&[Dd6VULhGF)9pEC1Z+,HeJPAe0XkiBTk@bGF8@rVK#[UECe`4EfY%kk
SYhA#&I@f6VLLhYB*9p6E1Z'+HPXRA&&[ki3VkQfGF%@pVD0AShEABA9IFC@pV41
ZU,Ge`KAeYNkiSYl@#9I8fcTkj@Yh(GBb&PICfcVKLRTE*ea4EqZ%+qTY(GC!&PI
+fcUX@5bZXVGe@"pCA'9[ki3VkQfGF%@pV41ZU,Ge`KAeYXjrVUKAG9M"@&c&EZZ
`!V1ibYl@BBeMFC@pVF2Uc1)UHeY(Um2ZVK1ZU,Ge@-GCA(P[kl#UXlM+hYB*9p6
E1Z'+HPXRA&&[ki3VkQfGF%@pV41ZU,Ge`KAeYNkiSYl@#9I8fcVKLRTE*ea4EqZ
%+qTYRA"&[Dd6VULhGF)9pEC1Z+,HeY&VXV[Vk&ADhAAdZZhZ1RSPGhFGeVi@9mq
lQijC6mqX@5Yr9TBj-E0GjX"ZK[AdHGAVCMdpF`TQ'RBp[9P0cibJI6epIM8ph"!
H#IH$&lX*eY1r$QcJiECDmj51RH89kX9c0SA#r(2Sj$$rA$Um+jrr%("Bq#RF%ei
*Ci32`[AJFA!dq"IF#Yi%*i,[`'AJ+A!3q!AF!9l!ZbSEaFD`l)G1B*2B&,B%@iS
Y`rE!PQ0lBRYKHf2lB2YLqf(lB`GJ"f)(B3GMKf#(BSGKKf0(B%GL4f&(BbZ`Bl"
MXH1`il%6X"1aNl#9f-RB+GLTf#TX0EB'1`dl(6X$1a-l#cXE1`Fl&cX21aql!&Z
,ABKGK&f-AB*GLPf'VC[-$k+GPpjFQc'mrYRdcQ(EGGeSj#A6lpbMFAA&5mU2(,8
)SH,)3)['H0U1'ShV+ejHrZipYLaj1ISlllVa+lr+5r'2R-Ee%cIIBp1aSpIr*2h
U26BI2(PmFF0la$[2mU6Icr0Kph$Dpd,`YU2[)D[-Zpje5hITrUAll[[8UjTl62A
5r[IZmI+$[('2VQIra6f1AH4RppLarIb$G"ppMjIErX4l3-2e29jj$A@2TU6X*Ie
22karMaB[Nhr[(YZIHpRMlmVA6R12%)RHZ-Fq,m2rRhG0hq19G8HE8Zr02hVd29T
6L`Mi[h0"hR[Z68mHq-IqXRL"0EafMpDYrXh0"Nd(PfrbUYCUh"*`$di06I,fZc,
QfC!!$bd%SI0iUk[V,3"VX"K-q6-#rC'qSdK*qm5-`&("JCd!'0db'MhImkIHeDf
!V5I2#6h%)eSrTP#(riRVPhpc#RAN(Xk!+C4M!$PELKB!rZ&SQ%*eGGPE8kJ6pcJ
eK6TaMe06U&I[mGS8k[Jph!Y6U-lhb%bK6Nep1ZrabkR2mAXi"+Be,pG3ce"A@Xa
*m@aG@V[*2kL4RQYd[UhcBqV6K@K[6Af1)U-VB1UMlb&#A)VRC,rUHkK9l'r6Gk1
IU1ErQeEI`cNRQp3"Gra9hm[(@Arc`@2CB042ZfaGUVLhh2TLe+1,T#GAfNNHHYV
8eb2fV8FZmi2NSBYrhi,5!!JrLdhq3UFD@5i1P&Ghj*a!INQbY8kZ6Ebe6Uj0iVS
XPc1'fD2)Y@RTYlV*FR(CbE9aeFPb-I-&pjb-(bHHA*ZM2rkGTdIpBAZ!rfc0@dc
@(#d0i*6l`k52fZajA'I&m@0e@'be`01hckYD9,6@#lI!dBSJI#85F[MVL&$8kfV
p0VN2mQilG6G'XR,k129dc9LS%)dc8FB9DQVA--bU,1PRMkA,4A*kN!!1@a4k`Er
rjV3BC-1NqZrVqdZ0hpJZ`AET#UfK9TBB@jDh#9D9&@(+Z5,+SX%GHG&aE"NfKLh
&*V"*E!Nfj3Y4LcA@ZX'd('1+"6[)!rRD2rlqbefCHZUe2pC#,prf93e!N!!1Ij0
%FVC*`SR6@1k8db(`eY'r5F*e,rch0)4KNi6E9IM[ZMDB64+1PSGheK`e@cbGGe#
ej-D9lHhV%YDl`Y*)fD9Jf1#)XU@GPhi@Nq,jLkpC@Pi&b@[q5lk6+Vqq28$d%qG
eZGp1!8CJG"chZkcMf'q)lNXE(FGqp,"dm16NQa*+%&dYa`@b*mU4X'),bBRjGAk
CpAq(&R"jE5#09I+[H-Pa[q#P1ZU$)d,X94GdF6,h!22kfFQ*$2rj!M@hR+5MSmL
24P+(bdNMrmcf#q4hb'%j1bk9Hpi0bEcTS+S$8p`@GH!',8fG,&@`GGLpHAlFKjR
jpK[hXHq)V0`,iYj)cpd4GC!!TVXckL"MGpIHLDSMYIrcB*dVjh@3!,PlBGb((D+
lQcSG"&efMRl`aEj`jKj3e-K8KTISTCV+`KAJ!@#mNDRX),LlB,i'H[B'la+Ti'q
#UF$(`JF8d"q*r"1qN!"E38JcC&Q,Q9I@#QP'4,-@rDkX%G,-F-L)D@iAdXc2rlb
BCQB@k"C&6(1lN!$QGJ(0TU-4f'`k'X(0ES%9bakAiZkCVXdeU0qeUNTXeXTi*8I
AeL6N1Ae+$KhpkUNB31r1p5,94TcGr5cGj-qbAVY(iUSM+`FTlmf,4@pPJ)q10VU
DI2888GFaIXaq`RlFITRpT2f8r9,l*IElfZpK[pcq+[Xpl@qdhmYqErYpjZm9Zqe
3[AY8hUc@06EEhf6r$2YRfUqhhmqqIQ[P$l!rd2iJqi2Y$l%re2i`qk[Y$lFr`[i
Dqb2YMl)rfRk&r6(fapSIChqmr3Rf*pUIC,r5rQ6l8qa2YImqqeAfUqhAf*pQIlV
p'IDEl-qd2mIq,2Zcl6IBAfPrVIeepZIDhf*rUre'qr2XVlHr`Ijmq`[Q[4lrh0R
DVkVZdQ6&8mAGp$fIV3hfQ2jID(q4rFAfPpKIDRqCr6Vl+q`[Rpmlm6Q6e5N9[A`
cjF,ldc)I&le8%+SKNA'Aq0&jfD6'YQUp"0X-2c+&@e@ME&iMG5[jHr*+HKh0A65
m+MmqVe2b-Vj%TaFM`XDNL-C@j4X-EACFBl2b04BVAf1amM8'``hai4(LkhV+ehL
Pr(MRf@HIhI2bVI2bMeQI4Iij9rYF64*er-Bk&$NriBq4c[Hf#V![bkPKB1k!Ner
H[qm&@H-IIN(@q2lrN!!eVZki$VX@Qm5ZacEUhXSZa5l$eQ'ABqZa+l$dj5VXDZa
Jl"$X81``l($X#1a)l#MXD'`&GJaf,(BFGMaf!RBLGK+f%MXC1`8l&9Z&VFE@B+G
KTf0RB'GLCf&RBqGJjf,RBHGM&f"VX3ZaLl#,X8Z`+@`*YK4EKZf",FIfa2E#pXE
f`IE&pX2fa`l!$X31`X+%Sm)KX!PF!UX#KUbjVpk0S"20@--pVhI!DDGQ)0K1lZT
A-q$@D4kRbAP&cB"MTjIF)ZId4N)ABc-lD6-IDjdVahfSLe&pjAl[1"Pd-E+D"'c
Xbp"%8@5e(Q"22Pc[EAebTE[q+fbX(-HI%X*M+ePG)%h%)L!hc8Q`I%D4$@B40Ie
r9eB#FVbq`0SaF&b"+eRpP4[q(hVPIrPpVlS))AQaED8&A'r(3D[#f)8`6h1*U)P
eJDddIe-0EXGEkd(DeKGh8Tr@+"`i9S9f`-(&K)m&XTPIZLSX4-YQGXPpJMKp3GL
[VASfpYEEA[2QFEDG9qQ$amk996VS,ZGpf%-YM'*R@U6$ALS-jMf-rq9,ReMCfAR
lRl@V8$"(dRPlm(drPJh`9hX$2(&e#K)"d34a[HpeJh@,Y@f+pr0[FIkR(2qdilI
kUrpR(,r0rZfHeGaKrl-6&414cT2q`2ajerQ#lh1RrEZFIlIVhQ2rAZIG0e&"`CX
@PJ3i#ijq*rh24!Z+Ze61CA)1B(0Ni-I[f0RjZjpV6AJBapCaIJ`M)Ud0`iM)r``
M)M'-L2cR-#,5aM#-F-hpqMpqq%3KN64F`%h96TmNFPidEcl3ZHh`GQI[i6-,,rZ
+,erS*1a0l[AAj&e4eqQCe3TL9(cq3q2lphIccVkleZrIVcU$4-hM0rIFZ6m8QUU
RlDMaPN,6)rG`"LJdGA`S+qhUMVH8PCkiabPPT5IZF8TCkD[hH%eCkI&lZ"H8PAD
qakq8P4jjf$H9P4krabPPTChAq+@bdK2hH&eCDFG&A!6+5PqZS9kKVK`mAf2VdYT
02N50Y!E4cKjaILJdl3+LYa5D(N9m9i"#d`hj80p@MKa[GA@p"@"[,3Tb6UJi(Y'
qTH+iD59[!GMji!#C@6M)e#!l*p3AZpP8%h-22TiF25IjQEk(8VEa0NQMcr3phQe
DcDIe"%![T1SS8Y)q-3&`9$"6*`!MD"Q0RTrkR(TAY`+5RcTmGlRiLR"LP&Y%1ZF
ZA2SBRdbVCKqhR'cR%Ri4Cci'qlK`eB9,rrM)cXi2[l-YTi8F*HG5Lb$eMim,eea
ihqIpjFl1NlrAPY0#MT*cQBA-qFI(K8r8Z("6[3M"eAB1A&Cj+EK`lB9,(hmAhqN
G$a)+(%rRp!9KqGJG2lLcjilX[2aMp[55C!q$dri[LR2LliI6lmq'[XFVmk'6rDV
[iC5B$jeZ92a&86Y8f-adhJe4GlB1)R1f[5Mq6RE#2E#A$"9Vk#aF%3jijEb1-T&
"FjpX(AXIGTEZM6T*aE[I%6%pdDL$q)pBe%&86ccU)!SS%A9ki#DM$M[f8P%(N8%
P8DFAEQR8kBeE&R8B%25)1Reabk012pbH8DFrEUqS-`#hGp3CL0XRkJc#l4Ye"Z2
fLcT)61SIGBEL$SJk`h!(4ThKZ)1LcJMF`9&R*1k3!+Jc#RGSe"Q01bcU-,%G(RA
'i)k)1NS261498@FFlULS-ajhG05CJ&X4G5ELMSNk5-!C'h83P6FZkNc'(4peTZ"
1L$V-!#G'R5VF59'R'VFbkY6J6Sikdh#R4"h%q%f01M0`Uk)13MZVSmiXh*US-aY
h@Y5CJcXpkXc&R4&ejZ(1M$VcF@G&R3@iXk-1fPrR4*f&Z(1McL,FH9&R-HlmU,-
%Gd(83GTBEG6K#p(#U&1(ZbMUm,0RFG4KrVFNk[!cCfR8@BQl,1V`BkJZkUc'A4j
eeZ"H&(1R"YcG6Cd1V@QUcPVFqVJhXqN98BHjlkUSdiLl*HTX`#f+1h@D(Smj4jr
1S+bZrK,S5ej5HEPr%B2*LbT[lflH82,+IBrBhc4j1bjS41cI`qC0S&l-pl"jNjR
Ma1mB)CX`FXYVIe%2j1G9LeqAe(Pl[i1B%)eUmFCKGGj(TG0!L%Ve5Gleb8PHkXi
e%N6E`4+pki#khSpqKJ4I!TIhVGbeha0ehUaI)B0jZMSVi,RHVI8p%TU*qf,d)JI
KHG(2Vq[GVjQFU'YII3V([erUjCSjqU,c)SId"lbXVMG6XeaI*&rNd$IMP0IeqZZ
0Q(q6aa[hU[0+[dXe*1mfhL0Chq2UVbI"&p%A1I`MHP`rEi1i2[0XmTkCh52jfq+
kc+r*Hjjl2&hReIdZ#9V%Pk*Thm!j[mlEq+-#!Mp[RHC`mUl$hdf-0b52qB1mkfC
a4ZE2j-'$rAG02R0HY5@2A[afRIILQiNaAeCR2A0Fla9ehJmPNSpjXMU0QJmp@1I
G*Nl2r*Lm(q$8e(PhkYl-LpAC3(p'IHrRG$Ge,dlc6qMTpe56Ici"Z6ZI21pamZM
2)1m#c6(lN!#Rp)ePmp4mbAYN82AehbV)fr&p1"@$UVak[lhJRm'cVdTa1CLJ6UA
QLckHTHi@&M"h*SqjQH$CG6p!M$Qc1[[Tbel[U[2ZHbm*c*A9ZI)E'cclNR#)1E)
kpmral%qH))&FGDlqRKQH*GrjmhSc2qqDYc9ipM(e+(0KhJ2H,[Hl3lM)(*LmFjZ
qIqkRLG%[j2&T5IV[FVdaFelbf(d[1(6eeiN!q(RAmNi'cjlm3a+Bie,[UJE2(Y"
-3+5l95*2dGcM!qS"lUM1*pQ[Er$XaMm5NI$cVRpVJfF2)@Y4cf%Tqd6cV[rf'm6
NlfAP"fI[QYVh(Q,-@FPlSF(T+ImNJL(hqjF'cblqF@'5RhI$VcGipSHr5J*c8h9
Zr*-'clCrR*L)PUe862$X%RhQ"2I8H4KqBr"XKQD@)MMk&ZBpD6`,KLlhN!#AaV-
JlplIQH1CcH-p9$f0@d(HI9r$2FifcJ9jMi!(L4V28[Z&%maEeEP*HZ#%RcdS(BZ
m&ANIRq&CkPle*I08G4jpH-E2NPmLIJ1r8qHlp+I"Xr2djiajUAU+&[)-RUe9,c%
IjAjh0hMfpBq5!"p4jbR`aZ$C3dq6)0V(EaERNrYG*hl*[*1mVcCp2rRhL6(I*1q
E$ClpQEJ3mdcb`!E"SBI91r"3GEk(Er$X@A%[N@*jmemdH$C,H!qASBr"-1&jJr3
r$)kQc[IK6!E2cY9Eb'D"TmmdH0BU6LAr$@m4IXQlAS(f1MeIT!r`"DI[9ima6q3
HD0H3!(IpS`m6Nid$6eqDi9RUPGp*M(QKHSSH[*2"Xhm3,i4cUC4bpE12CkPAIMF
ajS(U2228$-p5VaCRKNG3liF0RVfJZrTr8Eh2K)mQTRL@'6CkRddHq+6a,*-AHIm
Ic2%Xb(Y@I,l+Z"AFBi$Uc"f8eqTY`M'mcHDT1BEKEGr4V&(qQIkeH)RJh-AL%X`
AbEYfKR2*Mhb-'20%mT5%6S0c$4mK!Fa8jar"*i0c"rk&"2R)qp+h-f*iY-llGf%
((&QGR`VA"HGZ&cIJh@#Dk[i'jfV&YCVV[+MH@HjhPrV29jlJ[86c"X'$*pj"l!c
R`BfN,jrr0@)+rh8H[&E`U86iZX9jLZXBR,Y#A&(0@mL,#9ppR%[GrUI%hZqm[fh
`mYYRL5RmehRr2-1je(k`)I+eG9lLQ3ER[U,hJ$0bCE"Ih[9[p0ER1!mFP(IpT[S
-INSHr5R[HVH`MrN-HEb,m,CRaBhpMm[HVI"B`ER8IQBYND61+a&2%0kf5ac4rhr
UlIZV"ZG'#X[prkhHCm!9$-j0qcBb,UMc[XMX*-hE-RTM[$[I2ZGYQEc)qcm`alQ
JhR"aGc@(d,J9j)eJ(Z5ph[JAj!h5'a[m#r*'mSk#FkQle([bclG*Fac"Z5EY*YV
T21B8JR1cKI(qPJ$[eH#P`EQ[#I[mcm[Hkq!YJR1T,rJ3'GaIjGd+6c*mlLce$,b
'qbNqBA$Z,rkF",!#'&3Fb1$F@H,I-TGX&Zi)(Ra4Eb&lP*U9,hL`5Pa,jTA08Q%
UIINYBB6mQfm@VJXq25BFpIp8H`q)"`[1rH4[b@$QTP)@#)q%cld)CNFm2fh@V%[
ZmD%RLIQlRl`[rD''crfaH*L["F6l-[Q#FirTE@4M`P2#)hRAahk,',R8Jkr,Zck
ZGp+#8P8H1#([ZP[[JBj(mTKE#-lY%ViLFN(P,EVBm,R[DLlPI`,hhU#jL1$FPm3
leAb*[#@k[m`REK6hZpajLYmBR*XZc)CIU,`'lT6QFfQCNC'&Kh4AJh0"hNDpZm%
jQ`GfaSeR0SrjU1&Y39iVleVf6B2Up1kmfAYBmkD4L(M`m5H$LiVra"pIAbNVqJQ
1a"a$j5hl"GkeDM!UU@I[X8ecP$,QeZ"$CXlR25)qD[)#hMRXMr%UbF[GSd8c&FQ
cjbQp3IQ![rd(hfQV12hMJf4h6m(r!`#3!k@3"!%!!$`!!,2BqPfcf4ci!!"%Q3!
!MhS!N!0b!!arR3!"MhX!!"meTH`!!!d!9'0X8fKPE'ac,Xq!!!#A[%e08(*$9dP
&!3#3$i!!N!F1q'[3bDCCjh91eUfjfIIdqM*MQp@%44ZPaqPaqQefqqhBAYR+9Ul
b@c[Ekl1YADEldX9c8XrVq@AT0E)FC)l-3CHARG1m*)XMQd8@h[Z,kF)A[TcAQ`c
S!-l+Ee#h-XZ4Phb`m-JYr)VF*M[*BQ3r!&X!#-!j-J'!5ZIc1FGaSSlMcREF#p+
1ZrP5ajPb"hcHl%CF229Tbkr2V%i9#YPm)GP9b*q95CFmAc[+'4a-ApZ6l4r-CAV
6ZB@,-qXfEYL3!#NNZcF1P,,pQDTl6hjM)Ce*pKBbQ@,9Y@eMXC6[6kl-R(Y1[V#
qjVdSRFi8LmQZ9+Q[jYUE+Qc)P*)pQ9)T1l#KjVddQmXN1e+$JeYp6pQBcDe2,YP
8+U4UVPiGGAC9lj-@V%bbljGP"VCk,Xi@8m9LTRpG,P2BkViXPeqAbL8l"p%IfI-
D)GUc!fFh(!h!9&YREYYaak%JrB-SGLfXGJC#$@cYJ,DP(8LVkY545RIf*$Xb+$`
DEL#6UrThGE809jqHZkT2phh9CiK'pHRBY@6T0Up'6m"c8E'r8ErZc(RPCLRfl8D
[d$X%Vp#cKPfKF`KGS@F0Z8,R#R#&VL&ZE5qJ`&ES(+"@h6&XflTh[@[V%D4Tkhk
Q1b[p8J'XVEiHAP9m09b&2N0S&ES(B&9hh&Rd"P69)f`VZJ'U)DGYR4$#91JCSK3
FH[SbZDd)jAQ'k14jeC!!bA--8FRcUL'5jeK")mmY4++K)JN+HBi"!S91B51'R[8
Q$,fP!8-IdfIP(ULJ6GA23jUbRdBCcck%-*jVJ#kKdrD#0P!Pp+i9e+"*aD&@i4"
&2+m338jDF2EZ3DIL(Q**aE8'+"A[%&8UVM9SUAKAm+AL'i,-F"d&D5VH!G`-HBB
Y1Z4Hlp1K%0+X3ikQ3DZY8m'KEFiH'&@G05*9R)CJUH)IB013!1HZkMG3DLK%SrS
'VlCk0ASL4+k+D`KIZJ0f)eJp3JKLGHmDMY8$K&"@pkkK@6e!"G$UlL'Ql5bZ`&S
p3)"X$HH`[4X4kKhHL#*0h[!e(6h8@a@J'rEhX'l)Am0Gh@m)mHSK!Y"V11pYM!E
d0D,XD!`$J0XGGh4-#)0ela!**BHN!TMfE0'f`MCEV)lj%(%8lSMB&Z,'r`PeeZ#
1LDf)1bkfbh%hLHfYZ*[&pM(F#E&p'rFi2mhaBQ1Z%m4f#Ki6aIB-2#D*E5-HNmA
f-MbQL1eYH%`9fiI`Q#Df[m2M),(p')rTfKBj!Sq$aIB82"iQYUIKmA#ajI%i4'`
Aih'Sf&k2ab2%pJ%m(LQfVq&aQ0KqJ-IKfKCPRXbAYPBmMK6E5ZN[fXl%)bQf&q$
a+,&GMFI4BRX2(M2%pMNmMK(E[q!a8pYLl)e(Lfd@(VaTDm0MYYM@iM&(E1cGBmA
'IMT1E'r"ihLaI4b2&V(GMJGVb*BR&X`9'hYMRYMQim'E0YEi",&Pm(L-f$EMFD,
BrK#2aiVY6r%i5@cXimH*MEfe3'ahiI&iE@XLGK#AD'0[R#`faRU#f,VaH+,B"[&
iNYJZa12*BVX+$q)!EHr!Bj(B@(YL%@eIaS0p4"YVX&MEQSPP5m6''L`9'h0B*VC
9H#`A'hYpKGLHKmHTBL0fXPpSqf-mfXAf%6`ka2BY2%i6faBm1V8Y33cU%KYVIlV
BH[&Jr@NMR[@)lD9id*FfjXVkd-CFRbUf@r&BV@hM1!-3mfNMVK%RD@-I2PeXM%Z
XTZeX2-i3'rjC1Fm8fl9i2%YXl'pL%@hI`H2CfUE'JC6BL-AVa%Cm5BZ0IE*HE1`
RBJYY&q&"1fe[`'1$f$k+4jrBEX%MUfd61+ZF*6CL+1Y''rZFrm9SBjlpBRXK(J0
LHadHl#RDL"2%&YUBhh1dE5,lTL!fiMMaPMCLLSck%pNrR'YSHciHcaAE+r!i4fc
[`f16f2i@Mh2&aTRQ2'fEa&Q&H%)EXI9mXE(rQ4GYV0%&fREh)8B3'iJ*l'PL!$'
(Q%)-B1qcCX3NpL(c)rD`ppRcl(Af1(ZE2FeHCJqcGiPTa#cf&RZ+[F3HBPhBUqa
&pJjlKVh#AQErX5rCXq`CpJTlK,h"RQ![X!GBHpDF@-"Hjla*E#DJF+lN2-QCK6h
2HC+c%ZG(-ppb9Z8FbcQ5mb2R4Xk,R0mi(a+,f'1FG6LiF[jPAh&@Bfm6qcQ6%8H
)NCcY1)Ya"Z2XaGQ3!(-Mjcc1J*c"1(YajZ+Xa4Q,Xa9R+Q)GCbML1QG(cMLFE6M
6F*EK$-1CL9M2'BDc#qF0pMhR,H)bCbIL$,'-X`TR&-iQR%NiLh!'iHc"Q8aQ,M4
B1YHE+CCDdl5!S5XEDHPFGaD-ZHbkrR`ThlSqlpQF&31P61(-9$V6RPhRG)"PjA[
K3["G,@$$@K&'%ZV1&"@6feT`1RVDNffYG&G"BHeCdEPU6HJKI,"a36ji&P+&E+E
BHU1NY'K`F-9!eLm65,Ad+IRejqTbpIB9-URe4BERcc%Grea!KaFpPdfR5YRmJ06
%chPaHlYb34$a8Q93K9h3HN*VX5qRXe,I0,5VC[U5m%M1,[De`(Z1il&rbGQD$jc
$8S*2cQ@+k8*fX)4L-Xq1eC)Q8LPrA2(Mk#6C9U$A99XT'P9E9$mKCR*TD[D*fE8
,eXqTGKCmYBGZd1fKT!)Q&SZQIU!S#pRBj+16TSZ,6XGUd*E5NBVb0re9D4YG6*2
3JYCjiU!D5+@Sm`PcSeq3!0c+FTZ&I`$$VeEHMjR+"i3k$e[Y9(6l(!HC*9Id$qB
,T56XcLQTA#kI(dJZcq3'@@M0G0-6aUj8-3eLQ9B`ZSlQI*deECe,P`BjJ$d1c!3
1ACd`Hi8)I[CXr)kZeD(Cj#p'bCp@2dHD*E-3E66ClP2G2[XZ0[q$31@c4I9[4H@
[@IAR41@M42J[S[l(Sri[S[V4S2+[)2J,8+Iq'dbrAfh$i`HdIFM5Kk6mYVmi`Gq
MqQqMa[mLrdG4lAH&JJ%2`I8`%5+LJVI5aR8'6"FZa,"#"bpJ-$XB%29p9$*Reb*
93GIh90M8b-[5GJcr6ql%m#2N2Jcr6jl$m2rN+Jcr6cl#m2rN'`cr6kl)m2rNLB6
r9cb3!2$rLX-4rYqj$,I`rmkVF![rlj!!(aEqhhNrEZ(rREr",IbrmhAF`[mlYq%
@rYrjHpc#rk[b#[r[dNIiIjGmMI$r,VN8iIpGFL[#rl[N`i6rGmPA#Ir[NRm5rPr
p64$qhb82+IbrqdimK2phbHN*rqq5caIqhqAr#1(rAA+m`[p(@%IKrb2-6IMr#(N
LiImMj)@%riq3!0X4rMp#lNhir`Mj-q(r)q5"KIq2r"%H`[p(hSL(m2m4rMX3rMr
bPhJ)rarj&"l#rdGZ&KbJMAm%K2q2N!#I&2irbKi@rMr+RK(q2mSD#ImIj9ZiU+M
KX'JM[bAmIj3mT2$r8I+,`[p(fB[#rdI*!`Vr(bAr,2arP*bUm2p4mYl#rdH[`d2
irbKjDH(rSer#3rMr+2P`iIqMrib(m2maiTh`rc&LLI$r-IDUm2mapSE`rc(Q+Ia
rM,bUm2maiU,`rc(LS[$r-GC5q2mBDbRmIibe&2ir4S`4rMpf24l#rmIBSm,ralk
)Kr$rX@rJ)IbrqY-Kr(rXKhJ)ramRTJ[r(bF1#[mICef&riqcKiArMl1Q`[r(QC[
`rh(fU2$rFA+m`[r(bH8+rapr#4l#rmH[a%2ircMr#mJ)'Vm*$q(rijr"3rMr1$&
Hq2riMr!3rYrLFcK,%1-j&l$r!mkIr8dX)aj`YZ2Fa0ic1%aX-r`rHjMp5U`Q*R)
1)%B3eiKRR"f)%F41BL#aMaK*h#'1FiEJM-QCNlK,(#Bf%CXj6a&h16-4jcR,FHl
KE-ACN[-&CbML-@G+cPQF-cN(F!EKl-3jJ2M&'B#c"HG(cMr%*-k!a&RL+h'9H%S
F*Ajb2L'qF9BKER*1iQc)HB"i6hcNI-@jM6-ACcA11*`CL@A%,Fk*R'mj%h'Zifc
-S96Q,$9cQrm*R'9P$V)L($2Yfq-2jJ(&PQ%UZiUr**h0j+5#&qHBQ*V8QM(q05'
F+j5-*HjX`F%cUR$"'JF-R#J%&r5mS2khi%2G`JfCJ8`KQlDfiB52#l%+,[5Rl'f
B`12M3Kb-K#[D36dE"rRTdHB'$!BA`$Y&0#ldY0[K+!BI&i4h-R0N'Rpm8aDhLF(
("F-[G13,'AjD,pVGjJBI&q,m*eCA5l#ZRSUkLTAP@1AqUUM$2mRP*5(X,Qd!C$3
0BCXl#8%'G9aYiK-hAp9)kP*Zq+iI6lAQ0rj5qIM*1)ZkZL!Xi,jJ$H96IhfBcpi
)VK8Jbr"-8KhL1P-k9Ur&c,dFLR@C!N@CKP,I'MhZiU#MY+m4jYN6dVjceUiYPP)
&bi-mY`,5F9U@V2-AH1PK*F%LPX4TIReUDY-96d`d(90-1[')`QX$*6T[$mB$)'R
@)5`!f2+EaJ*DJUjGXLPE@TiD@%mpYTmH)daPRcQBmDI@*4)VjjaXX8p2ASG!`MA
kADdIXZE2,3LeFIdCM5RcqpGpClqJJ6@'l2R&3'mA''8Ei`KDZ%X0)j@"a0*b$Tl
9eVPibDcNV-@,HKIKfE@LV9G%hq`UKcM!!B"D8D3r#1(8Kk*'e6BGk%$rq6H(ZP&
*`6lDL&A-6e'N&'m#2$S*iTU*5+8UTB+Qq&3jP045dS1"Np'M#Tf-U(EJa1+bb#`
`'i"qTJRB!+ES2+C4M$LM(H#`QC*k%&-f&fr@Sp`%Y5VZE!+%$Y[PJ5D)S+SXl-q
5rRRR)9[6E8E[dCLp`ki`HZ%""Qh$++1[D3miE2NN%mG0'r01-R(FY&%V$e4Q%c6
)9+q%fRP0EG2Z`#))8iF*)*`3qR3-KmY84BPiZ-IKMZ'1ifl#hBal!ZlaZ#ILRSa
l5K8f9BT+[j0*Q-%6jb!i8%mYfIcDek)Qj5SSHm5*MIlD1da6&Emka!"UKYX"mZM
SD"GebCfRUNRG1"eGlD)kqHXm9VH*UZ@[kYVGdcfFiB0jp#jCdpZk6KBh'$kK52I
`8AQ)GZ51%qTllmRM1&&*r8dHH`[bNccZ,[Y2mpL6b!0jC$EY,FMB8ARXEI[4HR#
Q8(RXUdC&bReA23DKB@i*b#1pTl)MGHA2%j2(EL6k54k$XRh%cq[UjE'2H+G)rXK
4HHcT-XKaDU(p2BFUr#1jeTAkYajXZ,#R0qijR'-+aF+qkH1q21i4C+mZ(0!i45M
*f`(bi&&V32cb8&leY2b!+2J1(lHMSmX#m!ZIiV6e93GUjh$V"dH!dQk2m4"(X$-
2D`"(d(R+UD*i[[089f"SR+lf[!9J53%,#'GaGhFma&Q-jR%rCc'DarfFaIimlZ-
X4[+`,h!@`r8SFaEhF`6$HI`h4c#5Kd9JYXr)4MErHk`I-rRG52636,i,d@`"-lR
+3rEEfA(ZQFp8(Y$TqlmK69B$F&TrhE4UR[BA(fQFK(f#!E"86+C@J)N!UiEXCAh
ZVkYG!FR[2ICj$Id$NK1&r($M5$[,XFmTj0YLC,bhkj8'*PTGDZ3TFa$(M`5$dP)
FLd2&`1KB(#8#1"C(L31@ii5#K%%F+KFf$FF*!P,GX(NX(mS23[A4+-L'FEKeViP
$PF4aBh@NdZ,iXEbTaMKK,!lrF%iFLd-*`dRP10ZrJX1G)TQ6aqT)KG)TBh%S(6*
eT$j@b10L%#(QlY0S4C4BS!(l+hAFfJR9DR%hibC8ah%RF$IKMZ#1iBlL(Spl!Ql
ZmcbTUR#VFQ4jQ-`f[9+Y6kU1&KNr!#A4+lAEVI9PpeXQbaka)TB0i&KY9X5D(Ub
)9HaV`Hk)iCCBm'[A$-@%'r5+@-3$km@+@$DjrD,XmeVZqpH(mp64GR(feY-$cUH
R,j1cY5LMm9MR0M`iS'6B(cCKZ*Rr+BAhR@I(rV#5U%9MIeJE`-%X1iQrRe4E*4H
dcKX+8Gk6eAb#SVU,GH%6P"EY6#V&80S-P9fHXT3IEXT(FTR+Z)T6AUabG0r*[CT
he0#-kVdR8IeQDpeH)p9p&#abHihSI46X1XeM26QlpPh4r*H9E@1*SAeA3Pb!B&`
K9FMDf(EC#2GGXGAY3@1cfhI&9VFI$cp3L)ErVTrqcIBNG6llK+VHJ4L%4[5Z69,
X(`b!V@@6P&6"!X!2f3)h8V&1E)"LpG[F41@aM`'iTep9(PB*"J!+eEBDT9U,Rr)
cCA$`2$4QN!#!QfZ9MbIJK6K%Pd9MFA$Yh`e0*(BH14D(5MU(MHcJ*K)q"ir%XG)
I$Kj'U*0$JbIpC9()hLjrGLVZDd&BT6-CV-6S(IKVEq9@%6ZPZX1pJT@LPMKpC"G
(a1(N-VSE*B,3F3F[%q6$ZHYKBh(ZhGd5FFJ(MHjNL6MFhA*dedUep5#@-q6ZPQS
P`Z(G,@9G`P(q#elFhA*dpdh%i4k*SlYd)Sl5R4b,`pdY4hHbP282GqaDD6Fpa(N
e%q!QqLNP9pc%Df)a$m'3!-"H&j'f"ab#G*,CiDCYKT'F(6l(S"blr@HLC(Il)dI
5q4(F8G`6Q62Z'1iilLEFih!RF$IMCL1B"6I9H-"G0TN%Y+9NJ0!DZ1`DDZ"LAda
,RDCP932A)UH0E$6Ul(2Db0Cq$G`3&f#eYBd-S3DZV8iEf@DRJ@ZVdmaZ,Qp"YNZ
AeRTk6PT`pV9k18CXKf0RD3$lh"CNRPlqVTR3rV(c[S9&Up`fU6%qQSIXKVqcX!r
ZcMq5Kh9#mrb"hIQh*f*hddkh,q`cB6IFH2Z!m%%[haDcN5[ecGJ)`k+(34b+ZZd
383cL+!'iX6LiR'G40&,TT3f,4X+AM6SU3SNiP&3lFN58%A%SB(I8L2JPiP$X,MN
@Kf*iMaU,3ffiSmIL8$YZ9#36F5JNYd1X-SK$M6`lUeMPIaiA!`CR!L9d2Jfhf[9
IE5SXKb+1ckSj(B,li68RNM9Vi4#RaV"aiVLCUN@U('*jNJA!6GZFICU@-rGT@Kk
l@p-516Da&,J6Z-IK(Spl!R2((F8G`aeK(Ihq8+96E*4b02@efkedM0&iU[i!Rq4
qY,2a4fR13bPikqCLF9Sl`,UdqeFc9X[CfJ91BcAMaRHYEG1"j@`Cih(UNeZbmaI
,5hZ,5fpIaYJQXQ+aQXQY0)HMq,lPYi2PY[9YC9JpfH+hKBfhT25f(4q%FcUHMaB
q@[QBb`GhX$CE5eX%Q,fD8jhCNpeY&-I1pDM9EaImFI!LmY[+qPSDr'*lCX@THHQ
+pL9)aE`6I-0h[,`Rb(ZLq#XrT"hR'bd6&AX6hdK,fH%ANhM+$qpaNXG8X8pDeVh
+I2[45fehCiVjMB9dKRqr)T+&UJSE-iJfJG'dYZbj-*X-9FD)T5V)F88b0K@G**@
+"ENFc&ciG6DE6T@bq'VCPPr2,P%&3$"AhT&G5f(BBMlil&bKhYq)`c"8"`8-9G[
5ML'5D[rbm$B%9Z-R+kEA6b5Z0KZ2m-9!cm30%)p$K%,0"V4[1aIJaZ!mkEId*dr
BjcU*dflkm6qFkR4eENJmpRc!2U96EI0(VhT"3S#VAQLT9,Y1reK2cJ%&`USAGTe
@XSbFS98[,(5V'e6j"B[FkJBfZhARVE#V'qM2EeDAl3d1H&&@0l$D58kl"hQrpT+
cp6qq"d@Rl3f5db,'C`Fi0M24D,Z)T,1Y4Lm4-qhd3$5rf0Fb1*J14aMkQ3P&TJH
VTU5cU"b2,P+212FZ8SmiG*`eXPX*iR!Z2Q`X$LlXF3%2YI[%m'iUm1A1+D1lUFM
q&+-lR5!14@K(GfG"(,@!q9JFlT`bZV-,iR$RP0&G8Q3h$E[Y,LRh(H*R8hGRCfr
Je16VRl[M11(hp'9br)"Q00f98MVH5[XGEk-&2dAX%rd-)P-lmU9m)Cp,qC,X5Md
G!BdNHp`2'*f),bRHCY"`Q#C"M1DldA1h*#M5`frb9NAkf(mTdXGrTNJ22e@"UL*
pd`1+p1PAPfXGC*!!m"U-hBCEU`2MrDi[(rj$X-6fQK8Rl)1RJVeIqVIdPLfIr&H
V6[rB93iaJRqhq5q1IkBIJAZ*F0j,jIIC-S8QMV0FX@f1Xd,m6aArP@*[&hZ(fXJ
+SJaLlj3hqA'HdqAGV9K$aqQ4j9Gk*FiUbHHTmPiYmGC)R+H*rHRbISEiRD&B3qk
iS(m(-C[M`l8JU!MT121"LEq2RhE[Xj4dY#hRY*LY5p64Z(!SF1(D,9ZqD`&3PE"
kR9ECQd-IM3X,0AmelIQfR"DbP*bjX[HG2KSA6XDmm!GEYRc[I&Y1#eP+cMcjQk@
2aS9&a!A(1HGhE6NYC#Fj,RD6QqVd&dY9GC0Tm'ZLAe9hk4$i4HJh82&l"2`5NNH
`YYQMr$`#[ePq(S(I(2M&TJi@-QFkLHRm%bdcEXX#2",+VcPp%QcbFDq&8QH2e(k
ARJbEB&c,de(A[pCqRlN*$[)2rdR(mJH*pV[p&A!3hBT9hh5FJbl6IVGm'Jlm6iL
cq%NS3E1Zab*ZYk5C3'I*%T6JF"h[VCpNEE6I-[iTdINPMXc#TTNqCaPe9XEVH"r
k,'hLYaQ2LGV[TVI"a[prp,X8MmNkMmI4TTP0CaNf,(+EG,a"e&JB6'IjUeKF(@m
m[pK-&Vq[PI0STVl2&2'l(ARFV21ilT9`8-[dJ#Vp-"lVT0jA%!LdhdTqLj@qZIa
,X"dNIZ`jUHZ(6i4YZ[LK2daGcrNpaKDrdr(iK2Dl!6qQRBGT[rE$8)p$YGmC9,p
4Dcq"SRd-(Qr8IZmmLJ!NIPr"SeAlI@F0E)GU[mj2S5mPlfmI3f$5IKHqQ+hHAe)
kB[kRbY0CbaI!MeqBI,pZjM39IZaKhfm9*91Hd&r+8FdPL%HYSShpaASmrJ42pTH
+eEclB"HFDhlKjF3`lAFDm8,MA1,Khi-0ID(mf)H#FpIF$"YhQX,*BDBAR%ZX*Ji
GSIfHMarTJR1**a06MY4qPk!A$FkpL0*'l#RQ"i8N`ERQ0a&$4GAfDZ4TF1kLd`M
SdQFRP(&Zi5f`(5eqe#852,L9'$T$r2Mj5[VblFYKBfr5l``2RjS[ZK1fQGV[4C!
!Pc%ipelqcZ0q@)ahPSGcc4F3Bq5lGZFEbhPFZ4SffER`9CJE$-k9Q+[mhRm0m8[
MA2-AVSB0Fi(+ichPZLiQYSPbe+SRP1[kXFI#TMEGJKrVVHZD@-SC5LfrKI`iZ`M
1IIC'BTAfHbhR#F'j$hE$3Dh)j6L[HfSCjkj#$,8e&reqA-Djl(YKQkrpASrm$Fj
pT3-1l%HFfr"(`X-jrh0c0qF!Jh1qA`rhE$)ijrYG3Y`j8A!ZL%GX0MJAa10XBA$
1phX$qXrJh2YCDq)jcTZ*!6,2hI8Ic&AmL"1#FeHaKpPV1$GHk-pcr2I0'C!!mB!
(CTjl'r[JFGV[%m!-Jh1EL"1F(h(HM[fK$-jGI3NF(Urph[(ECCc,[a`1)VRqVYH
8mD#*Q%Y-S0peC6cic&p`*K#r$j6ai*40X$e4r)M0-SFpRYM$(UIIPmXiGbGR'0&
dH2Fh2*a,R2c[X((1aEQ1q#iipplA`EC)r)MIJR1[C+kLFhJpje["Z3(1H+)VG6d
9Bk9[,Z,-*cU%ecq[A0I0a$2f$[h3(kDZDfk&6I6(VZIXSR%ZmC62`lC-qhd9ml6
"ZCI5Krf1Fm-cbMMh6qbE&GV[Dq#Y"HF5-iRTTfUrV`2h$FjpP,dYqUcI"0jj11G
rIVq&1'K`c[HlN6D$Fi%Im4eq#ZI+IQl,2q,e2X'j)"jA4M-i&q6pcM,1A391$Aq
-G$c1`i*c0r0['c%+jeE@AR$Z6XlZR+e`lVJ)Z29G`5(1jCfk(P(JUjRRMZFmT$q
cZZ1!Li*cL4E1V*b[iAFiHYhJh,@FHcKV`'8'BJM1*BjQ[rC)2EjDaS-2AJ1Er)L
qNA1!aS2%M(0J@bAalLMM`H52`XEjKAir+Z26aCal1)XKljQBK`6R%Qh%6YB+,Sq
QD*lJh$'F4CkQmlL0r)MJC3pR9h)GM!I1`1$F5li&$q)*A'DrV)ac,rm)E+`jmb#
Q5PeI6+b8[F*Zir`Q12GZFL9UpcMiFDk3!,UZ`)jKHY-ij(GA'HG1IbjX@NE0RI0
q$qF5iiN0DJNjachf#al1*BiLak%PfpcMZ,qBi0a+eP9,X,R(rBQ(FiR9j)HB#rb
1!0rKiCb[*GA,qG,JA1$(1KQFmrfqrdA@6($,plZ$Q$T2m-rhZaKmL6IRPIhF%e!
[Jh1hIa`HqJq5fd)Z4h$Z9Xj!DSXkajh,[!AR[N*H65Y9ZbHKET0[%*cMr+fe(Yd
P`'1$FehIJ3IcKpp+c%8HcV%[b3-`2q#d`EN5HqCXlIG-c%!'jf*[JBIQ-Gd@mM'
5AcYVVT8@hAQF2`32,Q0[Dhl6RFpC9ZD2+pJ(@XA2R8r-%*cEc(KD1p0GLjUCHHi
DmL[2NALF(3AR*R,Qd(bV1jqi*RPmRjLVe5(GCi2l%Ca,p2`C2,3qP$ZII5,mh+R
N,,4qSc[r%f@FHc9j6@)8rEjHVQZ"["%aR(lNA+@Z,rXVf$LV`QmGX9a`EXU9X*&
,K&mDFjkCjblN,+M&,YheEbVMh(,1UC`IiCIK(#+maIGq"cEppm60J1mdmpbRfG[
kVj+l!4bRKh1qPZ$h1FFDR22p9V%A$Fk9rGbMfHX'jhbr'H6!MKHF#q+46c3ijrY
Y"%mkr[cqdSB+EqffI!k[)rVc*Be,RPm1pB1`8RZaj$4rrYh`)-l$Ei"qarF2&K%
[b1-%2Bm@5m30IijF4Cjd0[aUmFJlL&q3!(H*I-V8IQMT9[dijhqU2eA46IjrTC!
%!3!!-!"!!*!+Eq8!N!Gb!!!X&2q3"!#3#QMF!!!"!!!"HQ`!!APX!!!%23#3mh`
!!3#3"@N!B`"p!*m%!Np,!*!(23"J!21)A&4SCA*P)'Pc)'j[G#"PEQpeCfJJFQp
[E5"[EL$5AM$6)(4[)'0[ER4TER9P)&9Z8h4eCQCTEQFZ)#""EL"KC'4TG'P[EQ&
X)&ia)'*jG'9c)'&bC5"ZC@9NC@3Z!*!$8J!"!*!&E3"Q!)%!SJ3#6dX!N!8%!%J
!C`%$L$*6Eh*bH5`JBR9d)'%JC'PcDb"bC@aKG'9N)'9bFQpb)#KH-#NJD'&c)'p
MBh9bFQ9N,J#3!d`!!J#3"6%!C`"&!+d%"&&eDA3!N!8+!&!!(!%3L"T9EP0dG@C
QD@jR)(GKFb"cG@0MCA0cCR9X)3#3"3J!$J!S!#kJ!J!"!*!$I8&%3e)$!!"q$9-
+Ni3"Sfd!l!Yb!l5b-LXVieY0hP[[D[HQELEAJ$%!3!-!N!1kY3b!!!PT+[lJ!98
5,2Y+b&X1iq9cZS94MV)rcirrVL!j0k`Dq"(+KM9jKQ+MCf[`V&ir"HlX#m#`U3B
L1%aA2VhVbkfM'32&(&P,'cJ,!*!$@J!"!*!&A3"`!(%!V!3#6dX!N!G+!&8"%iJ
k8fpbFRNZ)#"*ER0dB@aXBA4TEfiJBf&Z)'pZE(NJBQ8JF'9bCQpbE@9N)'pZ)%K
'8b"fEfaeE@9c,J#3!fi!!3#3"@J!HJ"m!,B%!Np,!*!(5!"H!5@)6P0[E@8JDA4
PEA-JGf9bC5"cDfP`F'9N)'*PBf&eFf8JG'KPH5"KFQ8JEQpd)(0eF("[FR4PC#"
LH5"dD'Pc)(0PE'BYCAKdFQ&MG'pb,J#3!eS!!3#3"9d!F!"a!+`%!Np,!*!(5J"
9!41)1P4SC5"QD@aP)0*H-0-JE@&j)'*P)'4KE@&RC@3Z)#"3E'9KFf8JGA0P)'P
d)(GTG'JJBf&eG'P[ELi!N!-S!!%!N!A-!)i!i!$5"!K$EfjdD@jeC3#3"33!"!$
$!@,!!J2S!*!$e%&%3e)$!!%5$9-+Qb3!1iU)LKA2&Y"cV%4X%28X2hmrl0HG[qI
ZcJbR@0KK*5TBK999BZ@rm35aUJ8,XQ8l6L$jN!!I!93NQ2Se[)@RhFACh8h5b(U
5[AdI,N2FaCI(T3X@qBdi9dq9p3XN2%U1NN'qk(5em(4U&CSL2JAQ6XFXGBZPFi&
Plh`8(,JebXbQG8"2"b%-6&H8@CbY`EYPFb)Ah(i-H"r`2%#L6q-DV)Mdc!mhH5K
3fic)FDZRR-9M@e'jc-h@kB'VP$IIbIX-kIp8rmPY!*!%1J!"!*!&8!"C!'3!N`3
#6dX!N!8$!%3!5!$SL"P8D'Pc)'&bBfKTGQ8JDA-JC'&YB@GPC#iJ!*!%5!!"!*!
&4`"D!&X!P!3#6dX!N!8#!%8!-3$SL#GCEh8JD'&fC5"PER4PFQ9N)'&Z)'PZBfp
bFQ9MG#"`BA0cGfpbC#i!N!3-!#J!+!#f!4`%!999!*!$$!!J!!J!SJ%F!)*993#
3!``!BJ#5!2!"Q!#&998!N!--!#J!+!"e!6`!Ke99!*!$$!"'!+B!ZJ(@!)C993#
3!``!)!!)!+)"(!#!998!N!--!#J!+!#Z!8i!Y999!*!$$J!S!#J!`J'N!)K995J
+!*!$$!!S!#J!P!%5!J"993#3!``!+!!S!)d"&`)"998!N!-D"3#!!*!$!c8Z-!p
6G(9QCNPd)&0&35!e,M!!N!--#e9Z8h4eCQBJBA-k!*!$#!FJCQpXC'9b!!!%-d&
%3e)$!!Ch$9803b)5%HCHEK"N,4P%D[*%*!X3@DZQ*LHh2BZ-i(ERb%Qh-e2bQAp
h[qrELM`EhmbhY8#5eFlXbH4*f,ilNa'5j9ENLDc)laq42j1IbEcCeRB454B6XMF
Yb5)S31)(rdjCKT&84$LS#cYiiLGf)5c5J1e3aD%@GK*H(mq1D3bR6lpC+R)6)mR
Y[@4[%r6@hmf'R%[)+8FIZEr5&V,ejRAjaL3*5bPTf0kN&a@6NPGC,a$mi-RK`KF
HI%V$*QM4BN6+hFfqTX2b,*5j55k)jb(*(2h&i)XDJqim&Fee*9$cG*JIMZ6*i#S
GjViNe#Xq)@+3!*h[`af,NK")heX@$ED[(5XhPA-`LA1fRcbNbSE0RBqrZ,m'l)Y
Vm[NQUD!A@)"Ck2@aqNDT+'b%UlJKdF4%D4j'8D8QKLJRXm5(8JQR40@4X8N6+L,
JmB-'82KL!,85ECR3J#8d%@TbLdfC`eLTT"qR$+aeU)[Di0J#T6DMFe4B`aLflrd
NJ-)Z!m3jBTLiESAmcl%RFHbLl9fAJNh,JDRU`pD$+ZFdM(GdeX@!G"Z$#pDfYBX
aSNc2)HBbh"2bA1lEQ20L2d(0f,[Q&#I)A'ZQ2(KBb@@qIDUNT-rSkShVZbh3b(2
j4EE#Hi"%aD`5%YXK48JPi!JpjfESS#*')G-lpU&Zma9#N6ZP%AF+hP-PhjBJ16h
DlDNc*qDmR%1jlK@TB-cEfPh+FK[jplG1#3aZ,GrmP`rLNbG@J3Mpl)N"@`NmD#E
1Ye,'NV,SJ&0-'N"4lGDH(L15jV)kGQArf*KLjXEBBNT+ilSFVqIQ2L6S6,2!-qd
r5A,SM5rZ8%e+qrrFIEa)TAK+(ePf3"KU9mH96KeiJM&J8-CCH2(UplHlTpQ8&pI
V!mfS&!eYS22Y"H59K,,GX(5'$iDUN!!D1!1%4[Dm+R'd+EK+q$Ll6eBP[SHY1Jm
&+*f0f9@c1LPl$U`!LB0EA#,N"l-#h9`&eEjM4RfXIVf`GZf$Y!rlJeGII3NEUUX
[JA!5-Xp,Z*!!K9k#PFalib#6LH[)jR!53fYB8Y@+#cA4e!fZkRA5eL(bC5reTB0
Nq+`1N!#ULm1*SfpKL@KA(V8&MK(J'6fDpK)ZJ-$X$'lTUd'pQXb1L-Hl60lqhlJ
2YkIbbBfVNkBAI5lbXT26-1CCQI@i%dADZX@J'V("P$45$f-VG@mlh@!+D@pipZK
GMr,CUC9ZcXXMqF'dI'XXGU%XA8IkajQ+#fPh$2Aj@FVRjqVrINKT#[0r9hl1a'B
ar[EhjGLF9@FZ6fPZ&[UQ90aX9RVbi))fT0[hNY60m9Pip++5qIc2PqqBK`c8pE9
GaLXRlhFHm(""&mY9YB2CTqfiUkZ$G385RX(1bd[ERX3qk'4JZaVPpDGj!R%'T["
3[!PH+Gc$PhJ`"hHqIVA3@F0Eeq31!*!$'!!d!!!"(!&S!!%"!!%!N!8$k!#3!j3
!N!-m!!8%)'pQ)!FJDA4PEA-Z"&0dEh!E5A4PEA-JFQ9YB@PZD@jR)(4[)&9Z8h4
eCQBk#e9Z8h4eCQCTEQFk!*!$1N&%3e)$!!"U$9-$e1S'VpIeXJ8!,,aeGGNY!*!
$m0DZZXYri3-$NLhBmRm"LT[[1kCMGF6SE[+BY3`!!!M#384$8J-!$i!1A3ZX%L4
fE@IIRApiYl&XGjihCQ,BfCc(6*CSle-E)bJkEdHa*eS0Gj-8#D@M,#1YSQS,UdU
IEm-)Ejf3!1fj`5LMfG,4"USUd1Tp3kd8$qJBl3)PV8LV,Sh*PY#8pj8'"1apH0r
[E[EC)UQD9YAl!`hq3#-MB')c)N3K4$AZeI5R'm52eIGBY8"p'M[$-kQr)+C(ccp
I0[E"-prq[iV0kE%!MU6AKbr)UJUXM+(q$U`rekH!HKdfrSQJIrU)8d$#`'Y!DT(
!G!B+G8"FT83$c'p)GKN'L4@)'S5T$Z%8T(QD[X(fVScHNGNI"REeMlhpm0dZdZ8
1MJm%9UlqFVK'T"cBlIPImF44hQ,UG2$jjAPjMV)'Kfh)QmZLH1FGMdciUm4L@VE
a[blr@m"@IIaEYSNXUSrPE5klh-`lS*62`A-U&h&S+DY0c5MPF2EBScYFlQf@XH8
J[k!ZY!4MiB"rV9IC9#2UDa'P%r$,RpJ23Mp9mdDqFU0q"Zf&DJ1'88+i8@lkD+m
1mclDU@3fSQV)d5`VX2CANYQEU*q&L3k9fhTX,(6rbV8ed[)hlTdq1,)e95,QA8Z
F0j8lcYXYmifmf6i8ZHYGc)Rjj52G6k9b4qphIA4"K6b5!ZpL9R9IZ32qr*cJXFq
`kEcbjk8dhlGFcUmrRJZ[Er#XD1`bXeJ[E$dHd8mD4rm&'VBqNHbGkIj&[e$0U'm
%Tkj,VPhL1L'Z8h5pMkl9%ZTkdS6k1RLYpM0L*fZ#f"&0%MX00E'6pK1a%liVLaf
cADAG#l5,kTrikG%-8a09q%FH)rEbi$X&JYL61T20P*AHmmcjpU`rYYd1+@QMmY,
(EB,BKJiL)lC#KH,2p&CMDYBK5XZcMSGCKi$$CVQ%+!FhI2@@)$CrCX5'9haSZ*B
9[G`XVXQk,d)N2YX6$[S*4M@i+Ei)l42+dhd4Vj)QSZ[c-Pb*E0GEUq'@Q89N9),
dkf"d8"(L9H"%*34E1qU56*@(b@R!8NDeJ[[JaD4P4bLD%+jIhcc5ZqAUY9AppmE
("L*0+l4cUcBIQh3q!-Pa#mF,E5A@0)f#eBGhVIb0[)$&imfPSTl8fU'!blc)r"1
N*dqBQ4(bV'*TRqpH!HRQ!bD&a[GbQQ4DCKG$Cd##!X,!,L%JPNjBI6GY$Tk2'$5
CcfP$*Tpj-H3#+5*#Xef)L+AG`liLB8ZhZf9qaH4%EMTDQ+[QjLmhT0TF)%PKGR)
0dd*T&[9RiG#9SLI"X%qLUS+S[)(M*e#[3Bfil1!VRXUb*+M`i5*H8!3+I#IA!RH
IFK8N*X0X1h!`"TjYi"5G5N0JL8SX9ApmrD@ATVIYqhV`9IIECkmI'cMbKfYk2P@
XeCH2ZH8Hq"f%R+DSS)liI*l&d#Aq!@pr1688@Jc0@TKm+Pj$i&cCTjbJUZS3X2m
bf$1TLHR&8-)51N1&E'*eIN$fC9@Pk!a630&)bYDJS(e8dfcJl+UU9@clm$effPR
J#RcU(Nkp1MNEXRP#,UT[Dl[iPTNLLE+GP%AeP#(b!VLCU6eXh!RMHZeKcYe(a9a
9r8mD(Uc$i"M8#-R5`TU`l*jX3h8+SS`IkE44A4V#Z"Al3U4pbb8ZPLLf3F!NJLS
P)5-U,C9mCIhP3aThLC-"fLdAZGHeN@Zp'mIf&BUKUpcbXMGe9&[BHHl6QcpCkC9
0$aa#Gjl(ScGEXLQI0dADQ4!(3QRce[mG+&IJ-jl"jRQ4+UD8,$(PR%bNN!#Ac$e
`f&`4NdFb5MNSpH&NbI,Uh**rS5NXGqaCfNVq@r+Xd00b`E1bqB,LXcX)JD*#8Vb
QeS+5`T0'MJkDN!#P`4JNBZ$9+(K62[N$dKR402fS4[hdUqP#d"%5a@KdUKX'0eQ
06F(l[Cd1`Rd31Tp+CPkJqkBCa(%MSbUC$`PNSUh@rGUiIl$ha2VRV[K"8G@6b@5
Xe6UZA4mFHrGKiIXrQdSQJc6Ce(Ta[(i`[,[Yi5qIdcFJ9LSTkU,ULkhDq+$l2cf
P`BI1G+U$TMSUHqZG69qlh$%`j8pREY"U8lh@IUhAfGXc%2cMp`FKpceP%j+5frM
DDlh1[@dp1`F'R,#*$L8T841!5Ua(pF$q+L%"#d4rKe'BY$YQ0I6jpaK9,if1@Sf
BmMl+Tfrp20R&qNCrT5HljPY[dFj",e6CPVL1'U2k'9")+mEQF'cTbMHGCc&fG+l
D59rl$X"QKEK13)0!Xa-#+)S,iq@[(cU$4ap6S!5&l%+UBpIYAA[k,)2f,ed1IRA
1Z66cHYN**!VM#!,6p@M8`Ir)BZkdQ2T5r)2ESm,5c'r+k(q,EUVhTc&lI24!T0M
b8pIFTVlc#FIT8Ir53V'C13a,#&baCFNeTfYP0X$`L2p0X-F5$VlBBREP60Ur3A9
'K@,KPS,9qk1ENKZE5R5dPZhDdjdEeJi0"2QjpZI[$l#kL0Q9EeqQ$S@24GZ3!"a
c`jJ'Bp+'`ppL1S2EAa%pDB4RZ%#3!(rl)YF#IG&4U&8ZAqXKGM*ae'!X5Q!QpD3
4(ka+q'3RYfQPEUQqd4h1j!6+[I)%l+9c*2c)Mr%*58e-DHB%"q$MrAGC2Mpr+6+
i)rp4Hf'dmDUHaS1ch'i*i`P*&L409I$KH$[&bcRcl2$Z)3mafaQ+8`qb#DjX%dj
ZNmJ"D@G-`EPiR,Af0DTE*Zemr$Y0K-h%N4BR#8Q,Cq-bC`EF)@IM3F$T9J30F&-
9hTk`0P0mGVMX[Mel+jf*F0`2@a%dF%HTiJk1ZdYa@ri(1r,MfjS@'K@mMhkQdY2
JDJJN1ULEA20Q`ddeQ6BT95+hA'RF83$@d!"49h@Q6H)`)VX9Ql0-!KL%E6dQT#f
LA$G-0%j,'3B*efpZ5$bq9@-c$@,3**FRfS14N51q-RNiAQ6*Y%F9(@C%Fqb9mDp
ELXTN,ZicCjSMSh65'J`Y$E3RdaT9G#V6'*a)CaZML[k#P'',-#P+*EL$AAXbE@%
hr&YRI%Z+)EV5BfUpXl,+$*p(j&$ZP5X!N!39!&3!C!#,!BB!!3%!N!F%5`#3""J
!2!"!!,!"Q!!"!3#3"`%(!*!'!5*"4%05!`!$LJe6#TXN!(q'4E$G16N6X-81A8Y
16ahE!48$fl(kf!a@pFiq++KBI@c"EUcUaX!rBhp8p,rrEircGPBCaZS!#jNe$9a
@MI6"MNEhVP-Dl!5cmbJ8h-AL-N+fe,NJbA-,N!$IEi*fJZR44(62+AQc%pfmbHi
VKB3cc%YDkTT5LKd,2KqEdhm%m(Vq1HV+dqTUrjpIEXHVRre$rrZ4PL8#Z$0USi*
Y9X&)*Va&Ufb-9E9H@cjLQlH&l@%9IG`AaY*D6+58Y!*a(daqM-2AVK[QKkBCkP2
EpNhG$lS3D&U!*`6)!*`!6,hk,3$qkJN$%Am!m+*bi3)3()+!!B*LB#diLj&"M0m
-3Z351Z,UBj,-[5Ka(dcIG2P&a#YXbaJ!N!0h384$8J-!!)!08`YE)!-$TQ$$UQU
c-,!")Q*J0dZafeQ9S#"L`alUfF#B96%,BbUkpkG6V!S,L@2)YZ*heJ"5+2hK[F#
#5VM&3+GM5$+1VpRh*L)1[qR'r[[BRcTA6bLQN38GNEU#'ELMa4UZU'SRT%mb#Zp
&cJ8!N!0-!!)!N!8)!$3!'J%EL"Y3E'9KFf8JD@jcCA*d)'4TFfXJAM!JGfPdD$S
!N!B,!!X!+`!VS!)%5`#3"4d!0!!Y!4L)!Pia!*!$1J!"!*!&0J#(!%S!`33#6dX
!N!8#!%8!,`%rL"PH-#"KF("PBA*c)(4[)'*P)'4KE@&RC@3Z5`#3!kT"4%05!`!
!YJeE#e-`!hGc,@B'l"R6bPA'0c6M[V999XBrEdr[eAUhlMhriKXD!!$`$3!!k$B
0!!!,XLdEJDAi"hCRqrRPV5ecdeE0heRBNa&Y1kd$*bTR@GR*V[*iehG%KH"5a(q
#'"5q4!bGmd**U)B"*8+!,UJ1hY8&`*1&(+!BY25$@4r[#**R3EiJhiV0BEcLr@Z
6"D@&%LZ+ZA,FjlR#dP4ijI&K!3#3!``!+!!S!(m"F!5[998!!!%!!!%!N!-#J!!
!"%!!!!NJ!!!6N!!!!#I)!!"""!!!J3)!!3!"!!)(`)!%$q"!#"KJ)"!Er"!N'T3
)6"Vd**mb"$*-0HMj*$8S-K!hq#3)-1!)""rJ%!)!`r`"!r)%!)!#*!"!JQ3!)))
N!"2Q*!!*bL3!"*)%!!)Mr!!"3!#3!i!!!!%!N!-$J!!!"m!!!!rJ!!!Im!!!2rJ
!!(rm!!$rrJ!"rrm!!rrrJ!Irrm!2rrrJ(rrrm$rrrrKrrrrmrj!$rRrrN!-rrrr
q(rrrr!rrrrJ(rrr`!rrrr!(rrr`!rrrm!(rrr!!rrr`!(rrm!!rlr!!(mr`!!q2
m!!(!!*!$J!#3!`%!(rrm!"!!"J!3!!8!%!!%J"!!"%!3!!3J%!!(m"!!!"!3!(J
3%!2rd"!Irj!!%2rr%"$rrp!4rrq3!"6rrp!EZlZ`%C!$%!4%4%!1lZlJ%rrrd"I
rrj!!&rrrd"Iri&!6rqC3%IrT8"2riP!4rq43%2r[8"$r)&!3!$r3%!!!%"rrrr!
Irr`!(rrq!"rrr`!Irrq!(rrr`"rrrq!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!
Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!
Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm!!!!3!Irr`!%!!'!"!!"3!
3!!5!%!!%3"!!"#!3!!I`%!!!%"!!H"!3!rr3%"rrN!!3rrm3%2rrd"(rrj!!&2r
rd"ZlZl!4N!-3"%4%3!lZlU!6rrr3&rrrN!!Arrr3&rrJ8"2rlP!4rq&3%rrQ8"(
ri9!3rqj3%2mJ8"!!2p!3!!!3(rrrm"rrr!!Irri!(rrr!"rrri!Irrr!(rrri"r
rrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"r
rrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"r
rrr!Irrr`!!!"!"rrr!!3!!B!%!!&!"!!")!3!!4!%!!%)"!!"r!3!!!3%!"i%"!
$rp!3(rq3!"$rra!3rrr3%IrrN!!8rrr3'lZlX"'3!a!%4%4!$ZlZi"2rrp!Arrq
3!"Irrp!Arq"3%rrJ8"(rlP!6rqP3%IrT8"$rk9!3rb"3%!!rd"!!!"!Irrr`(rr
m!"rrrJ!Irrm!(rrrJ"rrrm!IrrrJ(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rr
rm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rr
rm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!!!!%!!!%!N!-#J!!!"%!!!!N
J!!!6N!!!!#I)!!"""!!!J3)!!3!"!!)(`)!%$q"!#"KJ)"!Er"!N'T3)6"Vd**m
b"$*-0HMj*$8S-K!hq#3)-1!)""rJ%!)!`#!"!r"!!)!!J!"!J3!!)))!!"2N!!!
*b!!!"*!!!!!#)!!!!8!!N!1!!!!"!*!$!i!!!!I!!!!2i!!!(r!!!$ri!!"rr!!
!rri!!Irr!!2rri!(rrr!$rrri"rrrr!rrrriIrrrr2q3!rjrrj!$2rrrrKrrrr`
2rrri"rrrm!2rrq!"rrr!!2rrJ!"rr`!!2ri!!"rm!!!2q!!!"r!!!!2J!!!"`!#
3!i!!N!3(39"36!#3"JG6C@Fb!!%!N!3(8f9R-`!#I`#3!`G6C@G1!!2r!*!$"d&
38%`!N!BFBA9cG!#3!`&*3diM!*!&K%C548B!N!@%!*!$0%&9Fc)!N!-"5801)`!
$!*!$J!!"!)%!!J##!!-!JdC548B!!`#3!i!!!3#"!!)!JJ!$!)-!N!-J(kNJ-6N
j-#dj1#""E'&NC'PZ)&0jFh4PEA-X)%PZBbi!N!Fp"4+!!*!$"68Z-5ib-$8Z-5i
b)%0[F(PbD@GSG##T)$%j16!Y16NX)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,J!!2B9
"4%05!`"mM""9#f@T!0PQMrph[LI$--CTR+E6Q*,A'0-BNTN4fC`XM*!!6%)BaM3
C*a("Lr+U1)18K0Q)R#`@QcY!`)LS!ENdTCE'!5&"S5ReFQNZfaXSZUM,FT&D&V8
ZT5br(k9#+D8B3XMmRZGpjhY#S1MGDjeecMlI!"ZXTb"+N!!%34!%3D)D8&fPlkd
jpDVCk!`$hmm"d"GJ'ir"@f8Y'Jp6iUp([khkVH8rr@2K51GXdGVlV4a"(AmU(1'
VE"bNUqq`89XXFlb[H)*E"*K$,2HmfMYLIhhEiG*elEq'XE1b[E"d(5T$4H2aQKL
Z+rfM%dDU5EN1Ya2Qh['j2ldr%EN9*X[52`DNTaZF`d8,*q9Z#jCZ3[AE9#e(G4&
99r,RcK&raC66r,Pca&G&e88`#KZQR-lk'D[Jr$+ZJ!'ah96hRGmRr1%%@)%lbiq
p'Tk8p62BNHE"b2a+d5*"Ijb"2jAGYNqdB**#h(caqdhr,#6mq2(MDpiRP$rmjrT
EJcHF2TLVA)NbIkriTqMILRY0[AYVeAZSZb044T@$PSjJq4r+eARN+SN)$MGCHLY
[9H8$eJ4-GZ+CmrESKaU#+8kI$N93RffGeq'm5GLbeX-NUBU)D"&9)RcLFV6,EUH
I[dAraPNcVHY[@XFHZ%Ai@9KbQEXXPkQla0aYZ5`Ie6i-(a`@ca6pbG+Mka'q3Q(
h+KqIb#DM`E-1ikRXpRe#Gr'(6DF`q91Br#RKUrRjIU&Q$[h#+Y(8GA-NUa4d"FX
IFDQY&kra8IV8NG!jIhjRF%N(I5ScAfrqqCfAPeaApJ'm1%6dPVa@8Ac&G+8L6cP
m)VZQLFfQcBFGlcXLA"KLGcRU5YGTcRj8j#SAU$5cU93qh2-MlB1&MmIF(NFNjJb
DV`Ma$b1L0HlR)N(4@(-H'Bl#dNdQ6$+H4V8F"Bf4c2ZI%#ACI&J)&-f0++qadcX
AYVmGj9h#HPqeHf(@Xa#E"06,5l+$GbpHr0j2K"G-i9AU5YFN)NV(3CM#X`C+A[A
84Vid*bVZj'39VmHaae%%!V%RMkU2Q`Ch,dqNPBl5VFSlT3mUfa@2iLjp$mCrYj-
2&GJ[Y3G[Q5m`SBb(PHhY[rlpI*''mGRIlPCeMel)`J*rAb6mRMFr@QGIB%+#iU+
5TaZ`fCc8*@AHhpp['T6U%[iL1dm-%f'`["P&1K&-`DhE`kMLjh8`j!YEiDl4kl6
Ya3365Cpi9E8`J)JY,)#NlqQqY++&3V`4@aSQ9`-!G6KNL606PpLmhI!$4!KBA%h
1m63RC!605NV5#cQij'61`BA%$5C3SpXXTIFH(,EE(5L+8&!8N69`,,ZjX24H*4+
rQB-pH,G6l2GRV@mADL46%QcSeQ8pfbb#i8dEfU4Jlp[PMr3'`q&`qBCjeq@2$!"
5,RA',NRKF$!FEcQ+E&q`)f&cEGJ*0%iI9a5rI'JRI3b'fk4Gccabr4CAhSh2d`-
h,2k2rS6TqmdEQ&alG6dZdl@peTjV@52f8DCVK@P8,X-YX$IfZ2J3JMNiCdCH`ej
reLej$I[`fZ(0DiLRjmh,QPF5"-*&@EGNcEAEjkiM&DQ,#bXP*eKRf*lK%Td,hD+
dV[66B1(6,qGAj'Fi%04f1aGl&!d91BYZ4p(*ImrhP"iY2DS-IaTiGMq+HEUHAY9
H(5b29h+dRl!9Za*qeFfXAV41e3'-@e@El&)a#@rDi2"Y+hak8(mlAX2kH9QV(Z0
L5Pei%Jj@Sq"ac,(XJ03*&Ejdi#BSm2VEEUf`IdZriDT3KZ-[+BTj8e-($"6qFKJ
(%rkVdUfpqR)k8V&eecL2r#XIH@RreRM)%5RPb+5X9EAcEVT`A1LAdL[rTJYfZrl
PF+&qq8dAK%kIPl9UeMSX16qBiaHSV-#&343d&BkIKCm&@3@9#je0i9Ak!`G@q+0
FV0IMZUP$(`D#)*YBm$-[@+L[bLS`9G9Gk1b"H"[#Uqf[ikF8%Iemqc3F+H@IJm2
1XU,I*9fhYHKh1,DdVP"rc,iDR8[j*hC-FrQBjX,%i8kLB$G0lPIiH6Gfp&hm["d
lfU#jlU,II9(H)qU&Xdj[i3)DPi[9(aE5HpQK8d0!2E)YU-m-4,Gek$fBqU$*&ar
UR+f[#MMe+J4FEeTY[cGKC5B!+8!dQ#2m6pc[3q'XlNX)X&BZR#,'Q1AJSLNSFPM
'#"FM3e3ELejc8('RL"4p`F@5)S,!Qe9k8lZ,2d"eq#+')#0ipc1#LhQ3!!h4FB(
Q))TlJTXDA!aBJZ8SJV)&0iab`B#8BB,K,P'jml["M6AqR3rLf-E*9c)[Y+)36pJ
HZD+fmDFUmkHcfLIrMR4`3qB&Vm61j'Z2R(8qb)J0!UTU4V#m5Q4HF(--i$rj),E
kF1*EQ4G1',PMSZ[aYjcAR@NX`KrF--IeC+G)2hP%q*h'B2QmXdpf#"Z5q-,B4'V
P!PBS4jRCTb%30d!R#J)9%m#mUI6"0S[cMQ$jb@eBh)F6AFjY[)MKEGMblGGGM0)
JGY3p24MF-&Mhp$#QIkh"PANKQ1D&"#)cA%jEX"a+BLd1R3aZ1&Rhp!'JZ6E4C9l
Xd8CHk,bh&!X@PXE,[0$9pPVUY0(5$TGN+TD$V@+)&iHX*T-*G*@DZ0L0L`KrAJ%
&XNkr)9(6DZ(LF4'"NDcZ2mBf9BR)`5U"BR#BUP%3bi'ip'0PHeY3V@NEdSlkq+M
5Lc,'#,B)19cdIr0KL+&'q6K@p%S&VeadkKMZc,586#JbCMk!Y%((%"6j'BS*c"`
"N!"2ZHc`m6@!d@A03Dlb3SV11TZ1#Yl-k@YV'XH&XbNAhMU$#iG5,PcTqi*p!5H
%r*G5NX-#+XLZX0F@[FB[al#pbpk9A`6`l"1qr1r,RF)UV2PjU%K#b[qqPN&D`)@
bE+j'*NQ()T`SXJ*$EH),9m)DF#pca49%e@9FF*5SrmI0`KqRK(S`c8Cfqe92YRS
Li&[Q5YJ#4Kc1"*'8AbkZE41lhNGaMSdrahFkGKp-Dm[XiU8@[FEXS(KdVE$%IcF
"mi#`1KYPY&hHJ(3X@k@LBjdh9%KFF)TXHPR`liS[i8&8%RR(49(+4E9PQd8rFaX
LD[hM5X6M8MUfHI6hEN0'3Ep%E@XbL%U)Uak9U#-#SC8TK5mf)[[8+NU3!)&F9HY
&N!"E6AA6%[&fS2DHNY&De6+!Q([a-a1(V*jXcMcSrp!Ym"!%("4mM)mM5V-P#ik
Y6,T%4CLmH*!!)8A[H8SG)V9cYd-(Y"l2CGkFP26jB&PhmR+,`SAP+%D)i()CVKL
4*9iepm44`3`D(l6@k8flV!JDUk01Iibcbj,eU)$`,VkA$@%DZCLSrVUc+F@0-NX
jI5J+5bQ8Ek)LIplSNT3MhG5M$filSMpf8bq!pqaT@`#m$a#i2NlJ@SM5f-E(UV#
a`dE%!XY-VQ2Cb+"GPc[%JQ$KY#hNV*UVSKM+b"dJ[&P!#dTfB)%8"(NQRTBeiE,
dA"+F!3NjYV,EY8`QX!Q@Sb$(FY$'ebqKb,)N'aI$c[jJ1F"PEBSJBa2-%4!L,pG
0b`h,VXLPa4TMLkh6$fJEp@JEalULFja0Jd*H-LrBQ3iPF'J4*f95X`K(mL`iIA6
&+[faq-@#3ReQh%[U3TJrP2j5M6"bE&2QE(+N$aUar4B1`2Mm9+31$Rlh3f!I&(m
["@%6Q%RX9%b"Kr4U##2ZPSq#fDam82Qip-'(LS8#X)GNpFaBT3PN8Ffra!*%RBc
NS3Z"VjrG+`D"V*f4Y@f2EDSK)i!E4B,aJPb-!H[Za-NqN!#Ie*!!9iMIa*!!mi)
ee$KH!k+BmHBYc)3`,94X6-9N"NVB(2P,%2I`iGkXqa`DdpS$V"*`pbHIlYdCkri
!h6kYHc$@hB2ZY0cp8K+&!Ge'V6Z*`SYZQpDG41&(X$BQ%`K)eAaA(jE0#"b0SIV
UT&`B0lZ3!,eJ!K*&Vai9"hY&P"59rFJS(&UlQ52Se-5VQ(V2CD"`hMTNFHN0P`3
8Y8Vm+$!Y0RHH@lXCU!f"++,G(9#AbPJa1XVXEA2k91(293aV(f#`DK9a%#UJDfF
Rd1%5)B"KlN#i`Pj$9iq(A09"C66Bdc!RlG#85$fZ6+&)'!99pRCRdedGDk'DJ%M
eB6kL)GB$i9+B!MF"k8$JYhS9Qj5MJm'@`4k4VkrG5LBd-DNG9kBcQCX-CT!!-UA
m5NCY&q`8IGp8B5H3!!9MDJ$NE-2KV*j-*T($%IpG6%$Q9SAN2+9p3T'B'd4bV$4
8%aNMb(MXeFLmiYAQdEh!c#(FmIVQMcfA%6P"'EQcHPGNcZ8jVYC10GVkX@HkXbV
@2Af1UlRc!KYE9[!'ZCBMZFjFaAeRpF'GEMFaYGYd!f#V3HPYmp393f%df1GH&5H
"@'ecpVDkqE"cKpZ@pbZ4MJm4ZGYF*AeRp9flh'llL'Ucp#ilXQqQ#GF5"Yk#PiF
TM-35M*GG9Ne54-G-9XEC)43eT"19ZY1LBfr8HCSh`c5RYh[Z3iE$,5bR,ENVpiV
d2T!!JC!!%'U!T,TS2!c4EUL8ETL1rIY%aMTd6dqLAmm&jk*S)K')!PhTI8l$fSa
8CFLq"JcU"(1kFd6JQ4fX3L$,ZY(9eQP#0&pm,6'%Rc,m4!jHX+m4Ad*m5cNEk-Y
LT3N#Le#dVJ-4XMZmM`jFGR+dA0iQ2%4@8f80@1IGi+V"UZcQL"Sr8I`SkP(6PEf
fUb*RKVUccDJk69IffGTX1Ap@fpTX-kqS5P[rc#ZQ'pU4S@9RpjA4CcH@mM#f8Yk
pNI$HK54P[`F[RAf%cG*Jdc@P23$,2H*,+!feP"$G-T'A3eDQG1(I0T&a*A,1'XY
3M-!iI0%CAYd&NSXF53d%+lT+$UEcRlNUU58-qZ$kQ"@EJ`i)YqX%IU"XGHdXbYH
YCN@bUb6HKU+TYlT1&,T4HDVVa$kVVX+BLiib9(#P`NENQQNSF5C,lhZ%P&Pr@FH
q-CBHQBad4FHqXf'S(SJ-kXE2FY50Aa$-1@lPjE+5!P0R4eE"qdSbQLc*6K!B-$D
%9ih[iN02)R-T`NmJHbPkS!EAMHpbe,hBL12#e%(C-[Gj+E"e@mIiVViqai@aAHY
b-lT`Ur3'&+2h5*%$`@K#BH8DRjdQm3ibIEGf6%Z`UR6-["#VbBJN02fpE,i1KE`
M@,Lm'D*q`0N8f$TkeI,QEHJBAe[AdC91(Q)e%QJ,eZj+R9TFT-HQ)+VS5L2DK5R
Tq#2GMJ9Z`SGT@r(bkqr4&3TTQMp4KZbL8aATNS"p@`H@X'UZUl2fZ,8A5Ja!lq"
a+`2IB-Ak0+R&,T!!b9aN&`GE53%B&QRUGP08[fUZd,U0h"eC)(IAePi9V6jHSQi
,S0m(*-*fI'$fq!!9P3r#8B%LF&lL!dJJ8mi61JjDrU#V%qPT)&(j0"G,UjZfj4d
AUeTXA1NperAr"Y+P"S#DG0G1L,+9@3k#fQ%5RZci%,S-@TI#ABRd+5"Jd&0FBP%
1$[XP1@[$Kj!!RF&Qf-,3YA0AdbKAP54[PhI0Nld[I@XZ,A5R0V%16hB+'U&PN!!
X[E2emf9!VcHJ-3',C!MASM"Q2)#IKEKD5UTEICa-kp-5L(MQE-2Rm6"Q))RK-#q
MmecA6PBPEm)PXlQMbidIUfcZq+mfA@'i4lmAU++*HM,e31`,'Q@N8'U&2bGJc`-
llFhNK4l*#436%6X4`$U'XjiYc*8l!(BM)1DdY&PRVZkb&Yr)V($kZJ#'%'%A(i6
iDaH@%)ZeYST$DS#$6Mf'+$CrhZU-JRPmaC9C)85AG5D+I0DqM1jhCh"94B,SX!S
GAM"P4VAJhR)LQaJ65%(@CeJl`-QQ3m3MC-UP$fE'-#%a9B`e05*+@ld-31I6NiT
[!*9-!frR%,+#k@ic"dTi%SaT6l%SdJ"FhckI&)98B6S59eQd5-i2!'`Xj'`"*HG
)[$hN3m&hPR&hDZ+4R!4U&[)KFe!LLEdEQX5N#)Z'%[jm"a**l@*XBMebVZZ$BjH
4l42LEG14K#eF0fQ55J`"j3R"c)ZF0-Q6$FIG$[(0JIMQZ0UN#34BQET-686P(#f
UijTBDqM%&Y`E1V'%@f-rMm1`GTR$N!#aVSmY9M#M1R`m+D"@3!c2@EiKFa#e#3S
Nj&jTbRc)H`+6UCf4"%TS6&(PE',J!R#M%!,C-2P@9X(#Sc"-FVBe*i9`Q*6FJ04
@)pR+Eb6FZKTKpef*Q`*ZZ&C[MEp3PiCUF4)[Bh`R2[IlpbCJ'SXGESaI$+6jF(f
0p-mk(`kAi@@-mqGqkB-iLTiQ6G-@!62[0bc(XQ948'"-N`QmSG"59PTT!M[jP@b
(+(f+#Yje@I0-1IjAIYAZ("B$ih2EJkK!eIhaZS59Lrb3!$%jAMT`%)BHA0i(!cc
BZMfSfRahl%EE(lM@*4h&(H%6--*hl9JTr'MFY2V4#rB-k*kFY6qH#*YJS+P3(Z9
XKjqfFMl+MDcJl'lId`c(,raU5rJ6ZZ,(B@[#MHidZQfSq)3I(p1k3H'A("84kk$
NX(6Fd5(k#9QCHe#NGlFRE(F`8VFZjk$GrmTRXR[F1ZLrL++@Ipi"`*kR[2-R&$"
h2YST)UC"rqKIHBF'TI@B`c-k'%2L%5cmi6ZfL(larU-jIUXS-qAiCKAfB1XbA"m
1*f!@le+bRmb*R"$HJ&Z[aTZIh!)Da(TpIlcbL5hL!q&miX)4bq'248Y!`QIESeY
J'bf$J-mVKpY"S(jJjHC',JjPTQ"`+KG+FV9d&49,3Kd81KLFf6KCVEDKN!$aU(0
imdFJ208YEdMB6!f*)A9@liK3IMm24Demc%9%&&BQS2#mQM82abhUZDZIlhS*dEC
Dq2@R@e$CqY,rH1NU+Y@"AIY!m#"'a322JP4#M2RrYbTFQIqVclDL)P9q[Ar[Ve!
*&aEb!@RVVUm,Z9+p&c@Z#1d2l(5p(B%F51Xq%FqL3Gb3!1i6re@SifP,KfUc$ZT
qI)a*#e3BN3DP$e!pa&%["aSF%i)a,6N5JeU`l95b&`"FIZHhcTmEJVU1*QqLAYG
ad*Z`iM@B+%2A)!K)K&U'E@'Q9f&-BQB'+L%(G8@,R$&V*P'qi*Z8+dG9AeA(EEJ
L9"X48c,C`"UC(84pHh$)Qa!CFjD,q+c4Ie+3!2A)@%lXE1Y2'ph(N8NM"UN2B4!
h-`L8SRiFEj5CXE#HTkElU3il*R4iq3V6a4hb!M28e)9aKP%CP0aI9D2KekY)T[A
jVbT01(C5L0"LG9Nj"k0GX+mAAM4'l"H96b+`4AeT'S%GbIUbI6X+%@rKLfG@!)p
%Ud0K+m4Sp3BlV,m`1G!%X3`[@b)pE9LePJkV1YQG-S`V`a&-T`PXC3B1mS+HJ-)
YKTlNM(epZ&98iZI@F$kB[E*8eAABem6pTB+CFNHqm'+K3aT46m5-J#EK,CAN55M
E5m#`3Rbd3I9l0X5fF![P56BDH0Nirm4(SMQm494K'i0*LUG,rDUre-I)qA0l2JL
c)!cDj"DJ+#F8%9SNLqZA1&V'4ikp5JIbk-!3(E$+NbK&&K*EY*6UiQ@pmd'BG!k
*DVA3PEjr&cHiNp'A*3-PG30#F,cE*[*%GCMSGrN6*9))bA`N&VMb)@r+)8-IKmV
!!(bdLN4M+1f4%hXl*hBFC'#-SQihLMI1!3"NXd$"6%d'&aUpG##iV@VD1Pp)!-`
MB5Xa3PVa&2d9c*!!EUm'3(GcF5JKdJ&4ZZMrS02+V0*HR3am)659m$iQYbNUCH'
([kXd*GUjJ0ET4GE4RDKIh[%CL&f+1a-fUrH@FR@@e@VT+$@B!400kRD($m4M9[Z
pb+VGVSmHj8)B(CT),+%Q0mMX1MP`bB4LhPkq@-GC[AXTUlF%MTXbHlIVIaR+CR5
idH($`AVl4"`FXRp&9mFL1crQ0hcp"d3H8iVVMB&+0T,`ePM#kl5e0lDePCMfM*(
T)e0$*5m-5S#iL`NB*l,j&fD8VdJBK*!!N!!!(XCELH"64JS)%rI@m9Ej01PTI)N
q[Bq'(J`++Q%Jp'SE$B8))%U,YY)Q1[YBQV$02'')qLYDCReXQA+M`FDlq0*%Z[3
9ECTFh['qK$f9#jh2md+iM`Zhhm@(PR"J"rak03BiXT--4C0G3Q+lK`+%Q#[3Vdh
@kZ6Q!GaFLjZ'b*1IhqIN(f!M!)bQ%4JKbf#m(6)hGp4ef%6K83EP6qI+MHcb+qA
QEL2Aj8Cf#5p8D50-KlZEZ%#'M&iLLQCAkblB8cpa!e&Nf2+20X9eq%"00%EZ1GS
%%M#hVYIqEc#UAhj2ESaiMJP583Kb1`l[Tm2Rc%8lFX'ChBp2(r"ahJ"((dF(&U,
X,Rh2J3D)['(4TQ'BVBYqFV4*YjU,l1bem5KG!6UY+FLd`5Dec0b*jD`Fa(,LrU-
`RMjjId4efRJUXLUE%KNm`!4-e'a'EZTM$4&@6BL`ET@&0IH3!#BXR5b3!2aENAN
S0iXRr&YC1&h68i8cpcBX[GIqKrK3l1!N0KCd,@HKaFq(#QYp+5l(qa,@fTRiP*N
8e[V9k%$"5p&2TbkHp@G$a60h6+Kij-C2CTB&N!"dF0(GL!Y%%QjCm@I3cZ`RNr0
CVRheh35DaDP$2hC6!mD)8bVZ4'(+`S!8BK"20M)X2QN0IQLjJJE'dPkqFK)'-D%
DQS[rX+RN-ST+f96G3!B!+Ma6PJSE+P&83+kJkLbp!HX-el)MK@YBq@p*+D!SLaA
fj3M[(6[6kL(GSm+JL(LQdmp&e&b%2FTPZ4Dp"T0BQr)a5)GlQSrr-Zq%[8&8SS4
FCa4IIkl$kraRYM6D1,5Li)80fhba4PVZfRFl&Z!Z$T[#&9-S-a3`EhiU1eMi)J`
UaBG,2XmUZ'-*)K*EH0@,@p5G%'(GLeY!2)G!MPjAQZ*$FTGXX[YP,G3PUpb&!aH
9*Vj'4S!G*Iq$5!0M"4FQI%,aRAEijf'PbHcFFBr5a-C!N!!'dZ%426IUe!VRV""
)p+Tm[9@qiU##eC%P3$2-M9P0MI'bYY8MmjYAMcb!+F,JTHKJpQV%)6dI"U&5+39
)TTN"k40rD0D+YR4Y!%E0+#D(JG%81eDiI#FI@jZK(A1Q('ZHi0J-l9JNHFcU-cF
AP4N*6G2FR(%)#0heJrL,kh6AU-+0I5rUVTFF19(#R9[h[I3eG8C-eq-fdc8deTA
-K4lKK'-i[Qr[9MNKIFGNf[j113p(i$B`ZFqK$H95Md!6A#UX((fipleJjk%MZBH
cHR+c-hZ1@'6#)8EbpGj2AY+3!0LQKZ30$8PRjZ(1iPphCR@HCM3b)Nj)8,R5@X@
S9@a8f5)RY)$!m"d4l91CpLP,kr!`D3!E`a'N@i3&c*!!9EGG4Y`jAia#YUSYB&6
qc*PBjfL16,4X&D+EkX1pPZ+56NZ*%*AHhPfIIlhrFqA6I4Aa6a,2l[Tk2fM*PDp
I1LN[0-24MbP6)ElY+*S6TbqY8IhKde`F#C3k!k)G9VVH)T6C(VVd#NG0)&FCDCq
aB`$Nbb1)l#%ZqlZbLR%AXXhfT6#l9H$SGLlF1H"L`KT'++1EIJJLkqNjE#Rf(1Q
9&h,Cd3qdC5&SpB4f*@phV"S&+f0)TFSRe020U!mdaEr8P"Np9ji!H"9q"&ID[[4
3H6Z+0MS$bd(JIfL$#eQ-5j,UC,,RM(T-YNfH1LGBS(`+2jF$Z[cl$M3G+RFCl%q
"F&0+q#p*Gjd@3`D+IZrYBY$jCQlfHf#D`jP(Y-!'-8)r+BIQj@[%1YCMeEer%CE
!-h)`dF*(c1+fkm"Drl1RhpSI0eb3!2J+XiGmk+"02T3aR`9A)bbj!5R[5Z*ada@
qmT[6(-Q*aGU5%-PG,ZlYc$*cXC!!%a5a6aP2MRm1DXAp@3A@`EVYXZSL6`F*`F+
*S$Fl+rI`DAPDQ"3+!b8'kQi@9pFdL1ZLBjKYkijK0%L)-e+(,VJAa$H#4DDf`Z3
-BL+1i,)+cQe&X05(%`Hj!)Q1iF2QV)*CA3HD)%jGj[e@&bm"CUTjVr$Z(T4`K8c
!2J@&2E3!ETjl59!Lj+EZ3c$0H$JC)QM@Q0kL$aG029pX3)BVDZSjY0%%NhUElTf
rEr*GphFrpJjIV%GMB'X%'H4b#GeZd"@9mE&`V[RJLY`[k@"iNY1fS3X%52ZC,(5
Yfp$%$E40Ed(aH6HF'cELB2Q3!&&'PA"5`!iPVf$+8h"Y5@@6h-Q%IldJU&Eql"`
04"ZY4XkfBX0",-'Df%&"$d+lM%B1G)1)+c*+M3#&NBfYE#)djd!m#63b#TT!1a,
-!rBT5$"S9X4L`U'A!5E!I1dcQ2R15eCMh'B!BHMD,c%&+l((N!#-Z'b-SBP%qaB
AP(`ACV1kdca%Kl9@Ba1SR!eJNp0(XSjB1M1lFiXFB,2!-&kc)R"*Q+U%4aCqI2L
ZB[ZXZPqabN)+d#bS+LX065#Xc248Yf0i#M-3q`8E`)cK+Q'6Pr),H5R@c2Zp,M0
SQmb!#&$MF1kT#4BK+,X!`1J-T2X'M+0`[HG)EZGlQ59m-D[celKF(ceFXIrcA4@
IleFmB1h2GheHmHRR,a&#+k["VQ)3Yq)RSPUjf"G00A4hXBN[SUE$&8N9IlVRL1A
A*GQja9a*@4!cE0`G@-2J$mBJN35$6r8'Mr4qI$LVq(#2R1M3*0dR@Q5Jl`icZjH
Ya29hbRIjPh0P`hlT+pXl'cIk#C3*YBU2d!BY@R)(FI,l,JT1Yba%0'Z5JrecL()
)B+-mQI5IbXffp"j*,N#HF%*Q$UKUC38!&@ADSX[-3eDmCMQ5HD5c115LJaX-ZcR
3$j96p+Jcl49C#5D*bbUD')D$B2@dEMG22$-E#(+c28Hbc)5"cc$M4#Ua!*Pj$T@
EM1m`b*DCb'e&iAMFIqP[P2`3Z4#a(BMZ!&c+N!"p-#,KH*a0V,S[Z(Qi#HV96q4
N&2K$(J5akmr,hb*d&9CM,%$GUKV1K4Jr#%ARS#K$IX%i2QZ`+I8c9)+m[VCI1dI
E2Tkk2CDVqkqj)ZXA4a#G9`QMXcrGBEmYBI[R$K!6b`(c03)'3i*B&jS&c*&hq-M
T`ePb`KUKi!$JAT[(dEmjqXLir*[Yp[8F3CVCk5`Z(XRUd4*$"MF4S`3C0Q689Yf
"`9*FV()(l)SV)&Sl#+eAM[SbrJ,de`e0lj4cJcS69"!#P2)#i`3@9iXS!9eZj)4
#T)aD9Y[$(@`d#CBlK0,%*N'pJ3jM`hFfQ-jqX4(AG)G#!$%#EaV%-hQ3!&R8Li+
*V++'T,M`q5`@"Y&E2,a*[Y+k2IPCdF9M5d,N-SN9bprPe$3&dRNSM+G2@r(TJ')
mjF*N5cJ#EKqJ4C5EhU$PYkpmBkqEMRkQqU[Z8+)RA!kC%-jQRX,"G&%$913d$i5
M#FR!!ZTD![(ABS1d!3fU%'JY!%YQ!"P&&%`!XS3M-Q&1c&S%LNbJd[4dZk'kp3I
K")L-&@fkpE4"P"U'm5+L++l0-66ThZ**aU11+&q%SE9C9K89eb@"MEhQb"-E`eJ
cN!$F10J*-T3B3'DPK"C`L88(mC0bYSJ#BBUmYDEiI!F!ZG%!YX9J3GY,2lRSDQR
#XFV3jFP$$U(!VF,!Rbr5i4TU),j)AQEUj("%S5-2GTqNKUE9d1630GQXI(@2YK`
$,H9m$@rJ0aJ9$VLh+1"!C'X@KLD#a8N4Q"@B9"R)40-8!#bk%UZeI#@6GeTF"i5
$Pq0Q"6I*Z1cH-YNX@SiUAZ[0pTb#$I&`eZRXpdT5K-U*+JSL&'[iY,+E&BCiUqN
0"LjaaA6P#kji(DamJF"XrZ2Y'+cXLf[,k3-PJG0a5qZ42rpH1e"3eF3La#*YbF9
3F0IRE4(q3icqBRZ3!)FB@[l4PibF)`AG$QY``mTVK$4pB0Kq'QJa&*U-LNb84"B
HLP,ZR$FG6,#!9!S8p3#-c'"(cQ*)h,%ZfH(RMKA*$Kphj#FldYc4S'JNk@LbYf$
8p)&VC,4bh8A"j%d*TUIHbr*dpRjm*+[%FXSXc'GBQ&Bfb[3Kc-C3BGlpLLE-aK"
KpTL&HAG&M5a-GcGKZUFU6$F,Xb"8Q,Nb)XT86#K+VE0+2$cGB@-aJX&bN`b@2(`
AUHRHK8NeIATZCh%*8UXQK4LJm,%J+!S0-f0e@1m)G`j&PhG8j*LGJFjKC!)Z5HL
)jTdZY-$Sd'&p9!9"Tl-*K6KIIbj%'5Vr(3ddED#)9`kik-M1`&511*[bYR-dK%D
6Tp8T-ZS[j1LE9DjbFe*ijA!aXYj(%0eRCahUM#RSL,4pEQfB%"d$'3V!0Y0N#X#
,L!#i8Nm"#&"pjaS1`19RYbFMG5q$(!GPGGKJ!#!l4JBI@L)[6l,2+c+Bqh@R*e9
i'@BQSZ&+%0&eF8DKI6F"$DpM0b+4,KCKD#5P,A9)@fS%%9CALUUa0jalAY$5M&V
%@f,D(Mp%+PN(#Y2U9hCm`GQ%3Hjb)i-[INR4C5ZE-AP,rU!PVrBK6"SICB8ZY`A
A@ih%4%JbMl[8"Lh,8@E+$Bebie%0F0*`Jh,Qh0!N#bE'8K$-[d-`QP31(bP1kV3
)S%A)f$-5+jTjPTJ0M'L%G!QUYb*r![#ZGF3bKXBY!-VS!TLp$eY&BePHR4`!f#L
jJl[reem(!Tp8*1600'B!X'eeX3(Pdd$&IKR8rr9YL)qR-m`!@PDV!NrNel6q`$3
jMXMB*9b5fSS$"*D*Q!Q&QINe"Jb$"P64J$ZrKYQL5M"b16YJ,8maG24UKJic8mS
CAdD&c*'-5PDDNUJSJV(988D8&@,0`0%E-h#B)fmG,aai4L%#[cK""'j!T&6LF'X
+f3L@A'DH5&E"l!b1+"&e45(3TT6&ak)BE'PHHiM#B*V-6FCB(E!E$%eU4%j!j`j
aP-R)kQ)CD%hYNpGYcR#8B4K2"$"A(9CcYKr6X&&@[BBcrkUXHT3PM3,IQ"GU&)"
D-8%f6pYJ#"ZddJC$$L[-p[a6PV*44&c80UTA,mVCc1l(S&BVI##C[Ic4iGjajLk
eMAABZ)8feMQX-@EaDCYCe5(CA#C[m1d!GjT&$60G(hR'U5,H23l%VkFLKZSa3@i
bKMJ53a`K3ER*3',8%*GTL#00K(K"&hHDX`"J$5d(S#(caS6ZT88Q&5SCX9AB0-3
YQY#phBmKir)!(dLUV'qbd$@09GXSLSfDDD-SEC5kL8idDjYie@l+SEc"YkEcaa$
9Y,YHGQBE98jpSdA63MGk06D4T!BFbh`2*,bdN4XE-8L)D-KeDTNjBl@!!eA,4&d
jh%Yj+!f"0CDBV)l84B)X3%-8e4*6bJ*('[P$%RLqGVJh"(DHN4"DTLk%ZHP3)8b
Q65D)"mjXXqM80kZ0KQlf'JNm'4GVMA'F')k%'`Z9FDD6Lhh1#cAHFSI1*[lT-cF
Df2GD'P&SBa2cYVD#Q-625Y[aYUM,0)5')cTZJPr5@0*lhUlZX&bf0*Bm9G+VmN%
I(h4RD!I,j-EkKaS2m9%h(chde+(HCDF,ac*!8KUG4Sf3!$T@1(A41CbbX"aa&B3
ZlXQ9b""EM@NL&GEakjmq`eIR6AiDAJ!@[6+T4DU4"U9FU86k6!T)Pk6TdN3TAeS
QEC,Q5)ZPFe+A2q,hqY[m1reK[mIrTAq[rlbrfMr@2mfrh&rZRq0Il$rRlr*&I#f
q'YqJ,pGAiS[lp[ZZqbElp,imhdEI20m5hk+d2fe0YkGhTR26*HPiHRrkHRSJ25E
pFVSJ[5ip-cdr2F[S0PBD@ie(M8(M)H0@ibkMbrL+mAAMDQ1jFBlaCZ-XQpY@EfZ
e(EAef!lCYYM1fkEEaYMbE"YYmfa,E)[kEIh4r[CqCrq"rXcq$rUhp&rYEq`Ie9r
D[lbr[(p0rm2pQrYRZIhZ-RHPZmfp`hh!EA)IFRm@l4*radpMb3e9p-Fep`Uj*c6
h,A*0Q[XQZF1D1jTFJqD1*9I4h0I*(G,FTmP0DfiTZlCCQUXRGllQ6L2hFFdG6ql
YQ[XLZHpUlL4bmc5hL&bpjZD61ePcPj*l9R0I)$G(FeH4ZdGcAbEhQ1DZ*MG,Fhp
#ESIQrT6F(CVlBh+E0AFjZI@Dqa@jEXeGaUja4(2rJp`(0,H!h(XepfINcY2FIb"
hSqDZ*2FV9*IJam9#2F4G,!!qP%F(*QXZLGKi9R0*U-BFc58a'[HNS0)6UK2D!AR
"CJEi!ER$fNF5N!$4S,N8"%C&3p8B3e@Q(5""')AQ8K#P&fM(hc42)EeBfqSX(CL
MZ3hNEY+19q0R$"eIVU'Mi%K25d%hM3k-5ZPkNETFfK9LT[3ZcD@!5'p0fH!k(EH
NG)fQVSk8VPHTL`A`Eb`m3U+N((L"$TJ&3'bB0JZ!!Y[(!PKM&Tl[CQfk8mLGUEN
Vb&fRAIaAFJXdPa+@lfA0*IEeM8PC`N4HJQmkUQrMCa3GZ*3LP'SkX$IPbPRUqN"
$5BR&PkQja)5q!bR--S@19fN(+'(l,QS,*i(iV*TlJebrj[ilZrj&U(jSATMr(Xe
pJp`C+GZm`G[ihdlTQNaGU3RJGHV5Th4pMlS'8VSDU1Y55YF2U@Z[YUarT+fre!l
m#$qAk8#QGS#%lcqJ,C3#aZr8MPpMTUIM,)"[-2ZEQGU[5pRbCp`PMD4d&9$AI1d
D"qBekTUCdNAX+'e+ZIBdGCN6!#eGQTCbJ)*H'TA548P'FU9dj9&AK6Dpki4%eGc
,j&SdpaUj2CVl&,P(0EHDh&E0IBhF5XepK9bGjVl+VXM3h1RN,Y4F#RCD'VZ6bAe
%%m&i&Mi[9TJ"),'-q%Tc*j)l4A1r6fk$j[k3!&`-&53fDB$L!LVr63-a!FhKk'U
V*N`'p#Hd$`ai-M@(8A9S$Qqj8l[!M0#UIIJHR"E0iB9B0BHMdA6d3mX0be21Y+8
R,lG32"BR9HB'0hC1%Z4VMFLjZCDIQckPZ4(i%#N`'dQ"HImcNGjM9Q"%#kJV5Ra
lI+9T9IlR@dD9R@N6,YB)LDk@dY8Q$%mi)hCeQ4JMJX)MeQ$Xe$ALN!$B,lD)k@+
TQ!Eh-l%4M5$1SlT'9)LciTKB*eE#'5AbU(10D+JI&NqcB&(4Sh)GPI(UHEbQUI[
aQU*@i*@[EX'V52d-VaI8BhLpV"l#kkHU"kq[9"0Hrk(fi282kJ'm9UU$H*@V1r$
DS&EKY9&Y`qYrUJTHkp4+['j6ShKeU@9ieDTZ[2kUJX,ELZDNaQ-TNjE9[B1I#Ap
V60fE)Xf$@[FbTP`0N[%"k@(4)0dQcC3@58ZNqG)jrd94kVG*)hiN,*([[bJ032(
6qBG%R[mLA*FS&bXJLKPLRPJX0BMjSPBXK!VTPV`BqdQ4@R()+A9!Q3a+*b52Y%)
UPEC)+T6+(%,`,KB,iR0T)LVA1('LFKd9&L)R%aCL)bSXaLZSl%,P,#Tl8(N,&4C
M05SIS2)Q*dj8,U2#BR`+P6!U'1a41SR+DkL`'&p"T3D99e&T4f@!%bFUSe%C3Q8
8+K&8hN$&MmTN"1B)+[q1bJ*8aU+b'C8IFH*%T3'9ae("i+GL$LS68EN0PHpciN6
PG93+82NH+XY4'F00-e(j!5Tk9#DK`J*BM3S,i#FD%lfV-G'r%K2p0f+LfiQ*rNK
-0*1BD!BadCh%42F3%pe06$5IQ1J[a%5ELBPq4dcd!$(4E'+LFm4%hb!QqMBad3*
LSZm3%bdb-j(2LfBV2f@5HZZ`q"BkQ-!I%9F+Die#de--[8$13`PNm)&J$5(l0d,
fCc-brqe!0NT$YJNG+kPap$)C@9E"2hV&AL!jLjr[JC5HUe9i[5ABbY0!cJrT0C&
HhmFiM8+m$Y*V[X$6Q886I)`Q1*FQ1%)6A%m6A%Z,bU"&f@1,'X5LLV4&r9rSD+9
&YD2ETAAr$"e$e+fMP`h!b-I!5"UT(d,6RL@SMX@3!1+Ba&qISXRid430``3X#dS
j5(P[#2'MbaLd$98TLYGNHMAJU5I#p80k6F5BJ-,eZJ3b%YIhk$9'`Z4FT3!k`[@
d9)QA(MNiiCSLEXFVMlTq*QEK9F#[DihLCY#fkG'`494I&b$bV$i,dBMU9m8P[%D
,AAK0*'H-J0QMqJ8@pC[9r1(08KERQp-`iVYimd8a5-XGJ*!!5MAQI9&MhU8Dmkl
5Q$G2BplP'[2q@'2HC4VcrL-al`TLhJ*LhVm6mhj)c2Xf-HqIL(RR%I2H3X`lKjM
hpm5mMa$crS'Bpcp6i$j1JIX`"HjrSF"G6)'lK!,hre$JhU`&lM%%cMILRZj"SlX
Ka2Kr450Z925P#5pAANBcDUTF6d49,j!!,#5dIb1dpa,Dqc@d0RUFK6!2+5)21%!
2b*'0"c!FL'BHXL0B6Ne0GHEKLp"``-R$`TJck@[2-J&TXdBi`J9#GAY![0j`eai
3XVq1"[ekaD6[Pe'KQ1YHhCj`$iE6X`A@-,!CV"%pD23H4X1G'R'Je8893jX,J`)
dB"$kec&X!-Leeji&mGJ8(K$F,qa,UHRqFRE6JJM8cjEkY3dZk#U#fc,mmD[I(!'
f-Q5N-`eZXAEL$X0DIA"$bEApaqmXQZ2#J2XKD"0T$'V3KND@Ci2P(2d%YbA59pH
S3`p9V&dYR+fVebjV@lef13Z@)hfCk,86`mjG[%Gq+)dmT!8DKcC6pk,QDMKZFXB
d9f2!*pdq$($!JcBq&ML4VCJ`q!X'h+)1ciPX050P!*iN-Zrc4b"INCYLF-1-@1G
NEF%GI5lBp0`A,'r3dYA("!MjEkcr%Z3bN!0dJGK&qV*cpYp["d+6*lYjHqJJ*YM
NS[`C43NiR,'-YcU@[Fr0c8IPVETISS0Vc%K2T#"P)QXdehT3,%eifam88a4TS%M
SlqX8HZ8`5,BZhKF8BbCB3!e3(@UZjKF10H0"Be&Dc+S4elJA!q,1e%QZ'XQC%!d
0H&+*`9(dq*Rb5bC`@UUBH#(i21BK(TM-*I6"28M5UlS80&[)J%Jcd+((!)0M--"
JCGB!QZ!DU*-2Y6k%MjJ@$dCP$3R-f@!IDLM)`+"l3-K#hQJ@mUVeiJb%E*jBVAb
9*Z01"Q%I'q5D0aLCm6`fQ#GIrHBEE1KkVK[`e62B`'AHS'[G'6(KUUjbq4S0Ej0
1XL)PU#AQM)@T"Z`B-B%0iZN`(1U))RM(@*D+-Eraf1h&5dQP,mHKbVLml1S6h+"
k4B!I`l)jK8@kY1'b0Z2(EQB4$$B$BP!cNc"J"0&j!-dPrTcB`b5[5)*lDALm`Vm
r6%5#UqEbm(kcL+"deIT"VH%%#0Z&jmMX6ECJiIS1lU$TRq!",l@M(CV$+2)e"qM
&if$)!r`S''fJVkCa!`0aU(2fE9AM"!D'cYNI4TZV'EPLSL&pXC8-'NCHjf$K+1m
-%Q4"efBC&5FTE-X#b($8PFq5Lk-BG@b$"QdUI0"+LDZY6m"H4N!`CA094b"`eB3
!d*`-jF'QV8lc)i[DQ!J"C2Tp-X81([kqV8ESPq()AKS-RpQNr@-H&JD&khMG!TE
KbQLCCGB3b`aKm,[Ga$B$fY!5"4MD3)Jm'XD'"qhT5Q'K%I0!LBlG)3`d-Ni'3Y'
f[BUD(44ZFP,4Xma!LkLKMXa!$r#M#!'@V@#JZ-C!0iF`d!-T$,3SKB'!2S-(TMQ
Jb!q-5aRXc%S08eKScEqL)+JrP8h%d4c)2QS!K1*M00&(8hJ)JEYhBaXVLm'-5LZ
Xb'&b,,RB4AQRhG2q#BTE4LF(6c3RePMa$)Yc2U1Q`9*b-8`,0P4B4!-JeciU0f#
B@k%PaeTq6!HQ2K!m2lH0"YC,R6SIj89G9(`T5Peb8pjXFCX)f*Iad#T"$-@8``1
K6,#G5'jAqcUf@aimAlZLVqeUpD(EQ3YXC)('*VNlC*+9QT!!dG!Qr0Y3%5ZqC-!
`mCH'D(I)`QYqdfZhDdJZ-K)'8I*8C$6e$#"Z-)!)3BMPFl-UZ5K4i55C-ZPDAA,
5Mq9MdSm%ccqfUDp*2lDD*pep%$j1UM%Ji`2"SPYqT&X!j%3QEhbN6E"bU+3ScHB
%cd"NeTl1fD3)!E52+l'(A$Kj"KFbBJ""$SJSU8JBi"$$TINK"YrQDS[VGp9`bd"
!b5"c'Y3&fd1pJJ&'K!C$m6,TC@*)BhSD0PPN8C1m!R%5MlfaRck(3BSjJGZ#J8%
K!cC2GQLLB%$)5X233,)c)*+1ZF%DKL'`lP,bVRfHeK[8-Jbk'fNr2M5Mf"8IDHp
8$UFNSYdm&"J*I3Z'LBQFb)jV`CMaH$)B-mDFR[dK(X$jV9FS'(H("Z1hFSKe6DN
$cb@"k354b9N!qD96M8cfKN3Qb$M*NFNLcp3LNa3NP66F-`pNXZ+-PBk#@4AbeYf
LQJ)Hp#fTZU81&)N0mLDFU+bBm"6PCG[Ech`4BQMF`Z%$hhP&AL340QT4)4V0m`*
ec5(#eaC[5qh%N!$K@q5Z@',$*"jcQ4rfQA+a[RYL5*Nm6lbF1f`r3E1Q"h"KC0E
E5DGfBp*CP"AE[$@GMVM``6k"NS'*,9JQ4r`aS9G5Xldp&08[$Jd!9KVNL,mfNa3
%H8Nc-0aU6#9i,)-Z$5@&BKiFeE%0SYk'i[X#D8fVB0$A0S4KF0)R,XmFYDcadpT
@Am-S1Z3$S4NG&'eYNE%[#2I00cM+6NC%LJpEH-e$QfU&kc4)$"i*lDkaC4TJRp+
eeQ#`d"UKDlM#56)2C10EbaL)M!8`b,3j!FV'AP''hR1GPrkk5UfFH31!)DeYSXX
DhCl'JaeFVG+*l'9A2Pd#F+,$`h""0*@H`"#1jP",KA@IMS%hX9+c*rZUp2C5`Bq
leLeKd+5$bQS0M@#i8C1A!"X6R8)*b3pG3*Z!ZZZ@)i[i(PQiXfC5KUI`l5fN5-T
Ua3JeeC(9LJ9bdkC[&CbHrICC6DhB(!)d&U5S&5-TDJ@Mlb'e`LFVTCfceqa"`eX
RaT5!)2pDG!-6mQ!D+r"633qe#"eBPK)J*X`$2d&B(H4D-rI!GB2J%C-X"N%USN"
[-S%K-J!3C1D!!QCJmJV4)i2#a"!2rZ5)D!*aCidqPUfTNlZeT2aapbLMVCY#UAL
kGDb@'l2%0MF$MACj-fbri`3H13fP,QG#`$&ejAAUQk8`+!4aAPb&&9,eaUERc4V
0JbBPr*G[c,aKD9aaY["Qa@KQY@j+pB5,2I(rp')lCrqTS([Q1!CBCSp8TcJ$+Bi
V"GLeFP1NC'El0XY8%1DR1(NT6RQ+8dU4VEd[*@,f,'6Q6@HZG-aqqjYI5)PS8J%
j1ZqXeY3ZrbhP)B!jj5!T!Tm)fqLrB$!RYcCFH6T8k+D"Z0ZbkS9C#[pB3cpDV5&
+k+!@p#HJR[KE28U9Z-K*9!(CEeZ9f*RB`B0aVIGB'&#dm5(&)hKB[4CffM`BZV`
G3k*[%bh"$4[aN!"Z4&XVZQI-c%-QQcIebSpkCf@Q0fap)P2iQdY-Hd4,[!a!&3-
+mG"Hkc&XQpEYaQ-I9h+j,"5ZR3Qh313"iMmE+NE4dPE5ea+8hY!'eq210-V"`Xb
`[TDCBAejLV-Za9Q4UU5e$i3DG[MappS@@jJ0GLmQF$f%L!l0U(C[j'K1pEB@8rG
ZVIYP22UF(`+UDp[$)#Uq1+BDmHF2BLl8b0hH[K3Nm`2dqej%T#&e%C(cI5dLXR9
ULiJ-T5lLq,a[[SLBJ$lkm6aZ(KFcQ-Z%le!TK8PMk)ZD#Cf9j+0*PG0p0)642i+
S$hF(-*lU&1@Rc`!a0fT32$)ai`3+8bL`IMKPB'BGM)0Tr,L$[p*8-9chjjZ&iKp
&'B3(QUYCS(ACH!3b6i69`@T0K5k3!#CbTTUU5ZT`&`4B[iaPZJZNV'5Q@`SRKG#
r!mK2UQemiIMBe'!mRX0C-alblc%-CQPr'"8eUCkE#F1YX34'!jU$&&,YFHJdjIm
f@NB1JhGc0J"*[-#BN9b-EAPb-EBTG'%RPY4+CJeNAQLBbp@T!k(h(I"R%SJbFmK
NUpS5Mk@`4M4P+5ep-0V!1!bXidMSU4XbFfL$N!"X6QjTebHh0#j04V"#(SKL,`E
Qq"MUK1h"BZ&@3Ha2TJaU,)N(!38jH6aN%ZRQbmQNBFk-"A3mM#3![jJ`5rEYB$*
,pQhGkGPcGJA2hph99jEXlRY#Xf6G$9`612r#"'QFq2rp"*NHQdb3!-C`DS)d0[r
[5T!![SVNBY,e+BZ*r+H5)(fZrp8*dPIf[bT"cPk46*!!XbmJ38i1RVpjEem*mZC
$cbG"QKG!6#%2mQ0YY5JB3&bCh$DNp,EhYRpd(c,+!J-U+4B5#$F@Hc`jB&,Aa"3
Qc9!X5!D80*JT&)Z#l1a[,F*Gr)*)*iAB&8mZ@,S0#hDQ-N[b2`3KBS2YF$1FpHl
Q)2lc'0Q%*XVQD!L@0k,(2DU+R#'9KHeI(*)3jP0#+(k)TY,mKP,-KN6PXP,m"!,
$mM+QTp1-8`@e&E*j1"Bih+M-@ZH"q(15Nf#($6BHbT3m&NaPp!Q-010NYL3J-S1
Kaj)2l*P!!'XEcP`!8XYc&F")aTN,`$k"!*l,T%HQrdX+8jjE!8ahikmj!5M&c4k
e[GA8E)%J08CHZjG%Ui-,dGTCHBkf&[r(lI%CVG2ElP"kRqJ9k53$rkFjLDlSmjT
%c2!PYX3-A`@L*GA`CDr[E[L5*f'1(Q1'3fEV%A2dq"JAqK3mGS!cT0d,U9-Lh$0
B`0SjClk!p4(c!NB@89&KeY3A!'3fKl&+EY+04kR@d"#alIij9jCF8k3lUeIQZFA
Rk@B-Ne`M+FD"kc"f,e(m08e96DN4@c-Mm-pc)A2m*4kF#Y25Apq%i`3C%0SaZkj
0F"JI[lYDh0(+@@rViQTXH)d[2qRb8Q*N`Jm3"aa3V"qjE[N*%L!HZ*Fa+!rXDIj
`+[QT)b4"+Tfc&fmQNJdEUV2k)YMSXq!Ea!q,Mp&&DqIXZrHH#BVZ#1kr,BBJjm`
3D)31KI1r)LE(JEQP+38NmXH#[Ml+M"2l"&0YXN!r8*AeE-$3a`,6X38f2Xm&PTZ
hXJrdNCLYciY!b)cdpMk3!$kRLGel26DaDFmPi1leaa"XHLi)rX[C')+(c`3"'0Q
YV*VCU!dbb`ipI$,J6`SGaEYe"-V-3MV$`%p"d$`Z"0S"Aem(aLANKaq)6A,4mjM
Np*4*9RHI**KJj[0PlT6,MimVd6c[bA@B*cHrqAP-ER,+j!Dk6qjJp`"X'0F%lG9
p6I"Jp`"Xq*G0mQq6Bj-XH4k6I$ePNJep"1$LEjk)qjiJ,Yr6eqAR-VR(Pm3QerL
m%r!1(&k0`bML5(!4XTZ1`qKk4J$b13,"P!A8Ip1!5*-5bm@-h3%[&[qA3%M",LH
(I#A#MjpK8VJc*eF%!!!d%%&%3e)$!'Ec%&8,0#F!BQZ6lq%XZ1++Zd5i'Z%"84'
*b%b4c-ijbc&XY"`eBaa(3&L&)N#Z4r&k*YqcZb!L+*UCN!-je6L018l6ecL0Aaq
BP690N9QKQD'5UH1NQ@-%Z$c[ZlZiA)q0cGGhrqlVrGhrqli"(93'!!'3!`$a!4%
K)b(Q$Tc[(43EqkmP%m33F`$jjj-#qX"9`3P`JA!4F1&`&+iFEY!GmCEUNV45$Q0
)iTDf5SAQ#!QaNUDqV1RiGM9#IPdVcTP1[jGVq%X*3b@,qSPQcaP,rba[jemNI#e
&UQAmTi5r5Y28El5T18ED4fl@r$RMk3,jHIjG`L*TR*V*jbEF)Ze62pCHb%QR#q9
#2M[K5qPqpA0Y3Ni$r8cZUpAQh%'rNRhmdi4FbDXZeSTb(SZP$mN2mdF5TNKRe"0
mFX+MdRAeGpT61FIT42NLMdkB*#%4D!rQl+"Z18MVc(Q!"X[Aq*-*!9+A@X9A*+b
8VUMrd%lR90+PmSeDGFi0G*Pm'rpR`K+T6Xh6'R1fd&[P5rcfK1A5+V@0cdZB,fe
5jfMe13*0NIYTb6P*XI4$1C(r1Q'!Y%[Gbpp,q)ed6(eI-q5NdSrN$$ibi8AT"rA
I@Na1+"dP[kYpQr-MrD@FaRq@-&$+9m2jm)3r5!I9hfXEF[E69q4AYGGbYY,rN[r
'rcGKQ,4'I8BVc5QJrbdIiAp+H%ikV,EcCa2q)j@Srp*fjN63dI*UATj`lL(T,qS
lfXDFpI582%BlN!"c%heE[TNrRA""1U31e[ENr)Uq*@Ic$a,k5l[9Sha)`K[5Ep8
hYErRC0&"FU!@PE10RT6rb-mQa%PhUrIab`RRTFI99QeYcMSD,lG`6d+)*+TAYAY
b0Y-`fDNT1@EU%Q69*59359"GD(GSbVXDerPd[Th[i`rbV6a@Lp9MTmGZMpdAqf!
X0eVX&@A&NGV8QV(kY1REC@G0mc44bM++NJUABpa-BF1RLp,TBP%UV"%P1e`kh20
`dd$d)K!3G!(*$pFmYF8jVGRHiY4S@BZcQ%jVFHV%EkFJ6LIH3U'#d#VB+%(H6[a
diUHbZFef8E+!XeBK#K@L0&dA*GdL5XBD9I[[TqPBiIfVk`dPK[E$KP6KIG@jXE4
!f"ZfV95S5VcbQ($0HIdf'%qA)'FN#DQRdN+&M3G,5JdrP03*fd)6UqZ%I+&8LZJ
8EUJriUT1)NMaDD%P"dZU8GrG`*M&E5ZpB@cC1$lfRJb$%"SQb!8PT@QKrdq3!+D
b+Gfkp69"SaD4DV+J#4C"8jd@MNJKeLaCZ+!a,eKNPiAmj%Y`*)XQ8SXX@-)d6UJ
@@G)Xi%m``3G,)#,&FJX@F"k'*B+)(iNY9$-le#R8`QB3C3V9@TJU*S(L!MG0KKC
U-6XYM#&P!L*bJTY9$@9B6F-8TG)QXF33&PPD`2@UKD)+Tj`UP-SHa0cEFP+JANk
)!TA*JK)(&#Hm6,dY9aN#pe)jc)&STV6&`B"k&4FKbe4SNEa8ZHUBlM9,)!8b&$*
E$Q%D[,)6iiU,S-K%JcQ3!+N%Hd'K!U1eH"J6k*BT%BNhLAH9,B$FiV4*L"rfijM
d0Ki+V4#-3N@,deM""D0+#DKKJ5`4LScrR8CH)90JZ4#"5#[-C*C)*Q+q,&5SNV&
#pS#&NE2TcJS5b4JNFi`+3DAJ"!b&F&+Td8a@XU[#bP`PDMCEp6VB!!AcD*0i9Rc
'"9BLHTJ(5jQ)CY-S%`&TKF+`"+2,*KQ1LQbq)"'Ra,-$`[FT#Bl3NBY`R")l8L"
3U5@-M&1@`l"C1&TbIKVEC6-Qb#%f"Q6F&T-pPF-BAl!i+h%("ck$Da3d+#GYk'b
fK`c2N!$,BjY-*BG@*j(ZT+"CT5@5bLl"XCN1D@cmXGXDENqFl&4))X!aDea9*%*
4MB3LYeC!(L`i-,KL9&a'JS,$3NdRNpVZR-T'E+k#,6#EDbe886b-[8)9Xf4M4r3
S6NDdkBPA(2bC(NA#l$!b#c3E)L%j`9XQQK8PK+PKpD`-[LHY8jRiM"c)jK-!)MY
4AM"$'%&35Bc8`d+ZbNi"hV(!DCa%J1)#2*+BkQd*Xbf41JLDkL),*4!m1(-YJXT
i+8i9+809UF#m3YLD3aL1P8j83!B[N3E+2$BPM-*i5!`9%&*a-'eaNIN+8UB,U)4
1Q4a@QF`1EHC!"`8A[@S4H)@&'b[%GibF"-Mm&4B"#i%X#!3P1eCK89`%P53pS-P
Rf6#E#X$Ua"6CL5P%5Lc-5!Z"M!rKCmCdXi[`4&BfNN-l6c3aar#a9b%fGJ5J-a6
#MI"`L+-J99U`[4Df9X$R(JpEYAJBbH`NFVJ)8b4B13c-[0bV-L"P!55dH&8'#Eh
)*cJ)J(V9Dj(Mb!#hJ'i"Z,1`#H6%,6)l3``S(SBKRf3cL2-UD"EFif%V'a)U$S+
Pf#`fbd,f`1aK-`LV%++H!q4L#Q0[Qfk'D%`QFk"0%'j&Z!SbCd0K$K&436(0J2%
f6)AS3H@LeeIlT%G43(Qdr!jPP&B[KLFD)NVapD#Hepq-pTS*38P+r2&BHda"D1U
k0$613JhYmY@Qd#FP9*[2biRjT3@KakaN$R+A@8Y3%D`Q#beK$pEM%+I#KB[5J8$
jeh[X,8QP5C[6-NS0lGY#)`T+0jDf'j*qi+B,S,pR2YF6#322JZ8V#$iK#bfK'@Z
8Va*5i#C#3j8XrADBI2@hTD[EBike'i55QE"K8dGiIG+)5VJGSR4c(dbeb'mI,Cm
Khq-&T8h6j,2GPTM9EK@ap`J&DjcaL-&NSBdBL294a+2KKN*6[L`GMB"Vp,d6(#L
'Pi+,`83qf88SK&'!qAb[35Dl3JXakMCV,aIlT*FE6'MDbj93PJIb'EMl41Q3!-F
R"H0XJPI!,CDPV#8q+4TFSSd%SCBZNDAN1VK#1%(f(-JV+8d91J-0eQ`!-9iqC@l
YPM8`rq8"d2iZJZ&`Z0-KC-+09C!!-&8`#1e[al3,D0,h[*V3'8+3!+UZb'IVYch
Ha&'S$c4C1([*)05V)E2!qJ2'1M%rUEfb6LK*ffr),Vh#lj@DeZiTS#-NqBP#1YR
l1)G1pNN[BI%5LP9CJ!(C!q[C0-qZT06X*#&$LNRX8'SE,5`MjPKDBMD15)SKLC1
`I'Ncf'A"TBV5lMfb*cZ&iFE(&*4Qaqc0ENm+2@CJfV@A8S'q"ULAi3D)8ME!I(D
+03'p)aifK*CH,!JY56X@LY*F4NcSX4e3mY)VfN[0fT1jVZk51Q-5kqA,FRZ*)63
YdITp8LJ*M'RRCXILA%`lBpU59K+49*UBcb$(klADkh83a)hi1*bU2ERB*`8KK6i
Ci+0"UKCNI#10l,L`&hX['%*65i5#8%0iK#'ae*!!QR(`AZDTMX5@&"3Xhc#d'e*
R$TGHrkaMZ26k2,2fqP)%d@5KI@r%HS42qKiAq,j4#m+ASD!LAdK3emcdRLGkla,
HI*mr%hMcr@'cp[eV#%k4KICpIkcA)hi2lK8Y+!UkN3q#NRdI"Uhqjh#Ad"ZQG,r
*pcHDV3#S6iAfI4!$,Ae`RqrR)X"pqZ!qe"5XJ(Rj$,$5Tj'"PG6"F"kiFYqjS%$
#m5j[efIr$,AP@Tp!QpSaCUe22S,qF-pU3IfkU`h'ClHJ()IDCfeU!q"5i-KL0XB
"Fi1'qci)'[L,kTY[#V9[",2f639Ll0Bhal@JCNa1mEd6Y')@+S0[8V9[fM%IeGi
hqq(#Y'"`$BCS`9jIDh"J,fh[DGmmU`8,@R$9CC0FbhY#hfm@QE["LQq@3XX8"0&
NSIf%MIRQDjrd%cEQTdBY@*9EX`IfNZfRLpT2Gf["i9S`f6BFlBd+2D$3!)@qV0#
h&2U"3NFTY%kK,bVdc`TYC06h8(j9U&qKIe$SK`Te+V4!S5XCpXd+hD[3Ea8DTY#
G#PfS8!rM1)DC$pNkA+&r8ZJCKUFVG$jTa&-IBiS'9iY#A6)T,j[C@,T#&c0f`2j
4SG[CR0XBDB*#0k"aT0$*+1!b[[ZCMMN+ADE3H$C`9D&r91K[&$T2S8F8LK`lR"9
4EQ6V((DI+`STMejL%YFU0)9TqP5KDa4DTY#6#[dEBc58LCLJd-F8qQq&GM&4mKA
k[%)2+r5J3Kp8k(F+rCk46M$KS$A4UXr1&QHCS*MmYN,I81MR#Mf[d)m91N@K[fB
baE1M[mCNqJm6b+I35(CEKGd6Qc&8SDF8qRH&pQ%U95C"UN+IB4X`6U(p&HT@D,C
#La9k8D%b1j(C#ReASB2BKE'AqpLj$f4hkk[3IJTpK`d[Bl,Lp2r*6QH%3[r"lV#
5kGM%lTbTd#d+[8QKFa8k4+&I+(5V3Qp9k#Y-f9,fr`NQ5K8l'PaQ0mXapl&M[Dc
3,,CE8(D1b3(G[lGQN@hX"!qb5cl#8"pAk(U&$QDS4pMT9l+$!fUZ3Yp8k&U)cVB
R'EaBlLPJqr3e3a)Bkj[BI[a1SDX8HPUKF3Vp,hB"X(!Tp,K#*bUa%cK9Fi4qb5R
HmY@j4D-M&KX$SrT8$FaIi4q8eG`e2$c!iQNCf[K4DPlKK81cMcp61Y%H[qk6ZT%
C5p)(lePiFGLDk!UR-U*Y`+jjYDI@pchcE2Z8XVLlIkTmppZPiiBFAG6jb[kJiV$
0VkpkEqrbKM%(2M[ah1(*NCI[qlTk91L0QIehcphakQZaENf5%qSr6*VM1rHA6ar
lemk(TTlFpXf9Rk@Y(2rQhaGFqm2"*fY#a*Hf['qipIkRErlbUImZq0hBeV9r[Zh
&(rlj`PZrq[M1rrhE*0ePIRR6Va2Rhr(1aUmHrNr*)p21r['[ThrjicqHIq1hhch
`q`h"dkrHmrfPhablIF,E0heqr8p((Yeqr[%[E[Khc,*p(f6ImZ"rEI@f+QQPTXh
0Xpf"daIl1klK[JJcDeqJKI"&2l,3[KL*pEH)Ri(VS`82P+@N#i#d+mcVc3qI-B9
"["G!qQ,b6#UbA)YCblAlVZB+M!Q8jKlAF[%9cJ)iQP[R#$UK'#hFA!9ZYjDlQe3
%XR3X(3kial`%b-'KC4UFi`X*lZ1S9R*2DEQ$Y1$QRR8)DUlbD'12&XZJQ(DFe0U
B9%-'2fTSMhQm2GA3cYD%ABUjCaXR,'B'`Q,F"F`rV58,lG0-V)GL[3UZ8i[ZJPT
5C`k#kiHQpc#j2$&RjJaEH`M`k4VYdhLcpZNZa"IJqQR486fBKL6QG0$Fk)$E)Zh
6T9TdB"1(9R#`PHaB1`diIFZd[RiYH[6E[8Ym*JA#[KHe[T[0@Ymka2I"(G@LqjK
GXpD-R88mdr*RhqHd[MPDp)U1@R+R()Hj1DQNp&kd3IZk1pK@C``CqmT[eVl#6hY
I(5F,l5X90ef1'-Iqe4iY1X$@9*d%e##i58DdpBah)GR'M*JMpd+bVdE0A,)qN!!
X&d%H@@KI)HGp03Ba4*TYebEj(C)*$XQUI*iJ)a0Xc+kN%T3C5'Yk9m(HLk6NK))
6'6T2&YQPl8PTT59X30JKfhCMN!"Y8JP,XV-`$8,Xe@B2-@ZcF@kc"m#0dYaSd8f
#a*-'qL3hC(0$aNN!+T13!$BRi8I85@Lc68+cEK+5X"YbZj(UC`r4h2JpG4+5lL3
Nh8P)ZT0``f#dDpfiPKXY0RFb(#'J#HBZmRQ#Sdb[Q@D6HGDZ'CJ@8j+0LD4ip'@
bf8BpjH!88r+,ErePU&RlmM##MmJ#Y5hXD&MY5hamq4)Aqr)6cDd5@iYIK$`&4DD
baXbDV$E@4KYVSrBP#[DICF+GdGaGa0C5J-8#2d(3h&'19(+9C-C%T)S1#k8I91M
S*(!A6RDCH5@rT'fU+-*2%VFCYfdaLQGS)lcDCU6DeUdK'r'e+1QJ(,)fKJ9[(LS
`P#$L0aP53fhKSIb#pK+'Y,NpM34A0bD9&V56d#GpMM,,jk2JRS0l&3iCi[1qF)Y
mjcllm1kNd)+NpS0mXf&A1iRNGpBQY5IQFcQL25f$V`AhZe%LP&eh&k!i'#)A(-0
2J[+E'h&"``qlN!#3!"j2,)dK`AdaKaP&[SV8C!Yp8V-&$M[9M1mTcHP`EA#!emf
!CmhiQY,F#GF#Y`lZJ-refBHSY+3)8R%eAr#e0JrL'hN"$q@T2)NI91,@mTLQ9I`
K$"PiL@0GIK0@U4LH3EYmL1F$UEf*%VFCUc6Vm%EB8SE!+&Sc-PEcXh")*me)5me
)r-hiJ,$!iMZrS)(I$Da3i#GK"UC[KUCGL+f8`,8X5Z6j5U#-"qZ*TJc&XjBT#lZ
EAF0JLc+),$+LBh!P[&3Th`KZ%C!!aX"r!&F$EeIL(`H[8YcAYVjm(q,$*JLA@f!
6Ce"`BJZ3!%8A!(3Z`&Ha"A[KfZ&3E&U!Ve8,d-CBJ!pR#`!(&Z###rVk3R#T*2k
$iScJj,`AqAfH4CNXrllj3dbSi@"%3@KLkF8MYP45*cbf`eD3!)TMSpD8[#M+NC*
$-Q)5Nr!&SG1c0bR43'Uh4GC%hMrl(P+l)"9fc*JJCl&8YkM8V#h#*j0&!daSfU,
R3%D'@I5U6eJN5KZkC'R$FEJL1(amh6m4EMEFF,KRi!E+R[f$Chk6)XG0lPUZSPj
bI3FJmpdK8lQqb`FC,C([!%1rLaHPrAZJ2![Z%"`%h)q[I`FKh%%)Gc!AEUMX16M
F"[C-90SJdQ0@-$Qi)l'X5,bl62KdX0#8TLdX""NYSS9)DJZl41PJ125@`Z'lk-(
9F*!!kb$N#JF8#iGXi5YN6rM#QFK80!Xb&I@5D@%F0)rX*P-1b$LLK3!k#r2`3!@
qB)32JVX!"pR#F9cKN!!VR-L&l3c(GrNM!8cadk9T2aLklBYMkiBd5G364EC*mM'
UaSm2-"%qhS8e6Z4MY+XrINf8MT!!+K"9ShZJcq-Hc6KHRX')m'QUQ$Y3a"#i3`Y
Dk4rhY@QCLc8qU(b-jX[(3G##Cj6FD2Zjbk&P%'0A(PV`3bpKREhZd`2&S@NZ31A
Fp8c6h0eBip2rA+6`ZIZK#FRK#!l`#*,$%4cJB94pKrXaaZHDq0QNYY@(2EAClZa
3K6TLlQbEUK5XN4,RSQd`0eU8$LH$26,jB@6b`e"l1"fU($Z5L%C[iQ'6p'2,(fQ
K6EH-Gq"B)FFYQahJiD-QLHk##jNa)j[GJPE*,A%Q01d@I*flT4%N9(@hM"!p"6Q
-q4Y@RMC@*JcCH,mHZRXMbYd96r4*+HQQLP1+32i-C-$HP%036'e!-V(dB)6"HYH
8I-GGEI5Q!dm*Ef+GJSp)+IM3Q2+Hk0N3EXZ80Qb6V'!k!6r9T1!,9FSm85U))N3
aC%2!V$AhhdB"8BMC+l"2eF+-S4JKN4B)l@''9'lMG0EdQlD99lG[iKdfH$SU1YM
`T-3B)5-`UG63,Fr03Gdd"aPYcLJYeQq#'8m`Hk@%1IMi1`G0fMPj@UcJE%TAfFF
-TDC0Zm&T6BhTl$38LC0+BpV[XZPAhb30'X$cd##CYeU,VE*TH-HUS5PM-[S((5R
TMR2+9)pMV(k(DP-e$lrGc3-XQMG8LbdbZ3[+lYhZ%[2chQ8H$QSq%XAm)Lffbq3
Z4%1[Zm6mcqib(bFf(bANq4pTXBkI6Xi4N!$j"1b,JemJidF5&'kACp(b#T[5`R`
FBKj5C4lZ'@9$[p#Nr3RD-k*eKXSmh$G[#"abl'V6qrl2pmjaSRR)jlG'`Sh6BV0
-,r8%ETiMQpb+KXfYD#(H@Ul&*MY0fJ*2A++k&3hV@r&er9Dh&TY[dr(d$"e2E,*
DMKECFT5&PjGUX4(Gl[1%*DcPU0HA!qJ[RkI&KRHlca1IY*DMr(%lbNDhCfQaT)j
!*LGeBAr0$8!e0d9c,hiF63,0[H*a0%%dGmSpD1jSlZCld1l5h,RCD"&UlMlCD+Y
UlTaXY+3epr$%NhZ6-P!aPEBA'*6![5J$C+!3JU**+5[0''3*2b5lEYlBJSGKU[J
9*HaQP-(`FJcjr1DNY)`#I#0T0d6%Y12A35ZS[fSYfD0kf1Y!Q[Q2UKfJbmkH2p'
XE0&@(M*V+p(`AlN(,Pq8eKbA2@XDHha-@%QePCHef0%G9$`LRECD'rd*HIM2*ih
qj(%YGN8YABa#r$hdMYAD[adMrqifiPZYMA+-M$)Cf6SVIhKqpliRC9I0"@+-kiL
CHSLBXU(-6#4Q@MpLl&(-T"!cYSXBE`ic$1N1aQ*F0$(2Pa1c6f#QL*NXCM+BSFb
`b3*R*Ke'%#5fm$$$e!XVL+Qh-m-Be60'pB(--,(UKa(6PXr--m4XBN`h-G+QfF3
d(QH'A@a9(M&94QDB3&@$L,N53BaFa`a6[j&GFL1lf%Cfl8-@CYM!)5E+)5EZ)6E
KCUEbjX(-p'''(FH"+QEf--0%2m#%[QN*-9PHCTK`@51CBFVfT$*6bJaMZZF6CKM
6h8b)E(E%f@ab0Q1DR8Y--KY1AXd-8lQVQCK%P4Nf)C%T5f@(PFSZNmU1)h8J-ib
GJ9hB`%3dX-N'GN`'*T!!J3PNB*YN##"Q,f1aPehJ',[f-6EY'$ZJI*D"mT1CB@V
bKc2$K%jMS[c)"2ea-6%CMFb`bf5`b4PXFJE,AM&-P!M'1S)*XC1*Zj-ahEQ3!*J
5PY9+'HY5fi*N1kPdLFlYq*!!04+Z6i@ZT9IS&DP`RJTGr`KZBS9Z`8"0&Gbk#Re
UAS8qVEP#Mea4SAZ29qMMe!Sp(8&M3)9HP38h'QjKK9jC"*F2YkC#2if*TrI!a9I
SG9&`B&bA#jF#"`@hi82DEB9`MA!Ai5)JJ%AA+jTe[EK1ebp4(3ad[5jHearXTqY
bPDiV(PdAFh6pRZ0`UESHjGIeEF2KKZVk(cNF%0ICi9VJFR9pV4%1$"iI$"HYkhm
4i%TerHpHA8mZJJ16j'IJ-*Jd60GhPHYkkQSi+%S&)I86A6F%k[TH)1D[dI8B,(C
LF#FQl9bLkqeGZPi#`8S`k8Jq(!EfAi6$JYXY1Yi!S1Y$,AT0[N8[EVESdb2J,X#
4a3U,ELb#f`-(iY4`Lek@BY'RG9RdXCMN(@E4Dbd@rIjbZ0%@IF)R&YeI#SI&q#L
,rMbB2VrBSUFA`VA!B8)Q"M+K*"0)qb$!2JcX!f%I&!SAi8!3S&$``!f'Jb*KL8@
[&q#!8*m-&`J("[9j&Vd0!V49`Df'@`-()GSQ@[40IVKeF""k%`6F"'D0+Ya#Lli
&NlEJBPZJH!X3YN$j+JkA"4F2"`DA)-JP)&`DDG'V[("JF18CLhiDLZYb,2TYB&3
0!@l!T@i)X1K&8&B%`BX`k6%)qKJ*)-`C-(iB$%j!L"1ic!NFkR8)I,fI4Hm#NfX
B[!E"VRd%emHLGaVKMX1"@5FZe!Q&RG%@I3FBl3$LMJ`i+0d"SSV0Nd'8`9c1YHJ
+$VXNMDr5LMfVd"c*Up$Y6Dr3()q#DDr5@#c@kf+G'[bNCER#0c[h&1ZmUeL[
Ui!,KKX0p8UcVKA$aF$P`dF@k"BJ@$e`rZ)&``q"bi@BAkc8VL[9L$%k2+NCQJHY
6V%mE9+cEMA"Vi*k"!f2l%VM&aIVB&VLmBRdl%#pKiU@2i)B@ke8@Z%Bi)&b"`LX
CF"#J%X*8jX0"k@N[A#SF'0ECLrAUNFAk8a$S1S6S%Z#bi-VK`2`DKm2PVNA!!HP
D5V(H#FDGUq&`f8i`l``SeKm!NcXai8&FA%DJB0!-T@B),%)J%3*Y6Lr@$f(#65"
QiC*CqF9i'`+[BPi06%NrMKF*mHN0H1VH9qYF3I&$bFS"#Vfl0Ri&6m%Epqa9I(S
NHZ94$9@qcr2NF$SGchIMqr@6`e[L"(mMAY,!DlKYmKdYY+9f%#DH'FFheI'U1Mk
fJBmIarrSjcYUq5E'C,RXb4V*l@!b6CE@cfjKM'AAQZ-Fd4+IkmQ"K,589&D%Y+)
*[k`*[aFDG(rG`@a)-lVR8"L'jPGAFU&4EEe5aqp)jq2Uq,jdhKJTZeEc"bYPPm)
l)eZNlK*1*(8KBEA3bUT["rF`'B8%*'SQp6Z*&XYK'brFPHEUre20XG8UdpaCf8h
cf8TH[BjILH69iIb2LY6pQ$[5lGL9CYN$VY0Yq)H(QCfdM!MNmc`Dd@Z[HSUf@'i
P4f(%Upr@cFKDd60Kf3U@JMqG'lfQZDb0C!aAa6M5EiC-Gq0adj'J0-bJA$dm$(d
G#Ne3$JrVMQ+Mp'!blKFb'IF,QCJ+JL2VcU3h5Jqp23ATQ-QiHk1QP9aQCLGjP`I
AXF!QP,232LFG[BPAmHPP0ML54lfEkFADZ,bIBi5"T-EZ)'R1'J+5!PI`@$ppPVq
!V&[+IHZi2C,lAZ0Y,!XY-Fe#@5-G@DM'jhSd`T'GE5NL@Mj*8N5q0*%A4XTKar(
f6Pl@S$"P!kPAP#SL5-4JcaLJ,X2lc'UMq2K)AT[*TlAa,3fm9LE52P[V5U%1K4Y
b@TUbX5R4eahTDV*a&IF9mKVC"[D3!*6Cm,4Dp&&KaaNN"fl)3Fq#4QeYT"aEaV-
+q6%[cfVM1fYj9LB2m4,c*M-[%U0GBiZ0c$c#501CHCkC'jJaXq&I-A-HCMAI`"C
rBZEAc0c#c&qC5@$Q5bpr%hBP@deLR(c-E)%T-N[NI-ZXjaY3Lri#rcp,SMD5p'J
%ZXl8m4Ur)YPUHFQ0cR2q@QkX038@idL632#2`a[q61P&*+9dK"j#d"Zi%+QkTSr
MKBV%%N)Ykpm(M1-%deFEYi,2-9)2HSlB8P$JaLjmIcR+DqS8Db9`&C9!-Rl543F
@DL4-f(-1lLJPc)k"V*i$*iemUmFS(HI&&mQGf-0AEd@2jXHU0r1f"Vk[PSqcmr[
Yh*Y*$"ElM#cp6L'PC9,""C&ULc2S4USYA'S4!80IiAR63l@"LhL-K5l(LbCYD6E
k#@(HGcCKIR)4qKUKd98-'#%j!%GlRH++Y%+4R3(+96XJp$KH%kNi!($FcS!1TLd
fQGBqV1Hde[CKYZf-00dhS@QArdGdE'Z+(`#qN!"2Vff#ijZak6-G#5%C!Dd8ZbT
02qii@9,BYN(+)6Z(mf6r+Rl*cT'RAV$c1ml`5$qrSjVll@C(%a)iV(hKQ"9Y*Dh
S4V,9&B'%SI%-VmP8(,UNM4I3@kU4epLE5$Z(Jp4Q3L,6jT!!pQkPPI3qBG4Ba)Z
+qC9#hPE'AbMM5!Yh3%ilNE20cUm,q',SU)*#XlK0@&YNNa(h(e,V@XKRXYp11eU
i-aqRGNMTEdUpdE0fYiLK[Hm@-E6hh8#k&hIlYSrMEVBSQR`kkA'hATQbppekMIH
ifp[JU3PYI)+GTpYjl3%q&V9b)GE@8J4"F#LheH$i2N4)+60)Ea15N!!jFbDfA01
8@3L6S3iQ9K*H4Jf3!0PS)YT96"2i1!D,($Fi0V4P5(,eFGlQrIQK`UGi*[YLl39
!K3BTP$IJ[1cFRNP-Jld$$VD8r5EDBmPiSmpe2brbmbYqhZERcrYjSCq2G3"K2(S
CTEJ'FT09[1NU`R4eb(69CET+TdfVPR0#`aPf46ZIPNR-rED%1FAR#PCl5AL"5$K
Z6dIi0eVa*e[aJaKqdVMfHiAIX'G@TAQD5#09ii9aGRl&cKXcLDQfbqH2mheXVql
2C$Y'$Kbe5jk0"d*(S4,KBPZj#1'8TQ'(#TpJ9H(IhA-$CcBPMM6R883hJHJiC6m
k+9Z2r-Q"5KLkq[-fPZ8FCDkp+5eRjfHQml&'M[TmV0GX1a&m1b8`pP$YeANmbAM
!"$+dSV)9r&jZ,$3&hqNfU0k6(JBkcjbK%K9V-cUjpU$pDdl,#9jAbqqdmbilIcL
6'#cU[(bEPeqTjBefGVDCa'"aaFMV@)-icjUEPeL6`f*(!Gmee-'I"SXpGp+@F%K
MHJB@k3b&VJbMZXhp2j4-#QTZqF@L-66)p[VSEV)aZL$ie6!#9@DF1@NMm3i(X%A
*U!Q0adhT5Zdl+hKL3p5Xj[fqZ-2YRSJU(QANCMprUj!!Qiem4cSr@8Xqeec,i-I
Yr!BlVm`N"SYVG##2J-hL0pRjHMYIQdN-&YI`IFI1cABH4E3K%ib`R4M#RfcRJ2"
VDc)*lNGq,Q$K4q6(!KD5K$@F6Fj&D*XbX)R0k#BfcpaV0XpKFZiX6I&JLUh*L9E
b[8)d(6k2i9L[`L0AmDRdG4jTJp36L4MXqiI[**U,bk49PIcK@RQ`RcFHCi$R6#p
i`a[T',-04PM2`Hh)9!4'X+mTS#f5DDV-`VNf&BcS5H@Xm@chAB#)XEZlq&Ub1pb
F5FaDJ,FLXQAAX+qCa1b`bi1kq(U"2eE,kqbNQG8Q%)2&BlDUkM0V'TKVcGMcV&A
9+0iMMG#Q0$+65SV-48*i#ChRY%1er8Iaj1SXIL@p`kV58F#I5@9*8Z%LDd++YU@
[PjBS0+-l2H4fifiqYKBr,h*M%`!NTI8CC3b"0c*)CLX@"4*5YaCc'!2,!QQMdKP
`'D$BCD&0Alh%N`4bfNh6CD%0FMDD`QTm(J2NV1Y&#dNQjE!QqDlLmd05a3R69NA
@52,4GCC"0J"#dUSZrVbG96kCa$a[a`q9I!Xl#L(69SeD[r6efL(f`G4k5'8X,be
EYEF(ZmUIJpddf`%EUdhZ'hM)`ZZ05Jp5P!RTDC!!NY,TSSiD3dZX-'kL9A1!h%S
fE5EPPSSf(TP1XYPdC5Dlf8+l!h"'2&@I53Gd*%"(V4(EKlP$TM9N%&8VT'rVe1r
fHhQ"Plbbm8!MhbV`!dAma3Cq)**rjq8(#V@T)*hJIkRPkqcm(MYA[2c1@YlPj`r
A1DSYK3eJq#pfIU"5Zlk$rhLF`1F#1pp[NfLSca88aElJNYq15I3Z52e)&1Tc4IY
*e!j5&BRLb'r+*"T$IP$Q5%B*Z("&1+Q$X-V"Klm+$e[K%eNZL3LXHBAm3Xh#!9D
@!mL2d!`3M3'0kIf@r,,p"2(dJ1F-k2[%-V8rJ8`GGprl"0kGm260)R)VN!!&Ie'
[lldRDU89XT!!F4R2TE-(8"b2VjLP&`54&"1PMHK(rF)k1,cEiSAMfk3A,TTl2)M
Ll2e)T6*QcZT-[UU"Er,bqe(-51IH"Y+U3PG*D1lM+(X$QN'%pDB8-MkDq"3LAD8
MZ&$V'6eVMfe566RTMqb9ZQYYd,#Y&aKZ*#8hmXi96BRVk'3#9eKlV*LPc+-i$Mc
1Za%2%'H'`Hf##pdQC4kHfA'FXmlQ681+Y-m[!Q+JQ9h&f3pPh94@fZ6X+8NVNm5
8$ejeYci3`)I+dMk)Y-m1jpmQl40Q*NjmGaDH1DKr,()r@X[RjirM89iq([qeJ`C
HkHATIJ,*#a[iJejq,G,-GX44rPdIb,l,NedEdj2-GYD+%0UdJKr84&pNAC(b4fD
Y*kqq!r(ZUT0HEe6CUcS&pX0$,4jpLXFlS!D3!)TBP'j!4rbU0M3QF16l`pG+,FM
,9cTPU5B+VlLJDk@rifR`DUFX&A[rcXibmbHFCeqf29,Q+1adV@h(-aZaF0V53MU
BET`ViXNF[*8)UCLC,KMT8*D)a-I#SE)dVPU@EVj2")JP+$F2*J-h[`j#(dD)*S3
$Ud4!98)iX)F4`N559JPK'#2JQH8$HE)d(Td3EPSUiXNG-TMP*B0Ck!d`rMR8rHq
+j+FADI`3,1CLJFE6H$a`GV54*TQPSk'LmfJ%EC'1AKDPSq8B@mhH-510[iLJAA6
pYK4iRYm1SdPiCG)Hj+(a510lGSR12DQd"Bm"SCqcY'H)+1e"C`4r+XCq`J)2IIQ
MX-$6qh[`fFKr4TCqj45G[rS)QRk&!r`9$Y#I+8Zlkd3m-85%hVf(QAj%p0hSiH(
(DkkbM9#4,C!!NHa$C#3EI6!Q6-()3$$+(LBkXh0*K"1Im*RX6,CJP9`S5XQi`i6
4k'#+,CX`'%mD$D1*CPH53'q!Z8$Vc9)5K%L#%)ABZ&hp4GFZTRKA-dKiLeGLY5J
Pi[MZ`&%P$K&GL6QB+L@k4I3pPqk!G+QE4FQ!$J+ek2&V`(Yj$#S@)"K`QJCbQJB
2SX%N'LQ5F[3FXl6h@a'2)G(j#*%lpT,FJHl!)Vidd45%)a!1*@%qQ1HMHd$NHPR
+[b!kmmNGmjH)0%f4aSk3!+8d((!D$RJXmYqhULKpZ`B,l1fhSd4m3b0X[iAFBm2
`X**!'2i)CQ2ECHR(9dAT4laHCqaZ@FTS&*dCb@#FX8D8-V$VpUpPk3G!Var3*m(
q#KDjSK5+cEDr*dZK1d4mGb5F3k(,IJTI)8F6cU(JCRp0PQ,`$TmBG)Ua)pI%S'p
$")*Tmf42"0i3Ce'NL1%LqBJ'S"1a!LThiMfF1`P+MZcCb9$)jc%-lea)KLGM'*P
jfNIiNPFTiUXP&YM'pYfLXad5ZpSMb''f$`-p!r3EJ3-jTQ((5pT%CdNMF%U1%j`
53,eTb--Pk-8dV3("&*'@+Y)d[##[&+QkE#%#C1q#+(+cJYG%2+j258iVb#(['Mb
X5"ENMm2M40)e3l,Ji!qI%&PA$3YbeZ%$SZY`-TPk'2fB,Ie"HN8N[qP+&N#,`e0
%dR9%XZ"8MN5+V#Z*"FGqT&Td(@'jr8Ji-q6LdT%!NAABXD$k$$mMXJim&X#Jm28
Lkp"M3AS,EaGC"am,EK*q5R5&-fJ4[P!N[Br`INMT)!!4kBbN6m%#A%MR*"hTiL!
fKh4@dV(""d0&ed'L@6SiA'3pUA4)I"$5NTj9qV[SC38fT+H9MMj&qm''p,c58Br
YAbqkpM-!Y(q`b2U'kC!!CMm5%HNVTU1@f`mfT1qB$Q8EF'I5PdcIJ3AZ[)(GH30
6[5%(!`#i'bCM))#3!0BdNSG4&BV$@K1reT-qN!$')YHmX&adC9S)J0VA+,VfTG,
EmCSeT$3"U8r!L651%Mf0SfNpF"Z4ArEG*dYEF*!!Uk"hAiXXV3S92DZ3!&@U&+N
+He996P49)B98,55X+SYN[$c#@CQ2,&H*IMq9b0J[!)a@BMGI3")iIEIS2,d1SkH
2)YT$SQm4CC!!D$qL055+%eee8I5B@DVlk$k+6$)1L[84H-%XB,XIje+c9j4Um"S
Y2h*Lm@HLUlJCph&0Ek6*CQPkK1LDIS'&cD,,@%6N-b,p'D&p3T`X'9'260JV5e2
a1V+TN!#U!CFX!pJSBf"M'V*K`fBNCDJE#hAhIiChjf%[ldI@V%AkUN@1+%6(S[[
,4HPq`,3lfQ6AK%r)9(qCk2,Ek5D%b2cq8V)crY(dNPND$l!c(TY3@iU(C%Q0*$h
rRZKkIL#3!*h2,mD&dfY&9hSK'8PA%,B3,ZR$4%pk(Vf%&dQqJ0SdNc$B,EXb4`2
2Xmp1093Cqa64Z3q2pdMl)N4T(h*@E43HX@dQR)41d5PJc#RX)Gi$,''`L#GXf5L
U-i&8Cmjk!52e3+kr5+,G)Tkb*5Mef0$kd3`P$b0Y&D+cM93"EDJdfeB6P,Ep#0H
3!%eUq`RK4(,I6AibC42ChNeCSR061)P3pfe#rH9$AG8)@1l$rM8Z%PeE518YE8%
QhP+%+N6DJReEaDVM93`JVN*2a98!-,jAmI3ZB5pG`R8[NHYH3QUl&%%UadXM4HN
512T`qDT)j%&@1eFG4FM59"A4M$4d"CbmN!$J0,E4LrHme5'YH*%4EJ1SmJ+)9k1
ZVdBZp3)QhM"-G0h!dNp4ZLJ8iG@S8Y%kdI@BNG!Hkd4iNB83q,&"41$(b2l6-jZ
P-dJpfdI,VSHC'!qr*dS2il8BfrI,VUGb5-hie',4GF*#G[F%VR##lF@*&D,V1V[
hpA9Nk2SB8ES1%EH$@4I1U@XK3E[Q&9fG6),1-`KCIGkjKK&'Le)R-Z*f&2Fl@E[
Q!8$Q5,IXI)!NT3G3!88q+dXA!HdLNH[[4'UbVj,TMXfZ(H6&MY)19*dl,V$`&B5
XjE-$4e@'T+)#Z`c35&C&Pm`bVR`C)8[a-U"&'D#0JLUL$,9C5mCpcLk5kLSU49G
&(F'T3)1U)T!!h,cL1B5Ii(iZ[C!!0"IdH%,@Aa9G1MNCTai0@5d0SX[L*iR#3V+
VTErSXFbQLE@+UfB&))ZRf%0MmG2Bp-fLChS8RBrIVSh9,)(()S'ME@IX3m+T"j!
!V*&!T`*D6dA#RBV$+80Y9iDYRBS%A6C#G*B0KB)be'pP!+Y6F6c6aSLZDB-J[XY
ZC)DGVIdCd@9RpBKp#F,&*"b,"$UfKB91K"i#4XFLpfc(!8p&1@dlFYa83+EYf-1
TU(A`h`#8TU*mi!9FQBVcp&i@RGjbk2HLjHK&bl%BcDll[`B``B%@Vj0G$Ai#44Y
`BJh$%ESQV'D'(!(eSaV&DVbIQG(%M)YL*S@Bjm1*5IFb-j!!Q"G8CTU*bB`JCTq
4QAl%#&h-j"*6Rdp-'fGQ%$'ELTMT3daM-M-"a'`T*a+ZUN*bCEAd+QccUN#5K&I
03jM(NLTJi58l#j&I,aeR)9,P*CBU,q(S,V&mA9A4P&*"V',0pkTh%BjNB9q%XeN
B*,UZ%1!LA8'MrNS'#`FJc'%K+Va+"MiVldE)FQSP'Tk9,$GA6K>eQ+2,dCB5S
,dI!mcEEfp)fSDTLSGBSShBDfAmf0J!F3SRSNQMUHkJ!k(br5[!%963fbdaP!b$2
**+1G`5q10D'bp"6UpDG3VpGJYjq+&ee2$55Ti#P)r&3dDFQG3)Bm!E"68bP,eaZ
3!,Mp@+!GI"dGI+q$V@@jl,UqJNM3PBRN,V!3p@SAJi*G5("G,-&e)BYhX5CSPeY
dAH--,*a!b%Sre`"3VN@`%&A,YB%X4+9fM99UR8KDRHcm1R&qR3aqGf,I1KQXld3
kl'3RfBN@BLHU``SNRJH3!$NVd%bqmh94ZK1j@82Tl%%dMamNA8i8!)8qSNX**2R
IM#-`Sp-CLRlQTBMaRIGZ!!48Z5elm(BSfG@55dj#E$6Mi9Cp4qNrSRq'IqAIIDH
ZXlRCdG%2ZGe"d9X(4bpKr`,`Eb,qZ@hrh%&I%Ipj"f%cr'62&m`%j",5E#[G*(b
%q+h["K'd*F3[Qq*f6r&i*L2qULQFraNC#`*r4c!2daaahSciVddcAZmJI,NT[(A
+FZGFTmRIeUES'@G+Yj&hVG&Yd3&1TZJlTeAIVA2G*Rr4d3(ZbH8"34jhR-HcJY`
V1X(M#I*iTMM`Tr6Y[PiB(IdP`hX)T``GNk2R%d0)YpJLKVKXS8f%aG'2HYc4Nk2
C05B'Jm056i!$kC'rIHX"Jpp&1`L2,[%%4%raZ$f-h8S21D+Jk%rM6VNpHH$PFGl
)YZA*c`,,Pj+ePE$#0XFQi#fHTT0pC1ZIb,`TK-hFk1L9K2i2V1D5hGX,rlX8+ar
('5pqU)R4I",GDQ9eZb1Dq,&lrk(A41[a)32ZHcTBrA(a)d[9(jDT0bp6MmE299[
NYJr9*2R3j*RmUEqEfG"NfI*Frl1YV821RKpb9QNj1d59Rf4r`d+HC[p'2A6KSIG
$cPp99jpp*H6fJ5HR,&9h1i,N%(A2akVmiT)h(eTbqmGU+M-rK(a`2NjGqp#02qY
rkZ58!5F[U!I2[h(qhb%I["GbqC@i129#Ac@l,rl8rf)QEb@aIHAT,&"AaVNpBHT
CBJEpNKMmGf"HhE"Vd[qAIrXrG@j)#*VhqGBrEId0fi4[Q-NCm9*6TYikV-2i$dh
ahjlpmppZG(rKhRVCiplkVlp9Eld*@@MVIccZehlTR11HlGake2RAmK@R-2T,Yc[
"lEl&l4k+cID1MpKfi9DeCI%Mbi+AU[RRP`jBpNE`4`jl)Al"IqEqCZkSN!$q*h[
r[3fR(MdA[1cIrFp2RMJJARj2EBPl0ql#eILiUr(UMm(r#LCr[ik,LhXV11kYCB1
@[49RX[K`F[#&bEmNrX,*Yq2HL&1cKJ`CmTq(hKemrTckPerIVUk&DeIAIr`LGKp
EIM2Cpc&ajbHV0cedibmIZ[&ripiIG1l0Xr%RRiN,H5-Zj(aFh"X$3bEq6)fk%+)
1hhTBrEeYVaIBl"6RUlp6mjd$R6pcUZZQF0YILdTPRlb1FlaP0b``X$``m'5FKi4
R@q&A[pJkjX0qjCGEhbmr&hLZpIeqrIUe[P-qS(rVZI)"-m+h@pm*I2Z$eN!#XY9
39aaK$!!!(,Y"4%05!`!`G3p9$@Be%4!KiZj#[lbmTSr`90k&UP2MdMj&)AT+[lp
%Q''CdS'3!!Ci[(EE+N95THRShU+5b)K#KZ1k2CBa+@fKJZiZUQ8X-cTGU944C&@
Z-FE!-CVSqjQ9'#pJK,'@i6"h))b4l*9CA1Ykj1rrpj)QVC!!aM1c1rXG&@C1-b-
2)5)KN!33)H8EC["e,KFH2,1I39$K6*3C[[h6J@'P[M&3cBX$9Z3(0-QhdZ5#aF2
ApP@ppjF&mm!5UikF'CdrN!"8KZAkDP2H8BUJ!mI"@6XBNiV2H3G@jqKMFHbMPP6
eD20*rHGi8@rFaelX"eEI+-((YGK(3HcMT,X5m"M"F`bFNb#J5*!!)#Fl!,*AE4i
H"i%bfc-pS4KE$d%5PUd5dmUETSVNq81)rlj"E5#BDQI$JHIRj'r-YR$Pr56IIdZ
p4G2IZGAI*$HGfVcq9VV5r53AjVLr8(Q1"`-,k2rF#i%&&b[iVBkU2bph4%DR#+C
,(-`%k5J+&LJdbqGmMjU#EPrh`9Lr(`9rF9#hilZA[H63-HDj`Pk@8I&9i2SjHK5
VbD$3SQ-2aH9iR2Aei@%F$Z,aa#[UFGjrbkI*%IpH)6*41Ah$!5%a3C@VXj0YT4a
&CVhpFF#hU+$YMbGcCV$pm3PZbPr1GKYT`lc8)L5[Z!IPCTp9p'XpbX2qX+la*ra
D5e4dXJQM[*3rJ9HYr)f@D(q6IjYj5@Jd`iI1M8#SdZ*a)BUrafNc)iN6GZLIKT+
+'8B3bqZ))*KRQ,+8Y$')JQf8%JqE"FL$!&V3m9Z4ma,j$&L-jHBPDmc8mER(2CL
m$[3qNZQKJQ6NUX8GVX9f91i`f+r&PK0!SACIfm)jKP%XU9KL!DKHh1Sr@E"d@qY
pVFI,Yc8!1YIDNip2h9bXQYR+p9baqC4id!ICEUNj00q0$,)8*%#V$eP+kP$r!$C
b&V$ipSkUPCCCL3$AGB5hKYV[G3qDPma@!R$p4V,I%Gla'YIBDjD#NplAZ"&bh[I
41RZ,EPj"'0$TVEQ[E9f6)BKXbjLFBqJ)lPdaQl,4k8B&X-3J($*3(JSZIXhG)di
J*'M&6!(!J6X5T[!*EZfq#kEARCfTUmf9J%Y0U045J0ie+%a#S4Pi+DBZP+)Zc$B
)GBB`@9&PeKd6GA1llh5bhh*H"FL&-*VJfpK[ph@,MlTlYM6f0qqjB%DKC+1KUhE
D8#HICIGVCP5XQ(@Q@,-J9ZQSYfPKiq(0ST9kT(1M)F`k`iBk*`hGjR!"jLTC%`L
-4@hhjC!!52VFHS+kNreZ*``be2lJiQD%F24-e"'Y$Q9d""L1FRT9Ud-)&A`E4$2
h#)K+%FIJY""0!,fF%h%jbFfP%,!A3S+-8*!!'EQ[,CNe$&00-3M,c%bjrAIIq`3
E#%Y#iZCAG5ZkYYA8"LQ%cF()K!me6("(Q-c`%d$QRF%*EHmCJ1l4c8d*dB6`p&P
HFh"mC6FhSh@GEKN,+dcf*a[AAH%)X6+6DT**[ICe9+f'%TNV5fL1M0@3!%)3*#c
Bd$,c(pf'&+C)6&R'NNDr36!(`K*"qY"iYLF4L#K!)++!kaj1SBEEADjXMf+VE5l
6mK&NJ,+H5QfDkVqGVTS)G5,3J2!L-KSb9"i2e#$39`@#iCAjp5PILeR42rJl"i*
2TI1V3Qd`3$!*m$![8MR1@f+C`8QZ69FLIiM3Ia'&,C@#k#mkDQ3FHC8PipL8%)e
R)6%K)F%2idMBeb,$0$iY$d[,ieBdSq(iLSkDX5Q)H%ZmmVP+(jm#-i1`(`rMTim
@CTE90b)Vb''"Vb-i$h!DC'BK66q'$I(!"lL#Hac&"(2LZ-84#Z@4`!)F+'+*@[M
i&!fR,VEYXUmj1Vh8k5Y2G'*b-&X*pD2ChUr9fV+kY3JmpAl0DmZq,PlM`'8TLX[
Q*0&a&"h&AeE059,(SDT25`iK5ar1I9TUpXj*lX#%)j)`cN"f241@cPN)(KT)6#A
j0&I&QdZ1mU"r[9Yqj%*"j'VN@U4S&6)%`fIJ%I'TelKmcNm[UNqp5S5EAK3Ia%A
34#2T"APjMm*-HN%U3405,hYej,)qA+BJ1*EQ(E($cl,$aNL#P%M"5`3P"kFZ8G)
J+)NJ'kTF-AiHG(ZcUa4ErM$AP(FZfl2$`1TX&F-mU(caQCf%YT0[l*dr8hPrCZr
m#ZAYMaXqYJpH8c48bD!M[-fH$5Sf*&X*"Z8VlqIhcVm*03fA-DLl"i28pBeC6E&
Y2Q0k(i1c#"khZ8TU`8L@X-NJfpVGki1Q&mRJT-fa$!A*h#j65![KYkU9Yd"SHZ[
Hpk8Y,i@H)9TkT[IhGbSRH2ML""1f2JTbJRNYI@f)M#1QhFlBd#J00FG"eF+iBYV
JZIqC"X--k33CN!!-,TI9YrR-E'pp@fhCTaYm4B'UZTX(-9NA12"mh86lIf12[K%
Mlim6$LXQpKRYBNp(e6Hkj4c,D!Y(*KH@lT-jbb3-$#K!Z2)kUTA60jJA16KHT`a
lkNB2hXBeclVf$bYe0qNLap)k8Fljdd*[RAaFX$@!V3,!(&0hD*+kS(GFA$)j5#P
NmlJSC-G0Bl2p`22ej`-1Jh[(pA%H,P[a%2(0*m'0LDb6LDc1K$9)BZSrZalKDcT
k+NAKBl0ia1"-r0j-&6iT32U3!#X'Rr++LC%V3YPabiKI)Q26IQ6mQqh5G4$jS(L
6A9U,j8e-(ZaVSC!!EfNhN8Qr6JFR,IfhV+)N#0G19'L6LGc1MS8[Y`U9CcQUDSq
2S%kDHUq3!(G2`FcfbB5%AJ-JEh,[ecir9e8[#!pcE#PB+Z#!3brMNEUeBe0(VQ6
4P6(3Z39(Ve'flpU50h$(6N`2LNP`(CQ$V12B1!kAcFXR*4e9*86bYX4IN!$B3Z!
PHU9ViI$J`8B#++aGBi+J5i)JmXJeD4JaI$)IRB,6eP%X4T!!Jp+#!LpK5HES&!N
fU6Vi(!r8"3*PG3U*A&dA"'jLI@rGDCJUiU2N82f&d`HR9J4aJ$U*D!-XpKl-6Hq
q2K9IJP338!TF,LS-D%-B,LD96,Mkhq!%dS"PH%QBXG"U1(AdBE,jemMq[rBKZlL
634B,YJcZ#(3C"YI44HZjEc-5VDaZ!X@jA6IYfFUCA2EiG'3M84Lj-eXTeT)J[$a
V*UHX5%SBVP*4[&4K4ZZ6VL,$(I68YiPT9YNpX8Ad`44p+HS!MNQ,`fFh61U%53R
ihXNbm)8PXdFT1bb)CG`E3"JBNp8#KLp"[#eiD*J9rL1RLT&aEk#-'pI!0FVfS@X
$-S9)88rb&#V+84R%hAHL8XYXCjX'NBI*DP+6'P9HPU1qQpJLZM-9aBIrl@Q@p*[
`ml+$9pqEVI5ET!+EI"RJr#DS'*ZN3XSiDUK#&-j-UE`3i06#QrCY&0l@TK5HX+M
GE94X89#YT')-Relj'A0(EQT)`MQ@l2D)KB,cVUfSr1iEGqcbq1PmH4aCp!4ADq%
38cc4hEVSlF2la#3EY%SD9&D)38l+Q'K32pL8ZcECIMVim)8rIR9Lbk*2LJehZI8
$Gl2ijKqrmQ[GjdA&l8aL`KcUEJYjIM$$A$Tic8"HK1aRk-Z[3XEJY4CL+,8jpP-
#c%+"aq[*SHlcBe-L5,6b0*LPKDk!Y4h3UHI,VacD0fdRZ1Y++Q1E*HBG#a1e`-H
"MrYcFZl8KRMRa3UBSVFHS3p8mS9,me+B"A,,f)F+j2MQmr@Rr"$cEf39Qm9&`eY
9lbMJ,F*k65)KI%0q9(PRSQGeNhcE(b``CT`M9P)Gjee"%#kiUAepX8+JDfC"T50
fj@*bqJL8eEm9U+Tr9ll0%VM$iAcr(BZ$m1h2C!eX,R*!1VE8,8dU'NeL8l18jh,
Bi0)qkPLI9A4d`Q9'8Qb830d!-LU2,jP3%L3'EPB)2q1rb('#+A+mVK-&Hc0Pd*h
T&`62dFELLS-&Se2$-'4p(34(4jC9N!"J)SPTSB-%Ja"$i-B,b2c'Tc)JXZZh&&Y
)qpRF@c$#m)(kGmGJ%*!!hjEkYmUq52I@[k[#p@QA#p"3Mm9hYb&Nr@0$K91EIVV
3e(DhjImBfFS9%`0$aTlfi9cpZhm$"A!9aG4aACV5bVKHreCmq,,ECKK&QV,kfJG
XBLFU-#lf"@I#"9E8m&$cYG3KT'L2RG6d3r&-TqjaZAaIj@[kl3J[hQK'[FeBA[8
r0"PFEbCL9eD8!GNT8EjA99mRikGlUSbVRqGa-JE)MaA,F&VKTPJ+*6H,F`5U"KY
4YSQL`Rha[fmX8ZFIX-KNM5"C,QD#m)J*`M",*`EPr,UdaHiTNDYDr-!0kF#ZN31
lkYm+H[L"KbCI1VDPUraXI%XphdrbG5,jS'`aNM!lNS4G5*6X'T2`a68NB@ciY#5
FL#GK2NY#203R6m!+ThiJl2`JfiEE2m40qXkIr6,C,X9f,r1c$rj(&CLqPBkc
-[*YCE&+adECDFl5"&@`4Ii[KhL[%I(IbfZBMcSQZcjVT0FdbbFYf+[*I2N1XGiK
0eGJR)JXE6QP,cT8&c"j[%`PD#!)A8PE9'V`P,R$P$a'icMbZ0l&1&&Ak2Iih49j
D#h082r#'KFI2hmPkYV59ldAAbqLk-jf*2SM-Hel&bBLBc!C#V2#2Lf["JQRdJJq
92KkEjA+"+3[SJ5kYE%XXipa%"!$!"$R@)Aa-*$I$L9Kr!pAf+XrM"9bDGZG!Z&r
Ffj6eG-*SZpZ1(6H`A@'MJ@b#(1cQf(f&4A$c8CVeFCI,VehPBLH4eq0Q6G29b,p
@bH0("NJB,Qid9"#Q)!%jh91i6-HRMFL9ed1'V,e3GMN9+-KSF*Ja#RE0Z)9N'Qh
*+[cZfk[21hECEJPCZMbNrH+MRABVmZpR8S"hC@,#e+`8pmGG$)MTP&bC"$MikUH
c9!3M-6h*aE0CP3TS4""r$$FJJa0a@p9NU&Z[k!'"Pqd(+CQ4l#,BGjI,kN)eH[G
QMr,6ib[h05!*e$31kSra5N2e&CSp1$U,ATEecU[`PXfVS+NIhc+iH)SqPcf'ca1
SC)fqcQaJ!JNQLF5rJdLi0U(DJ6d4KIcBi9$`[SmHDfV4PJ'iQc4F"G")`dXI-Pa
GeV1R93SCq1pN!r&$Ml'P)B[j8bV`9-!KbL#S*%JJMcPh$SacfrGAFCZV4LUYJ%V
l&991!RpfZ5BNiS5k#f-'GlIK))K8pRBU@IS21*VITEaMpQMN#PUTdk-(iH"RX`I
9B-GI!e1Di$S[4#6`0+rfHTKlApXpM3B"*p[kTdr-L,fbLS5*a6%beTH0HXFT@,I
lShXD@hMLd(4#KL2RVRCpK52AQkKV,HYkK,SQU5#AF"Kf4FVemY@,G24iq2i'1Vb
F(IlrhprK2T!!)MZ'4$(%hX)TE,5lY@@M`T9'lcJ04+AMQpVcBJkBZp[qEl1KaVT
DbjCR`KH*,$#fmkpr5`@(k48d%k9L)DQp'#8i&K89C9C$8qaSU)%*BSNN9UedQhH
FUMU+1HX1rpCGD991!j)*X1f6418U&I*eX88UE%TESJTcchI3[J-&5bV)e6D9lCq
fZBh5jNEF#jq*%cGVJRpQHXbaQi,bdqYRiN!)(58Ba+e)!#[J,mhF$SLR#q,j)@#
3!)@q)X!Ife(F8P%S#F%jqe2@@G0lLJZZ%Mc+AD8)*CBUYNIY#'1Z$-"Ymrq"5F$
2*S*dhD[-m3T"qF*l,MPqr6cJ2"iT"kbVSAM`$(j@9PI6+`S3*I46r8-Sf($X+(r
#p5h($@HDkhII6dIHY*Z!+rqmPEr(TAq!8YR(4Xk3!&!5D*iQQ)JRmHML(Nl)k)Z
FBMAGj#!-+Nl(6J4Ua+X%2,0,F8dPJrkS-1Q)fTVJJVjJlR8!9QhLpBHTN!$6"iM
k2CS`[HEB"cM%$6c!-a'B"`8Sc'@aB635U9VCKJ,EJ(4XlLbQ4)LprKel93-ej"+
Vf,afUVc)GQbEcar[fpb3!-ajajGF1F)hV8J0@aaBcG@3!'IZAbM4rXXB!GjNr%G
K@[aXSK#ZDa0q5QN*FipPZq)#QG'Y)`KPC"!UeJ''(q&kD&$8R0[k'q3'IiNjD-'
G2A5%Da4i-eAQ(!kA88I1GXXhi,MiYKe!`4p#kXmqZQ924P*I4'eb0j3EjLhcEL*
)C-AFM3-r#2`3a4B@d,Vp$GKr)j)pM1BB30FAl6c-qFZQGmF+VLfD3@4)IShV4cK
raKcmFUGPZ*(SDbqB6fa'3-E+T3',G%BI2j2Z%V2Zi*BQ+Hb`H*l"$aI'2SeLR38
["RIBdSBS6%5pjiJPk@qDeI6+l+[FZJe$"19hZHEA3(jDFIA@Pe#$2RlGR#"RGE)
!JJ@$h@hZ0Y(!a4MUYLIlVjqRiKRBJ%@F&hDM(3aND)a"K)P*JV,(TRa&pq0MBH1
*2VLbR[hC"4MTl,QFZ"8KkMi@aVDEr6YXZ&3(F4%HX'("QTp[HLE"`&##b(1j6Ne
`1[lCr"e#pS,NYTm!eDK`5kC#SL)SXPl)4U8`Ubq,#F(p('d@iN0EUjB"NrZ$p$*
mLVVAMA'"$U1ipjkiN!!fa6+"96"rpHCFpL#AXS(2Z)A+p"QILDULm$&8(C%r"eS
qKNRkAi$l2Z2R@1K-&imlqYM(dGM%#BH6I6`Dqr$'"XLaLB#ML(hNa`jXM!e)acj
#Sr3ST19KLfM1X,[YZ,kjJA8Q&M0LQMMd"c(8XKPZf%UPC6`M+$!L(RCkh'8[GpQ
,c&jNpM,%ASEX)i%B5AL*b6[&CjVMjPLqJ($Q@qCiFZK(Uh%&#lC%pr[5-p%`*#m
S&Q+6j#EHmkEGTcpmRZ$*h@d2eKKQrrLH3B+`6Zf$3hJPQKaC"8*Hej-Hi,%$86T
!Pe4`AqI-#P#X,Y&-155mF2lKmf!DQI"9*NHRBJHe8rFrf-pRGPmJ#1*"K9HBr3P
JK36(I36LN8'!'3+$`KVAQFMl&E@Cc1MS@Q)r(6D4i5@(8#MT-k-[f+@AfbZi#F1
f+,E(lEiqr$L&0)mUGX8QCV-!4da$Y%bRQ!6)1[1"0dD'kM4FF,+"4YD,BDVTC)Q
9%[4f5mbfcS65(4IFbQ),m"bBiCJ3%rcShbXP[EL9%MpIN!#-a&ea!BiH63K`p%8
)F!FHVAa@4)h-LbaAmp8DpEh)6k)[X[mmkX6M*J,1D,J&H!pE"a&3#9!b6d(*)8N
d!5[`D)Xd$1(E#4k80JKA&#RJfV+'iq'13k06-9(Qk[ha5k"#J`SeVS)8C"jbRIS
D(5#91jCce@ediP*Nf1'*#EMA"d-D(GEfEV',`TecT"CZ)*Fk$[8hMNl*MDHAabS
B-+hBTUGGkHDaUC&P@2'TF(bU-cl9&jq#kd(+aGLfpG5A4eE6j3(Ij1[a(aI4XP2
-h"GIH'61NaRUIh(`DQbTkKU5ahU5EI5PU*15+lljL68CcX`K-F)MLG'(a("1-NV
i5B`L%6Uij+a*m80&J!!0ATdLF1&*5aTi+LAGFE%V"N`SI(-&XSM6X5N[94S,B[9
c-"1,IXR(I1A)#1(3b6CG$J8''B)4A[I)mHa6N@#T!L,EiD@H!&YQD89U3A`Nm)X
J2p"fC*G%A$*`,'!-+LPj0`B)8q1j2QqcJi)VkK*lf8jU5$ILG2)a!ES%I&V2`Ie
rbPA#$Pq$UEB`Gr$90*'XPHh)J'2!-8eChD3F$0jI`9$1P%&S)(%*B@[*K2hP"m#
@$+adYm(iIGMQ$$Dd"+qEEL-B*T(Cq,"NQa@1$Da0$+61bZ9ZJklbYV%J@96DJR5
-J%3d(kH3!#+Q[9Za-5G6mR&##69+CSGU*I2'J9r+e-!8')1VH3R!bY9S3f"el"J
*cM)#kSieMb"hLCKJE'E%H$Q)k`qjXZjTX-%D(S2F3%2HFR-mp"`B0M!pb[p"BB3
G@8GJDcQZ634`Yp%&a'aJFhXcD(3I)mFIZ[BQQ!S3EJqBL6B%$[I''k,5rpkMI#C
B366STB((9Up(%#Z&h5Km*&GQqSUd(!*L,AM4IFlqR'm!2kTSa!Lp%$mqS0&aN4S
TP"$Sq"X)-CDMFFqkIVBmP,(A$I%a!11[mE(rbDhiFIe4RmLfFJ)[VrV#f%BhIJC
&NjU)dl8)H+N`J@HDf#i624#rNRL(*&lq!CTN*Q1LiaCSm-LLR*-@a9ej&PfJ*ik
BQphBmQq)j,c'PCH18Z,KJF4$GI6S!Nq65[pCFfLXEDb0Q%Pd+03``l80cF-&N8h
XH"D[e!R"3P)(@DJN,#8e18l%%rVc8RjGq3YDmA$P,bjU2[PYQ+@B9f51m1XmKdF
hpq!abK8m4$kBfF@@jC!!R-9)2"J*FH*54N,L6S$S2-,B9!j5maU4'ZPk#f3+bF6
KD&@Hr%IcNFkFe158-9iJ$(VM$CIV6km%[cXEj&K`P)Dd9a[HY(Fh@*(&C,E#`fG
0M4`C6F22"[(PJ4T,lSEc10q64!9FGKQZDheZjj,'-X1LL6[LJ*Xq2KF,NN0Mjmf
K(ErNQU@i$I'%fbNh(hNeX)L1LGU@TQ3cA#2Iq1EXBL1p%H'mTY2,Pc3HKQ2CQ(f
*rI$![9r4`(YRNp)lMFRQ"pi`0BmpD@IA&j[4NCIZ"pi3Jh$2#rlSMGr22RcChBp
LG+2jRl"pFri!`[k',q5Q5cqrpa0k[24Ae)8`%9`K@!0r!f,aDRbC2L1f32@lXj1
$TZi[P1P`MCq*9,SGb8h,UqNi"(GGQbR(@6jbbFk%*BFEUC'dVqrKmkD6YSQ#[Ga
Hb8M3kJ3*5MMIa!QdYAH%'+b16kDc-3+BFM4fB5d4$"N,2EB(4,CQ-T%p*S`3fIh
6L'a*+T%p*L6Eh1'(%Z1le'NM%Y[rZX+U6),%(K1HP-5QN!$T91+'Rd9JJ@HN6P!
&63NbPYQHl6JdEH+Cq!39TFfUpRdI3-5jKJI!J''PI4m4kaLc240&lm,!kf#j@`K
%33D(["*9SPaLL"RmpS(2H-%1ecY9(2hpG[q,JV2ferj1r5cr`,m5@@D,'6dHPPJ
-jeQP3APrTpfaHDIG(8(l[3rmHkaQ+*eJ`eq@(V,6GjBZp&i3jmP12f@UZ[Hmp`)
8Vr)aja`Bi*p6`#8$,QSHL)MZfjJHGT9B`mLLHq*X$5U+,DPJ)miI[F1UH"KCX0j
ab0Xm1S9UX8*j@XU)dpHkTa)J%h-JI68ZZJ5FUhrURS,6X5hZ+*IU*!`Bc!DiHdQ
Ui-8Q&ij-5K0I6*UiIp,%[[J%CImTLVE%1a"BX2R,i63jdKR*PaJhjTLCQ%kQ112
3)GB31fA!k(3RAM5EM0SDMLrpeqT%Kb1+CUlkbD9r2aG`&3eU5&Nd)jS%1R8Xr&A
*2H4NU!C3R1UH5P4!1[32e"@Cj$"Xm8JUN!$F+Id"!*EjJhL@idrK*0e"r$%Fd`f
S`kpCYkhJiZCA9(+C!h-3cR6"*&[2`VQ%#P3q$Fb!#9)3V5"h%bF&F[ckRFEI[,e
ZR#H4SCUB$V0T6@iq[53ER1k`b"-J$aPp1`YGj-'T5'$UhFP"&"b,C1rTdU`6lR*
DeLN@QB1MEH1rFU`bIrl#$!4A"dG4@2dkQ[J6-p-9*e4!92[LKd2Ek($@'6mf!TL
10('(Xka3`)ZFFKT1*#HBSmmSAP6I@6RU,i+jeF``6q,(l&LiSr5H()q16@&!e%q
13+Sr#pHiF"VG[8m$4#`(ffaQHZ"d8+kF4#DU5iQhFa#N1PN3SF8+fR3("LQ464Q
ZKc6d$Xb$U["2D`0(H4(lC(rd"Apq4bDQ+eiPq"mkA[%FI'rhmr-2I#HA@ljlcTE
Ff$rGq'0ZkXrNIl0ilI2cUc(UL4FqZC(hpS&&ceGr'@KpIX'A1Gp#6&rXq)mEFSr
N6YfiR2YPlZPc"clj5F@"-bYAE&hljl9r[rGEhrV@6rrP`+HIAhif*prillRVqjE
reqEfllkHqrc'R9rP(VlaGlQ2EYc*A@Upm0hDZVr*,ILdpIbCA2qr,+pEN!#l$!!
!4)K"4%05!`"kK""9$@C&!4!a41j%[frl(-YBC-KL&l(kC5c,-R8ZP&J,"Q5+M1&
4MaTUL#GC1E"CSV*M10iH(QkkJ4#5F&*#1*4bZ-m0"[$pDq!!6DQePQ-)T9b8`fd
)*BE5e()&5LQKA*35,b,ZlrrhIGmfK35HqhPrer-#'kdR+4H5)!J#)!J0,qlPhh3
im1#(Nf3!%)T@RPa,N!"2Mm@YQIaR2a5p%BmS6D&A4I5D!"KDH($K'k'Qd-IL(3(
%Si+[[1lj)-%%#8`cGBdMIhS`ERfbCf*&3#6JD#3X0K&TTXeL#S#!i9ji('![!VY
4-&p,*)!Z$@2*[96N#f92UFdX6UahEc6TkRUj%SN65&ij)EB$9"d!+F3PcK4ra9e
Le#3&I`@aS#5iSR'@2&`[qYY1Z5f4,A%F%A*RmN6)Yc%LaHmNiVrFB,+l*92BA3!
b85m2c+RNJB1"q"dDeR6+@6c,NVd$RFhZ5Zib4CrUXClJVSjjfh2&GKZQ-1e9Tlf
B6V"TVdh(&A`%E!AS5P)8!#b6H!!0NKJ3HHe62@(AkAU!GZGYY`"J#4"F[pq@DNX
e0#Pd1UJ`M1%%k"5ZY)VY*JpG#Q"0VU',VZe'9qHd%54d#1chd4"Al(9FN4IXEH1
#9DS,4Nd9!6!Y4!#,H$'6DdHR6'V+RM,*23C'jMd#[q+#0%)F%pI2!C3mjA[Bi"!
#dijHkj4DdC2E%bN`4R+)fqC0U8diNiVMeN5$VF#`2$+#*AqU&k@f&%63BM6GDNe
b36KX2i2$YV,$5[32%d#B[+&r-#A!2H8r&G[2M8hj%jXX+$@j`hh+"&%%m*XI)!3
pKqchYp&fm*2$q32k5*GX0$8kjAYJ@baZ)'(bpSp1f3Sd*ZEf%&+BV$9Pa!8(R2M
rhb(BCJ9RV-)9Y5MH,k2PbHe"FkF0+""BeaJ)!'0Ni%h&"I$Q'!I`pfjp(pII6,-
-Q2@D(L-JFC6!V[F10'Ph"e`Gc`*mlFEr-"rKFC42KVR0VA[9(GQ%)+$&jjf)MJ)
$2PXLL1T%&clr,Y+!c`*mGN5Lq26JXbF5J#2iCG6SFL13!$@XrGN2!GKBK8ADE!T
PfK&-0b0S4F@#1HmI$)6F-pIjC`%-0`!(@L8!i8-@*L3maN1kL&6)K$h)I5AX`1[
X`1C-1jCpFf,N&qZi&!PARH!P%@p&*IG%T*!!1a(91r`jmDM*Shp"9bN!0Q8Q3RI
FmMEB"LlK8F!pRk+S$f#5ZrY-paQ`13hD3@@2pTRrhNV!VV#10`3j&I+jilj&P*S
X)II$p4GqcaX5!GXjpH*&XVJ6)XbjUP3!dK*)!CG(hC@+ep63Ve1mrEh+pBjjL`T
$[,[(*,dpS(M4@F)k5aES,%&R!HXX@+#c303*MK(Q8HBHNC'J6VPVXS0)9lEaAD0
3GZ5KJ9m!2R%["%NH2NU3!$@$j,MaSSpR+Qi*Q@*"a10'*d8pJK+!PiimkmF*9fM
3iDKpNC`Kf'j`4-VF#G#0c9V6H#YpM!rb-3,S'aT*0!d!A$3KfAaY*pdR`@EkBjj
aPXMHB1$j&#cT998-,(,k*eN`i4-$D)J*i5U@+H6T,bUF*@a0mNpQJ,AVd9lHcJ2
G23#LrbR"r5%5H"6d2Md'L(FR26J)'f%)q8p"dTrkHaiB@%ILP+DD,-ND6bqraq-
Q$km%j)3VVSD086mA639iD%e42$idZI$i)Y+**Q1'*[)d$B3[+5iR-3-E3`Uf0Z,
amhX41jY#KX8QA66*VK(T%"X@Q5)")P5d2S*XSXTh(ba5hTa(H)aB%q&J5qQQ133
Xmq@S$A1-$FI380[,id4mZHdJBI$*@D&,4&GiBpBBL*%00-%YE#+"#CGcc&bTZ$`
EJCM,kD%A,)SL0(D+KJQKFCJeTX95m#V4kpZ2m2@+&ipQT352E8S"(Le+!alGbJK
-+&c+2BM@C%a-91lLNDYdi*&3QMjp""c-46ckP%%m)XT%2!iUBhLiP@Bd'P+'m3J
T'MadbRSF9U`3NEbC4Gb*,"r!bj@+MEdqBKfcM4PHd`&JPPqb$CmDBZarqpQT%iU
96I66",dQ1&r-%+3,EHc#)@@pJ)KkE6-BK&"@H2(#6mFBSN&P$&-k0Q($4+25pa&
YD!K4S"A)Aaq0+4G`9'XJiDi-*%bdTBc!3GTN))dGLbA(S,6!)d"RBm!##YEYMmB
#kCM-$Q3lRE8TEim&FS3PJbMS-!dD&LkLh08liNI+8fa$LRb)FK(6MbL2db'ePB'
$EimT'@rhqE-`0-HIL8I-Rd4N2U2`FXa9QHk#r4bNk1rDjMXfM'C2fHVB)JHbr'%
%iK&Eq(-%3-I5U5XGZaEkQVQe(N,'TI8Rq,e&l[Q1,C%4)3[raKB89EI3&$*aPr-
@'Z`%djX23#J%6memAJ)'ZSiGFi@1LI"la`"1A`G(Ieki!Xfh1&B5+02&(DXr*k,
eFQ+k3j*)62VU1HH2H-ALQkI!,+hHVp"4-`,"(-I+aQKS#')k&Makp@a)`PAX1Kb
qqY)TDNE#[Y%M$M@(h3-jKC4YiR,H')hHQS*r*PFQ")KVVlZ4&d2`$GE#m-@e'-[
Eb#8`UREmK2%6a3pe[iMZ5@"b'dap%))0#*lDIKF)mVAd+K)a5R[6h-r&)BK',4K
fN!#,DF+T45(-Ljm5%!HBm,8[3N#1ICk1i[Si'ajXL'Jid#*-')qmiB'6YBeF4%&
e("h-N!$p"T!!p@&3)hF"A,)Sam8-!EjVIip,(kAcBJM,G1j4A(Li)$,ai)'hdlN
A36QGPbJMH"3JS+Ic"J6dG$k#J*lMU)06TI01,XRCNFbQ!,MlPDQjXC((R)ik5m3
V#mK%`pY$%!2T#0BGH1MJcZPFSecXIMhMG@G*MH@5*C'"MKMV$V&ZC'Y!X&(*a@0
8HHSM0J#2IZAaVjp3FKdr-IR%SDPVF&9*l4PaE'#GNN#%D4`r5GC30UlNCTA8QK[
j`r8eCbqGGF1j)d(h[8KF#c-ZDrfFmpNMj&E-&31#+dUVB4Dc%Lkc5!Yc"M,'@9d
)Gpi!Gpk3!0YM+U&Td52H!@"Q3l+'AKXp$fme("r(mD*6UV)F@2$SUr,4#,jq"0q
)8iNG(@FaGAldZ#+biUhidGpl&,c'f'Z-AK1H6p'0ReKZbP2R4HNQ)KT"1ZiqSF4
-!$eVGBTB@kR%-4PNVc%)0NcZX63U0HD(Ye`kbkBl%93UBY)$!(D$8qGDMT!!8ba
+F%Rka8T(4IT`)d$DerI40KlHmVF65LIE6!bEkA5IcePJ+rjGmPBSDZX4YG3%BQ0
eZ1"d2B*(3aXC4L@cab*k"#"Q!eG,XbeK([&J%0!)l*Fc+SUF+!`iP28(ZKDi0PH
q0K%@MpkFleMj,SC$9#abV&DA%X6qJGml('*aXUEYpH!G&"I9B1c[`TDqLSb`l!a
%990Bc46@-`1Ae3QA-diI3BL+#KC!F2fLK#[c'D"Ap$QbC`402+cT2!!3`U,qD%G
9H)f@LSe#-)[+`5``0dPajJRC2M%#kUBY&$K-dQ'BEab'k9iNN!$%2qT6'X8lZ@G
LlS%r+"SbVD(riKfiXje06T3R'I*Fb6@Jcj8@C!Ia3!+2)-Y@'J0T%2ZD`!NmqJ1
28(E%-T-[!YNqAH!%KSa-AFAA$k`,C'(V8V)'"@621d8)AdN4`GbiNk,"+G(Lk%H
'XTNL)q&PABZS'dZrcRr@bBlQmprak&[XD0&`Y,M!d9RUd@+CSd8FhEV!`5jfm#!
lYX4`E-N#ahDTajBXH#`6i6i%m%8QBS`E@!5$cEVY88&CK4r!R)P&3M2,c'-3(`&
VI@fP2iXbDCBpGiQk3)kFh5C+p*XS'53QG'43#KH2C#84E43'1K"23iaCJ&QN+C!
!T,K66$![9BC16dV!2ElHjkM[NS$f"XU1V5F8&eM!$H-KZ2U2iV-H,([8@UrMK1V
+"h3Nd'f)f1XdMRT6b8GSSJa4TKd'-da"LMZ1Z(5X3!23lJB``2FSQ(`d%d9AA)"
LVmDa!8GCBA#'BQq%*VCJBMLh4mL5e8`iar'+'LclY(k$U43a%EX)D%!&dV*-!S!
&1a#`mV&i1DCFbZ4&pp3eJ5b)eC8NT!2C*Lq%4-&h,+B5J!NJ4T`FV0!*4"FCHkb
Q&q&kHC%4q&F6Q%3[LLmL'M*-VI,a5N)qARPm@XFVZFEMP9cjH#8$SV5Tl2'P&U"
2IrXbF-&K)`B+C'0Q8N('3J"Ff68DlXYdZ-qDJ[h&ibA+b[p(5FJU(N9%H8efm3i
a)`0lU0Lj[SD+R963YYDEZ$m1Sp15dr@K-5"HJKr[GdL3!*C!Z$`2dF'BP-!+!,Q
cTJSNNm01*a$Hce!m+aEAISRA-qLm51J,6%kJdURmNU,L2VN6IXCP+[Z9U!BXadf
6&apDI%!1Zlq-M,#1$p@1,``G3R(3PHRF#91(6!l!mbk`Q1F*C)UI9EKdLcJdTjc
I256KJLf)LVP@qU(L63k+Je9(+r3,-[J!kIAS$#b(VlqihbY-V'BZ`iSeb$T80TF
VUrUp"&cHIUQCCr4!G#hlf3pr[4P$RN+!M3-BFSq@')aRFc0(3(f+"382!RBA#Kr
jDRE,q@TNQL)qeMhC-el#m0D1H@ZGfRBK%m8'pS(&fMFp&M+!+CPV$5'!l$Xb4S-
!DP,J*[(D,`Q%YlC"E4*A$pcA[a(6663Y0dF`DK@DXSM)q4cCYX1'V*p$X0L-P`C
[G'R`(5qe[r1PY"MBF!SLT"Xr,ILaiUF2!*00iKd#fikf1ES"K$b+!8%'J,3#*1J
6@eKRUk-&R9&$CapEEJep1&V`Bm920beq[lHG!!R-b9FZBLiHT-aiSBi!M$K1ab,
$cNMlVq0&a#8J6SRl+#YR6BqV6BqcK4)4E,SkUTkq4!%'BYNV"#%Ql(3%SLJYI!5
!'!&kJ++G!+Vp1Rj3"Nl!dV%9JR1-&@4DK5""*+a)P,TTHQ9(GimqN!#,!4Y)Q!%
-4X!,#")$iir!#*+&%XadiK(,e0)"UjVFR-#9,#[`#)cR6JY!-Lj4dXqZ6&DD8'$
+'@PQQ8"TJHmJe"R`b6@H!j!!H!m4$"21Sa$d1bfdlB4(k0Blh-1jU8#ImFXell(
X0+Z-')Q2LIMT`%mLN98'R321q%i,EH$h$pJ'QPMfeX+%mJPLR(GD%K2,$0,NRNV
SbNb11%8dYCHCPT`P1be'%+`D84)Crf04!3aUqUcTM2d+-Vf`5AT&-Zd0KdrA&`4
1IrA!SP@-J"m-+MB1Jf!0#d2EcTZL2JbhBhK&`,5+$EmL$pFC!8I*C#+EkALbTl2
#qeLihFGKk3e$EJM)C*DS!'C#6-5[`1GcQ"lRp#3RYL'3!*NmiiZrq+XhN@JF6b`
"XM"%5(,jZAETbPqpMb'ik8dM!(M,4bJB#YhNS))C,81L5LjJ-r'VFAb-M`Pd"-"
Q1Bi*JL!5,U@Z"#pHDZLZ3[F*S6[#LhITCdFJcAKV+cPPC2P8@*C3@#C5P&T)RZq
S3M&CikJ5#XViA-d5'f`)@5R60i,AYi&39hb0XN`Kde-[1a"p[qedkiI)2LU#Gii
Td9pPYIcP(lJAA9D!2kJJ@B@A39D8r0Mq+jLU!HJ'PK5&4l#N%J(j&4eq02KC$lF
UJ"X5`5HF'(%fJ"$KBBpS)ST"BIQ9X@-&DS&D)NDlQ*`r5J3-ElIi")RRkP[DGTL
'`P#I)P-Sp1Be0+Y4'ae`1&"8imTbHG$X(dB#af#)9hf9M0IE$PdcXH38`Q(raFK
4R&G#e(!q`bJ1JpbGFZ5Df2CT'S*CPpMfGMF50D4KBckRY`*&+%bPF5r[G)BV,1R
E`2*eU8"iei&'!a!qM[mPq0q!JR)*3*%"hT@JMf*mZ)3*@bV%%m6GQL$!Neh)i(b
f%`#fR1$ddB!I1hkk3%ESK+(k@qrFMBmBL%iN1Z)G9H[1pJrqhCe$rba[9GKSDdp
%Kif'M0[%T6'a$3aKR-3)Mb9Vk"UZ)mLMlB4#L8-'E9RrchF@@,)i$K)j*C*5M-H
e`!hac`l!@*!!$X)4)Ic%fF,rk0V!!XHdi"JVMK(eMm(`1!fRBBpHqqId"BBe8,C
3DN#)"VKG*JR4I'Rm[HUVB*+5BDbh*AMRp#Tq%-i8YQErY&aJDjqYG)pp"i!+J,c
$#%U5Ba+j@'*%kfmDk2SQjrYje-@ef4imITF6f+pX[3G#)48&*X&3J-KK1c%"UJk
1V!-l[38!'6Z1&GeMh6d),VVQARi!aF8$`9lqQ0VJ!&!i+&`IQ#02-T!!cN%'*%,
a"&-(8F!RN!$133E53G#@36U"(GX%aLJ'aQM$,"aZmQaM"8kPcK!!Qe$JDf0"X*8
&`3a1!0TF"+f$&,3Zch(@G-L44Y'["Z(e&)a4r'c,#YHE!I5lL%3Z8@ar138jqN&
%M#&CK8rYZ&5k`e35d2%rFJ9!QRh"X85$f0+pcaLF2Xe!iTm-"+55$bTjP&dMST!
!ZqR6$#@1Ra!5mN9c,5K)D9K'&`H6VX(VH[BDBYPHR,+pKq6K",l@B@J3"K*JR9S
'YF`T@dmpV(q"jf%FK*re$+6GCL)`F4F&"j!![P`IAGI'Q`D%)0()+5R$A%[fZT!
!UqQ8GJ!!4%mT9$er`e(i@3rb925JDaZ"9Z*)cL3)Xa%5CS`TNBMX)N5S3S5@"PE
dFP'"E''l)2"9"Qk#bX!"f%-0H)Rf2)"D(qXc2IPhCDBRFaPM#eSK@Yhi'IS1NG5
*H86JY1ENha@b&mBfkS!'@#6''JNX8K40,ZUc50pDhmb*25T0p,2q*NSQ0bc*aF$
6XjLTl,!pSF-55A(39m+q@'#f1@#Q!ZBHmrS[I0ckP4JSXJM!m*r!i&dXEMX2NXk
ZiC5@[iDe+U-e!B4qlD#3!05["-5GNArF!2")5S4)h8KGJNe3XAH5X!@BV'a'&ZP
P*2**F2eAX%!&*Nm&P[PIZA)rK-3cjIpIkK!bXJRD`HRchKU#5G-%)Mq)JdFH&88
NB0SkI9lX$"2hVcR$p6"%*2CB(-c-,Y8pdDQ`cQCa-1X[fITGF6NK)),ZeTXhA3#
jFdJ[&,!9*"ec9Ce+$i5+LDJ2Y*')MAqpr2Z8i!FN@Jr%"k%I@(`+"K3Z*,k`T1p
d[dRJdK%BRNCD#,40*KCS($@5[8X0H!kIF@T)aKGkMF,b#bd4J#cAhF@Q%PDN'JF
N1XZrc``XhQ$Jp5&M8Cjl`6Bd!5bb#B@je4@R$NSShUTJ%f'a)b2p4rX&0QFPLPq
&9`%N`6(,9F!)0C%3AI@P,K69#irriiC%'!H3!0XAB(J95`!*8ZLdQcXGB#JQQ3S
SdY9J-%NY1Z%UN!!VNP5R@5BE#)%!6UED"ErHr,-I6[4E[aHmTj'Hqr+jP-0+4p9
I"`QS!QFDb2'Ki(S@l-!XQ#p8rDda0K3lNdZ&b-R%*-19LJ3JM-Q6p11Y-'C-G*B
e+I!"B(DkRV0QGS[fRT@',DZeN!""K`C*)TGmAcY!4ScB@!&,S*EIMX,ShlD08%$
bZSXM(MS!6TF[(U9#Kf0Y4p@b'5'!@QK#MMbJC"HM!,cF3rIC)(9(pE[j)Kc9J1-
,qip5)J&1"E2&C(kFX,(NL[PNfN3G*'`B)Xr$M*N+%@Z%B6!d''-&Z9@Q-%2T4"*
-3aaQQ!d0*I(i(4"kPbFDh38!M`-i6N,[J898TUlM#YL$3,,'RXrVm@0T'QMY!a2
qCP0Ia8"f,4EhSRBJk#&3qCphdI++3h%N@!3,CJ1Bh#d55(#BL8*Li4Y!'+3)#4N
'A5SeL%M*8A8B`!`S&RU)#Icc(&SZ[+!)q1FC-*USHNj6"J#eQ"`$!*J`@1MmAfp
ZPRlf3jBe,Yr2+H)*r!V@HlQl,kFVL624`3-Ab5Rql%2aSN"`Li#94"`9*J$"%ac
$kraarAQ3!$5H6F6+ZJC0bkl""PUf5GE[YTfR)QBMQAHY%ee,b)"V0BVLbdd8I5Y
YU8KbpbbZ(F&`#NTHFJ0Y(bh'LYHQi4DcY(dL+rc%lL4V-K&4L@(KJMRRdh8S4N)
X44Ql&ZP#C"&T@k%)[(Qf$D4YfdKEAaZ5Z,!)'jM9Pcf*h!UZXJlAL3ZkQ8*&Jr`
)QEU[lUKk*Jq1R3q3!#"0kMH,0@!6TcmfEBTHZ$IIT-('!")I,kPZZ@`LGemJeic
BXH62XU@TFeJQ$YkE$f1r4E3B+1+ILR59(HJHSf'QZh$hNfc*@TKVVk6Pk6pUF1c
&UVZ[aXY5i4!ipl$BhSM#+!lZBa%[Afa@,pi2Jme#&[%(5+KKHk)3mH*TeIRFBJY
F$je`[SR-CEh-C@qba*Fd0+MY#c'hVAQqc'$CFIhNZ14JMR`'9%ALbTUeY-b#)pH
X-6Tbc6*bj$p(Y&,TM*db44*`KrNa$T!!`R8K1e4LM)P!&[hFQ@%95!ELUd5!r0!
*j6VFTJ518-aE$l*T[KT6'KV!pp)a+1"h`M"NcGY@jESFPA53!(!)Rh4B1DE!f!6
')bq'3`$eB8"k5-F6LBL`m)aKm*GP&hi[UFL)%6Fa'fKbJKQJl*@4M+bR3@!Z@`&
SQ3b3!)"QHd)J&S*C4[%dEd,Yr1h[lE53!00'A,-U!8"mMEf)Z$*$3'P4)4MB$(F
a@%mIfp*+"0B5X2YH%GFY2!lfp$SYSja*%-25bC,db%A!Z&TX(#3`@5qhpIIb[[k
Ma+)+aABU0))Cf'FS-Qi3XQDjd(LkCfSD!Vq&#L*aY5!b6"RhqQLIBmc81(dND$8
U#AL*)5d,cl(YfC%9KT%dr!%f01p&hmY@LL*N)8)"aP9pYDa"AUGf@K[D9RC$IVd
0*CAHMSpY4dhHAJC"E!ANB@*!`&BD1[Y(IhUrqPH8DIHVaNX[HVUifi@SNi$m2+(
!MF+3!)[36K$b[ajI6-K(baJ6-Z!F4Gd1paL##b9M(JU09RL#SaA4hUB+6bp)*"9
4)H1(-+MLQpaM'BMZhJ&dpP9%S4BMZ`)"lhDq-i!LXKFG2R4dN5'$%F#%$0"2KkL
0DiA%!X4`AkN$k@)[c#Z*B*9[1'iqCBhdJbDA!$TC1`X"&flEa9$XG#03QaTkXb[
#&5)HpSTi,ikT#10kZj`)@`958F)a$`4)5rGRBA[#-mI(%MklC[q[3fZG5[!*Sq%
H,B8HNSeB@Lc-P5jaY#)mq`%HpYQ9A!$NSZ1f!+4NLa)Z*03-3-Tel$"LT%JC3!d
"@"MB8"'Q!LleBbFqeJN[NKIXh6V+)Q!LK85j6T!!J-E$V%XpT*`#X[%#1*d)"LZ
-DqaUNb`biaD+$@`L@EdNbhL*Ir*K*BPBRa%8U#%ZkFU`GTM2@6r-UG"pZRi$%U[
#e6d8%1DF2E4#$i93Z$LM"e'DT'r!jd-"#LjaNJMlR!bUT$f@N!!L+Y-l'EY-C+k
#Q&XJDp*MB$8cRS`+!j)eeL5*!PNDJ-NH)Z($"-j,![MF,4*3[AHQl!3$fPlDQ)m
-ikLi"P20R4e9AFdb3L#1l659X1KKAHI5-mK-G'IT#%CK2ifZM*qK6`M2JSjj5#E
6p1%admcMJ2r5jarrj9HIJ5('jp@UCANS@Z%c[,ieNpZ"9PMI%&4`B8FbC@LP,f*
"%iHrk#4AcHdjiQ(La)P-aQf)b!UpT,04&,E#c['DMH)&A6KB[(6I9JZ+F#ib$[J
0-5TeYHHK*N&U+SH43aZb`VS2EZ*4NIAeaH9Lf`HB6Pc65NepBYZ9kp`AlH0MNB0
*r$"2$-AEF&"aL)U#kiG(b"`,%E9qq0`ehj,UNaBfrF*[ceM-++iMLDpp[FqA3PG
,5iK39IrK53qF)RFQMJ`IHSA)Qf)E`#&88$k6K)b#&(%!l**5LZ'VN!!,!Q,6D$I
-kjY'!8j!N[VaBP-S[26e,CES!"p1pa+cP$4meC*JLK55NUjDQL'S%2b#&-$bLM)
jFeF["&)6SD5M6A`c9pl%0h10QrKQVV`*#C[iTVS*2pY%"G[%3'iIVLeKQkJ3Qi4
0m%Pd5AG2iR#3!+l`krL5-q)QMdFS(00a,eKmZBd&BM%kKN5Yae0daYLT8DjBI%q
KS*E2'L#J8"-BSkPU&UjBNLkLZe$Y,Q6G2VhZae@dT%1@-N56Sq3@-4C83,)HL`'
NZA'1,pI(QmDLBcbF[FVf"HFKfC(UXH!H'4!IZK*m!d6Y0lLRm3fiX64NU6mENmD
G2fP"C"6ZZHNb2haL4Y*1XqM2HQ&aHFcramp1)Y$Z6"(pD(SqjKqAFY+LJHU'29q
kc'ZqpmZlbmbL+mZ1TUjV89VZ4QAC+G'&aLP3UA3+af)T(E9lbVR(CBk,cMq[-)[
&@EFaS2MD&4UJ8eD!p)N"Tf,&imkb!9((-Jb)ZXaIr@$AbKUc+'9j-8#keN!$JNV
0q9*S3i'+B`d'K&hQEablr9m[M6UDfj%iTjcEAHB,Afl4h3Mp)05bl0RR-TGVKcC
H"ZTGMXdi[-YPhMldMmTPS#ikDM"!G*PrC,PDFd28iilRd6cZ-VrHpq*rAFE#"ae
l-5$S-MXFMmqq$23ENA#SR$Hkc*pP2$cK-Y$A1VCLJ0CPIZ6QPGJ0dGrNf)(QQl!
i9rrMrAG#R`"%HPXBGK4Kd,$,22QI"ejlTbeJ8,hH0JBGUc"Sd'8qrBVR`fPZSaK
!SNRB"JD3!"X[kRcl!%2r(+(rHaPp#FhUJ6if5bj32rD6-BEfYaRDRaM3PYJLZQL
E51+6lc+((V[ih`cC!SCXL3&C2eZqBYSFQKDkc(qBpEe+KQ+8S@JhS1KL5bHJL'4
$,[21r[#r6`2*BKEK!T)Jjl[-J6jlff@JZFTPVTQqe(`CD+jaQArcd,0E,`20jeh
Q$hrl,dY[L'D4brcaeqlY[!`dPlR-DrrdkTHAJ@D0bcccS[hTbd"cKmYFrErr8(a
$0'YGj[`r[P9i'@KZGTP04`,2A!DD@ehQIp+e[$P00+@I@f+Zf@BKZKh,IfGM+(B
4LRm`"+KI@',&V"%fr19r,$)cp$jLk"de"U0I@Q)5D`CRc2jrra*MU)8*0HY8fe3
ji2c!%[1cCSL3!1e,KU--V8mB@YpH!#d%NaN6e[@p*&*`P6[2rGr90d!+blASjhF
50d!+VMcKhqUF,iN8LmcJhqrImT*S)CLYQrlbmKZJ"9IEm8IYqCG%#d*!1[2eiKX
JK@$`c)lDhldN8R#%TArqpC)E))9!fTjmV2!'5`9(RI6Hh8264!ZZEdNa,X6D0f*
#&)i3BNrV1ElPP$&k"R51Rc(8'KKUARfhYj`e1Xf[EKe2CFKGB8jr@prT,HH0cTc
rrX,I-I51-[3qQLCk@**$Mcrem3h33c4p2lVj`3h4JrXirVMfrlS"HR$UmbRrrX%
0N80J1e+q[qF'b#'kmKUA&Yd!16M4@mU!rBB,"pIZm&bCIN2N%1KHE0YrmJE)34$
mB0[U6fqiF(!QhF0lIRj$p1$N[crld,[63ZrKGjqTjY+IUlRREp8m#S+4R$Mi+TK
3!YGk+"QEmcBBp#YVc1-X4,LeeUZ&#E1(Ker)ZPe[eJl%2%XqBj-@-,8$B),$f4Z
)'GG*+miIHh9Cb[kMcb',cV"!VCPdea)FFhTV8kJB*%VGa""88-)[I,cLr)4ec"'
P9TTi$i4-QLJATBXd-30!Z"DS2&!!lV*6-52VpJ2,([15c`DHVNKlk+Z%PjKcpP+
[(4!p!U*"VBH,d[0RXQk21l[NXjM@ajGJf@0Qjqhk,`%dGRUiBb'BH8j0iNFRQCH
m'BI&rj)h8bbrII2mZmlEXHJibj,24TdqlVK1`jrr$+a'(3S"',3%a45@*!B0-9f
K(RK92R$FI-FVaNZG[Yp@RrUeFccVQ,2NXlMdKcG6j[Mi*%[X**Ym$j-Dad*jQK"
J(H@XilVFBEACE'VA$0Ce9Hl#&CARhfdD3),m'IJTEb,9!cQ11IKj"6m9q+PVDQQ
kdh5KDDMe2)XSRMHRjDmq1H)CN!"'+!Mc%3&JSmL!#,c`0q@#X9a!3A(Y"E83KB4
#SX8i`4EQTR%#LBAdAXeAM5qA0I#+1[#QX@!P)b&H-4E%`[9i$HZrbS8m[,bJeqM
bKUMAKLe'3%Pl1-5)Xa9TSBh(P*Mr@[[ceH210[UARGeRKL%#6-pM%UE1Nr1rDGi
2N!!b,aH,ej`*&PrV@[,H'B[i`Z`8jrMk&,MRda2@K1!Uc[%aUHJcFV1T6pHY1BZ
S4#!0ia!f9592qH5T#MB9,)kpm*-8iD"r`e6TJhk``%%rAq#JA`J(Z4U,GG)[ccG
GL&iJKh#dLX@,cd#FY*1B#(dPZ[$UBLrQPVpk#XX#ii"3@X`km!H1")AL-J$LPJH
IH+P'`CV5M4a*T%3`VJ*1i'K*!-*X'6fQ(*pTFK51([[X9rrb4`C+C#lil-&-!B`
3*X)@!RMK#h1Xh#U)(8rfZN`P%3be3'a&`e,@Mq[0XmrC4S61G-PA%&N(8Ke!I0Z
4!,Hl"b5i(Hk"5+ekU5Dh4eB[b""E4)J&"F!Ff`B$4m'3!,&IkTMhVG9ZcSJShRC
5ME`HSJQJ-@e"L--X`%1*fQ&!XJNQ&3("K8$Sc80KA`-5P)kAd+6#S4C2EH!JBcl
q+C+A$YIa!#i+X%Y@X-1(b45AViU539TH*1`HRC%'%2VF0RbJSa)Gjp$KX3N6Pc#
4kFJcHI!"!mY)K[cH"RN0NQVUFM(Vk"eYRjVCLqmZVYiX`JJ!K+'JdpJRak#R
"R&e)RJ[MTDGRr)J),qF'CU54+@QL%CHd1r+1a+1Mh$%Ml@"$%j!!3'$&BqV6-p+
Zc#HbIB+4QDZhpK1`9E)+TXQ,V0R*ikVrL6f#YLCEUlU-NUfIVeHMi4U5%#-LmKC
CFr,bbkm4Q,$m84#kH-,HK!G,IX6K![a+(Cr#fHXFA(eSX@cqJB(,mD0h@IPdH[3
$)4!NUV@MbC0JUQ8CM`6ib9ZXpGr"CrRl3)qATj!!%Naml'2'A*B2XY%d#56q!qb
BC,am@!lb&K"lP+(UJX1X`T)5Q(K[q68NJik6)C@46&cp1N@3!$@*M%qK,1XHSVH
)L!$PMm,N@PJB-R"F48S(U[p*Q"a2j,I4Z4+E**9c!*21*92&[1Th+4Y8ScQ!D&j
+#mi%)L9SiM!ZmeDIJUP@1a'Vbam9QYePB1(i%b&$i-YE+a-0'NC6P`J,$6[bl#N
T@0iJ-h8a'XDI!GRf1R@kJmVl*KXD2+Q5ETZ&)FJh-qN6#@Z5"PEQV39)1#G[,8e
Cdj4E(9@rb4#@c+Pd%`NiPlU-ad5k3"b*d[)%B)$pVD8C2@Tc-P&TC!B0@%kSXh$
$8)6,'de!+F,AZUa*Ri3T`J"S6(*E3$DaZrfNQU"jTr%3CBdk1Bj)3Z3i$*J0Yk'
Nb@ci[,86C(5&ijip`!c@3X+fP&Yd0Fa@0A"$6jQQ`e#4C0cUA5+r4,CHhX)Xl@-
'E@'DZS+!S,bI4'SeY&J3$V-`@K*&@"*-MaLL`+FA"9&jD41NIIbb&jE[H+Q&rA5
5F@'hLrS,qqPq[80ZUT-RhQPKM3j&+QQ@cKHfcT1%THNR4FL+-)48-5pGb84VJkQ
6(BE'5+*ebqQ#)R2p"3SEYUASEbXXP6D%eP2Z)*C9lJ#e'bY!Q08m*CM,&L6#+K(
)Jb2ci+4fH@)mQL*DZbN3kK2FS#*T-,T#Hd(d61q%-SePT(+iIl$ld82AL+`(TFe
2K$a"0i,83+JE@G-e,*@RDq2T,@[1*U5ZFkHh(,kpi@cB6q5D"JkcNaJe'0PiqVY
VcLHNNA1R[`Zfm[a9lTXN0dUXMaEcfp0Z@+2Id"XZ2PhrK)8QSIEQ3[VCA[H8e62
A+92aX8Mp@0lpC[HEZiraSe2bHNPTY@-blh92PS6Zb4le)kSfHh9bQ*SGG8`Z`(5
$fMfLIR5Uc8SQakMC4XIN1+D$DRHMqU'9Vjbm5Efb'G2Ee1k*kSH004P5QeK,!p0
&&C4q68Q80&(L`[#9fBKChN4QK9I@"mL!m-M5dN64)'0S28XK['I"6'Td5MP)h6A
ZdHQc"H+q,AYb65)G5M$+%`G#%Q9l$MAE)h%03Jq-#FKe2dPhFaMffN3hh2)DCB9
rq[MUU9km6&l61c"j&4!A*krGR6fjCA+4EGlN(GEXb9Xa[%JGVQ($BFL9FfRmk'5
SU[qNLkCJ,S-KT45S42Z2aP49$Q3-#)E6,YT%Hbcm%d[XbQacb#`LS658BNZB!(P
JY[RPU5!NABP[r+NP$KCdpXNBLR8`VMYTmLjqNjmN1C!!##aqmlL05k%Rp)LNDX)
0PH(A6*2`98)NVfN4['KaEc0#"6&Z5)392S`LRhLkpBbY@R,K*h!0MLJ'PTaK**Z
6dC-N@V*ABRUBTKZ*pHAK6EQmpQb0*C!!`TJ-%+TLJ5@II3KfeXITpF1c'(bq#XQ
L$KX2U5p!BMX89rIU4h3*BmcM[9)Jf#ZjBRGD2dXd0jd-R+5$G9mdmTVc`L@0Al6
`iqIaFaCTYiYVcj*bc0JAABb8f65I4hm5KVPrZ!d+Z@"'1H&PQa4iZ8pbJI9ebKZ
hc8Ze'4E+c`4b'Vr)P1a$iGdFG,1AZflk,)!bqBcq)#2Umpka9&Yh$beirbJ1UH,
E525$K1d!fiSTLJ)d,U&$5`q#FBU$2N@r858j'DD'"18dd83BMB0J$Ne3'H'!@,j
2U-b0QebcjVe9Q,li5CBpNFS34J*QKTiljlf9VcEcLRiNamYr&bmJSa,KGR4+5NI
9jK*Q+K4Q+0U-K`KNFe*%JNEEDNpK8j4pCL+4Ph#J[GqVLRPUiU1$Zh[++Yk4QBp
-$[16ZrUE$S)pCiafPF-R,"'8(a`d*NS0bZTB4&,T8RSS8e@5[(1-CGe9d45@I*8
13'*dTCNba6%H#630,$J8)[r0XSU-QS@%KKibp)MSh0QTqdcKmD1TqeL!'0XpP[T
D4JqQEb+JM#DR4Mb-GEYArM)Lrli*CYS`)I4L`'YLGZVpMT[Dp['SQJ!'(!1m39d
-aMab8P#&UkUr,EC(,BpH1aL*0$"$jE"JNZ$)BN-,`%b6-Td#0Y!V+`F+j3L&&)E
#%%0RM!SMrff*$"2lcj)bDkME*'9kBHjhMd`Ebi0PTf`QS(UcHVm04f!$$daG6e)
a`5YNJ@`6$fJ6l@0FC+bkU+SB!U[1L2C!eK3#XqQ&59SR3i35Q%#"$2FDMbCe9UP
hM!bqBl9UB'erLLTd-#j"VRXdpBjT@hJdYB@bY@CZ``4EB$+p@+kbc+[",P2LS1c
8PZV(S$V1DhKpJLU)k$FXBYkH-+'ZBDKV$-XI&Tca54BXDD$YC6f$qJBJN@jL4k!
c(8X`e(%c85+,6@'#(H4KQfNL48XkY8S9YX!H8ZHcjT!!S0CRlepBT3iY24GJ`V1
3!!b#D"[9i9!6*A'(-5L5qc"c8%b$15U`eQm+)S(1Z&Z@@qD@Bd&8P-!$RpXFb@4
BGV55#LF!Lc8CAfNJUJX)@lr#3$X'QQpCJNeD1ij'PN&('`q#QZJQ(,C`0a))TYl
%)jDkVaI+2P2[ia&-IF#5%SCTfpJUNXfm!F8r@$`X#%8%IPSkUR5Af#CK4NJQQp9
2U%Zh5AbLejSkK1++U$Hp66@*T`TECS`IA(-)8E83MHci!3Z2!$FkPl&dr&le1JM
))Ih"iN`SMUm8qk#%lchQ9!"VG93&Fm!fcJ"L0RDBHJ%1SJCha`rZr3YH8$8+pq0
)#BNE0Bk-MUUAbp8M%MLL%8IFT84rXMSV`5&BXFf%)0M&62Pp"R0q3iDC9f!`9Q&
L&m9H%fS$UJ,rbdefE-K$99i`GrplHX``840pi4*28PS5BbcaJiX"$P`-F"$#K&d
YXSp3j8SUJ%e$&B`)K@N`qL8r,95k6Dji%aMK1U0S&B5*S))1@G(e3cUJe!JhISJ
5mJJG@D1eCQ3Qea-PmP5'K5EN5NVkrAT(,$b8$P%dq1brNB%c,8Yj)Y`1GY8I'BE
lek%LP-0L0`Lj!3"VdVJ,MJZ$8LKVb%[h8C*qI1DRPm!8hZ9B-iS"$S"S`,j534P
9flaDNYY6#SQ&TBbpQ1SeGAN(88R&--!eP,9UiBj"l8!r!Z`-'!#Y28BIKS)fZG"
j+K5Sbql2k*%ccE`L#U#b5[k3!*!!'++!*FFF+C1pN6%8-iZ(H4SP0r8Yd'"%D!!
RFM)&6-f#ZHN9+10"m#"e2[2@GP'#6b6)K3S@5P"2"Ca`*4P!5hYB)T!!aeL$LD4
m6$mcSX+@V-6Lh-c8bA+K,e,kU!3lkJ`TYS'DJQCLD52E+(NbXR#!GbK4)BSMImQ
k"P3@)JZK!R)jBcT,(q4M"ifaKH!m$bM-3I8d594JI,'#ML@M9[PJ"-N!SLq%3bq
TKlDfpV$%V1Qlaj*Ik6d41*KDK%FLG9QrefCLABq-ji)+!Z($IdVp1+pfT12MKr9
3G082FaNB&b,VpeFjafJ+JE26j1SpiGqIZSbF!@E94a'3!%-G9GqZ3qC,Qikb4++
%8JZ5-B`Q9m`j%8Jc0E,Q)GQJ@A@0Nh!09!4`TB@'`[64*EK*Ic&YPJb&#cD`#1G
+Q"d!XepfbE3@i*D`!0Za!'AF!bS19)D)%LPI&"C'DD+&86TSBDJCkha+@!,PFA9
*6USI+@V(493(aKJI+*hkQR&j!YH4X%CrH3kR,J2b*D@AU1(51bm4e0Lpj"+&GD@
A#)XfKah'!`8X8)kSb-aE5iQX[,38qDKb#L#)RH6mLfVGA$$Z4I,!b9#M8)RN,j1
3!+aP$JVfYjbI*#HB!JN0`!kh!"S@C58X!3J24ae%eK5ih5CmT)*j+6ET@-+9#DB
BXTar-m8m'XM%1Y0))#I2iDKcjF`ZFY5cai5%5jK%*+c(M`B)lR56NMi4Rj1#P19
@i1F9S%r'm,AXX3&EX11D6P84@30$EU++A+Z-h1J*TF'a$)m44a&YKfh&QjaJ`jT
0%i(F"*11N!#2a$r[bd1M[-8!pL`P`I$K1'4UPAJY`JZTeJq$NC!!Pc!X*'%a0H#
SHe#L8#+l'cVIdlDVUK@1!A3EC+Ej3A)h8HI2ZPN1Fh%ZX1[rUj@CJSFMV3$Q"Nd
GD$i4#fpM`-a'(19PL6UeB"1#62(!(FG%HS%TQC!!!#"S8%(3MHePB(Z0cQ"bJJd
i,JJjJ)"'krmJQ'BLbI`XZ)@Z&F&QCd[T$"6!%5d%E!&85(G"k@3R"#iaqc(4cl+
c[5B2@!jImRb`&0R*mm%BPYY'NrrNM0DILN4C)j6U%3JEGPqBXN+HL,MF&c$T%J"
Fb[[%&Jjb5LK%5J-)m%j*me$ifHIZ-lNDS"`J)68JL6eH25(hKGmV#E"Kq!KN)4!
E!(MY@'B#m#"kLTK+aARI)J0JHk,[4XI3%He"J!$6P(pmTf0B%21JNK)%fQL0#R+
bU8"9!M[&%l(G-e2,%5KISHUR5,8F#R[KGqHP&QPRLKlk5"5`*[)VU9*G!GCE*YU
YS-T[YJP-*aAE5c)9*>reF*aXIY9$%HC6AYI4G@1PBd[3jQkB4K8J[&)qFF4D6
3%8Njm-R!F%@)q#)!e69F!D#p5#$k-M$G#XTXK8C0&QSfX"I%e6YXDN@b*MVJr`f
V1%Y(%apS@*9m43$m&hG8M3bcSU6AG*)"b4%)1ZFk%5b0eH9X6j-065PceT&KF*P
XFA4Xq`Qe%#JD9D"Yrp%a+KT-*[0NJ&G[bL"-E+iplkDk1A`+iP`#`$B2#P#mB09
HV9Fc0kimKk3G$8%%E&NSjBAe"9)H%VI*3JdCYTH%8Gk)+C!!UAap)1mS#DN)%Mh
P(5h9,+`L#f`TN4aVl(9VmVbSINX9,pYINDmKY!6P+RND"J#&`QG"m%+T9K%6"mA
8L+P[QEGf-L8qQ)VY)Z'3!#"FCjB@VL51&p8aN!!6pbp%dh"C33Y8MTTF$(NA5qS
jJ5&RR`Ud&K"m-ih#MKep3$ekb+$djD4YIPkFK&0HI&V#D9+&+Tabh@KSDN,cE4#
4%dNij380`QQ6L!0)1!QEbpY'%k2GH34BeH6&C3'9ec)k-bmAMB+#J-+Jie3afcF
f#)J&jX1B2!Z&N!"+Z-C2YL%E,3YL#(('QUFb8N55$$c"d'ZP!#G,p3%RHG&T!dl
bSJ,J41-hJNkUGY"fDE'qdD`L06)Yi%K9[J!F+3Z1#!QZ9&5UF5d$Y&5jdY`cf@+
5fY%a8[KR")eSC0")V'dQ+8kQLPIJ2+55j6rh)CK38''*'EPb-[SP!ij!bBTlr[B
68$R%'eb8'2$F31TNYiY)5JEhJYXj*Req$1+TP)ZY[5KX6TP)cNF90C'V)'0C"ZA
a4G0d1d5)bF9cS%+MlTdGEN(Re(HrEcd[A-ZhIYkhIG,Sc1eEb&d3R$BiabJC!J%
)YNm#JrJm`"L9b2U$P29##+dCj*N)QJQ!IfB0C5pATqm#S-FFK94bTFih0H$B("c
V4!-NA0QHJdB!`59bffD@FJG4F!Gap+hmGqIRLFEPlUKDIS*B`(kSd5SG#GrDVaF
*)Q1Mq2DEHNVj8He#P`S8)a!1XT%GbR*1%ShcEd2K"hhZa--2h3NFLG#55!d'4iB
,!!6"`@mVVl'Q!3*qS+,$Fq8SSQ35@HJ9%FV9CMqG@SIS+XI@kXSIPB&$JLJpA8m
9&NDeQ3TMiP,d"L3*!q"k$pKKD8%LA$0`+LPESm6c8BPV3)k8q$N-X+SNhp(8FHc
chkP56"K0V(5XAEJlCU%1QkRkh`8"aii%Z![*d&JLQqT'5QkP,EE@"hNE&2XpaEU
U2aF8ZlXY+SN$bQ3*h#'Jb(F5f!F%+DR#%PQ2j#,HdHcT`e6NR$l)+[R+9ipI8rf
f,A[f+[bXY1+Mh)R)RCYSGISaX!-[HdDK9P``JbRr$eB&DD'UHQC[GEUf(54mEb3
Q9%e+R@#Ddp6TU,"TQ9NHbF$'*Y*#LDb5a6BHd3)NRf,5#F4KKRLRX,$SJ1Tbr@M
`9P)dK%QTMaj6T4Bm25S3)UaRKZ"K"(3l!flCpB"VH3b)1HKIN`LTa'Hr(ZPjG#i
Ab-P%,QiDS'c(#+#L"'ZL*l+e00!@4EV4e+m381V!PXp,(BFURa'Ge8mL%"'$@eG
YafHGX%NN'r+J81aPbGF!3RVKQK&)d9m-m%(&Kh"eIJZNM&[a),rqLMP5%V1+Er#
&8'pf&CR+JeHJp)%DfXVj$2U)@BqRm9[m1KjAqF,i'rcU+qM+6R1AmeY(0ZP`N!"
B$#B+e5UB'Q+")R2,S)p88RaA,#kbY)cjP%4",#"2YXc%4##,4dQC`RH2Z'+$V#Q
Zq@)Uhb!U6CD@)+"kYeU1HGJ!9)-p3pFqM3eFr6pa!p43#fIk))hIR-EN!lf0dY5
me#f)lLe(10p&cF64e#e)TX5f2KFIk4)U"Vr+Y[Krc',!8EISp"@X8q+[%K5Y0aJ
9UL0$Cd'8,8f3!,q'kK')[@brEd'@R#i-fVJ1aEiI)*X*%ELIQP+RcG3rH0,M+#V
r+59(TD)%%PdTU!kh!ba2G[dk-LdCjT5K#!0SBXl!%Hhp[J4ETVBJ6brERE18KXU
6(9@,8D9J+5Aa"Q64S%9&Mhd)KLaChPSc@j3arPUC384@44GPe@#T0!)iI)&KEMe
#,,P"N!"I04#M5"8(c%F)+1J1mK`NL5Cam"(FCTH*b&flN!!JYSY0YS2YRJ2#!iL
5Q3T0YI[P,MQM#5$*A`"9a5Z,mE%0)-b,HX)Q@a$f"N*B(K0()P1cM`1`k5k)C#Q
$L9-9pFeJRHL+'#+jLAdHea0UKS8$)@qck4S)Z9p,(SH(0hN5(VEN,AKmN!#m&9R
'fNUlB%LN,[-ZB8)f+9)GC3-!lQ4Fp08H#aa`kqkTH"%-Kl*R,kqdliBj8I*@)R2
,(BRZGlkdV0N5QhVV(Dm5KL3EL,43b)3&G+Q,Y3J%bp(8$9"lj#%&V3C!,a51(%U
AA`')h5!X#T!!''CS68hH3PIZ6Z0ENbF*&fFGV68$X,@eQFr#Y%Rca3$I+PVC%T)
Chr,+&i6Y#JJCPYI&1ZhkJ&jFm(@pcBmD,RY0hFjEf2`E-2pkAhEZmT65$S`Jq"@
1CK'%lAV+(Qii8,eJpc(P$IP`Bq!Q9ap2fH`EKU[5KD[d(39(I++(VXq!VPX2AEX
HZU,a%%5!3DMS)bdFDMK)24KSq[64(!kL-T@ql''JHp0DhbaC2lj[F3pN#k"`'09
4m9cGMPY[1hCQe,DS2-8S,!6'J"K09JckLJRQX#h)@r#6MKra#c$lh-SH$b#bBDk
,B)4V)6T[XHN0*-MaXa!relmJ4@YZpRJ0Mk-F&EYFZ4M0GMKQViUi!GcBa4ae$j'
J+)&EhX-Yahc%e!Cf6jfpdNM!3U20)&k0*YF5m5UVHSG-VR,YX1bfc9l&MP`0J#H
BYpPlGq1"U!!c"kFF64k(6Aq(1H8@`E6248580mK*585!6Ia2J6&"`A!A@rj0dHa
l2(P$YS3UCjM"KhFQUrSF5mj)#LmM!5Za6DMf[()Q'eJ(%jc,(S5UdYNJ3I3)BSF
YGC!!Phpal([$I"Gle,)&h@-8B#8C#`S`98KjNG%maJ)6$SPXJk0mNcRM"5B`PT(
V+&p2h[S8%hG-E$$fLe@2K%Ge+d0TA)*%-MUVRe#GY*b+*kq++1CdbFI,V*f--V&
i8"$h*9`U@[kQRK,2I%(dUfk0M--NZ09$M&ci%'8*Z#*F(43%Yhj&)d)9Fe5S'Q4
!XaI*B+BH)-&C-*Fd`E6'-XA*(ZQl,daZJD(-Bf5XBmZH2Jk0"QhcTUq`c8YZe3H
HQ8$fIT`8S@pkNKlE8,cIT`03,TV0T5NV`)M8-+8PMQ#a+%h[T+6U%GrL&*J*m"m
ATUp#a6V(U!VC(aI#a-mamqRN4M*C5K`154ARMd$P&*Dd%5"ETL!9KLCZpXF&9$f
rcpf88cJHSQH*Qa90$e`kK8U29TMLF,-rQ6UGpqT23DhGD'Sj9&@IJQ+f3(#!M(b
J'Z9`G`qC#Bfrai#p9F@SR16jLFa`U%VD4@4*phQK@&#!"IR19hh+kDqJl*`lR&$
E!N8DbLiBiT+LQ#dbXKHHRMkhqrAZedR0%DQMrR&KYLI%YT4J'f"(Ac0XC(6+-C!
!@SB[R4)DdjACRU!k)%J$8#b5qUcCdqF#N!"(!f!UlIGF!SMMIpphRk)"B!VRBJ(
baimQ$`*pUeSirdqf"#'f"1)l,!'l[LC6Ea%%K2,G+E5d4h,GEA6`p('iELmlH+M
-`UDB[-edl-Fl8Ee0L!PA3V%QaJlY`+'5LM3TA5J4LYajDi5&m+F,'r3I*$!32`N
AAJB(K#VZa$@iH`e6NAA2Q[drZr%cM*mar&Jlj[h2Q`4q3h-BFAeM%M@Pa#K%b(1
5+I'X)3Z%cL`BR9XLMIS%i!49i1FY4@`jDb48SV,qH5r@JMQBP9a4+J&qS9bj19A
h$P&@P-0-I*5*`S)'H5dQbB!F,Zb"'9%4&X-P4$T9@KKrR43eUF#RG(&dEKcCI@(
kJG(XZA&(IQR$)%C`B%U1QBTX1maHRJ'`(k#ea8kRJ`!$I'XC3k-+UV)3&338I[#
!+J+NDikif1'&T3i[*!8+G2J`9j(ad!!#Im9ITdqUIPhBNUldPR$"I4JkdXI2d#(
HqH"MQ*f&Bb"m&TdN"8!j"9!1m`c8b!,dmYZY)%Bk3&XL4iQbSMq8SZdX!!1)EAa
,!q$P1LI2e3-m%c-la6Rlk5RT8*58258G$Q2""d!$H5N-D"ePjNp4DYBdEiU6M!i
0NC-[9jC%a'452$Z,44!KQKLbd@2XT4BDeG16NTTMJJ+Me6IPa3931ZdqY[E`5N2
8!5!j0jicPlPq!`8SQ+G*3Ar#-db,0URQ9%L#NXRSTe6a&UQHE(cl$[l-L`%HKp+
0J(U)p$-mS,5YK4CM0CMKEcc(PN*I)3HCP-&FjUm9c&c5,jM$kTP,%Z-Hkk8r,+5
PGb#C'&Fa14I%R("b(iN9E+'Q'3Y-6P-df0T6LU$2M!T*6*(!8+Z`!RYDC-HIBP(
+-#a-$Pr!8$#Bj*C"BRh)6B+14%5c$XV)+ZQ2iL!`'+Yk,!k9Vb*[C&@2qCLa9Sf
!e&r,@h[d+dC$KZ@,M$"hXE2&,9(02#$1(eS'Yk%M4KK)TF#`3'%3&a3D#%21&Z1
!2*Ce#3P8qJGi*pXm'dL9m2-SLY%ecM#FHiG3pD#"qFir0#+)Nrq45H,%`)E[J")
UEA[f$*-+e2()!S(pd3hdCap%+A!2Ei3+m8*DA0XY)4#Q&Ke*`0bLb&'Bb*8GF2a
'jRTH1BJcaFX$A)Y!r%"``,eKS`1LmjMM'A4I)mGY,ZGMFN!R)Y5IkMqiC3#"Ub)
PqlkU+Vh3H%RCS-i%#NZk*iL9jdD!`RS)PK+K5@V4"lF)+@-5%&TdZ&Y*mX6Gj(3
f[(L6-l$3eUR)mJJ3EA5F"4[Z"QY9ZUN3LCQF9CN*Sirq`Car5%pRLVIS6m!Bp,a
GhL!)`&"l+@-G"T5&3@bR#PU9j)B)`%be%+bCiIK'GCj'Jq8XlVk*#Z%$!)9)N8#
@%PD-&8)*J3,4@)HIHZFJU96!jeD+f-4K4VUY)p@Fb#bfPAqI%8N14ZF2GI3e1AC
%,NERrph8J6C(6D5E'Gm0XJ&cdIKVDQ1G-+8Hmh0dIDjfKF&#r0cNY6e`"U$d5dT
iid!#P3h9Fc+am3PABm#`-!"r'-!elH$fmV)"PB3I,D-cl5rr#N1#Pl@$aD0k5p-
9Ek-N"SBQAYC%NC[)39%@2J4qBQVTSCCAL"ifM,*0'XL&J3QeUN59!DePLXFj,4N
PS8&!*)9hcq1$e#P"#@3H&8KK(T%RY3['JcY)Z$1#9!2!eBqT8ddqlTEJqJALUlU
N6b6f"jUJqNK(3fi23qA4(!)bl#$6,[D(V4LF"5Kh8*0)cX%X22l"HC!!'T!!ZLA
KcbM4$Kke'jV'"55hPp-V",hpb4l"q5Ki1J2Pa`f,arNFTYk1%K#LFq%EG-PIdRr
d+,hfKpRNfi``qh`TC,*Bj+hY(ac&2k(E&6CdY`U,XcfS)Y!R0+FP)Q',+!m,S'*
EURE`e@mE"RB*LjLr9adB&4Bh[iMFRL'MSdTH)8TU+@MRDFALVriTJkNdC+ThmaF
H9iqBV`kG,+#5rjr#NZ6IerU*V+@[d0fS)%T3jmX,f-HmYA1e4XAcqB*+hhj"C9D
*DZ"FSC8GC$-8E2&"YC,E*%j*"1N2Mk!r-J*1X`BrT)jqXr0HFJ,+Mm*9T)44JK,
$a8d$lVl)$P*ia`f+XZ3%#$+T5[e[!+*5%M[paJZ2k`FB4Y`KjD`Z%N!`CRXY3D4
0VjcN6ZG[1GCGM!,[80*3c5Rm)5M5`VLa`JUBYj)KFi0cU+8B19h6"r8$YDcDK+&
NTU46ReM!$)SpTC5&$aQ*6$i$3jNNfYUS-#`S2q6ecA8XL1!2Nb%5!FKkDff8A!m
Ij8lKchC"CG*V(BAdCm23(`e$aSSSZ0-IV`-J&2l!K(a-03KU6GP%hP-pP@m3-5#
4`9bYN!#TDiT4T*GA`X4fN!!%+YcZeFT'['V8ep[X9869a@QSiUfl'5!*kV+CU#-
5X,A0kNX2$2YTm5Tl9F9k#jPU3J-cXahQBXPec$$ljbCbRMGKQ"P)),MR,D1%6H5
N)1mY)m#DdSZPHSeHUEZMkPrZ`f34i&ZQ`RFGA'39I[D#c,L-+Y6(5b'*'lM0XS@
2iHL`$5"0pLSAL[FQb)4(-"AE@rdIBCJ*`X#(QpDT$9Dba9MTG236L1Ch*'6T@'H
!@!0KSDJ"IPk8K6D-+Pl8Mf"+)PMp#eDJAiT#pY+&Ep#M2ecqhkc3XF6BZ,`E"A&
e3[mI!!!FPN&%3e)$!%6B$e80Gc3"%#(q8!CIS@,&aZXB-m`3I6,X1S+8Q-8MaLJ
JFl8c,DPNi6a2+p!L6U#Tb)MC*A8`jicCiEBMhV,EHGkLk+E(R%HmaYXjBjcc&X2
-cMQc'1)a3p`dhSB-!GYrrlrh[GIAdJ,ZlRIhq`XEY%AP8))JH!)J-e01LQ5R%rr
%i-H85"Qh#!H15d(f#H"RUjF+4jpMUlIDGej-&NN)Qr,$LF!VekHFY&3#28qdEVi
`hMdQVZLA@T!!6,40Y0SY6d-)KQL"Kad6fM[hfqbGE3LcpED0Q$bUAlTL`,DQFlp
c$4YHLm,T#BUba)S`USU9Q6j+rr#AUr4,"j%@YBMaG9C+'[AKdJ2SS-6P!8bUX@k
3!qiX,D[[FZ[cQNYTb(,-Z[R1r&ZVR8jPFR-TMTqYVPKDHY56@B@()@JdEPlA#(+
GTNm5@CKq`UaAhIPKT(G41IRD6r,$RheeA@-`R8ql)8db5*1m9[[!'#BG`U3"A,j
Dhrm'ACCJM#A!aRV'f,34LE(ePLS0B`QCXEaeMH-05)4$QCB9kaUYpQqYj8!dCYZ
)`ASFZT1VZKk2LeKf@9E$Z8-AAF4$Kj3`+THf09MN@1eMlI5"aaUVr3Yf()63eVB
@!hIJeGPiYBbrHJFH#khfclMSJikKUp@[p*i!#FJ9AZY8CF)6G63C(IdB(Z,$1(K
f9C+IEB-Q$E-&A6(+&R6pNf`"YPC8X`ABI8&5!@e'HTQff3eee!Hc!#l0YNpfVKD
HS*8[2U*Lb1`f+DK[b4JqD,JrR$Pd#qU`E*1CGeZRRJQ2Sp1hH@QTUl`@ra*9b4m
(bj*TdfdSJL#P@"1,M@QS(LN6a,+,r*,&QNZbqX-+Fe`-[@`"m4jCb*JQd9r01J!
HRdZkYGIr)6BabS!5H'(QMlE(G+mNCF4F+5"X-fGZ6dPIX#"Q'K#LjdK1mUAMZHP
UZTB%UYY6,UA%CSUL$q"NmMbjd)CC!K4Z0&kPa3Clc"h,ha#9X5'AXrB08CET(Ik
Qk[-eL,+J%'eU4aH5f1CMp@NeCc2+c&Ac(mdiMQhCX+dJIF#j-PRIMmp51"m'k!1
2rHLQS'`r(PHa5(ZY9'c3jedJ8E`+i$%*1%fpb"BiSLb(,HL#8e$60)"9Z`EdVN"
B4bhPDJF+XNVr3lfJiblm"&-GB2YDBLGH2SfK*2V!ic`@1Pcr'-#,f$NIFMfQ0Zr
Ri'98A$$@2H%p+@Tf3Y9GbXQ-UE)5eHb-M$dkA5aG+0V0hT0b-cYaNdpM#MqHRCQ
EF61QdfAV)K@"-TCe+IhQTH2(Xc-LPT*55)jZ5MX38),jifEKFYB!YF@LeEj"8VY
c8cbe[e)UYXKUVib[GY%B6qh$LYU(1+STjiLL8P+iqD*D'9RKVfJ9AKP4iDmLpHM
qXeFi138Fc*'615&CQ(d-#+U1iPqL,0P[,-rdFZ64$NAeR!NE!6cCEViY9hkB"%I
C#(I0A,085SHC$iJUp9UQ`p+&&-%eVVB%K4DN#Vim48HG#@X2'ljT[LNG4Qk-AR*
86*fC+`)L!)%2U2Xbbha6Z4Y+4&hBK3X$Z($Sk(-*"jMGI1&6A"fJSrX,-4epNGT
[1P5IYqifIGkbZIKia,Tj@6@)UKX[cLAQ-@d+!S%fQNMZqXlVIfcT2INfMKF"r(2
JU#1b-L6@KQMDm-R#6'Jf8KNPF1dNDZ2VaYHCa)dcHT(q$62QRBe)T#X)$G1Tm,U
ZUB2IVN09mead-DU$jRjP-*')3LQMkU#Khp*Z'4'9H&4&)44#D59-`%[`D'3)CC!
!#AKM#%)TN33mk*D3!+JX3-F3A0jaKSY-$dqk&bfLV%"XV%#@45k3!&)9bTJM#3-
PPEpNk,bq4!rc#h8PdRi1)BcX`dSI!d,iaYF)!al$H$b2abNm4[$SKLP!'!JN+5"
`54+1Z%Zck1X2"ee4D1LiK)D+"aNDHJMG$I5"aa`X1U!Z$p#3!*8'3Y4&8kdQ0&5
Ldk)K"CRF'65*DlD#+[*LHGQkRkUj1@URERXX*cI$9#[-eLeB%'&8c#b51'S%GPa
5(J"S"#aim0(02ZjL(hhd-Cj*bVDdN!"SScJ1&aC[&-a%fId&)8d5VRdeRV`UefL
0*cX+SI[INP3jT65#+LFVU[6A-e91,NL9aBCSK!j$*80QNQ[IFRlpFZAkhHckhEM
q$,mH6SFT6p)(QDQ`kmPFC3PGIk68lf2A,d&`DlUq9A-pMLKG`aDlTHYV)'lCF0e
&Up5BfKp'ak4GrPp[KZ"Y8BqK@M24)JRF#+TP%pQLfh"XAKS%8)H$Yc,'Yd)!Vh,
'VeVYM45JAX9M1Q0m1KjVLA&-Daec-pEA@VCT@*qZB4f(60R0&PZC#'lN)KL3!+T
2Z5`+biQpV'B"CPp8YqIZLSNL"%ak,CD8ZcdP0bG6qfl"VeC-j(0cFP0%"B6F*JH
!j)S&'MbYUDji85M6U-Sb[,Sr$)1E(4MBJC!!P3Mk($2%K`S*)8#A''H"ISpekSL
!k0b!#BK`hHUGpi-0cK)M%!SKci4"Rq4dNQ''M44E4am%,Q19,"5QiI1BHQAm1EV
+DPmjQ"qQJ02qA"D%dmC!`dDJ88+&E)0J0lA3"ai-0'`!$GYT*TbP5K(E6QZ&dkB
"$6ULF6&Eb+#KA2rZBU1!'Xc+dPaR&U0M6J`&&kX[qCj6$iMZ$p,FiQLU-6@a2cM
1TUda#e41"B`KK(BD[8BG[IUAD[ZFIHbe,``kKI,Lm#NJFHAD8AkYF%S9"e,h`fV
9QE!8MJTr@ARJ@08fpll+Dpi[,riha`IY,`fpF2JcSdpFqAc2&fE28QIf[Mfmd[b
ZiCfZcikX',0dIfR#jqlkdmkrlI[@JZqZrYUd@`1GihX(ApRaQ[k)mG9$hlH'qhr
J1pVaSqHrN[rATrlbc&rGZ"QmP*@4(NYNRXJpm1,a[*aXe`pefe2f*,qFp00G2h[
bEhlbBmrPae,6(Mhlq-PR,Rlch$HHrXrUU8mppr&reApel[ppp292rrq6rjhd2a2
rjDh[V&hAX'V0'fpZh[L2YHq[Ifr42p9mHrkrflqhr"mqr0HPVfrj`m)r,VP[`rf
Er[RKhdhqEGhGFhjjlhp2[fIHlHGrImH[V[kQj4GErkleJB1rE[[jk8GZZllrLl[
rrU%(QbmdhGNiTE5iC*R0UF"+GM,L[$djD[SH(3&35#@S+0(AQL#3!"[2f#9@Cbl
QS5bK)r[3`[j`NZ#11m'4P[fG-NPiRFe@qje$#+e'8&8L*!pRThMi5MPFaCmrHRC
@1Fb*&'"!9GJ(-JVMdP1($Z!NUr(bQA$#bp25%2ZZr[l`'$V9EEcEClbFF+ai$3%
-VZ!6Q[[$5!)GUi%*@j)rH-+AjJV-pq3&Nm3S,JTD+hl91`Il`eede6(09DpSVVU
)j(MJD*V4NeL6*)aR%dJJ-U5(c6ETCG4Y0`a4L#'E28'4aG95`%AUdqF8ed&pLbd
VlMY2e3--Y',J)K$,N!!8AP%e0l-G3eGS1L90KTI3X5YIjB!h$F0[3H5Ad!+G"c'
e4r1bJk%P[$Ml,0$5Ui*!Eab[6F*VGNahKb+N89&im!S0"N)(GI[U,U0L*4`"A@I
YC8TF*`j6!HLfNlPJ+*%ZRUbJSZ,*%LSUhQ5e2r3mIH#a48&&a9[`Q-Z)G+1#LSV
RDSNdRmT3%4haB"TE6*C48EQP8Nj31+a6ApYIh2VD)`'hi983[Rc0&NDY8ipk[V*
d8,``)&Cc-dc6LdLrQ!99e8+'mBU"UJX"c5!8J@Z(3`mfSUUCq6%"!$T!!SYVV2E
QG[SJm6%FBNc6F)mXP,L84%#6!%VLiC0'j@E""@6cKBNe(P`lPNQUAF48Z`JNHLY
AEDh9[VZ%2["SB+UP4c8,*%mce9D(U,C"SeSFm9!A@bc5)(N)@1mFeN(LXiJY5!#
AXJ8%Z*d4+",Z$l)Sh5L&kcRC+HSPQ35V%JU+T5-,SiYGbLX+%Hhel98c6X3bAYb
q*dr0bpfHGbNPim4h9G"i&mKmqU@85fVZGT8&#d8L096Fi1kSh3M6MbUBYEL$J9i
b,20V+h)0AUALd(!Y6X9K!-Ka15V!8S$UB"9mHq@pRGI['aNqZA+[F+"Di+C!,4'
GJ'L5!YB['Z@!eHlGa!*@5[2T!3`1I9ia9D,ZL!TBlGk&TS"eGe*d`)T`F*jD,SH
##&&ie8-6XSS@+@6G[bP#b,TF#3Y%-`[mPKF8XRka84ZbmS3P!MpXI@MP!55j[Ec
5aU[jZf+kE$9EKa!`me*+ER*-cGU65-4d2*UM#'fFVf2T4h*3V%HjC%"@FL!MHc*
5U#Tb*+`TfS*+Z9$`&q(X"3XLM&C!H16+MN%TD!!)#BG,UG+iEDa+8aQ[`Jj$5Qi
U"M,Nf(S5iH&3M5HV[4I+3K$N9FXRMLQ+-k#,*P@R@35kh(UARS+J!%--$N)-P0i
LSF`-h!1&`lKV9*XBS'X39!iPfVQa9"SYb,(JFJD(MQ*"&i)JHKd1aEadq+E*f,0
(P33ET-jdb)$QN!"d%-XKHfUk@5f[IY4#b4#[hT8IaD4"e1-9BT)RC2J@G@VYj9K
JiPK`-3cG+R[hYFmlkNQ8pRCL%pk[B[Um9,V-GUmDb%F`&qJ,!F`V$$#IL!1B*q)
"TPZJ`,C8&$!I@@m#c(d6SJ#c24jJlKXa!HCY,Fm#-,G+J2R)K!)!Xl%LJ(PE-"*
J+X)&*3c01'#'1Ek0!*Pr%D#T2Gd%QpVK'3A1,G(!@@@Z+(!#q"`F00-b$@UJ1Y9
#BZd1&@fSdL%K15AF#ic+#6b3!"@!bdC+ZD'*3F"%hL-#+%mm14%qb#!*iN3J'SN
j%QS$Cbj$j5rU@A)jK$dHF2H4!iC2'SD`GI85q198"!5eQ`'`'4M3[4X(k&`XSFJ
C**1ri8H642$%1%a5M@QC(@S!eR1)U*'JD!a1ikNqZrm+Vlj9NTYhkcHrPaUX8Ml
**)DR#ZfLK8m*I%maE'hFkU%$A(kBTM3Ql'VJJC-VdH81q0+mDA4mAM82[E"GQ,-
DqfA8)59UCf,VJB#Q!-TTf'`)"06bPT-`k[8HHAfir,h(bKiMC2M!aH&Z3q$pama
P-rF'!NVM!2BLQZdB@)+C(%($)i%!YMQX(XSrkAMLb0,HX[F[PehQKcbMPV@Fl1d
H&HpjKXA4Y%6,1q1"J''@38DdD+L$SjC@'ch2)b3eA4+[!i@`NaA'Rq)8aPb6F%Q
SEjp20HT280AL`Vc1kaY!Y1JIh-,$3%0$ieeL9$A5%5B#)!25MX)[S")iQXP&eSX
'@QMZS4aZ,cqKJ0NqPB'C0f*5cfBT4iMV4b%l&6$jmL33-Vp%b%"B+XR)@L&*@X8
E!45C2IMRb$aXN4#lFX30HTNDF@L%GT!!+@T[(%9Y++`SGjHXU&CXfFihEUq3!+)
1&Ak"+fSaVc3`i0HU+l"I8GHfKq+V5pQi[#QZ0RR6CcA)KTaG9mQ"caEeY'&*1CU
*@UAYd#M,aj6eJcM+fUe49U8L4[H["LRPcJ[9Q"m1G8J`TFa@TLNEp4XMZ@bd!+T
"P0i34-NBMjVNd%i#md'fLCZ40e%m'V8*&2(p6eGS%dp,QbKI80!QCK9QmYPX*)G
Y*#r14VUM(86hf`Yf%&'$#A++iK9[&`rSb1@&TUlQC"(XX9`c-@Y!3$QI+V'9,k6
e#9pUcD1a&N-jTA#pS8(BNic*Rm9KdP8)Z"$%G&lI"&4#U$N#!-e@ZVQL%FB8T'K
-1"h2!4Fp3-*ZUNKV%+b-9)P`1EVeH@mDV*ZEh'D*G#p5YY989Z2T$kGIi55@1Xi
T(4G+KY'!%!(N6ZELDY+iZ(DMXYd&&eGE4"GAQq3b9ebI*NG@aUAY+A'5F&ZTm4@
T+PNJL'cLTLUPB1m+qd!#PU228G9R-)Lli$L&fCK6q$`8USZp`Lq(TCZEKXk%Jei
D9&,eG`E02Z-EH+RUm4GK(Z4eqDQ4f@1H9#`0[Zi4C'+A6KJ42IVAYb$"CYhXR-m
$ap%3JEM)"1+C1!*4(5fdQha&#HfS,,4%C2'D#L,E!j%GQM@K6fM&eTGk*Pb6&QY
6QX)a)6%KYlQ-ZDr'B8iKQ-Gk@HL5)R3LH%8YH`$)I01"1E9Zi@-K3H@AK(p8V(m
dYV9VPZD#YHb#lm5jB"+EZ)K0I#r1a0V#"+RdBZIehpB","#@iF'V,I%"L%rPL+T
d9d%!"#Df-'CHMm0-A3Jc$MUdD6C(AL"I!3"#kD,1kh@*PIU!Jclk6q,6cBQM)`*
cIB8R+i53!"reP!,d6@T4K0#%B!1DK1iXQD3eM@L$1l0XG%%[XFYf'9-jS,5cN!#
C[8L$CQfKeM%&r6DbJNSFTJeL8j-)VB'X!c`ZE*684"@2*M-24mpS940&B1j5$L!
!CDrCYff3!*F!ikXI&D8Bj6!BmahJVb-3Z#@`3#$3I+"lPYbaK(8id1(URL89P+e
0FRkMNlC`&Fe)"&XJN!#!J`S024'5LBPM3"PShJYA#kU8c6ZS1AC(1$2+i55HP"a
1GlKNKa1FJmcKe+C8S8@b8S@Qkd-F6[BTTdd1Tepp%Ze`ZM9Qfmdf9-8V0S6i+L8
RGmDP(-SdCVYL1@SLpcL[[1l!"daJ-$BMe93SCXk-+JC+5BG5q-+bqKEqP(rSZ%(
++U3UQk5Uhqm`UDTa#929HDDU%UDUmp'UDPaU8Y8G+G'U)Z019PaETH,L,,"dJih
5$CXi#dJ@R&p)(hJJMGXi5"pic'%X,'%XK"JJm+R6f!*(r2iKYYLY+DbY5Q%G1d@
&YD`M3Q&PS'DI%SXU,Q9d4JSXIY(2q'%JZ+FP`bCP!i&6LUY4I#U"8b#*`!Q+2G3
pDkGJJhSbHXcR)"'59-U4NNUhhc!PPCUZXU65DDCQ&dXURBj1+MA0-b@9cTq,6LS
a`Z#9!JT*XFHcYj-D+$mHT4(UQN'&(*38JZB2$P6(Zi5h'KHE"6@,2FkEX4Ma5HB
)NSV+RqF)Ka`X[&,5l#09NBSbGGkpcYZjQNUCQNUK*KeA8j292Sr-MjZiSChp`Ra
QNRH3!+NT`G4d--S3dRjK29[JL0X6TS"(84-Cfpm0PPAP4aUiUL!CX#XJ%cL6GQK
`4T8M)3TH349L$DqL#M&48CDNN!#b(9%+bCG!-N30+C)DlTPJ8N2cqSUUSIP0NaV
Q"H1TJDHZ[")S[Uc,"3JUQP$8`)GQ3!dm5$f0ULiRYE4G[i&!TP"k96CiQYjK!S8
(lp@#!X`IXf43U!`&K3FRQd$KRXHL3B(pG!'VRNZ')k(5cda1CU#!H8"`P38%[iS
6%(6,PBq05X"4+!KD($RFP9k%H9feP1T4,Pd&iLrD5@L8-!8rJ+0j!6q085B0G*0
$H5QrhU-*BTJKBN1))5)'N!!m,KQP9*PbLA0([pbjbNfGF0lRV8++`MQLk4T9AN1
e)@r9-$SGQNi$kbc$iLiNlT[l65TDc93dS!e@q%&*INTTP%R"VY"eAVplR%)T[$B
8Vc*18j3J9b3A(15Z@U!SB0@hiK4DIdL3!$Y+c5QNB,IU-+jUB-Q"dEL"l@aP'NX
Z0aA"N!#H-I4D()D#@U08CQ6N*J0#I&cM4V"fTe8c@)C+%!@*2HMB5@jkeK&J(Ah
SQ+hTF,11$R48D6SFV-1&SY[2Le(T8&R(1A4-eh3-X)i'G(bS&#A[m,!10&H`VAA
jmI0$,5"-V8LEYA%96Y)DcXT+4,YU1GbP9bI*5lVJ+AP*E+6*5f)f@9jL5lB6mK)
EYjf5Pe#2l4!c'lEEaPN`h4djQ#D8`e%jQ%i%L(djI6G+k6X[*58VXi5rUrZlC9A
@BM6d80(b,PpNL5G&[DJ9$iXfId!FGMPTqd(Kcb'686pq))`I+I`hH#UXQBber$l
H@5ChM[21HEacTk*!I)k!I25BQ1M`8!HIe)kZ2JelFKIF3`G%KkQVhp4e&9dZ8jI
18AGClYb#cR1D6PA6Z4DG$CV1!8hR4A3Z0(9@NC+N+k-*3,T%!1Sk)TKTFQ1d9bJ
880aEd33Ja%cclN)%)"6aErpTAPEfm6KfIpr[f2(pl26Bm38,-Q-TSN+1*8ZjC#!
X9"i1HZ%JDL8K8F[aBh&GSX8m+a5T'aY%k`dY8QF1(#iHVFRq&qL(pYVJbQRK$Ja
rSJVZPpDJJbr,%Qke[-i$FYdkREY$Pf@CTZ,k$FUdc+8%B(!CYBBkIiN"R5!@d!$
(@GXJ@K*P1Vr$Vd&)cc1%p+-i#-NP(63Ma!`(TV1$-q)Fl0%35mG-RRk0J1`,ZN4
bS,FIpHMm[eLeXP0*Mb3,3hY`51-'3hUJ,R8kZG88Ske@F[f'+NV$Z)iarX-iM$G
S$F@"qKq5NXIi0d3rd%EZ3$)!Kh'*pi'6KGbm@N$B*3(#l`i9B2LG9K($lmQl)KP
qbiJ,5P#5fh(-`%r"pa[@TFGd$#"#"fE-q(ZfSKEQG293%HBAN!$`TjqC1Q6!+3l
ml+3AKP9Zr2KA!-BiE3M8r8F[SmLD6Be$+%'R[L1mGDZ%iqd"qYNr8V1+aQLGZpd
#ABklUfP#l5SaP'%BAi@8$MTlhm'4l6!`pF$8`X-2q$TrAERJS&N6D1LiLbP2D5b
"i`%fJH-bf%M*cP8H*LJrML-SmfPLjr8je-cEhAY5!U%SC3h4P#+5S(QVRQDAI52
1CA8K6JelqBFi0SZ#U2`i58,UCXk-088%,*qbblmHjr+@8)G+8bdRZ%J[0Df*Nk6
XNXNb64Z4'[-d65M3BGM)+Nf88(Z,('"5UTd0cQ8!J04ldbHQ4([6*r*QC+HCrbP
fD)Z5d&FD+cCjp-T25Y*L&e[3%5bTiQbKihM$P$l&H*0hikG0,3i6Q('6eeE@Q@8
bbH#[8U+qN9ha&P[3a$1(KCCpBcNeK8KmT0d'@p#V%l5*5YS%Uh!jf)6R04[Tefc
%U0R)Z8)E'5aJ)p-d'cNAYC'R0"[T#pR)Z3JE1DIC5%M#eFN6N!"5XTp-9`MGmB+
i,DSJEL1&d#&m#LQb66&[NDHd-B@2"$ZNBP,lhjq$UZJ#[M'*i5bfD1C(RC@0H%d
+Ef4($3FVf8XRmLQPYPXU1U1!qqFMNiP0U2!TEQ+c&U$@-)"D&3HJGM2%XD&)a,'
K5-3aRehflFLA,A1%)Sj0YXlV[dbRCMXJT$IL1N1lT'P!m6G-MAJH&[(0DSKS5Mr
B4Jh0b)J@VjM0BMkDYI!','ZPiiaTq643[m[rmmfFN!!Hdj!!d4Zd*'*HL*Lk*'+
k4"4!6(G9K*MH0aD*Q1*(9!eUZH3%MGHXC!IFGc2HY%6jkEMCA%%M[#%H'Nf8Jl!
G%(H0Nr-TeC[+M9Y1SqX`0C*!dKP0*T3T2MkPjQcX)*CpipA*rQ#[QDS&l)MHmJH
HkIhFD!RF@#8dq1jPcC(6F@3h(AN&"j)"Yd%jYNrYGLZI0fDQJV3'P'(jXSG"("h
+"!1QlK)ib!S&NFQm%5Ec[BU"6f1TBP`0YdZe$"VfaK))5MYGUalc23U$T*'ADK%
M5GI`)rNe'f'%raY[NJD!PM#KrQ-FSHi1&HS0%0GlKbSLe-Ud8+'qIf4'KITqAm@
%ZXkM&HSk6m&#rBH4rkK3,ccel)Akk2(XPjq08"I$U6j,&ZUa-3V1re`&Hj40lD1
THrFAPlb0)dG0NeS`D8+dm(GLSJ8#5%d*J-5hN!"3dU$#$SND@0TNhXBQ,$H!"2$
#ak+,AP-@@m`"`l'DabQ0P@JaE0Y&a[X`ClZ!VD+Sac@J3Xe!q)p)hjR66ifDqYJ
40@0#1YJJ#&$!kXJ(Mc-fKX#'R4RDdm&Ve'28j-REU!'@HaQ`r$)bX0L5%(E2'U`
Df,#MTr2K6[[!NS'2"qS(XJE5"hbGlJ&VlFF$1`DU"pd$8`H1$1M(p@m1R1NFU[Q
`Xk'Qmd"R[@"r!!!aY%&%3e)$!&L-$e8,ECFJN@bVrb3[)3V[kRGTTSkVZMc(F44
A84YhUlTQHe)S"I9#&h*TcGEHV[aFfS4"1Lj6Fef@lA*"rAcT#8jE)eDRBE9H$V0
@CFYeVC-CVY[9j#bXB9P18f'%X&cl-%*3T-TAfceI$jIQqr[phdY6`*klhChCRId
!&AGH*$-M2a%5%3)4)JEh+Q8UNF#2R(F))-AN"Q`+M+Ja@p&`NJ98[SRE)*DLMMl
3[EP!cVGLKAlIRjI*9XlH"NH,)5S0'@SjT1AR`4kjFLb5VdSNI[4,&MaSc*9VXCS
RVG"-HF$Kqd5MY%*S[NB8!aR4$D45')JI"T)rJBCdRSpHB4AR+fT$D"#@c26)%Pb
4QK1AbqMEpLGGEmdX""B!YVm351+R90Y3Ni5`k)Z&T--h"a2YUrX(`'F4[K"6aN%
+RS3*PdbQB-)Q62GCQ!eDeALB-e[VrX%Cj@4TQ59M3BB@9djlU@CH*X9,C#2ja)0
Q%NLM`cGdfP%1r5Lj!3$aL$J1$9&j4'UQ&IjpIe'j[Y[KkM8BpJ`Y(G(@(aF$e0r
hCj8"rIS!GE(YY'0Da6%q$NB-H)fmHRq2E$eBlD[49Lc9f50Vd*LZ!BJF*ZKi"%f
X%9r@+R[#k3TBU6TekT5-"9l`eQM$P2`ajkP,cJ@jkPKe`R!(V2$-)!###%p$)mj
(dm2%N!!(V*XCU&AUB'0@J)h-@'4KTKU6ii9@KL2Uhf56ImrKEE0#'X'8KMepFNP
P9P%,2"P0Z6LDFAEhl[c*$Ef6)3jIS!QqQDYm`2'+fcS*36MNcQQY9UUV(-$a5@A
)F@9)$&1$1qiXKfB'VE$,!@MhpV'`GZ1*"c8eVcjeCc+P6&J9%`k[Ye)#fLFMl@3
MjDCN[LK9Q',F@6j@lM[1CSXJSYSBAIp6@l6$-HfcLY,XZNT*9C6aVU[jA(f4'a5
&k+6%dXJX8f)jHG)$-'%bL+1jk@&Ri'314[[E1b6ZEPQj+S*&+l-bXRIEBYMBPNM
i8KBP11$&U`KRYB)SIF'kZCE&8kHr+1dhVZC2q8rHF&LR#&aML%Zpi3"m-R*%PUU
!PHamq,X1c6MeKF4)S1#48%'pcEh6`cCeY*ICKI#0kNmLL5+@U'TqE-*`RjF4'&(
3eFX6cB*%1LKQq#`cX*Ej$"f@R*jJL&LQ*jP))YiLPRCDMM5K$V"JR)aLD@D@+f)
j+IANZYHY*0G!%3Re,JY49XD$a(Saj)6#HLPITQ6b-BYmmHA`fTm@NK$kXVk-%q)
0KpC%fBMjY18`El#!d!F0H&--X*Qrhij`#,'XUBbh-RVlN!!$QajL"X2dHUeFdI6
kq4L#ammd&'9%3)06UT4G9hPMJ6+I5-i(Y%#f+#e[bM+kUTRK@PL!KTcdNcKm(TR
N"*md8E&CJ%CiLB!5@2Fq6!H3!")!PL[h)i2q0#-G!$KjHU*IiLaPNH3lVQB5I1!
[PFbS$Rf0R-a+S[+,CC'SAMdV4c+CYLfIh0`$XmGa8qFp3DR@*S)r1"9&-VbS-,N
2f4r#&FKq2UGKFMlh4E0q-LhM&0ciQje+eL[6$5i$*aS-plc+`J+*!@Bb"$fFT3e
2E*`2F2!8)[K'3h$e`EAPe!KLSZKZ&S%(T3%dB*e#+%MP+K1SpUS""0c%"CMiKPp
P)XTpUL(C&1)%#pcfaXp&Ahr"QcdA`dr9Z4"q20VjSdLDpfp1KNQdJ''*Vf2EmDc
8CXpq9,'J2&ThpU1qJmSMkqa(hhK0H45QV6hKfQK8maCpN3idU2j9*[b@@NZ%X8!
P!FD3!&LFNeZB4+%S5eDGBp@,*APel4eV#S#AFd0rrQlaXF6!h'1*[X!JXRmV6H$
m!'b$-EpD9JNQeYpNpV*)*q#i5#$b!SY@llM@H*6CTNi'56da3`eNp4*[1bqe$br
dq&k9mMKhSFIIq)(bf(r@Bd#a9cj8(SD*l(L##Bcdc*XLi1I+Hr,,dKcXNI'*Kk"
%P-Z*#5a3NMTC)T63C)K8S!8#"14-#$+#$`KM8@#LfA#HBVMH'j(PN!"XH)J&0,m
9%X'm6,#4A#FSY1A*Hkc(8!hZ!,*#pE#QjPFR)j0aU1l(j0#DMNpSBK2#FB)-Hbq
8U!R$MJX$a(5e-BCUAB6K0PYPU%jl#ip*"J1Fb%U%Xi3'0F!XDBI*UEM3c-T!0@$
#'&FXbk%K[%,,F[bBhlS,8D%qMQ$pe0p&l%T6-)kQS"4+cdk%QDk%6ef*lHH'rUN
VdIH`'2MH6J5jB"E4%prEkB[6aADkH-JUYdNmm+'bG3*J(ECfckkL`4fIPY'#%(B
Ll#3UQpeFV4BK#`i)Z9CrX[1B-,RrL8[miP&G%'C98UH5SE'*V50c@bA6Z`3Mp'Q
("A&dRa++H*3*lElrFbr&aKTMDrH,*SPPIJk[M4l*XFZqkA$$&a)9fLTHQ2cL@,L
K,h&2Up56BLQ[pV$CL-[V8M[D`lP$XX%*JV8LPJXP`VPZI'Uk!JCC-mT`1bHa`cS
jbXd26QJ(+9iLR+*$m[rcrk,rMrpLCrdA8[j6m9m3rqNA&4`)+6P#ebc(&6KM[B!
rZN%68C)K5'(3+K[bRfj9$,Rc6lGHd*!!ph'SP`hjIc2VC(4crC!!%V3E-A$j)EP
BaB[[*kDErR3V"KbTac808D0FbQkjD2(Lla,6pV!MNFM+ZY46l9hPB8a`Fe8BQCe
LSj%13&lUNDMQiFq)T-qB0Q%)-q(2%!J9J1M+TkVPM4j9+Tp"c@ldr!-X,6%bV4i
*DkNM-3iE*1iP4UU#)'E#e-#pBbf)DLJ2XGNpl@4R%UqE+YFkUP`HUP`qUPbP9,Q
N[!ke0`C#rjpjQj!!F2pYCVHeQjVM)jd8+[eIr9!*2l2`b*QQ!d2&N!"-GI',)8p
c+2kV9aXLR*!!eY+jChJ!-4FKp%r#0&+aYe"R1G3DiHT1+Si6CS@5a+6N5@SemLf
dd+5f`SXS+`!XBM,rR65R"3l,Q[%Hq6#lG-6ZKL@$%RDS$`jCmNFp2cJ9PEL@,dr
4j6%YjNU+4c3P@[I`M[fq9*bJQL3HqdQ)QlF48-ddQMJ-6-SLJJDHFFlilJX(r[j
6TcM35eNiDr2I,NdNC%a$-2,E15c#YLJ['Kk6X8SNiX%&Vem*d313!2JbQVS)m1-
K%cc2hHD`pCGc-JcLcr4a8l$[2Lcj8kJ4C8-I-G&a3U+C'8Tma!U``%'Llch182*
H*%cF5K)BdJc(6LLKK$0rKKdX[!D(kYMC%bphi[V[q@5X!QiYhi0DXeM03E8PSDK
5I*dQBcZJm[C0KTkk!lM'DGepAb%BrQd(Kh,Q*"`qEb)Nm%)59h"L!!MGdd4%le3
d)Z0cLDFj8EYZ0dC*P"rJ*KHZr"lqI&5)'cNdZ*M!*9F@GT&T#RehJTRLFKb9liG
"1Y3`89`IMTfU&-`kZ@-rZ4(ZTb4ITL3r6`B%pcqUCP,ZS%SRSd08"3&,!(k`&H*
eIcjf#NV59iM2jZSUR+HJf,XQF$%$JdGLcrbDb08leYd[Sj&H(fI)$["Ha*V!#l@
5iBdL,PQK5rb&Z#YA&h9Fk*+"&TF-Y,a%YZNEN6p-hdKGY-8P)bdZ'6RVNZhk4Z6
Qp)h8a9TF-YcLNZ%@PfMem9S&L`Fj1'5TI!Qca$Y4kH!3p0TGqqi!h-b5DF)CjR8
d6@`ar-3d#iDR`N$X,8fRlj!!EMV--UGJfFU1r9lla+QmI+jm`ahhh8G1*5VUirM
TQmP91S`j0Q!dXPq(kE6"YI3-6+1ER8$ajaVqA!CBH)f$BNa5*Uk"N!#lc-dQ3$!
0%&VAB&5(B-VAm((SFa`kJp-PQVrY)#+DdC!![QbK`LEfVReTp[BSJi41,@AFBM(
Qbjf3!!!"pfT&&L+ch($C`d6Er#U8eJ&@C,06A0hRGq0eh'D3!*0S'cDcpb#ZAT4
pcbTE2ir'S&@AFplfIBM$pilaieQp1[$PF2#,k4@#UJ()X(9)EVdD+!"%c&K3+N1
U2R6Y&**1T8U!a[BhZ%)La#U(MP)BpFV"m8fe&3j9hp%5(")KHXi%J,#,T6)r0Er
E2H8*D,-im)h*F$lme"dbpTGV+r3+(l+5PB!4cN!Xr!q#k9!&N!#)lhiC+KC`EK`
2,[T5"'aGI(`E`VIE%$JDY-V'"UGr``p4eHB`k5S5B43IIL6A99Gj&N&M!'40r(N
NqXc20q,+3Re"2[0LIAe1MTe#T))JH8pJAC,KImrZ3PQ6Sk%AKVi(m-29r*4R0cj
f9PE*a$+J&+dQ(hcU$QqXS9#3!!FAPY6+d"aJN`iF1lfL2`cB#Y+h`3SMbG[&NG#
c#qcfP,fjpN8Sl$C@f!6XGc1Bc!2`mF2PQeT92RJmZZAR)P#"i"hF&[0"HM(#,b#
F)`b(i*M0f)(N`!-PNm18-ldGJp01*B%lZ3,#8BS2k+3K2BNI5ZNDE-C@&f@LN!$
1Y)T$1P$,![Y6ZBS$MI,aZa9Ybk'j8+QFQ+XB)%9VeS@F-15+BIcTj#DAYI[T0XP
#IF'rHYm@DF*-2F3L-"a'hFfUB&ihEpf3!!r`KiG0[3dLIJ(-Qr)Z3F9BAKKpS[[
8&bVkE+EerEqi"NGQQ"dhH0!J6+%#HN5c,Y%0S+!8*M08P0im6f!RGFqIf%cr)Cj
QKD%8H,*G1&!1U11EB)a6c"j@%4Y'49!8f6jFX@Fbq,kF*(Mej&8f3q!RFa8lf,b
4c@l4Z,3mJ"$XmEQ+!ka3TU)j&5#4qP`r"-##iZDfqUR$LGf*()Mm96KA`UbpFB+
HSMjZ)"UfT28NE`kK`P@PD5dD1#j5)Z1N2(bN5QbN3)k3!2SiARH6P-TQ0%G[Hq[
U(XC2Bef+AJl@RH5AQSf6[')!41(AT+`Bd9l,[)M4Lr(-#j9H6'9H41K&9HC&P&i
8ji*D&NEG8p'Q@A0"@iaCVY9J'D@P8@45l%GL'V)GU$MJkM9K*,j'"(m2j&e3p+p
C`HIkBADHEpf48K'SqcMamkBY4mEXS+C[fA[9Nb%QrlUU*b8+(8!-Ged%G*TFdr&
a"PAX4HQVXC)Fq(BcQEM[FqaNFqLqYb"+"dQ8eT4+RH#!idf%0q+9pekN$8Nj$&B
-XB$dTQMEIiE+h#dDl)+TB2B"C[D8c+NfqeGMDaVE&SKYUm5fU66#HTEB0NpXZd4
XUb1QZBKTPiKT'V&X9R0PQ,8Q`kD&$)2@C9K6b$!P$kEi&DDdCTKLCTJ5&Naa8c9
l`JRApQ`q1&0qm"CFrRUp3aBPNIrQFhrrr"F5XmprdT5MEphAMQ3SFcX#Jli9iaD
lb5k+Dri-Vk6FCGed1EMDSqL1HPb+UUb9-+"1i[Xk9b)"UN%d-0%BF9A[[AAXKp6
NL9Dd(9Y43"M!&ArcV'F6VV!$#&4Cd3PRElMUI!a1!AMj9$r$dYMLA%ARYY[1fik
HLQ'h)qC)$#F5q"Ka1k"bFVV+i5eTGK)Cb3Y9rjCZVZ4F6+jL,05SQ4#(Hr`)ZmI
l$c(*T!Lq#+SE-hH1Q"XKYNjSTA#K4m#"A0R*RB%cp)@*l&%&P"ZhGM28NaPJ#'*
%pLXJAY9T!`"Ub62LXA+*r8+(22T$r4"[mM0i68NArpEKa!#b$h8)S*@61-i3ek0
eRNd%"JR)m#F%%0V63$*5b&cP!JK8H1XrcH``2$SN#i+!Q!@iDE*-E"JJ&Vqd@l0
V4[0(Y9MM!`5m4I4,U6'&3NJSI&*#8*VTC,MXjj*EZ#A8p$K#Ma[e4P0LA!&b,3K
M,4fU`XqFc0Bj3-Bd6L*`I(-AMQjDdr&0QfF6")"8ed1NA1+U6$pfVfFZT$ANEcj
h4bHDmbB#Ni8PK*8ie!YiH-&GIL4kIbmlTmJQba2)4VIlBM2AAEG39-Rp3IRLG`8
%J0!EAU!Jd!-!bLVKG[A#a$[Lm"qr#p2Nb5`'aP&SiVcm`%Tj9c!!$2ca#3mlldp
2[!140`kcVX2,-r6b')BX4h[`iZ[dBJR*XmbK0KqE4TDR9cLj1L6'0ciV(k#L2Ph
cQrLKaCGPCFQDMQFqj1-6ifcU[(R[(+l0bPCFUiT(r[1beISh$%!!#MqTEaf@49Q
$Ri*%%j!!VrmXIk3qb`m`#"9-IafA2[a%j1%!M0khNYPJa[NrmD@0cdDh3ffc#q#
i,89Uqc*pV0$(Y5are2a-$%M5bjejrLKjQPkHDT-Ii'8A$DLM!5cqadRY(q)PNEV
G0-"(!rD)LG%H35,JJ9q3!,hdNDH26QA3HiSEdVMYM#Jq44q(k3-"J&L%f&SLL*D
amZNi'CXT`)*j'!L#c@j-FJC-l`))LXY-#L0jVPR*ZPcAE9C!&U$da-kZkrL)VqP
ipJ&&'FRS05[1d+`9KjVi+-Y+kD22A3GTr#9LldQq$RqkF19jGN&%Nf%A*VI5C"Y
-[aN((m,"lRaCV*a""SD3!!!5a(N4Nej$!"3#F-$JEJS3lD'V$kcTf')`m)YD2%L
LSikcMQ)9IKCDajBB#ND5X8[60FY6B,HKcS)$L[JmA*2ffC++L"4C(q,L9PBFP@B
[h#-q'UfqEj3E%8V'6MZklAU,SaI)F"$!pkil(MfUmJ6,P!jS,SP%bd`8cY&A10K
88j5I@NJdd`8rmDRid"#%!053!'MfcLUE@L'"%!HFXrHq83j0*Lkl18[*cie5TT,
(SfhY@pUa94kBj%9L$iD-+%-'a%Z`@ba-465B1%VHHeBFML92'JmXSfSC#"FXFp9
kC2di95fPUKYJkM4AcdFH'0q%Mf1e9If4CRUe*#Vk)cdJ,am5BZ14AH1E@+%L8jS
h3ZVd*eU03UT3jJ+M2U&QEj!!3%Z4))+jB[YK&N*TEPX&!GDc!+qK)J!)IUdd@Xh
P5r@X0-F'IF[,b5F(1mSABj[,mm(RlR#6#L)J#A8@I+UIQhTI4P,)IYF2*"5#HMk
YS)1TZ&#[F'%f$Mf!H+Ub@4f1TBCXfD(H4QX[VRfMR08p055bXTmGfRef8550b#4
fCd(SQTa!(++3!&SNV6#5D69550KGrYQlY)&)fN2D!)5amGFrPqV6EePPMGBBM[c
VYh"*T$ESDEGRDje(NK38@RPI46",)5!5p8bbSp!G#kqP`%9I25VH!!9JAS-#-pR
*k@X[m+#mp18Rb[k!JJSbLKm!C2Lj*d-D"b&9VZ4bMZ'$[!b8qqb6C@FI9F(1"LZ
X"1hfXa`()P9c(2cRi+Yl&N'SH$jJ'hVDH3,KSKN("qkA3c[qPK,ZidMZBC!!S2h
ji0Sl$%F8NQ2ETZ-Fb"cEYQM3S'%-qVLfK'CJD-[2+I(0X@h(5UbE@pSjbIPcfV5
#bYAbb9XlrKE+X(CiPLpEBKHP6Q8+[9TF!IPi#m8J1QQ+bXH!D4rhbF3j,)Dp5eC
`VFj8KZa'BJiZ'HC0a46`@EY8#(2Sh"pFQeDij3f(HaEZRL0N%M#j[-P+19C1Nde
Za-FFI!%9ZiNr$QMb4pf*!8UZ%@6B5(c#iN)L)XJrd!*))&#rb'lq)29J!'iNGVB
4X%i@jLB,U$acXNKKpNjf!',5N!$C"5A3"hHd'PYdDql5VaD#UlfV[d+LXmShA3M
C#-FZFMEVd`X0%43i"&*jjGp,!D`2jdA96HAed2"91[,VE&j-TSPL(l+SNfaV1YD
@8MKGqM3QG%'!YeTPA,RpjYKYZ"+a#KU#kJ&!2A1GXhVI4GSqJ'j8qk*Q@I&CaeM
e0#ZTiQb2,+,T2Mal8G0GV9+ZYaMU3-0p(@r&PpI-c*AQ8remVA+`8A[`8MF4EES
6`4iff$NN*K+b@)U%a-#X*4+63rDhN!#8HqLeff*h*b3R&8GQNMPbUNf0XkU&f+p
KXCrZ1!4`dUmR,a8@1'#A$))rTi6J8E6R,MZ'E,j14EJ)mS1CBH-FAX[R#Q8#LS8
V9*K&ec++br[Fj1)8*iDX4l0PrC'B)P$c4CdY(8NU*'+bFpeTeb),fAb5XYI%KBL
9)KCl80L8aH-GGY"Cdr(FC8@e[mC9jVlV5!L%&E)jc8h*BhEeMYdk*N6j,l99I[R
p88fYr2lRHl(*!5A4KbM4c!c$M3acbX&Z2(50LL&M2G*BP"Al@M454K4"NTqi@mN
%mA+KI#+%aCaCrLNdPB%f4[53!!+lGhPGb'`0KdFB*UXAEVA4VR*ZZ-V@I-jN-$m
'YcJ4D2d43[X$!EcdLKG2i%8E"SA!U*&#'4hSd--Kj(*D3N,$C%HZ3$N9AiF,'MY
H9EhTUkP%)AcTYqi%CVhR&-DpTVRB9H`fULU5fcJK5k6QFHqHhEhZ661*Brj&Q!-
E`rfhf!311RcjbPlPSShHSVM)DjM,-NSCGfMf#F#c@P)*"pf"ND"i0j`6f`1c[Mb
-d#65)fk,96VS)LTH*LUYiVi5Uh9E3L+h+mE2a4bc%#D&8NQQYCF-[QL4q)$U(i,
U(l+iF"SFlH[-qriB4YpZj8"d-VMeSTDL4Q3lrVbSZ"2C)8$'X29@C29eE+f9R!T
8@`&Ed2$bMj!!+%e)I(CLFq2LMeL!8I95#[Z6i'S9JJ[%U`m+D%)h@+9EJQjbCCK
,[)JrlES6!%L3!$p#!CFaEKDLkX@2QSUEl()4MK3!,MS6V`2#2!3(eMf*EVM[VNm
FB#IH4"XH2TVS"%Q88SJa'4f`iLl(f+fP"9cr+2imLcrVZ81%,h*d@iZM+rPSC2!
3+CG(De#Gl(1*e`qU[T9!#'Ddmb"HBh&jBQ0!pGS2UYjiIG#e844X!)RDr19Q1$&
*Q&+RYjjraM$GQ`A3(8edXRX9%)V()5"i-GH%UF,&PUB#r!6`GQ$(+KI&eCL`lCi
&p&N`,c`3$Z3(B%b(k$#rFYLMA[Z&0M3Ki00QEUj``9)q!Z`VjT0k!E8N-lLbY['
Hq'Mb*!QKEL+%!9EqAY1E$j**l"')QC0#5'N,C(iQLMdF%-8e)5,F'B'Mm@2p)"$
%CQh@'TbI&`8!$rLHaBD'))EXT'DXM!Lb)))X)B)5!e!Sh*6U3q'I6YI&I2cJV89
jlld@JQLrlQKP[5+(XZc1`NfGrD5XYe0eHE&49*Gb%SlPpBm*Gd--D"HN%T,T)fY
+U5jl,e!GQUNkb0"[)&3+5T8Bdf6S25U5de-UL3Lkc2!lQjGT(TGfU6L3!+"KSSX
p*'1l%(Q*[IPF%Z*0#B@fLQ+Z"1(N#CjE*Q$Z9@fHVViI$,fXACS)3E6HMcqAYB!
Z*N0V&*%rL+S!9ECBSMZUK*V1HX3QIPPFU'A%DSM*r[Zp9#9FJf"0cqrC)([qrR#
L4lJMFN)TS[GA'(`Ca0I3a203BMfk%N-c'#38`KF[@h"["pQE`q0I+S8&VX'KcRc
DL8#ZLZ)-e`iZ6!r"35JmYV!BA`CdJb)%`eYl%[Xj20$KU#h+RpJDN!!q06$Mqbi
)C6MTV12NLREN['&EV#2Rqj!!Jcd`[K#&U(E55j!!9SQG6h%!GbI-`1#YF2K+[,k
[Ki!"Cm%NXBe3iSPB35LG8c$aVX"j+"XTVje3QHcLX22a%),1%5iDc`94p5[G$+Y
H)mG,C%QiAMlRH-,*F#q)[K`QKIpp20(PLl`k"#F0TmD%DM0F!Rk&60hJiSK`iZ[
@QYa6Xe2VKNM9r#*0eBM3"bZEb+Y"ZU"*85GAX`c6Gd%-G-'C[d6lJ,BIa2D6[$N
8,ZSj%81PCbM#'AMHPqH#"0iiAVh)Vdl%L)cp5@+lCY$b!5aPe&$%`Xf-8*M3J@q
)J6%)cJ+*"5H*"HHDMKm&&$IAlA"lKi!NB2ZkU"JF9T3&ECXL(QkQ#3Gak#rj82N
'#BLE3M``8b!FR0cXP`83NB@#ir22)`2V&3&Kk@BmirKUJN*QIm3AY8&Fr%"ETX#
&U0ClU$+h*2`1S0-1Z`l5m0981@3IKdDhYbaBElH6k$"*G"J+i2FZ!$mI!Akr&Xh
RVcNBaS3kkZ#`TRH"QXJ,"2QpQJeTlVbU3(kmB4hdFbY%T4hNAlQVQJ%q0&lhA4M
JLrVBHEBakLch4P)%9-Yi,8$((FR`4KlH-drJ(`*FVi"FpPM##G*1BL9!%2m4%H5
A,l+S1[UBI&0ad6-8d$[1LK*GB,J*&J+Tc`B`L9$R*l1X+,0F8+$RVc*a*+G-E2c
,6f-#pjrC8A!1%erpUdhmQf&PSZ+%5P"d'SL4[6#)S3S3`fj[#@)!%&1+JP(R*-X
N8,Si%F(Z1$YZVRj"4K*lS"T+X`(ZH+08FV-j'jUTeZE3k(hqf%Sf1&1pV$ijk1T
&!lB93G%l5S!d0[Em8Ndak"VNac[q9Rr8A,ei[aAFdXq1h)@bXHHRCHKPVZTMcbr
+N!!Mcb)6i3!8S&KKN3P")80R@+"5jdaV)1+l&9'&VQ5d*)RlEQdZm!Uk'FZb)+C
,Kj8Vfj3,4j3,4h$K2QdV4&Bh-TA8Vf)#L3iKB4Pl3e4HhI&mV32#p4#)3!F&893
)2j!!$!dm+,6(X8l'0U*-EbLfJ0*P3D9)%5i9c4jPSkR!M&I'G[%'X58UF+CXD3"
EfX%1T@-,ddpLNB,LZ((@aK3K(P08,J4cT1A@SZYTDb(DQT-+'i%%*ZEe3ENi`9U
ckq9mlSJXKRDmhB*piCRUSYVGkaVFm6EB&pjb*`0AJ(dF@ZI(1pl@(h@!IIR`FC9
K$3*+`-$S9S*+`-#SFcjJ*Fp%3%$[`lBmY8-C'P1bY%p*hU6)a&39H4!Db!T2'U+
Xa#JVPeXQFP8SYNdQ!KYpE0STe)+i0XHCE8$f$Ql%4LD`NH6B4QbN8V"#+&$4k3N
Qf!1hf!')*chaAil)E'"q5V1R'H1fk3JCcVDPL+[A5Sle6ZrJ(cJ)Y$%BGbE&34J
'cE9cr#+6SA#kZE6)N!"`0)`L1qXb@hfHLr659T&NmQf4('+VqQ6HX#dZ!(V&aHi
*l68i5h6CJJFG)"&8Q!dAm$f%)&Z5!fCD&AFJ9NJb)0IJ3--RpJFiPf%4`L+%44!
,&BX)&N%X([i$Zj1KL!8@0aNX4&FZiUMZPSddFQ5h+i%U!`8*9*!!0@Sa2PI@I-Z
l!Z%-Kka[KG%ee#fIHfm[[3+mCie`Ce'qC*j"2aJXYTfb*3ikDVYfXJr8!RBS9Y#
aFS-K)bZApGM-RcQ2`d(!E')B!q4MhXVYr`b6bfi2`Y5"4*m1J-$9VP5%'[)"VC)
G4q8qJL-CK0cQi@krKT63-EN,2p22RA$BpYcRY#)Bh'icRRC#18'"EH!KGlN$2k-
D,!JZlS9MD)dH0Ubi`TIjiL`#B4TSa#&3$C!!&GeKGDGr,Uk#$30jer22b1XJl9k
e44XBXKrfVcBD[hM39N#(I@L3!2KAja%@j3mi$Z+a&4)2V0k*R19#b2Bk&p&!Pf#
iE2qbCHM&,J3S-95j6K65@MNZ,B-6&&d#EN54Qee)a$!$H!e"lMCUbfeNfF1%`Sh
qr#N3q#RIDa#6+GrA5@J1Z&q"bJHJEL8A(*pcZ"`Je!C-"RFBPZPlRi11B24N'6U
TZbcFJ!V"9HF@"fh9`ih`V[jmlL%-PJBDJ,KZIi#""Uriq!c#RLXZ('Ma+`Jd"#r
8p!)NST!!!$YT[V*Z6FHI6lPch%NA$R$TPr0f[HS-IQMMFFV%#XJE3i#r*ihj6@Q
&'[Yd!"Z91!QLL)PXGMG"b!#0BBNX!8kZD"C`XUq9P5dpQU2XeZ$KI['3!1'j5+C
3!LGkE8GB$#fP(i!2qjNN-TPGdf'BR15@QA9SVC0ml*!!FVPG+A$#"ap4$YBI)X4
4N98HIMK*'mSm4!'&#N0j1)'+"@CmkYhXd3cF@AA19QIMkRE6cd%J$"ZL!(5BQB3
U!rDL!m%4UAk@`p-4JKh6R&G&X$Jp1jPNQTlIP*B`Xr1E4,KBGhSp2D&T+QFdQjR
+@@[0I&*Q1!Y$6qD2+PY(GfXhphNfe3BA%+4Lq$L#SU0-'KTD$3&!RSRF)cPTR`#
F`meHX1%l6-M-8aGS,%$-5NZB(Nm@C+8*XR)@aP[+BLA!iT+&f`I+Sh8fpcrjmk[
@5Craq8f[lSeC$8GA(d3iRF--8Rl-QV'DQ3"'H"G%ejYC#MT(V$[C'3j%FfG$EmB
TM0`R3[EX'22Q$R6m#&,80i%QbE$e*2rr1hB8HI-[P+iKhkbfMNj+[D2)0krcjm3
l@"C%jiJmmI&9C&ZG+"*4#!,c#SKHGmj+q36Nr%0YeNS*NF29C,4rUT4$Hp,k$$Y
U"2a6F,J`)%j!bZ%9LYb)!ND6+2KL'q)&KmlkpSR3#lXhJ#d[ch1J$-[@8S6*3))
MV+pDZrGrNeNRXYXkM5"FL"021"YBhr%ShFrTaY!S(lSEI3pr0Y[N3lRSEbFHLql
k)SaY%SbP!(J*X4GZ#IKST%kHfN(S"a#XIS#VqA1"q8eRXjd-m3!cRT850R`fkrH
XkBLm`-@r6f2pr93%r[jrmQGA,H0#l)p@@l2%rPh%p+[%FR69q6XrXAa!9-6IM5M
XAV*fkjdkqJpCXrm'PNHh%mZ4F,qlRQ%jIqlA@Ikl9iRPR3$31ffjIr,lClqj#XH
"b1NEJZ-i'q6X"0`0!)V1`UQJPCNeF)fk)6h!4E-9dj!!FLXhLGdj9+Y"AILM%%[
'5(Kkp$I)%!c,2NX1#`ImXhHh4&mRSm%Re*L"cH5L(eJQ,q4@Z&p63)PHrf$L)IF
X+f#i5(``QB,bkX2dRXQ(aBHYlKG1I)"T9lCbB$N[B9KmQ*X0blH--0bCD!mU&dL
hp%EVri@6dUFhLD+(J#a[c!XcK(+cTXJ-"`3,rY"p)62-##8"NThd*YdcT0KFPXP
&4'lqfUXf2U!9eR5%E9#U"NJ#&`I6RZQhCS@Ui8*'h&(SP8iBhXcqEh,BLJ[-Xp(
T4bR#TNphfX&&bI`XZmiM3q+JAA63UcJS`P8@"b'VdGrJ)0GC"c@M8Xp3Q$YXRC'
Yk(CiPSr0A["BS5cC`#N-cbjb&,#!kRp!Jq!*ESB4#0,Y!bEG-S+kMBN&[8XZ*UM
#"d6AYli`N8VV44Hfr)1UD!GM4iL`BN"ba&B8VKhC'G[jRcQeqYT'2JEFa4Ckd5%
"0I'CD,2-,B+d'PC)UjFcC&9R5l,UH&3cd*9aVpGN-Xp96HDJM98[2DX[&h2F#5`
48D-JSKS8)UUYPQa#GD[pD,-%39DY%%qM'H*Tq%,%%bG')a*$,6#TK-V!hH+Z#Q'
1erFcbDQmVUIApd6M2$%#8INLJ"#B8&U9Zf(dRM[mTAm&C0r,+XdEd3`8dc6SCd8
,0h)iV!IG&XJcGV$3"0`Q!"F(AI%d(Sm@9)@X'UJPUe")0%@G-%`4kE105,D+#j!
!E"AZhHaB#-+Y`PY$K4SMF-U&J)UD3XMVT"NUS*[)-Gj'LJNbX4',ZQDfLX+0$9e
XPh[Y4MNL``mJ6'ai$9`R(1H+RNf+3N"5a&hNDS(%53cJFi%VCS[#`3`ZJDL2E@9
a&,*4plFTEadP*N6m[@Q4P&k0&EIK8",4S54LJ"*4j83-,,a5eD!UT#'%60GS2XI
0k,1)3hXQbG))40R*"'+k`ed*9iJN9h"dBAZakLLfq!BU+lDP0,ffG9h2jMa6k(l
BB#GPfjrr`,AZU#d"m"@LqD9I9KjGC4#mrrhJ5frS,hcM"&"ajb`QGbqGGh#&c!S
'jc,$'L"D!T0P,ehR9qKm22C5!UmqQjG#j01J*)ScJ(QQaB!Ea"m,Sd4ccUZq(hl
TMBjY@!4IfTafJCST8P9EN!!U%RJ,(I0'-(NCIriNMA!cZA-)([*TG!+EZ)H$e2a
4+$afpEN(XUILmqMFeL%RUaD2RcXmm4!'(F'I8TYXrbDka#8(%`SkA%@ikNML28!
aQbHiQmGhi8Ur$S,M1N*DT3KmRI3ff-[3cFYZI`!313SXl*rMB5"[(,X-"(K3E1i
VjeqE6Zb(Jf[2iZ&MMBRY2SEZU80P,bSmGi'PZ62$c-b`-!q$Z`)GK)k*-TGkEp"
N+"YcVqd*3@,30TYSF!1libD'-,`*3Xe#YU"SBZ(j63ebp8%[#'Mc"9h`LXjeD`8
[([T%&m5S90Y*X)GCYE#ScA3ac!rl-`m4mRCr*c2*4JmL3ZRSda5'm3#22Z"El2b
RZK@'dF1QY-Q4#db1YjJF5CmX"p)Q'kG2PSGD6$EF'804"ZaY-F"XFIQlDCI(,h"
jDB[*mI6,Z42iNrZYlr#MQ0)Bd9pD@Ea+kmL%e9dH)@[iLCBeSS[G3Y,)4H%8i3Q
ibJp@,`iIV&j5V96,MNbiSfQ3!*!!283d-pK33b4P$jS`15)8(a0XS+kP-`iYNFV
M#D8MC0%K+m(jL4pcPl64$CmAa!P))9-4#T9(heH!ZbPQ9!+B)(dpJH$XAE+I
150#jI(ecY#$8bFS"S@5SDpmcdKa(m8N3632q[jMr%q(k`K9&%E%3UL[$%+S35U(
cll3J9IP!cS!i&0@hNNQXHdIJUQT`GqC%&ST(0EB#%Ba,I&(+I-F[1SElDPI*pB*
-[HHE9`M@d'ZeemN2E"j5[4k3!)8'%G(@1bfD8+GGH*@k*%AM%851kCp"df6EVMP
d9$q$`U!3EZa%baHTBQ[$Ah9V$D,"G'mE0`3)6[(i(EBFE89&NqBNZIdJqc%'aq&
FpY,QLCa@j#B-%pYp0r3-bBXLQD5'Ua*l@E"L-(Gi$%&UYQcJ#Z1cQ5K%ddI1Xhe
j8fXPYC1QBUkJm6466JUTh,FM[F($KNJ%kB`E(Fp$Q!HiDhQaT@rX*1"#IT("hm`
-2T3qQ)QBNNTbKXEaaUKSQ1Bph*hmIbaqCHRp+ZP3rSN$!'G#DDdlbSj@dF1#a+#
1`6N!QeS@X#,q`34US!bXqHP)YRM8#Vp6NPd9M1#TAVd6TcPU#-%dM9CKbRbKhq3
11p"eaj396MGIShjm8rjUSrYR$eV'*FIa2QGe0JHRFp8fceeeAh)iUpfj,+$LVUX
2j86K*PV52cG#5j1EX,5-%hM05cZ@F9S1B@QRTBAP%#hG@&Udc',TTQ84bb`Y#eJ
@DGQ%CB'@P9JfdE)+bdTDjV#XSZ8#PMPDVQ+j3-XT,>kF&bLTDc@(TS1BrP,#h
(iE,Qc`DTS*(m6c8EA+KqD%'Dq"2((c[q$1'2C3A28Z!TBU5[lLZ#NHl[+!6rbf`
@q#F3VZXLakdileHFbh55a%9-Z-VXR$bT'dL)35FM$e)#T,[q!"9!(8PrS+[pbqF
@Mj2Dhi8rfeRYFc28@iI2,Yk3!#f+6ZGq1[)fEi)ISBS2kT2rp8[([R,kC0m5EkQ
#L`YfSBV(S**h*F,N8Q"30lX@LSN-falHTE%LpMAJTB8!DY1&TYN5&ji'N4j#Xli
DS6'I1bH+!6amR%b8!C8Z[k[1rBXr6M*dALYNKfRBfq-%,&3iq)L+Pe'FlQdQ2LT
'6e(RQK@$I&`&"j&Vr[e`aFZ*F6Vq3hk-*[md,QdAPqkD%q3NGki2KrH-NL!KJf#
lVLb8C0Ym3VTRP3,B)mY*G*!!9$R2EU0p1K(UFC!!!TRDlkk&!k#5`#`@@#"!Vd1
`-r#UBM2MqH"89B&l5YQfiD,rVK#c%)S+i4l0LHk$I$(A,H8eLmU2eEj'8#4PcEV
3F1)MDJR1[GZm56V35&0d1d@LZ!jc-P@F)q*,9ZaJ&i3@6U,F2ETp6R3&R46GMb!
%A,2P6MDqS6TrPd@QY9$N,XCU%)*K4fGdH80KX-2F3((emT!!MX(&!af$5qc+h'V
eDMjVPMX-DUlf95kV0ZY*"iF8E5Dk`TZb3RTL+4[YBm@"C0SS93TGA45(jN'F2I5
m9,q0Be!3PS[$T"L`SZC3UcA)#@'4bl5pKF2V8A*ijHTjl[a5ACUBC@J4lVF`N[G
B2Hi2#(!Z$d)#lKA9LqV"kQ0LJ)d'Y#6im3q-6#UGPkY&*FLqQVR#*',"YH(Rk)[
S-ENd9JlhiB!9fY*IGllVYTjKjD)NL+flFNQ(*m109!9'G&%3pY',Iq(,SGELZPT
M%!kQU+(jrR)fadepDKCkPYQPU3mK-j1EU&BC`(X`L8('LEXr[LXMq)0`cSq4F(!
NLALcj',&aQ@L`kJUEXja@1MH!-0!@IPMr*-!-,GUhaUDY)**UG-Q-5$-NbkR69V
"T0C'mqN(S8K)&,VDN4JhCfiaJC%iFe4d4BN-"lp,$G*r%GN0IM41+[qPAkGhb#5
k2G8Cq4mY'GQQ-c+fQ8%&BQ5E`XK`1L0MjfM!@Bb-I8L-"%J9@a+-M%ePVSKR'-Q
K-%0Rj$2pGHECM)c9%#-0(A48HeSb8[eYKT&Y#QJMJQ'G'@C'RK(-0%pMCKaQ11T
Q%jM+2mRrNkPP#5Sf%2*Y"A2-L4aqNX5SH!--`,[FNP(rFHir[m+-kKY+Be3FM-)
r!8E6D[KD6%eHB#UCa6GfT%fYSDNU6E8V8q1R6B9+T+RYD92Y2&9ZTDQYbY5D#d`
p4P-2TdeYTDQM0(9)Q@Srfb!a9@bh+@hU%+CHSSNPAhhLIk8MVr5P65c"a")!m$h
L(br*'(0%0qB+hCMCK$k4EXba0M,QYTE',$Skb41`Ci8b(8J+'(#$CJPc!2M6HXM
akA)3Tjr!&VJj&"C$cZl%j'JP!i3I1dkJc$)6b4mV9CT-3b"kBpiDJ%IFR9A%E)B
X)cJHDMI(VbE3Q2lBU`5-$GNXd9ca-QY#e2a3k6SdYTRBPaH*f1rMIkK,YJ-3$RK
fcb9,ZA&ATM6ZGU-Sr+h&iHCE[JrKa+!H[1Ac,)GQHb(NJifKYHdH4iXUdqLHr5b
%2(I&b!i1RYh&QeTbiQj$qEI[X[-K%jedCHrLXaM8,`BeS&RQZNkK5e9d`N+Efii
'6F4VFPKUq!UD#![m3Qq8%236iBFI4e!,AG49XD,`,R2PXMa`8BjR5(IpPCRq#Mp
6JU6RbmNKap!,&6(F`*f@iH%RU1N-d*!!5C6K!B8*8[k@f#$PHi#mb+d2*[ab&Ni
[P0J1$$CSDT`RIV++!bM+F5DZlrM(eqQaSErqa`rSY5BDkM6T1,eU6AZe$YI-YXM
DE)YX66&Sc8P-hDIT3F@8q'HH!1P)11X(p[phELa3jk`ml6-8U)YB5G%e'X-flNc
R29cN(1V%AS0"h*8XB1-jr*X9(0M$TIZAdcYjik&eAh2HVQYpUTdlhiRGC[qAFqC
c,cR3lE)dq38++F0j%J&0iI4NT)2Tr-mVFI%A[$i0D)mj3JNTkdcq*e8Z2)$YTDl
e3J03-5ArXhYFL$#4B)0jp(i'!#3TH$%GaCbNAdhE)Na"fNqlL$YM0849"Q5!%"X
jV*JSF))#a34NV-#iba'ZiX+8EE@&Lp-lq!)!!#'!384$8J-!@r8293XYU3$CE)Y
IGjGeAGCQ6feU$kReG9eHPe+k$%0b1`k6qlDfX'jlffDhbTVd*$X4GkZKXXH,R-C
K,ZYY#aYSX+89UK*$J)P3#S*44#I*D5l%dkXG"`e#0F4J,NTjIQ8BKm&H8YhIrr[
HGrIGEAI4RMPc1Xr[c[-"'Q`P,8)!*%%3*%%JGfI%P-H$QhM[#&@Nf(NP&UX)dbY
Aj*2b(r'YFDrci2*[QlrCfV!mAh(f05apC,p[HEikiFX6YTP2K2MV@2[Fj6G`DF6
P#LjfA(EKNJIKfC&-Am1Qce#8%&'F[YVP-llIHcahjD&cm)R(mh$pYe"aZIcEb$)
(L*5E[`mL45BL4@P%2X0P$LkpZ+c#C4NZ'`e%qUU%dd6SC#k%bM9#Yh0#JbC#JfQ
%0Z"5KFYLA1EKFJUAd44#45C#2mq&d1fFd0c9DpeHYAEefPKc3SKe[NBL!D'mrEl
9DeXE9Yq&jIRrXP0-SaX*d[GpVl@K+i6*)YPN#)lD-$QB1YNe+hfb$i[$YD[[HXX
R4YL2j6EkSH*$V%,0PK!Gl%AA,2CLp9T8d9[KDMp9Z%@qSAa$PZPH9MAUEL("C,1
j2hj`p9VZ[YeAfa@LccrN`3QErYNeLhhbSi1*lr15Dl3J0+8k)bR)ieP1-Np%3++
D(5&Q9%4S+Z'r+05XmVUq30dRE+J+M*KYjIqHm)Gpk[ZQLN!9SJBd(A%[3r4qBfJ
+9Hcd14!8-H[3P0YrFGUCGGX8'p"le#bU(bVP&D(8485aP-[ZQ@eeGcD+b&mibMT
bP#&LD"URR6Dh,CK0q"XpULea&"Nkl@[dH1,l!E*!F+c#5G[TFYXZHK)1MSl%FGP
4V0L)X-Y%1'd6#R6R&EJFQR*$R+Sp$4Z4bk*Z6)!&Na[iF"'#bEf+S!a)h8DqQ#S
YX9J2FiI,J*JfNl)lhXN1NT383Hk(TP#3!10*5#$KEhp9Ice@B4!-3[!D(GV"4FF
KPM8)UVEQ%YS3qBC(Fi3b@[Y!96#+5eF*'bl'D*0J805SV+8-M'JCk(Z')I@H9Ra
Jb&PfK%V+-2&'LmIMl%)J@H#S%,I4!Fd&UCQ%6%AP*#9N)$RZ4$Lk&6S19EIjV,i
b&PB6kbJFc,C'9%`(Xha4-B$AUlMFMFYPA0Ek2X60JmXM'VS,P@)lCBeUMY`*P-G
F0M(YYZ$QjaXE"Y"fYGe"5iN%Ah3kGC%mZ&!j5F@d9,R[3Y@(3pQ&J0RUlVC2SdP
$&8K`qKpaE'GKVGGZ+bYfecN,peAE24&VHaFfZ%XB%c-ATe9EdZUfE-FPBEQ)L[k
,IQ6YBABF8k#R,UZ-paX#+&+L[`K0SHR5UbK2%a$3``SH#!K`U0[kNEcG&qdHUQc
Y@qXj(FS%IHh0p$Q8k65f0pXpFmS"[RUS-f"f+Br0aXIf5bhC4,"4)-`IibqmkRj
KQe0NCNRGTECL`MLRfBa%1fjcCXd)6I@aZ)KE!KcJZVS0"A(4MY#N*aJ8Dk%33Um
1$e)50!9Hd%G"4JRB@Ba3!jJNCX9GXS#k6TNBYr&%bcGcTSBR@#&1mJ)`&MC09*!
!kIXh(jTHkKBC#)#e'9P!MHX"94N&j4&APJG4PJH45%334+G03G6%JSJa5,10XTL
a+&EFS6-'3l8r%TMM+C'`ph3Ldji4"DAr[Gmi1l22&V43!2EElLpH9"cF&Tj3*eA
,NqUFTpqaVHa*9+-+f4ZqVfidD69I$[GYZA"6&aU(NRfGFDqk26`8INldcj3b*S,
0U85LY9fcQQhGB03ha2MRXF*NLE2Nf3VeX$`$Q'1+&Z""jPKHchj8,[e&U16B06L
Q@1K)rGRl5qT,i0JN#VQL1REVT5h,4EHcH&mB,U"L0lj9FfpNTT5a3V"rEq`F(#T
f&MpEP1i3!8Ld8G6XSE$-1C5*C"6Rd(Q@)Hf0I3hcBdSQ0)@2e`!ff1KM+"2+K'2
KM"+M"D@h[qd6[`*cV)lAm3cZar58hL6R)0*"Ld)DQ9!ZK'jGbJMGZM598%JM4@%
GMCbqb3l1@!q"S$L#"521@EaT)fB`6HceCbMDEhp'K!qK@Y,K&ad3UV4E81"IJ'!
d-N"(mDP)2Qi[Fr'[Bk'T3a-X8H(L`X@"5`5A)#lpZ"a&J$+3!#,aSaZ!@AC5iR-
CCC[GJh$[%5SZhEK8iP,!1b)pJLF0*F1%lG1Fi66K)#21ZEhpCQpXl[+VqfZAAqh
Y9`lfFT!!*cJ8Q83`@dSh#lpUI*)RXX2ff9C8If8Ic+LlK&qa'k(3B*jTAHZTk@[
SH"%GGIT`4M+BDY+QQV5TK[RIp2dHc'1%%TJ'r)6STED-,qI+)K-))'21!%+MrZ'
HJS3(J%S6U%kTT#`R&4d8Gc[4T2)YD-rN6q8'J18-*K$mcTk$KC--XbNC8CG'e(8
RLHSN`i3JNQPh-j!!Tce$#r1RFJ-A8HbV!d[)ALe4"QG+BcTSiY$!)8GXPD!Z@&h
k3ShS6JDk-j*h&+YHBMF%qNFbrl,6iq%(BF$r31i(b38`$ZD1)2Ta$!Q,Q"Ge)`M
3r(6!A8$G&Rbip+l&T`0QQcU480#mHGd1j[B[LjadE0E!'GZALdKN)Z&rq529QCT
!5%A,9lYk(R9+lUl(C`-Y&b1XkD!1#R8m!M'3!$f("(9l9Mr#Zcf5hZfKVNXdeTF
He%&IHPJ6bUj*MR*%KR,@RP#U-E8L"k+9kBL@fiD&U#N9%C,ZT+E-pKr35PM&UUe
B32KUHbdXShj@!@4'0+UFY6T'iNEY43fU0*f*DLUmi3L(d0Qj5`I3U8"(Z(3Q"L4
!1M59,Qi5eS1`Jm*2)l!UYp#lN`4V!K*XFKlXrCDj43FE(,diEMAI(#X(9QTlZhR
`VaXb"4NjTLrik`"eLAZrK3dFlfZ!X*bCTahD"'5"JD)CU@205)3e)p@BZXk1qk2
G)1E95Ia-eZ53!$!(lPcSM($KJh0)@#9AKfKLr"V%Up2%kpTI*@8MYN3*mN)KfD)
[K`+48"+T*,kX#L6qYLY9[0)Dd2h'92(r94P3A%S6Ra23PIa8mHZqJ-L0DH,c!SR
hldi9reCM)2&JQL[GMS$La@RLU`+k8TmUrSB88$`Y-pmB$EJT4DRL(ICFa"ep$I1
ZSXRV)KBiEc-e4)BPVaX$KYEL9!+[E`bBS8G5aG@4J-kREEUk1k"i*&AmmEb!VTa
+&3q,J*Zq)8fm2U$iCkRLEad0'#bpDH)$!F@ATST(%J&GZC%QhK43[#99r&!cLVq
DKXlPRr29cPr*K)j9FH"4BiU1CMNMrGNU)1``!"-3"#"(`%3lP'i)4+A+!3iXZ9J
cGh#3!$(SqFYip5CRH[qa8Cd!SQijF%B9"S3)P35Sc%!hbP+kAJi5G`VUDLH1i*8
rBKmKX#554$LEE8&R`[r+)-"SX&"@'DQ"DFDCd[bT@('Sj&VK1`-F5$+iX)Sh@pc
&RPjUYQLMpRQeKTBDVJQpbN!(DVT0DK`!jM-bB$i$B$k$#T!!(%l2YVicMZ`3ULe
QT5iG*pI%`@m!p`#pr,H@SFRIkPD#%mPH1S`bQI![[$diJ8Pf'*Im-'SVJ%aET0"
3QC($XD$-X5!F#lB4ah*dIYU)BdGNMKf"BdIDL'0@Q@0@1'CY)iiebKaVK'10EF5
aR6,(GX+aR@h%-E[--6XFXlF4ar*NMZA"XE`fiPL,c,%@10E54Kccb4cc`6&I'h%
X)A-X!FF5EF5aN!$-X4!F#l84aiTPMKA$XH)fiPK%jPJ%MNADL'0(CBiGK@0(fiK
M)c,(4Z$B5"Yal)E-X4Y`l%BEFHb+c,%VF1a+'h&-NMNQ`6'TM6Lf5qEB,MLfUid
iYPIQf&iiYVH01$BTFf`5MNff%FH'C)i0`E'K0Z*B[XbaI$L@hdBF'j-j0JE(a[j
21"EHakZTVSBcEqd6eIc(,2l$+)b2l80KS-Zj@KJa),GKrNrISU+R!b$p[Vc!K9G
!m1U-rFHa2$q5BF@,+3SR9!MLJRJPURdGTEFV4KSF82T4d$Llq&dULRj@&+MRF92
9Ff%RKVpQSaAHfNeU0I)#'TN6krSDr[a46LGb#2SJD0ZcB1IT[SD(r[91#%)Yl5&
rUU$pRMPI#H1l$M8ZM!qLm'(,BK8&M$02U,@MJJZi8J9'%bD"CUi)JaG2ZPJJF)&
e6#"A"bEl'Rjl-V!$0eAU"'ikNTX$0jNF[,mJ0`IZMd4hi!#+48pYf20'(9J'3HP
1#!le0IbpD-q#345eh[r(9-'8S$E5MkVLF)E#0Ue36k9A@1ae@eLPEI6#`&b3!)j
&46SfE+54U%JM`d@kjR3dT'Y1$a[TUDK)6`dEkB@S5#m-'qQbU%LA$4YTe'"D-qa
J@Y-B&@RMX*(ZLSTdel#4*R5N19mqZMR!baX"APUL[hb`2X$,F25ALfF(H$N5rH8
rp`Ci'@$K(`F$[!a&IrR!KJ![CaXb%-C(B%U&XK$&5RjF,,Ki-96@p@#QAj!!@U'
QIV-95J1ape289pj`"$03VfY5M!B&PMFFi6I$B1N2q$Z0A)QPL"G%('C+,&Sa4!e
AM5X#X&%(04lr`5P5ZZHU0bkSlIMTp6p93U('Im[R+&5h()*UMD"KG+j%1!L"1&0
qYU1S&ImBDM+M`Mm6T-K!"M4NLK*kSF5a)"8m6#Vl"C5k3ZFq[@5qM!)(9f65%+4
Dd+B@)4J0`pHC`KkCR9(JPMU4U[+ML'XPliBa!,4Q'bp'JBSE9&F"AMh''T@iPDR
8A5[CHa4LTb&f1SL$UMDS#8ebSba0f13Q,#MJ`jKBB8k#PXN-#06V#R93TA+iKIr
#35$")#XiRqS3U8,#**%&QqNYrBRKa4`XI%F)'Q"pQM)DK8Rc12QPiGEb!I8qZH#
lHk'ZH4JKiB#6VD9PV0$TRk`JDZ('ANjT,f(BK9j6a[RXH9`KpFGA@$B#p5JT@$&
4(aTl,"cP)L%F,T,i[Zc9B4T%bBK`T5af!!25%#Hpfi#3!"'jT3c$`hBE$KNR)V[
jNMP%K!RIJK"2L1N&1-TDE*PmUcE3FIGkqpB+"`9i`YK(!mTmh"K164K%bfPc6CZ
cZaQ,bKkN`4IeHN)*'Th&5#MIap)U,"h3%NB96aM2HJE#P'!@BqU#pQUapZS#5c5
BfQK+0KJ#lYQBNR#U$!N(`dZ1+be)1YrMQ6p)JeCBGX+KG@654Y[Q3ED9LXqNi,C
95f"Xbrm0BYS@!m%k@UB[i9R6'@a"BURij(EcC6lN2,HNYiSP2DKdqT9lH2BdB9%
*&'bEc%h1%fl(`@fHC63N6dp@-16M4p+hU#fhV2A8)j&lFeI-l+(KeNLd(,JIP#F
d!ZcP8d&"hCCqiEZ#!b'"8j+L(c`!QL1q6N`'@cN6SD3rL+52T-P#'SSk&LU5[1A
cm,C`4ME3U%TQ8X!&9P'Y6YSp-DZcdRaC)I9&JBj9FL`6m8'TZ0PY55l!B-kERa*
UdMi0df0q04Zc4T*c`&$I[8(*X$qlq@cXj2UcKhC!+F4L+Yk&%TRj3e*6lYFCk@N
H&MYiZ"`h64mh6508qJhXpEL'6!q6diB`8C121h'ij10[JUNRSH"Q35GSNVTmdET
"'UY'*L'CG"K8CcU0A(8'DZf49[XdP$2p2GR0,m91V(rTd$BFjaiQeQpdRY51Xk&
(Gh`$Gh`E2dk9DEV+0)hMp"L18k8Kdiqc3GCBl%"MJ+0!0GU,!Bj3*S6*08Yi"ad
TfS&),E2pk)K3#Y19,pp`T#YImLQi)fZi6-UAEcKb9Eid+(-[*S8jBXU4@9`KeBE
%@30M6c%lQH*B6%0fZ,N[dp!GNb+G,qL$85XE$mk)%Z0GDjj)ab[6%PU9V)RM`kT
SX!-DH+0Dq[Kc`SBI8"p8lh2lBk8j&$4(d'$Cd!LUbA*cGbSCA9AfB6ZFm%CA[c3
S"ZV+h'TXb5rFV`8*0C4*NdAQlL"$lFS0GD6md&r)6Fd9IkcFF"3ikk,K'8&8$H"
)$KLX+`ePPJbDQi)`G44h"HQBqN[r@qSR!dM#ll1A+3XYiHE3lrM5Udb!CBk$c-9
ad`hN2$+R+G&pF!b00-ZB'Pq-C8Db*(51XJ,Ui[-5B8VmB"MR2rl)I$NY-aDcc*!
!+q!1Mj!!HEL%Y-%UC(K))j6-55KdRK(kq")4)XFi1ip+L'H*-BHbV8TJijd$lR-
Xh$#mKAm-$A2Ki2!@r[2)-"If$QrKiQ%5A$c-M(J`2-b&pF0Eq+KPQ!Y[$(2KjZ%
YA*1iX`YT%%$P#)"rSk&Ke!BQ#*'*6,#'mD++4UTDcHkfQX"#RqV5QX8D8fHTaY4
CLYU&8Z4GU'c8,Y5NeQQMTQj)E8&eCiZXXh#E2P#+9`iABT!!j'&Dr*kU$j,Xcp,
!&(3(2J,Lfhbe$p#`RP0-aBXk+*%*!eMb%h6`kE9"8Ie001mrk9)b%&eX%Ph-4)2
18!9hhXA4c@'LD'*Ek'$I8$Q3!'YUBRr5T42K(h`!PkEm&R4Ak`V+3(3YI`SQ8$9
!*lC8fa,Q-UQfZA,*RUrel!PQ0eI%LYGA!!5Y9QfjCY*S8-q18CiG,6b6PTUQPjU
QN8P"3bBYe6UQHLD0TQD5#A5T4$B8S0'da#hSl2#Q-M529Ec[Y[*XT-%Lfj!!N@c
!b(%j!-L"PRRDe,aFJ*CjD8#,D6NRX5d&D,R00!"0'l5+-"M-'3ESNTj@*Z9KS,!
`Q%J0Jf!'SSY0SSZCU$S"4AdM$`5E)4##Q@fTJE!e8#!SUB'`GCL"B!`L$!iJ$#*
mFlHPE5i2ij609FK0qHCZMEkjHQLTXFI6JNZV2TR%pSc+3iY[f&*j@'&+6R!T5cU
jK46)S!2P,(&hUc%&J(fFc-C4pdiVbRQ2"[@jP0ME"2SMX*5BJL+J,@AY5Gl%9rj
$'!3D3rMr'`!GHJ!iD!!T(`UX$DiY-i5!P[fAfKmcC$m(jQZAAkB"'"i(c+CLk!N
E"'%BIS%"&dIRcqHh,I`fbQmhmG[pr2ChIM[&ElrPYiIilFqiECbrKYqUq'd6[fh
QYrAmYJ'ha*Clq-h)ErIaQjIIY[)E9qSPKc'SD4&9CU,bNJraPJmZ4!0Z*`%-cHP
%0kT$K@((04Pd0)aEbP!GB)Ylfpp@Nc20b4,Ha5Na2m5l+ChkB#Xq+*dGHL-EGSj
2+cllfDHQA$bH#KV)"dajEZB$TQ#Za&GEGCaeA#RKT(Ba0pPj!eS92eKfP4ZUhD!
hT4#Z6`h'6ADHa"ie#GISLBf%hfrBa!2PaK&H"H$5Jh+6R8K4`""JB9U`5RF#apM
"KqIFE"LHBqKUNfMqP+&6aS!HEUUEGrL`8Ec"DXPANc#Qi)hT6+i46E8cR%4KX%8
e1QibeaJ'eE6Nkd!!IZ`f++*6mP8Ri9!iK@#dM[6-[HT)UdT-5kM@2A@LFqh8(Y%
kYGI4U4d2aV30YKSkY#J8$0#GT8(8G1$Y--DlAqUYd#GDSET2"d8KIB9j"lQ&aTm
U@`U5FhZEeB1pc93F1RFM,`jYKPMcXipUBPISCVZ'bASD#+[@pYE20,IMCcc1`VK
eBiJM6d0E",4&K,EAJ,BS&@eS&bEAD@MAFE6V9TpQMXlDk&Cdpd0f%--3Y9R,k1F
(pDBA9kL#QRILB9L#M$``mBZL&3-4i8L%'qDaPQ'Ve[S-!a(pcpae4YK#8l%5Zr2
@-[YEXkfemdh,Vi5QZ0Q**mLS"!dE)'5jSiSCD8JMc'Tij+M)P!(-4D3Lf*Q#)'L
hP#&,rfJN)kVZk`i`JFh'T$!(3[ac(6%a)kTk#$X5PDlr+qi`@qUq"e0&A[c`QQh
iF8IXGqTdmQQRe6a2,iL4,I$b"AI`"AI`"Gl8"F6Q(Xm6ed8BY`kK)-'0Pkd5RD@
VK)+TFA'-$JF'L'S2CCr3$(pXbl02Sr#p'`d1&CaJ)B*f"`EqdmIeH"d!c0GQQM%
Bh6pE-lH"4+BJJ'd+2Y#JN!$"N!!`(SbJS+Tm(!miX)R$CSH1J*-B'CSL%p"JILN
1!(8Ba3rA&523c!$F9A*G6S1rdPhk&EQNEL@(8K`Td"da(8jS`lLeB!0aBK++Xa1
E@#h2A-dma`8BFU9Xh3T6aPDBD4LK$(q8ClMCm50k0-3GK)!,im%'b1"MHKLX0m+
kpcarThKG'*r'*,hQQpU$$FYZYm)%aM'M3je1I*-*#ASBK*'BMHCZK5+Fh'b*f3,
!Ac%Vj)6CC5#EF,#PI-UP1H*)8SCJ-f0GJX`)1&Jbd)bVl#-c,IT3c9#M%`B&DXP
)6*!!YSU@S[Uc@PrH+#SG#8fG`CF*B[1BD3B+AiB`'%G&&6*2hkDFb1(5,Vjj,KL
CKK%2-V(!Kdar5"Zb5m@'+++(R$GY3d)BGB3*PAh%XZZhqV2kGTlS0)M39[kSf1K
S4m00CKX-L9ChMTY4YAj1f6TKbQ`E'R'HaG-@#Q8c"edqU'#CCjiaCE3I#9Xbr54
MqpfD%4T[LJ%2CQ,M#p-K9'(8JbidTBH%1ceNcZN-j!2"YTd5`*,0SX2FSC2`Z@J
MhG8T5iINQH`SPU%jT[q!5ejXG@"%4[jKfMC6N!!8j"SNaf4"8Q!Lrj9i$)%5&im
P`2E!i!YSQA0[8!c*`N9(R*M-&A@r$,A$K,S%L,1*DYhiNBk8'mbK%+S$Lh2%[K+
1FBH[a(I*[)cBLRk3!!imE!!NMqSE`-LCUq81B#"dA!6$F3,6d$LHSJ6R,XL9'5"
lr6XETjqDYMZ``BHVM1ikZ3M-drLI`Z05c0@bc)#aRhkE&P)GFYEKGU3NH4bFLEP
JjAH[2%K!G[Vce%D'A0daKcBU6I"&-0&))ad"YRP0#,2[2'RBJL4Y!4NhiDqh@hG
EIrbeX@lXr&Ma"b@*1X1,m8H-MPKaXL3D+`-4Pi(%hKICM`q%cYki%iXidl)i6q,
(1IjMTjbjG@+lH0)"@rYL$f`03rjfp1"MpX+prTi5Q(C"L+KI4MAZXQ9diD+&kTG
Jr"!VCFd"($($Y$3qmr#j&q$CG46qG+!3m6UDQJjZ3'XI!ITTlSAhl0lS3S#0ee'
ie+%RHCS'J'p$D!9jmD+$'qjTj)m(3Q$f)133R%If%*ch!-(41a@D)r,*$dcXM!,
f4S#3!,dKX"NT)CXDa%NHa*ffrcHf12h#[@#,Y1!CK(*3#q@eP0PJLGF45S@BH%K
RNf!C(FdC9-NTV``DJX2JZMRLA1K@ier#-FhSbpLTS$i8eUK1aQ"JS5F$S@0K#UH
*Ha93&-i&UGYTYSf@*(j&Vm$+A6##VEPL9JdXZ"mERXU%%GTH(Tk&#-m4!Rc`kD6
`l*5&TcTabb88FSGpfe1BZGH!5![#e[3JP'8Z!p4XZdmNVH&lC'(Ca"KQ0fI3UTH
ce[b8)#1M68iGT!d+$R+ecc5MY*i$i1d,1+!'`-cYdX'deJfK+4J)+DCXJkN3bNa
Lp0`B(*MdL"`J!9'1I)HGM*j&"F9He!-1QFZDf`SCQh2*@DU*)GN-c"@"jQ9#@$`
N*i"XeJ"f-VE9U&9V"f`i05D!c"PRBDXh2!5NAa((GNjEra%&UQ[IGdecdeI6-(e
PF4i3Gq$K6@rYPjB-NQ%Ba`'HV#cU!6c-k3Re136f*R%pI%!FZbh$AV+M`G3RrI4
q!&1S+S`*k4fff#R@BH-2J0JR+J(`U$rHUB-kC(3,4,'G!,ddSNKFAP-R48NliVM
XL+B&iRll0-#)JNDK"3"Bd90LbeG#4A$jVeRGHAUfE"IZI(hMh4UClF,X3a2E$4@
'mEeHlI2BAL2E2J!8Q'V'&!,UqLeP&1*)eZ20k(j3`TCRDF,#IQUX5%+RqFISG(4
59`!Qap$d`B"81@Fl$RG",NIK!1+KID,EN!"PH&M&%r'X%SI5'%"&'*A$MBI"%+r
iHPdhq-FlAK$$im4ia9'F,H%AcQLT@qEJe8a2N!!Jf,E4rc3pRSB@h&)@XbBXAkY
Qrm`6#,@VT30DTK&b4fGF9!+8MBX[lHSAeRHqDFm'M5h&!eCRXG[i3V(M8V,BI"Q
*Cec0qU4f+Cbp8[RJkRqeUYN(-YDR6eU$KcGA3,4![C6k$mXf0,iq8,LBAP[ia'9
lpL-m)-jY!G*#mfAq!"iidNF'C%Ehqe!C3*faee!-AYNrk83@m#)TE0KljqahrAV
"aCV2&bM1,CIXGrqkr'dBk3C39Nf(rl!LiY0I1RX&U[lF,ACrf3)c@+'RCYH)Xhc
A%FAjbr2[RAH@ShSJq6L[mNKB$Y#(kPc1(hk((fSjc1&[KD'V!M+i6Cd1M3!kLj0
rcQFGYUfNUS$'!@VqS3b8EQa[2iGK!%BN(4FU-fe[65$EU%"rUm+bcI@EAb"j*C9
9A-M)9"c`DF-R"K%S[(+JqbM%ZaYV"XSM%lGHk+c$F3TKN!#``cjG9JL6GJ65FU-
b(bC'5qcCXR*VXB,NSZc(`d6mCHA8NGKPHE[B9j-)4bCH[L4I-,mB#aCB5b,@3b8
M06$j`j8"A50kjj0#MlT'Y4DlC6BpGXQ6f-ZUTDMbJkSJUGTPbHi)UPhXdjq@m3S
@2YdqabK-SPHdPkl2m*!!"M3mda`m&SP+0X%UDPTE8-f9R9P!(@#p3aM2AJ6L1A1
A9)'K6P2!!fQ@NAGL'P8!23b3!)!TBhbJq%mD3`@ihBp%9C@SSq#j1i2J@8H99%Z
U,NkE%&a4Xd5)(Ne&,*jAC@93-3&#[%UQGY0GV$Q*eqPG"S"%9UK",@!GALCSjiq
TbKd*AmURKFU@!S4+@FJ0Fe+PS(E4'cP+G$NDZ*E'a!$!T-dZeHEf`Z$N89b#LAi
b5!R@md0aQ$1L``Q(Xh#Abc5PLX2+BCLPR$DCFaeK6)!+Eq4-BU`hP8RN%#Jc#*!
!LKLaMV'[K!d2%(U%R-IIE1QV`8&T&bj25IqlkU8rr+(&mD,dVY6qaGqNE4ZPKM-
akDHR6Qfjp9AT[jdk*9eCq%TQBAP&qp1E6(pV0XRq(YfdZIe9UHqPprqc5rq6(T*
qqBYAcrqdU8q9RMVcYH4qi(cIG-1CAZNACliimmT2T5@&jB@c(jiVMC8AVZ2rRem
RreZapYV(VdSIRrR"Q4F@R9fhAPUa5RTPi-cF4@HP(Eq@[VY+@[J4rp9b5AVT[26
8Z6qF,HVGr0f9kbZ@2Eqbm2c*`ZF,I6[k1ZKj9khPhfh0NliM6GlEIhdf5@SrrLI
T1HRUQNeR9Qii,IhfV(6ZiEjMG)!r5HihrqY2dMG@5#I2r1"28ZN++@p!DT@H@5'
C2j,Hl,Y(H[M0Xhd(0rEY4f!BTD,"Qk89,ekp+MfaV("CdAFh[Vab`iS0VhDYR,h
PKG8rEjD'5U@*h@FrhI,m#ZNh,lc`YmqqPTlqiQqIR0dipiG5jY5@,G++%i@,ARK
aB89&qF)6,f9+IrG5*[GrVq3qIql%L9HNAhjmllF!rpU,LSSNr1(HrMqP[ccIppU
D-pqqZEaVcGI51HPLArj[jVEI[%aD)5@NIrp%'PJRr9lkD[-kU6&cVVcd4(P*dBR
#mmd[,HU9[V2NKbp+fjFXUTHqmdUTe(*+NTjI8#pY2*0j@$*,FmiXNCjGqI$b(dL
r2M2dKI61hkA[&ldJpCf6rR2C)ZR*HZQrjNMrSqVMPh(kiTI2R6Zji,`8D`B!N!-
B!!!dU!!!AdJ!N!-)!*!$)!!!2c`!"kR`!*!$#PM!!%U!!!"+J!#3!aTZ!*!$!AB
!6R&+JfBL3Hd!)#!m2c`!!#)mUI!!!8T"CJ4+3'F+5%")35#!)8%!"%+R3IVrcY$
m!3![##mm!!!CELm$B3!#V&52Cd"#1!TH3UF[2%4"9%%r2!69U"p`!4(!#Pj+RfF
B6R%`2+P`TdC$qJ!U)SK"qJ!J-$bTF+C(5S0R"(!"6R91l3!L6R&+JfB#UI4`!%j
eB!B!N!8"6R%I1[rf5KpQ%NMRi1""q[rU80"1ZJ@Z60m("bmkrpj1G@"b38a"4%4
$69!!!`#30&"b3@e)jf$`G&#I`Lp)!#!J6b*8-@N!&!!B)8!!*$&m!!%!,0+4)8%
!,U!#hm*-h`m'6R9+1!THC``J+J!)C``J3#!3C`B[1[q%6R9)jam'3IVrRR!-)LS
!"-+i!aTKT'B!!6j)H[q16VS(EPK2X(Vr@QB!!3kK'Li)##S!3!!%C`BJH!+QS"X
X+J!%+LS!#"JU!!5Ae*A8)$Vr9U%H2cJ#)'B!!1a86ba))$Vr4#)'`VJ$'PK"B3$
r6#!krcc!Z!-D3IVr1##!5S9Q"+%LB!3J4D!RCJ!!Y#T))!j3J%(kr`JJJ#!kr`T
4J%(kr`!JJ%*R5(S![#m95(Vr!LmkrZ)[1[lL,cVqbLmkrXS[1[l+B3!06M!ICb!
r!%U&C`JJ6D!US#YJ"#"0S#-J6U!I)%HJ'c(I!L"JB#"1S"mJ4k!EFJ!5"1F*iaR
N%3!"!#!#!3$J)%fJD3)!!"q!!5"0S'V9e0I83IVqGNU3!'F)F!'JQ(!$S*JJ659
)!!K`!%cIB2K1G8cIB2KJ!2kq2`!J6U!I)%HJ'c(I!L$9e0I8-$J#)$(!#Q#4b#9
)!!K-hf$i6R919J!!51F!1#KZ!!a(q[iU4IVq+L!8X**Y"#!5+)"+J'm5)&-LEJ!
)SLiJ&0'6NC*`!'!%-$crf8cI(!"1ANje6PErb%MR(MJQ,J!)+#i!$#KZ!"""q[f
k,8Mre%)ZrmLK'Le)rma96kJF-"mk!!a&!!"[A%KZrq``"90&2`#S$e92,blrl+J
0-"mm!!a'!!"[h%)RUCYC6bmZrq``"P0'2`#S$L!I,8$rm()"(`'TQb"Zrr"+N!"
R%&92,`LTTM!I5-"b"-#"Cm3[,[r`UD0J["!Z!"4R#PP2,VJ#TL"IS"Xr2+$m6VS
%KP42,8$rd%U!C`!"RLm!6VS$ePK25J"R#R!"(8!!&Nlk!KK)E[rN5'lri%KZrpK
1ZJ9U6qm!$#!Zrq#K(Le)rp`J#'F!!@3J,[rNS4iY52rS)!KR!!&8,blrj#m)6VS
&Z&"2)!0Q!!#Q@8m[2%024%9#CkJI)"mY32r`5S"R!!#1)%!L8()Bdm%[#8kk",4
B6h)$X%&QGL!0)%"`+0(!,8Mrp#*Zrr!N8A!BeF!Y5[ri,`T1ZJ5k@%mY32rm)'l
rm+!T8%SQE[r8*dS!+&P2,blrm%kk&F`J(h,Sd)&4J#G!!#a96dKkrM)[,[rd5'l
rr#m-,`3[,[rF,blri#mZrqK1ZJV'9%m[,[r`UD-NE[r8*@lrd!!-*@lrh!!3*@l
ri!!8*@lrk!!B2cbKQ%kk!eC86bC!2cbSRdkk!dT86b)!)!Z`J@B%F!"J!R!")!!
P3!!F*83!)#9-!#4)H[[-2cbJr$mmS2a1ZJ,i9%mI!%kk&9)r2+'B6VS$$&425S"
R"(!"S*JJI!!!!9S`%%M!i)"b"V#"CJa"qJ#Z)R`!!!-m)SJGI!!"rmJJE[r-S"Y
96kJF-"mk!!a&!!"[G%KZrq``"90&2`#S$e92,blrl+J0-"mm!!a'!!"[h%)RUCY
C6bmZrq``"P0'2`#S$L!I,8$rm()"(`'TQe92,blrm+QQ-"p)`()%`)&R##mZrr#
TSQ$#*'lrm%U5Ca"96bm+UDB`(dM!FJ6!J@HU,`UTSf#N%#lrb"e!!"C-haai6Pi
JAdr[!!j1d%j@rra)j`!`3Llrr$mmS2a1ZJ)X9%mN3%U!Ce`[!%kk!B"B6dS!Ce!
J#LC!)%![+!!-2cbJr$mmS2a1ZJ(H9%mI!%kk&$JJ5b"S!"#J(b",)'J!'+!I)(`
!!!&D-"")`1#!FJD`J@B+F!!JI!!!!c`JJ"em!!(rr"!Zrra-h``!6Pj1G8j@rqK
)jami@8qTG5!I+J")E[rSU(3J$5"!)""bKY#",8$rr#"!A%K$l[rX)YJLf&P2,ca
%394"2c`%eDQJ)"mS3#"!*&!b+J!)NQS!"$`"0#S!"T4U!!)q!MBZrr*)`cJZrqj
)a*D%1!&)a*D%DJ*5Jq+$282rpMBZrr")`cJZrqa)a*D%1!*)a*D%DJ*5Jq+$282
rp$BZrrE@36e$rrSb,[rddN)p3Iri@8p#TdKZrr4)HJ"QFJ%I!A)"2`&brbm"3LG
#TkN6)"mQ3#m!U(-'K3#3!hJ[$#",F"$4`#m)U2CC6kPe)"q`K@3#B2496kPd%"p
Q!Q$fF2mr!%*R)"qJ-Lm,U43[$+QM,blrk+Kc60mFq%jH6R8!!J!!6PB!!%MR!$!
NEJ!))!SQ3#"!)LJ!!Jb"38a"4'B@)LJ!"Jb"4%008'B+-#J!#R)$X%&R"(!!B!*
`!8cI$!"1ANje,`TC6cmmU'j`!4m!6VS5H#"I*%KC6cmmUQj`!4m!6VS5CL*I)%U
ab@B'-$`#!'!%-$`%!#4I6R919J!!,`-f,J!)-!0)`!+!!!!)!%U!E`4`!@!#F!!
Q(djH6R919[rm51FF!$BZ!!Jr!dkkrma86ae!rrab!E!"CK!#3`Ir6VVrJ,"$EJ4
`!'!S@8mr2+LIF!%I!%kk%I!J(bS!@8mr!amZrra1ZK(J)"mS!,#&CJ*`!%cI!$K
1ANje6PB!!%MR'$!i,J!)*'i!#L"+)"!Q3#"!-K!-38&%CLJb+!!#$%&$8QBH0J4
brlC"CaSJ+!!%FKMLU!+!!*!$rc)$5-'`J@F%F!"J!R!"(8!!$NcI$"K1AL"IA%p
1d%j@!!"96dKZ!!K`rcm!6VVrNK!ICa)JEJ!))#J!"()BiUJ#3!$rB!*`rdjH6R9
19J!!98p)EJ!)F2mr!%kkrf33(fF3)'i!##!S!!3#J!$rN!0J!R$r6Pj1G8j@!!"
)jaJi*Qi!##KZ!!`J5c#m!`&`!#4-*)!Q2!!!!56ANJD5!!!#5!D5!*!$)#Jm!*!
$J0Q5fC)S2!!!"*!!fC,ANYQ5"T)!N!0m"T)!!)!!F!!NEJ!3*)!'NJ#3!b3'NJ#
3!b!'NJ#3!dJ'NJ#3!cj#3%cI("K1ANje6PErj%MR(cJQEJ!)+Li!$#!,+%!Y32r
SF#6C`#e-rqa`)0R!,8crm(")fF!Y62rdF$lC`#!-N!#,X)9M"R"P6[S!XN*!2J"
#3$e!rq3f"h!NYN"N5(!%YN"N"(!!B!a`!$!$@B"U!PD!j)"i!$J$,86rq0LZrqJ
N4"5!)#lrq0#!d+lrm#"!-+lrj(!"&"*b!")#if$4E[rN8NGJX%*!2J"`!6`!0JG
`(lC!C%4`!EC!C!4`!'!-F!!`!e1!DJ*5J1+!H!!i!be%rrcBV[rX*%38J#!Zrrc
3J0#Zrr3J3$#'F!%8%R)!%J,MB0a!8NGJY%*!60mFq%jH6R919[r`51FI1#4Z!!J
QEJ!-1Li!%#KZ!"*#3$`!-J9`!$!"d)!d"R)!-J+`J@m83N!d"R)!-J,5JG+-)%%
`J&*'B0T#3$`!F!)p32rb0JDf4@3!!,K#3$i!3N!p32r`F!!`!q@!d)SJ3#!3,8$
rp$)'F!!`!G#,)%!B%(B!&J5f4f-!!))`,[rfFJ(!3G&Zrr"`!$!$8i!d"h)!-J+
`J@mq1#lrm(B!0J3Y3rrmeS2@M#"$5P"Q%L!Zrrc3J0#-)%!`V[rb9'lrmM)Zrr"
`!$!"d)$3M#"!-"!p32r`B"B`"G"!d%Bd,[r`FJ!b!Y+"dS`J36#!8NFJ,[rdiSJ
Y32rdB!$rE&*'B!$r4%cI(2K1ANje6PErr%MR($!NEJ!)0Li!$#CZ!!ib!h!!-!(
QJ$J!-!0b"m""1J"`!#e!rr`d"()!-J,5LL""%K"`!"!"0!9b!$)#iU"b!F#"dDl
rr#)ZrrcMLG+,)%%b%(!!-!%Y32rm8N8`"A))X%&Q"N*!1J"54$)Z!"*`!$!"d)#
`V[rmB`*JUK!Zrrm5,J!6dJ'3!!&-h``i6Pj1G8j@rra)jamJ*'i!#$JZ!!`k,J!
1-J4`!$!"jS!m!$)%G!I#3Mi"GJ!f!0D+)%-3%(3!&!!Y3[rmF!!`!63&FJ!b!Y#
"jS"b!V#"C`ab!E#"Cb"+J'FdB$)d"R)!-J*8JG++)%%5%(!!%!&b%11SJDlrr$3
'FJ!b!P+"dSSJ34)3F!!3!H')JDlrr#!Zrr`d"h)!-J,LU#e!rra`rh)J0J9d!$3
$NS,LU-"Zrrj-h`6i6Pj1G8j@rpK)jami*Qi!##KZ!!iJ2!!!!564VJ!5)$`!!!*
)dDi!%L!Z!")Y32rXFL$6VJ!5)Li!%Le"rr!N2!#3!i$9VJ!5*#i!%Le#rr3N5aJ
5GJ!@"#e$rrMQJhS(aN953ce$rp`Q,[riiS0k!mC&9%-p3rrQGJ%k,[rQkf-p3rr
SIN$)"h`!(!3p4[rLH!(VC&0%286ri#SZrrKq!FU(C`Kk!$S%8i9J!RVr28ArhRJ
)286rj%T'CdB[,J!5,`!r!e*+,`T1Z[mk6qm!$ZG!d@lrj#mZ!")[,[r`2`-[,[r
X6VS,#%r[!!i[,[rd2`-[,[rX,blrm%kkr+a2l`!13N!p32rB-#lrf,"Z!!aN!!%
k-#lriQFk*%!r,[rS,blrp$mZrq3[#dkkrBj2l`!-%J!J#R!!%!%p32rDG!!d!05
Zrq`J3K!3FJ!5!00Zrq4J($mZrqBr,[rN,`Y1Z[h`8%mp32rD-#lrjY&Zrq3`,[r
DX'lrhQB@-Llrf&*ZrpK`!$!"d)`J3%)3B!$rHM!ZrpU`E[rJCJ!!P$!Zrq*R1L4
!2blrk#mZrr3r,[rN,`Y1Z[d'6qm!$")!)!T`!"!"28$rfR3!0!$8V[rX)%)3%()
!%J$6E[rNB"`r,[rQ2blrj#m,6VVpD&"228$rfM!ZrqE4E[rN9QlrfM!ZrpT6E[r
D5N"R!2m!1#lrf(B!0J3Y3rrm8i2@M#"$%"!L,[rmdS`J34#!8Qlrf'$1%#lrhG!
ZrpXd,[rB8Qlrf()!-J,5M#""%)"J!2kq-Llrj(!!-!&HJ1D!60mFq%jH6R919[q
-51FI1#CZ!!JU,J!-+'i!%#`Z!"3Y5rr)F#6A`#e,rq"`)0I!,8[rc(")em!Y5rr
N,8crP#Bm!!!"*0HZrj3J2!!!!NM4V[q8F#$4V[q8+$`!N!1!fDlrP0QZrj3YE[q
8rl3S2!!!"*!!fDlrP#eZrj6rZ0HZrj3YE[q8rlcCV[q8,@lrP2r8F(c4V[q8,@l
rP2qN)$`!!)!!dDlrP#!Zrj53!)b`K@-+F'8p3!!S6[S'HR!!,J"#3$e!ri`NE[q
NeI`!!)!!,8VrU#eZrk6rN!!YI!!!J!$rk%KZrqJ[,[qN)'i!*%k3!&"2)#lrk'B
+F'Fp3!!S6[S'0#4Zrj!!8NUel[qSBfJJE[q3!&*)NHlrU#e)rr3JE[q3!*(Zrk3
Y52r`)'lrU*(Zrj!!,8Mrl#!)C`iJE[q3!#*Zrk3J,[rXSLiNE[qNeHlrl#e+rj!
!5'lrm#mZrk3JEJ!N6T!!8%mJ,[r`X+lrp'3+F'Fp3!!S6[S&`#"Zrj!!8UlrN!!
3%"e!rk"b!")!dN&636e"rp!`,[r3d%!p32r5)'i!(#!3d+i!)#e!rl!N3#m-,bl
rZ$mm!53[,[q3!%kkqr*2l`!1-J!J#R!!-!(4V[q3!#m-,blrY$mm!53[,[qi6VS
(ZNr[!!i[,[qm2c`"*#mZrlJ[,[qd6VVjA%r[!!iN3#m-,blrZ$mZrp![,[q3!%k
kqk"2l`!1-J!J#R!!-!(4V[q3!#m-,blrY$mZrp![,[qi6VS(D%r[!!i[,[r82bl
rd#mZrlJ[,[qd6VVj#Nr[!!j`!#i!3N!p32q-,@i!)2qX)'lrV,(Zrl"N!!5S3N!
p32qB$'i#52qBC!!!`M!ZriaQ!!#-*'lrN!"55VAZrkKMD#"Zrj!!8NL4l[qS,8M
rp#"Zrj!!NHlrT#e)rr!JE[qSNHlrN!!Y52rX)!KR$L"Zrj!!)QlrT#!ZrqbL,L4
Zrk69l[rX,8VrN!")E[r`,blrT#"Z!#41N!"36b!Zrr#`V[rdC!T`Cce!!#K1qJ4
#)'lrN!"5V[q3!")3F!!3!5i!F!Jp32q--!Gb!F""d@lrQ$)ZrjK`!$!"d)$3V[q
m)%!`%$e!rjJJ"q+),J"6E[q-B!$r1!4Z!NMrQ!aZ!3$rQ'33)'lrV&+Zrk`3V[q
CB!$r#!4Z!3$rQ$JZrjKf!$B%,82rq0D$eUlrc#"$-"!p32qD)Llrq0+ZrmJJ34)
3F!!3!6e!rja+3'F!!-)-EJ!BriaL!!#B*'lrN!"55VAZrkKMD#"Zrj!!8NL4l[q
S,8Mrp#"Zrj!!NHlrT#e)rr!JE[qSNHlrN!!Y52rX)!KR$L"Zrj!!)QlrT#!Zrqb
L,L4Zrk69l[rX,8VrN!")E[r`,blrT#"Z!#41N!"36b!Zrr#`V[rdC!T`Cce!!#K
1qJ-S)'lrN!"5V[q3!")3F!!3!63Zriab!$)#ikL1J&"ZriaJ!2pLF2pb)$JZrja
f!$B%NS2LU-"(d@lrQL!(jUJZ!*PZria#3$e!rjJ`,[qBX'lrdQ3!!-)`,[q-CJ!
!M#4Zrj!!8NUel[qSBfJJE[q3!&*)NHlrU#e)rr3JE[q3!*(Zrk3Y52r`)'lrU*(
Zrj!!,8Mrl#!)C`iJE[q3!#*Zrk3J,[rXSLiNE[qNeHlrl#e+rj!!5'lrm#mZrk3
JEJ!N6T!!8%mJ,[r`X+lrp'3+F'Fp3!!S6[S#@#"Zrj!!8UlrN!!5%(!!%!%Z!(!
)28$rM$!(FJ(!3G&ZrjJb,[qBF!!`!G#!d+lre#"!-"!p32qB)!ILL#i!8flrM'!
!rcB`,[r5N@lrQ$JZrjKf!$B%,82rr0D$eUlrj#"$-"!p32qH)Llrr0+Zrq!J34)
3F!!3!6e!rja+3'F!!-)-EJ!BriaL!!#B*'lrN!"55VAZrkKMD#"Zrj!!8NL4l[q
S,8Mrp#"Zrj!!NHlrT#e)rr!JE[qSNHlrN!!Y52rX)!KR$L"Zrj!!)QlrT#!Zrqb
L,L4Zrk69l[rX,8VrN!")E[r`,blrT#"Z!#41N!"36b!Zrr#`V[rdC!T`Cce!!#K
1qJ&D)'lrN!"5V[q3!")3F!!3!63Zriab!$)#ikL1J&"ZriaJ!2pLF2pb)$JZrja
f!$B%NS2LU-"(d@lrRL!(jUJZ!*PZri`JE[qX-LlrRR!!-!'4`#e)rj5alJ!JC@!
JE[q88UlrP"!3)'lrV&+Zrk`3J#"Zrj45V[q8%"!JE[qX8UlrV"#!)'lrP&+Zrj3
3%#"Zrka5V[qX%)!`,[qD8flrQNT!C`$lhL"Zrj45V[q8%"!JE[qX8UlrV"#!B0a
@E[qD)'i!'0('-LlrRR!!-!%LE[qXNqi!)*!!LC(!,8MrP$!ZrjTR*L"Z!"M4aV(
Zrj4M'L"Zrj45V[q8%"!JE[qX8UlrV"#!8flrQQ$8,@i!)2q8-#lrQP0ZrjT+3'F
!qfBJE[q88UlrP"!3)'lrV&+Zrk`3J'$F)'lrV,(Zrl"R#("R28!!+'!8)'lrV*(
Z!#!LEJ!F)SK#3$e!!#K-haci6PiJAdr[!#"1d!"`2!!q)!!!H#!q-#!Q*L"i)$`
p-c)!!$T$Efe`FQ9cFfP[EMT%C@0[EA"bCA0cD@pZ-$-`-5jM!!!m!$iJ!!"i)$i
`)#BQ)(JJ2$dc-J!!1N0[EA"bCA0cD@pZ1N4PBfpYF(*PFh0TEfi`-c!a,Q-!!%j
@rqK)jami2Li!##KZ!!`f,J!+F!!`!cJ(FJ!b"*!!JA)"X)&[!!'d286rk$e$rqT
5E[rS-#lrk,"Z!!TN(()!-J$5M#""%"!d"h)!-J,5M#""%K#`!@3#B0C6E[rU-#l
rkV"(Baab!$)!dS`J34!30!Gb!$)#dS`J34)3X!&M!Q$B-#lrk,"ZrqTP!Q"b1#l
rk(B!0J3Y3rr`eS`N3a)5F!!3!6e!rq`k,[rUH!!i"5e%rr6BM#C%%"-8J"DZrqd
J,[r`d)$3VJ!3)%!`%$e!rq`L,[rddS(5VJ!3)%%b%#3Zrr$8JY5Z!"!J3M#")Ll
rp0+"dUi!%#""-)"J!2mb-#lrkV"(CJC54f!!r`3i"hB!0J3Y3rrieS`N3a)5F!!
3!6e!rq`m,[rUHJ!k"Le&rrcDM#C&%"-8J"DZrqdJ,[rid)$3VJ!3)%!`%$e!rq`
L,[rmdS(5VJ!3)%%b%#3ZrrM8JY5Z!"!J3M#")Llrr0+"dUi!%#""-)!J,[rm)Ll
rq*!!J63Z!!Tb!$)#*#lrr&+#NS+`J@`H,bi!%#m-2`Br"%kkrPa2l`!--#lrkP*
!2J"J!2jF,bi!%#m-2bi!#M!ZrqT53$m!6VVq0Nr[!!`pE[rU!!TJ!2ii60mFq%j
H6R919[rN51FI1#4Z!!Jk,J!-*Qi!$LKZ!")Y62r`)$`!!!%NfF!Y62rd3N!m!$B
'YN9N,(J!1!-Y42rif)SJ4"!3)Llrq0+Zrr!J34#!)#lrq0#!d+lrp#"!-)054Q$
1,blrp#mZrr!r"8*R6VVpXNr[!!a#3$`!0JDf4@35F!!`!p#Zrr!J3%S3CJ454Q$
SF!!Y32rN0JDf4@3!!+K+3fFb)#lrj(J!1!-Y42rmf+lrm#"%&""b!")#*Llrr&1
$eUlrm#"$&K"d!"3$NS,MU#e!rq3d"R)!-J,5V[r`)%%5%(!!%!%q!#eZrq6rl(!
!,8$rk$!(8dG+3'FJ)#lrk11))Llrl(3"`S+!J5e!rqJJ,[rXiSJY32rXB0Jd"R)
!-J,5JG+Zrr3J36)3F!!`!H@!d)XJ3##ZrqK54P+Zrq4J!2p860mFq%jH6R8LAb"
IS#8ZJ'S#3TG1d5*I%Km`(dS"C`5R4Q!#SdBZL%l4)Pm5(c!I)&p+!@F%TNGJ!U*
(6Y%!N!-+!$LJ!3!&!*!'!3!!!ATX!!&jE!!!"$d("!d%)@`!N!-F!l)!%d4*9%`
!$3#L38a59!!+!8TfCA*c!!%"cP088L!!!3(Q8(0PG!!!!Ij%6%p(!!)##P088L-
!!!)Z4%a(@!!!!MT35808!!!#4Q0TBfi!!!*558026J!!!Pj*3diM!!3#DNC548B
!"!+Q3Nj%6!!"!Z*"9A-b!!!#qQ&eFh3!!!-'3dp%43!(!a*%394"!!!$FP0*@N8
!!!0q4Q9KG!!!!iS%!Irr)!#3#)Arrb3!!)!("!a`!)Irr`#3!pB!N!@'rrmN!!%
Q"`3-N!!!J2rr!!!"T`#3"EArrb!!!J8!N!@#rrm!!!*h!*!%!qMrrb!!!Y8!N!@
)rrm!!!-"!*!%!J$rr`!!!pN!N!3#!Irr!!!%&`#3"!4,!#J%!"5X"`3-Q!5[rrm
!!"6m!*!%!3F!0#!!&6S!N!3%!Irr)!!%B`#3"B,rrb!!"(-!N!@&rrmN!!5$"`3
-I!#(rrmJ!!56!*!&K[rr*!!%S`F%$)!!J2rr)!!%X`#3"B(rrb!!"--!N!@)rrm
J!!66!*!%!J$rrb!!"18!N!3#!Irr)!!%p3#3"!5[rrm!!"AS!*!&![rr)!!&"3#
3"3(rr`!!'m-!N!3#!*!$)!!&)`#3"!)"!!FJ!!8c!*!&J2rr!!!&2`#3"!2Srrm
J!!Pf!*!%"%X!%!3!%YB("!b%!3F!(#!!%Zm!N!@!rrm!!!Q5!*!&L2rr!!!*dJ#
3"!2Srrm!!!S3!*!%"%[rr`3!%`X("!b-"%[rr`3!&$%("!b)!)$rrb!!&IJ!N!@
"rrm!!"Em!*!&J[rr!!!B!*!'Jrrr!!!C"!#3"B6rr`!!'JJ!N!@!rrm!!"X-!*!
&JIrr!!!E&`#3"B,rr`!!'b)!N!@$rrm!!"XY!*!&K2rr!!!E1!#3"!%!rrm!!"Y
$!*!&J2rr!!!EB`#3"d!!!"ZE!*!&K2rr!!!E[`#3"3%!6a`!(!3("!bF!!)!@4`
!MD%("!`i!!-!Ba`!UQ!("!`m!!3!E4`!lZ`("!a!!!8!Ga`"#iB("!`d!!B!J4`
"26i("!a%!!$rrbJ"AX)!N!8(rrm!!9lX!*!'rrmS!&Q0!*!%rj!%!!&HhJ#3"[r
r!!&jAJ#3"!C`FQpYF(3)a#"cG@CQDAJ,5@jcCA*d)%4TFfX,4AKTFh4TEQFJ8&F
,5@jcCA*d)%4TFfX,4AKTFh4TEQFJ8&F16hGZCA)JFQ9cEh9bBf8*8f9RE@9ZG#!
a#90PCfePER3J-JP6C@GYC@jd)$-*8f9RE@9ZG#!d#90PCfePER3J03P6C@GYC@j
d)$CcQ!:
\ No newline at end of file diff --git a/mac/tclMacResource.c b/mac/tclMacResource.c deleted file mode 100644 index 4362ede..0000000 --- a/mac/tclMacResource.c +++ /dev/null @@ -1,2210 +0,0 @@ -/* - * tclMacResource.c -- - * - * This file contains several commands that manipulate or use - * Macintosh resources. Included are extensions to the "source" - * command, the mac specific "beep" and "resource" commands, and - * administration for open resource file references. - * - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacResource.c,v 1.7 1999/08/15 04:54:03 jingham Exp $ - */ - -#include <Errors.h> -#include <FSpCompat.h> -#include <Processes.h> -#include <Resources.h> -#include <Sound.h> -#include <Strings.h> -#include <Traps.h> -#include <LowMem.h> - -#include "FullPath.h" -#include "tcl.h" -#include "tclInt.h" -#include "tclMac.h" -#include "tclMacInt.h" -#include "tclMacPort.h" - -/* - * This flag tells the RegisterResource function to insert the - * resource into the tail of the resource fork list. Needed only - * Resource_Init. - */ - -#define TCL_RESOURCE_INSERT_TAIL 1 -/* - * 2 is taken by TCL_RESOURCE_DONT_CLOSE - * which is the only public flag to TclMacRegisterResourceFork. - */ - -#define TCL_RESOURCE_CHECK_IF_OPEN 4 - -/* - * Pass this in the mode parameter of SetSoundVolume to determine - * which volume to set. - */ - -enum WhichVolume { - SYS_BEEP_VOLUME, /* This sets the volume for SysBeep calls */ - DEFAULT_SND_VOLUME, /* This one for SndPlay calls */ - RESET_VOLUME /* And this undoes the last call to SetSoundVolume */ -}; - -/* - * Hash table to track open resource files. - */ - -typedef struct OpenResourceFork { - short fileRef; - int flags; -} OpenResourceFork; - - - -static Tcl_HashTable nameTable; /* Id to process number mapping. */ -static Tcl_HashTable resourceTable; /* Process number to id mapping. */ -static Tcl_Obj *resourceForkList; /* Ordered list of resource forks */ -static int appResourceIndex; /* This is the index of the application* - * in the list of resource forks */ -static int newId = 0; /* Id source. */ -static int initialized = 0; /* 0 means static structures haven't - * been initialized yet. */ -static int osTypeInit = 0; /* 0 means Tcl object of osType hasn't - * been initialized yet. */ -/* - * Prototypes for procedures defined later in this file: - */ - -static void DupOSTypeInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, - Tcl_Obj *copyPtr)); -static void ResourceInit _ANSI_ARGS_((void)); -static void BuildResourceForkList _ANSI_ARGS_((void)); -static int SetOSTypeFromAny _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr)); -static void UpdateStringOfOSType _ANSI_ARGS_((Tcl_Obj *objPtr)); -static OpenResourceFork* GetRsrcRefFromObj _ANSI_ARGS_((Tcl_Obj *objPtr, - int okayOnReadOnly, const char *operation, - Tcl_Obj *resultPtr)); - -static void SetSoundVolume(int volume, enum WhichVolume mode); - -/* - * The structures below defines the Tcl object type defined in this file by - * means of procedures that can be invoked by generic object code. - */ - -static Tcl_ObjType osType = { - "ostype", /* name */ - (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */ - DupOSTypeInternalRep, /* dupIntRepProc */ - UpdateStringOfOSType, /* updateStringProc */ - SetOSTypeFromAny /* setFromAnyProc */ -}; - -/* - *---------------------------------------------------------------------- - * - * Tcl_ResourceObjCmd -- - * - * This procedure is invoked to process the "resource" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_ResourceObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument values. */ -{ - Tcl_Obj *resultPtr, *objPtr; - int index, result; - long fileRef, rsrcId; - FSSpec fileSpec; - char *stringPtr; - char errbuf[16]; - OpenResourceFork *resourceRef; - Handle resource = NULL; - OSErr err; - int count, i, limitSearch = false, length; - short id, saveRef, resInfo; - Str255 theName; - OSType rezType; - int gotInt, releaseIt = 0, force; - char *resourceId = NULL; - long size; - char macPermision; - int mode; - - static char *switches[] = {"close", "delete" ,"files", "list", - "open", "read", "types", "write", (char *) NULL - }; - - enum { - RESOURCE_CLOSE, RESOURCE_DELETE, RESOURCE_FILES, RESOURCE_LIST, - RESOURCE_OPEN, RESOURCE_READ, RESOURCE_TYPES, RESOURCE_WRITE - }; - - static char *writeSwitches[] = { - "-id", "-name", "-file", "-force", (char *) NULL - }; - - enum { - RESOURCE_WRITE_ID, RESOURCE_WRITE_NAME, - RESOURCE_WRITE_FILE, RESOURCE_FORCE - }; - - static char *deleteSwitches[] = {"-id", "-name", "-file", (char *) NULL}; - - enum {RESOURCE_DELETE_ID, RESOURCE_DELETE_NAME, RESOURCE_DELETE_FILE}; - - resultPtr = Tcl_GetObjResult(interp); - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); - return TCL_ERROR; - } - - if (Tcl_GetIndexFromObj(interp, objv[1], switches, "option", 0, &index) - != TCL_OK) { - return TCL_ERROR; - } - if (!initialized) { - ResourceInit(); - } - result = TCL_OK; - - switch (index) { - case RESOURCE_CLOSE: - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "resourceRef"); - return TCL_ERROR; - } - stringPtr = Tcl_GetStringFromObj(objv[2], &length); - fileRef = TclMacUnRegisterResourceFork(stringPtr, resultPtr); - - if (fileRef >= 0) { - CloseResFile((short) fileRef); - return TCL_OK; - } else { - return TCL_ERROR; - } - case RESOURCE_DELETE: - if (!((objc >= 3) && (objc <= 9) && ((objc % 2) == 1))) { - Tcl_WrongNumArgs(interp, 2, objv, - "?-id resourceId? ?-name resourceName? ?-file \ -resourceRef? resourceType"); - return TCL_ERROR; - } - - i = 2; - fileRef = -1; - gotInt = false; - resourceId = NULL; - limitSearch = false; - - while (i < (objc - 2)) { - if (Tcl_GetIndexFromObj(interp, objv[i], deleteSwitches, - "option", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - - switch (index) { - case RESOURCE_DELETE_ID: - if (Tcl_GetLongFromObj(interp, objv[i+1], &rsrcId) - != TCL_OK) { - return TCL_ERROR; - } - gotInt = true; - break; - case RESOURCE_DELETE_NAME: - resourceId = Tcl_GetStringFromObj(objv[i+1], &length); - if (length > 255) { - Tcl_AppendStringsToObj(resultPtr,"-name argument ", - "too long, must be < 255 characters", - (char *) NULL); - return TCL_ERROR; - } - strcpy((char *) theName, resourceId); - resourceId = (char *) theName; - c2pstr(resourceId); - break; - case RESOURCE_DELETE_FILE: - resourceRef = GetRsrcRefFromObj(objv[i+1], 0, - "delete from", resultPtr); - if (resourceRef == NULL) { - return TCL_ERROR; - } - limitSearch = true; - break; - } - i += 2; - } - - if ((resourceId == NULL) && !gotInt) { - Tcl_AppendStringsToObj(resultPtr,"you must specify either ", - "\"-id\" or \"-name\" or both ", - "to \"resource delete\"", - (char *) NULL); - return TCL_ERROR; - } - - if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) { - return TCL_ERROR; - } - - if (limitSearch) { - saveRef = CurResFile(); - UseResFile((short) resourceRef->fileRef); - } - - SetResLoad(false); - - if (gotInt == true) { - if (limitSearch) { - resource = Get1Resource(rezType, rsrcId); - } else { - resource = GetResource(rezType, rsrcId); - } - err = ResError(); - - if (err == resNotFound || resource == NULL) { - Tcl_AppendStringsToObj(resultPtr, "resource not found", - (char *) NULL); - result = TCL_ERROR; - goto deleteDone; - } else if (err != noErr) { - char buffer[16]; - - sprintf(buffer, "%12d", err); - Tcl_AppendStringsToObj(resultPtr, "resource error #", - buffer, "occured while trying to find resource", - (char *) NULL); - result = TCL_ERROR; - goto deleteDone; - } - } - - if (resourceId != NULL) { - Handle tmpResource; - if (limitSearch) { - tmpResource = Get1NamedResource(rezType, - (StringPtr) resourceId); - } else { - tmpResource = GetNamedResource(rezType, - (StringPtr) resourceId); - } - err = ResError(); - - if (err == resNotFound || tmpResource == NULL) { - Tcl_AppendStringsToObj(resultPtr, "resource not found", - (char *) NULL); - result = TCL_ERROR; - goto deleteDone; - } else if (err != noErr) { - char buffer[16]; - - sprintf(buffer, "%12d", err); - Tcl_AppendStringsToObj(resultPtr, "resource error #", - buffer, "occured while trying to find resource", - (char *) NULL); - result = TCL_ERROR; - goto deleteDone; - } - - if (gotInt) { - if (resource != tmpResource) { - Tcl_AppendStringsToObj(resultPtr, - "\"-id\" and \"-name\" ", - "values do not point to the same resource", - (char *) NULL); - result = TCL_ERROR; - goto deleteDone; - } - } else { - resource = tmpResource; - } - } - - resInfo = GetResAttrs(resource); - - if ((resInfo & resProtected) == resProtected) { - Tcl_AppendStringsToObj(resultPtr, "resource ", - "cannot be deleted: it is protected.", - (char *) NULL); - result = TCL_ERROR; - goto deleteDone; - } else if ((resInfo & resSysHeap) == resSysHeap) { - Tcl_AppendStringsToObj(resultPtr, "resource", - "cannot be deleted: it is in the system heap.", - (char *) NULL); - result = TCL_ERROR; - goto deleteDone; - } - - /* - * Find the resource file, if it was not specified, - * so we can flush the changes now. Perhaps this is - * a little paranoid, but better safe than sorry. - */ - - RemoveResource(resource); - - if (!limitSearch) { - UpdateResFile(HomeResFile(resource)); - } else { - UpdateResFile(resourceRef->fileRef); - } - - - deleteDone: - - SetResLoad(true); - if (limitSearch) { - UseResFile(saveRef); - } - return result; - - case RESOURCE_FILES: - if ((objc < 2) || (objc > 3)) { - Tcl_SetStringObj(resultPtr, - "wrong # args: should be \"resource files \ -?resourceId?\"", -1); - return TCL_ERROR; - } - - if (objc == 2) { - stringPtr = Tcl_GetStringFromObj(resourceForkList, &length); - Tcl_SetStringObj(resultPtr, stringPtr, length); - } else { - FCBPBRec fileRec; - Handle pathHandle; - short pathLength; - Str255 fileName; - Tcl_DString dstr; - - if (strcmp(Tcl_GetString(objv[2]), "ROM Map") == 0) { - Tcl_SetStringObj(resultPtr,"no file path for ROM Map", -1); - return TCL_ERROR; - } - - resourceRef = GetRsrcRefFromObj(objv[2], 1, "files", resultPtr); - if (resourceRef == NULL) { - return TCL_ERROR; - } - - fileRec.ioCompletion = NULL; - fileRec.ioFCBIndx = 0; - fileRec.ioNamePtr = fileName; - fileRec.ioVRefNum = 0; - fileRec.ioRefNum = resourceRef->fileRef; - err = PBGetFCBInfo(&fileRec, false); - if (err != noErr) { - Tcl_SetStringObj(resultPtr, - "could not get FCB for resource file", -1); - return TCL_ERROR; - } - - err = GetFullPath(fileRec.ioFCBVRefNum, fileRec.ioFCBParID, - fileRec.ioNamePtr, &pathLength, &pathHandle); - if ( err != noErr) { - Tcl_SetStringObj(resultPtr, - "could not get file path from token", -1); - return TCL_ERROR; - } - - HLock(pathHandle); - Tcl_ExternalToUtfDString(NULL, *pathHandle, pathLength, &dstr); - - Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&dstr), Tcl_DStringLength(&dstr)); - HUnlock(pathHandle); - DisposeHandle(pathHandle); - Tcl_DStringFree(&dstr); - } - return TCL_OK; - case RESOURCE_LIST: - if (!((objc == 3) || (objc == 4))) { - Tcl_WrongNumArgs(interp, 2, objv, "resourceType ?resourceRef?"); - return TCL_ERROR; - } - if (Tcl_GetOSTypeFromObj(interp, objv[2], &rezType) != TCL_OK) { - return TCL_ERROR; - } - - if (objc == 4) { - resourceRef = GetRsrcRefFromObj(objv[3], 1, - "list", resultPtr); - if (resourceRef == NULL) { - return TCL_ERROR; - } - - saveRef = CurResFile(); - UseResFile((short) resourceRef->fileRef); - limitSearch = true; - } - - Tcl_ResetResult(interp); - if (limitSearch) { - count = Count1Resources(rezType); - } else { - count = CountResources(rezType); - } - SetResLoad(false); - for (i = 1; i <= count; i++) { - if (limitSearch) { - resource = Get1IndResource(rezType, i); - } else { - resource = GetIndResource(rezType, i); - } - if (resource != NULL) { - GetResInfo(resource, &id, (ResType *) &rezType, theName); - if (theName[0] != 0) { - - objPtr = Tcl_NewStringObj((char *) theName + 1, - theName[0]); - } else { - objPtr = Tcl_NewIntObj(id); - } - ReleaseResource(resource); - result = Tcl_ListObjAppendElement(interp, resultPtr, - objPtr); - if (result != TCL_OK) { - Tcl_DecrRefCount(objPtr); - break; - } - } - } - SetResLoad(true); - - if (limitSearch) { - UseResFile(saveRef); - } - - return TCL_OK; - case RESOURCE_OPEN: { - Tcl_DString ds, buffer; - char *str, *native; - int length; - - if (!((objc == 3) || (objc == 4))) { - Tcl_WrongNumArgs(interp, 2, objv, "fileName ?permissions?"); - return TCL_ERROR; - } - str = Tcl_GetStringFromObj(objv[2], &length); - if (Tcl_TranslateFileName(interp, str, &buffer) == NULL) { - return TCL_ERROR; - } - native = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer), - Tcl_DStringLength(&buffer), &ds); - err = FSpLocationFromPath(Tcl_DStringLength(&ds), native, &fileSpec); - Tcl_DStringFree(&ds); - Tcl_DStringFree(&buffer); - - if (!((err == noErr) || (err == fnfErr))) { - Tcl_AppendStringsToObj(resultPtr, "invalid path", (char *) NULL); - return TCL_ERROR; - } - - /* - * Get permissions for the file. We really only understand - * read-only and shared-read-write. If no permissions are - * given we default to read only. - */ - - if (objc == 4) { - stringPtr = Tcl_GetStringFromObj(objv[3], &length); - mode = TclGetOpenMode(interp, stringPtr, &index); - if (mode == -1) { - /* TODO: TclGetOpenMode doesn't work with Obj commands. */ - return TCL_ERROR; - } - switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) { - case O_RDONLY: - macPermision = fsRdPerm; - break; - case O_WRONLY: - case O_RDWR: - macPermision = fsRdWrShPerm; - break; - default: - panic("Tcl_ResourceObjCmd: invalid mode value"); - break; - } - } else { - macPermision = fsRdPerm; - } - - /* - * Don't load in any of the resources in the file, this could - * cause problems if you open a file that has CODE resources... - */ - - SetResLoad(false); - fileRef = (long) FSpOpenResFileCompat(&fileSpec, macPermision); - SetResLoad(true); - - if (fileRef == -1) { - err = ResError(); - if (((err == fnfErr) || (err == eofErr)) && - (macPermision == fsRdWrShPerm)) { - /* - * No resource fork existed for this file. Since we are - * opening it for writing we will create the resource fork - * now. - */ - - HCreateResFile(fileSpec.vRefNum, fileSpec.parID, - fileSpec.name); - fileRef = (long) FSpOpenResFileCompat(&fileSpec, - macPermision); - if (fileRef == -1) { - goto openError; - } - } else if (err == fnfErr) { - Tcl_AppendStringsToObj(resultPtr, - "file does not exist", (char *) NULL); - return TCL_ERROR; - } else if (err == eofErr) { - Tcl_AppendStringsToObj(resultPtr, - "file does not contain resource fork", (char *) NULL); - return TCL_ERROR; - } else { - openError: - Tcl_AppendStringsToObj(resultPtr, - "error opening resource file", (char *) NULL); - return TCL_ERROR; - } - } - - /* - * The FspOpenResFile function does not set the ResFileAttrs. - * Even if you open the file read only, the mapReadOnly - * attribute is not set. This means we can't detect writes to a - * read only resource fork until the write fails, which is bogus. - * So set it here... - */ - - if (macPermision == fsRdPerm) { - SetResFileAttrs(fileRef, mapReadOnly); - } - - Tcl_SetStringObj(resultPtr, "", 0); - if (TclMacRegisterResourceFork(fileRef, resultPtr, - TCL_RESOURCE_CHECK_IF_OPEN) != TCL_OK) { - CloseResFile(fileRef); - return TCL_ERROR; - } - return TCL_OK; - } - case RESOURCE_READ: - if (!((objc == 4) || (objc == 5))) { - Tcl_WrongNumArgs(interp, 2, objv, - "resourceType resourceId ?resourceRef?"); - return TCL_ERROR; - } - - if (Tcl_GetOSTypeFromObj(interp, objv[2], &rezType) != TCL_OK) { - return TCL_ERROR; - } - - if (Tcl_GetLongFromObj((Tcl_Interp *) NULL, objv[3], &rsrcId) - != TCL_OK) { - resourceId = Tcl_GetStringFromObj(objv[3], &length); - } - - if (objc == 5) { - stringPtr = Tcl_GetStringFromObj(objv[4], &length); - } else { - stringPtr = NULL; - } - - resource = Tcl_MacFindResource(interp, rezType, resourceId, - rsrcId, stringPtr, &releaseIt); - - if (resource != NULL) { - size = GetResourceSizeOnDisk(resource); - Tcl_SetByteArrayObj(resultPtr, (unsigned char *) *resource, size); - - /* - * Don't release the resource unless WE loaded it... - */ - - if (releaseIt) { - ReleaseResource(resource); - } - return TCL_OK; - } else { - Tcl_AppendStringsToObj(resultPtr, "could not load resource", - (char *) NULL); - return TCL_ERROR; - } - case RESOURCE_TYPES: - if (!((objc == 2) || (objc == 3))) { - Tcl_WrongNumArgs(interp, 2, objv, "?resourceRef?"); - return TCL_ERROR; - } - - if (objc == 3) { - resourceRef = GetRsrcRefFromObj(objv[2], 1, - "get types of", resultPtr); - if (resourceRef == NULL) { - return TCL_ERROR; - } - - saveRef = CurResFile(); - UseResFile((short) resourceRef->fileRef); - limitSearch = true; - } - - if (limitSearch) { - count = Count1Types(); - } else { - count = CountTypes(); - } - for (i = 1; i <= count; i++) { - if (limitSearch) { - Get1IndType((ResType *) &rezType, i); - } else { - GetIndType((ResType *) &rezType, i); - } - objPtr = Tcl_NewOSTypeObj(rezType); - result = Tcl_ListObjAppendElement(interp, resultPtr, objPtr); - if (result != TCL_OK) { - Tcl_DecrRefCount(objPtr); - break; - } - } - - if (limitSearch) { - UseResFile(saveRef); - } - - return result; - case RESOURCE_WRITE: - if ((objc < 4) || (objc > 11)) { - Tcl_WrongNumArgs(interp, 2, objv, - "?-id resourceId? ?-name resourceName? ?-file resourceRef?\ - ?-force? resourceType data"); - return TCL_ERROR; - } - - i = 2; - gotInt = false; - resourceId = NULL; - limitSearch = false; - force = 0; - - while (i < (objc - 2)) { - if (Tcl_GetIndexFromObj(interp, objv[i], writeSwitches, - "switch", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - - switch (index) { - case RESOURCE_WRITE_ID: - if (Tcl_GetLongFromObj(interp, objv[i+1], &rsrcId) - != TCL_OK) { - return TCL_ERROR; - } - gotInt = true; - i += 2; - break; - case RESOURCE_WRITE_NAME: - resourceId = Tcl_GetStringFromObj(objv[i+1], &length); - strcpy((char *) theName, resourceId); - resourceId = (char *) theName; - c2pstr(resourceId); - i += 2; - break; - case RESOURCE_WRITE_FILE: - resourceRef = GetRsrcRefFromObj(objv[i+1], 0, - "write to", resultPtr); - if (resourceRef == NULL) { - return TCL_ERROR; - } - limitSearch = true; - i += 2; - break; - case RESOURCE_FORCE: - force = 1; - i += 1; - break; - } - } - if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) { - return TCL_ERROR; - } - stringPtr = (char *) Tcl_GetByteArrayFromObj(objv[i+1], &length); - - if (gotInt == false) { - rsrcId = UniqueID(rezType); - } - if (resourceId == NULL) { - resourceId = (char *) "\p"; - } - if (limitSearch) { - saveRef = CurResFile(); - UseResFile((short) resourceRef->fileRef); - } - - /* - * If we are adding the resource by number, then we must make sure - * there is not already a resource of that number. We are not going - * load it here, since we want to detect whether we loaded it or - * not. Remember that releasing some resources in particular menu - * related ones, can be fatal. - */ - - if (gotInt == true) { - SetResLoad(false); - resource = Get1Resource(rezType,rsrcId); - SetResLoad(true); - } - - if (resource == NULL) { - /* - * We get into this branch either if there was not already a - * resource of this type & id, or the id was not specified. - */ - - resource = NewHandle(length); - if (resource == NULL) { - resource = NewHandleSys(length); - if (resource == NULL) { - panic("could not allocate memory to write resource"); - } - } - HLock(resource); - memcpy(*resource, stringPtr, length); - HUnlock(resource); - AddResource(resource, rezType, (short) rsrcId, - (StringPtr) resourceId); - releaseIt = 1; - } else { - /* - * We got here because there was a resource of this type - * & ID in the file. - */ - - if (*resource == NULL) { - releaseIt = 1; - } else { - releaseIt = 0; - } - - if (!force) { - /* - *We only overwrite extant resources - * when the -force flag has been set. - */ - - sprintf(errbuf,"%d", rsrcId); - - Tcl_AppendStringsToObj(resultPtr, "the resource ", - errbuf, " already exists, use \"-force\"", - " to overwrite it.", (char *) NULL); - - result = TCL_ERROR; - goto writeDone; - } else if (GetResAttrs(resource) & resProtected) { - /* - * - * Next, check to see if it is protected... - */ - - sprintf(errbuf,"%d", rsrcId); - Tcl_AppendStringsToObj(resultPtr, - "could not write resource id ", - errbuf, " of type ", - Tcl_GetStringFromObj(objv[i],&length), - ", it was protected.",(char *) NULL); - result = TCL_ERROR; - goto writeDone; - } else { - /* - * Be careful, the resource might already be in memory - * if something else loaded it. - */ - - if (*resource == 0) { - LoadResource(resource); - err = ResError(); - if (err != noErr) { - sprintf(errbuf,"%d", rsrcId); - Tcl_AppendStringsToObj(resultPtr, - "error loading resource ", - errbuf, " of type ", - Tcl_GetStringFromObj(objv[i],&length), - " to overwrite it", (char *) NULL); - goto writeDone; - } - } - - SetHandleSize(resource, length); - if ( MemError() != noErr ) { - panic("could not allocate memory to write resource"); - } - - HLock(resource); - memcpy(*resource, stringPtr, length); - HUnlock(resource); - - ChangedResource(resource); - - /* - * We also may have changed the name... - */ - - SetResInfo(resource, rsrcId, (StringPtr) resourceId); - } - } - - err = ResError(); - if (err != noErr) { - Tcl_AppendStringsToObj(resultPtr, - "error adding resource to resource map", - (char *) NULL); - result = TCL_ERROR; - goto writeDone; - } - - WriteResource(resource); - err = ResError(); - if (err != noErr) { - Tcl_AppendStringsToObj(resultPtr, - "error writing resource to disk", - (char *) NULL); - result = TCL_ERROR; - } - - writeDone: - - if (releaseIt) { - ReleaseResource(resource); - err = ResError(); - if (err != noErr) { - Tcl_AppendStringsToObj(resultPtr, - "error releasing resource", - (char *) NULL); - result = TCL_ERROR; - } - } - - if (limitSearch) { - UseResFile(saveRef); - } - - return result; - default: - panic("Tcl_GetIndexFromObj returned unrecognized option"); - return TCL_ERROR; /* Should never be reached. */ - } -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_MacSourceObjCmd -- - * - * This procedure is invoked to process the "source" Tcl command. - * See the user documentation for details on what it does. In - * addition, it supports sourceing from the resource fork of - * type 'TEXT'. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_MacSourceObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ -{ - char *errNum = "wrong # args: "; - char *errBad = "bad argument: "; - char *errStr; - char *fileName = NULL, *rsrcName = NULL; - long rsrcID = -1; - char *string; - int length; - - if (objc < 2 || objc > 4) { - errStr = errNum; - goto sourceFmtErr; - } - - if (objc == 2) { - string = Tcl_GetStringFromObj(objv[1], &length); - return Tcl_EvalFile(interp, string); - } - - /* - * The following code supports a few older forms of this command - * for backward compatability. - */ - string = Tcl_GetStringFromObj(objv[1], &length); - if (!strcmp(string, "-rsrc") || !strcmp(string, "-rsrcname")) { - rsrcName = Tcl_GetStringFromObj(objv[2], &length); - } else if (!strcmp(string, "-rsrcid")) { - if (Tcl_GetLongFromObj(interp, objv[2], &rsrcID) != TCL_OK) { - return TCL_ERROR; - } - } else { - errStr = errBad; - goto sourceFmtErr; - } - - if (objc == 4) { - fileName = Tcl_GetStringFromObj(objv[3], &length); - } - return Tcl_MacEvalResource(interp, rsrcName, rsrcID, fileName); - - sourceFmtErr: - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), errStr, "should be \"", - Tcl_GetString(objv[0]), " fileName\" or \"", - Tcl_GetString(objv[0]), " -rsrc name ?fileName?\" or \"", - Tcl_GetString(objv[0]), " -rsrcid id ?fileName?\"", - (char *) NULL); - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_BeepObjCmd -- - * - * This procedure makes the beep sound. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Makes a beep. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_BeepObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument values. */ -{ - Tcl_Obj *resultPtr, *objPtr; - Handle sound; - Str255 sndName; - int volume = -1, length; - char * sndArg = NULL; - - resultPtr = Tcl_GetObjResult(interp); - if (objc == 1) { - SysBeep(1); - return TCL_OK; - } else if (objc == 2) { - if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-list")) { - int count, i; - short id; - Str255 theName; - ResType rezType; - - count = CountResources('snd '); - for (i = 1; i <= count; i++) { - sound = GetIndResource('snd ', i); - if (sound != NULL) { - GetResInfo(sound, &id, &rezType, theName); - if (theName[0] == 0) { - continue; - } - objPtr = Tcl_NewStringObj((char *) theName + 1, - theName[0]); - Tcl_ListObjAppendElement(interp, resultPtr, objPtr); - } - } - return TCL_OK; - } else { - sndArg = Tcl_GetStringFromObj(objv[1], &length); - } - } else if (objc == 3) { - if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-volume")) { - Tcl_GetIntFromObj(interp, objv[2], &volume); - } else { - goto beepUsage; - } - } else if (objc == 4) { - if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-volume")) { - Tcl_GetIntFromObj(interp, objv[2], &volume); - sndArg = Tcl_GetStringFromObj(objv[3], &length); - } else { - goto beepUsage; - } - } else { - goto beepUsage; - } - - /* - * Play the sound - */ - if (sndArg == NULL) { - /* - * Set Volume for SysBeep - */ - - if (volume >= 0) { - SetSoundVolume(volume, SYS_BEEP_VOLUME); - } - SysBeep(1); - - /* - * Reset Volume - */ - - if (volume >= 0) { - SetSoundVolume(0, RESET_VOLUME); - } - } else { - strcpy((char *) sndName + 1, sndArg); - sndName[0] = length; - sound = GetNamedResource('snd ', sndName); - if (sound != NULL) { - /* - * Set Volume for Default Output device - */ - - if (volume >= 0) { - SetSoundVolume(volume, DEFAULT_SND_VOLUME); - } - - SndPlay(NULL, (SndListHandle) sound, false); - - /* - * Reset Volume - */ - - if (volume >= 0) { - SetSoundVolume(0, RESET_VOLUME); - } - } else { - Tcl_AppendStringsToObj(resultPtr, " \"", sndArg, - "\" is not a valid sound. (Try ", - Tcl_GetString(objv[0]), " -list)", NULL); - return TCL_ERROR; - } - } - - return TCL_OK; - - beepUsage: - Tcl_WrongNumArgs(interp, 1, objv, "[-volume num] [-list | sndName]?"); - return TCL_ERROR; -} - -/* - *----------------------------------------------------------------------------- - * - * SetSoundVolume -- - * - * Set the volume for either the SysBeep or the SndPlay call depending - * on the value of mode (SYS_BEEP_VOLUME or DEFAULT_SND_VOLUME - * respectively. - * - * It also stores the last channel set, and the old value of its - * VOLUME. If you call SetSoundVolume with a mode of RESET_VOLUME, - * it will undo the last setting. The volume parameter is - * ignored in this case. - * - * Side Effects: - * Sets the System Volume - * - * Results: - * None - * - *----------------------------------------------------------------------------- - */ - -void -SetSoundVolume( - int volume, /* This is the new volume */ - enum WhichVolume mode) /* This flag says which volume to - * set: SysBeep, SndPlay, or instructs us - * to reset the volume */ -{ - static int hasSM3 = -1; - static enum WhichVolume oldMode; - static long oldVolume = -1; - - /* - * The volume setting calls only work if we have SoundManager - * 3.0 or higher. So we check that here. - */ - - if (hasSM3 == -1) { - if (GetToolboxTrapAddress(_SoundDispatch) - != GetToolboxTrapAddress(_Unimplemented)) { - NumVersion SMVers = SndSoundManagerVersion(); - if (SMVers.majorRev > 2) { - hasSM3 = 1; - } else { - hasSM3 = 0; - } - } else { - /* - * If the SoundDispatch trap is not present, then - * we don't have the SoundManager at all. - */ - - hasSM3 = 0; - } - } - - /* - * If we don't have Sound Manager 3.0, we can't set the sound volume. - * We will just ignore the request rather than raising an error. - */ - - if (!hasSM3) { - return; - } - - switch (mode) { - case SYS_BEEP_VOLUME: - GetSysBeepVolume(&oldVolume); - SetSysBeepVolume(volume); - oldMode = SYS_BEEP_VOLUME; - break; - case DEFAULT_SND_VOLUME: - GetDefaultOutputVolume(&oldVolume); - SetDefaultOutputVolume(volume); - oldMode = DEFAULT_SND_VOLUME; - break; - case RESET_VOLUME: - /* - * If oldVolume is -1 someone has made a programming error - * and called reset before setting the volume. This is benign - * however, so we will just exit. - */ - - if (oldVolume != -1) { - if (oldMode == SYS_BEEP_VOLUME) { - SetSysBeepVolume(oldVolume); - } else if (oldMode == DEFAULT_SND_VOLUME) { - SetDefaultOutputVolume(oldVolume); - } - } - oldVolume = -1; - } -} - -/* - *----------------------------------------------------------------------------- - * - * Tcl_MacEvalResource -- - * - * Used to extend the source command. Sources Tcl code from a Text - * resource. Currently only sources the resouce by name file ID may be - * supported at a later date. - * - * Side Effects: - * Depends on the Tcl code in the resource. - * - * Results: - * Returns a Tcl result. - * - *----------------------------------------------------------------------------- - */ - -int -Tcl_MacEvalResource( - Tcl_Interp *interp, /* Interpreter in which to process file. */ - char *resourceName, /* Name of TEXT resource to source, - NULL if number should be used. */ - int resourceNumber, /* Resource id of source. */ - char *fileName) /* Name of file to process. - NULL if application resource. */ -{ - Handle sourceText; - Str255 rezName; - char msg[200]; - int result, iOpenedResFile = false; - short saveRef, fileRef = -1; - char idStr[64]; - FSSpec fileSpec; - Tcl_DString buffer; - char *nativeName; - - saveRef = CurResFile(); - - if (fileName != NULL) { - OSErr err; - - nativeName = Tcl_TranslateFileName(interp, fileName, &buffer); - if (nativeName == NULL) { - return TCL_ERROR; - } - err = FSpLocationFromPath(strlen(nativeName), nativeName, - &fileSpec); - Tcl_DStringFree(&buffer); - if (err != noErr) { - Tcl_AppendResult(interp, "Error finding the file: \"", - fileName, "\".", NULL); - return TCL_ERROR; - } - - fileRef = FSpOpenResFileCompat(&fileSpec, fsRdPerm); - if (fileRef == -1) { - Tcl_AppendResult(interp, "Error reading the file: \"", - fileName, "\".", NULL); - return TCL_ERROR; - } - - UseResFile(fileRef); - iOpenedResFile = true; - } else { - /* - * The default behavior will search through all open resource files. - * This may not be the behavior you desire. If you want the behavior - * of this call to *only* search the application resource fork, you - * must call UseResFile at this point to set it to the application - * file. This means you must have already obtained the application's - * fileRef when the application started up. - */ - } - - /* - * Load the resource by name or ID - */ - if (resourceName != NULL) { - strcpy((char *) rezName + 1, resourceName); - rezName[0] = strlen(resourceName); - sourceText = GetNamedResource('TEXT', rezName); - } else { - sourceText = GetResource('TEXT', (short) resourceNumber); - } - - if (sourceText == NULL) { - result = TCL_ERROR; - } else { - char *sourceStr = NULL; - - HLock(sourceText); - sourceStr = Tcl_MacConvertTextResource(sourceText); - HUnlock(sourceText); - ReleaseResource(sourceText); - - /* - * We now evaluate the Tcl source - */ - result = Tcl_Eval(interp, sourceStr); - ckfree(sourceStr); - if (result == TCL_RETURN) { - result = TCL_OK; - } else if (result == TCL_ERROR) { - sprintf(msg, "\n (rsrc \"%.150s\" line %d)", - resourceName, - interp->errorLine); - Tcl_AddErrorInfo(interp, msg); - } - - goto rezEvalCleanUp; - } - - rezEvalError: - sprintf(idStr, "ID=%d", resourceNumber); - Tcl_AppendResult(interp, "The resource \"", - (resourceName != NULL ? resourceName : idStr), - "\" could not be loaded from ", - (fileName != NULL ? fileName : "application"), - ".", NULL); - - rezEvalCleanUp: - - /* - * TRICKY POINT: The code that you are sourcing here could load a - * shared library. This will go AHEAD of the resource we stored away - * in saveRef on the resource path. - * If you restore the saveRef in this case, you will never be able - * to get to the resources in the shared library, since you are now - * pointing too far down on the resource list. - * So, we only reset the current resource file if WE opened a resource - * explicitly, and then only if the CurResFile is still the - * one we opened... - */ - - if (iOpenedResFile && (CurResFile() == fileRef)) { - UseResFile(saveRef); - } - - if (fileRef != -1) { - CloseResFile(fileRef); - } - - return result; -} - -/* - *----------------------------------------------------------------------------- - * - * Tcl_MacConvertTextResource -- - * - * Converts a TEXT resource into a Tcl suitable string. - * - * Side Effects: - * Mallocs the returned memory, converts '\r' to '\n', and appends a NULL. - * - * Results: - * A new malloced string. - * - *----------------------------------------------------------------------------- - */ - -char * -Tcl_MacConvertTextResource( - Handle resource) /* Handle to TEXT resource. */ -{ - int i, size; - char *resultStr; - - size = GetResourceSizeOnDisk(resource); - - resultStr = ckalloc(size + 1); - - for (i=0; i<size; i++) { - if ((*resource)[i] == '\r') { - resultStr[i] = '\n'; - } else { - resultStr[i] = (*resource)[i]; - } - } - - resultStr[size] = '\0'; - - return resultStr; -} - -/* - *----------------------------------------------------------------------------- - * - * Tcl_MacFindResource -- - * - * Higher level interface for loading resources. - * - * Side Effects: - * Attempts to load a resource. - * - * Results: - * A handle on success. - * - *----------------------------------------------------------------------------- - */ - -Handle -Tcl_MacFindResource( - Tcl_Interp *interp, /* Interpreter in which to process file. */ - long resourceType, /* Type of resource to load. */ - char *resourceName, /* Name of resource to find, - * NULL if number should be used. */ - int resourceNumber, /* Resource id of source. */ - char *resFileRef, /* Registered resource file reference, - * NULL if searching all open resource files. */ - int *releaseIt) /* Should we release this resource when done. */ -{ - Tcl_HashEntry *nameHashPtr; - OpenResourceFork *resourceRef; - int limitSearch = false; - short saveRef; - Handle resource; - - if (resFileRef != NULL) { - nameHashPtr = Tcl_FindHashEntry(&nameTable, resFileRef); - if (nameHashPtr == NULL) { - Tcl_AppendResult(interp, "invalid resource file reference \"", - resFileRef, "\"", (char *) NULL); - return NULL; - } - resourceRef = (OpenResourceFork *) Tcl_GetHashValue(nameHashPtr); - saveRef = CurResFile(); - UseResFile((short) resourceRef->fileRef); - limitSearch = true; - } - - /* - * Some system resources (for example system resources) should not - * be released. So we set autoload to false, and try to get the resource. - * If the Master Pointer of the returned handle is null, then resource was - * not in memory, and it is safe to release it. Otherwise, it is not. - */ - - SetResLoad(false); - - if (resourceName == NULL) { - if (limitSearch) { - resource = Get1Resource(resourceType, resourceNumber); - } else { - resource = GetResource(resourceType, resourceNumber); - } - } else { - c2pstr(resourceName); - if (limitSearch) { - resource = Get1NamedResource(resourceType, - (StringPtr) resourceName); - } else { - resource = GetNamedResource(resourceType, - (StringPtr) resourceName); - } - p2cstr((StringPtr) resourceName); - } - - if (*resource == NULL) { - *releaseIt = 1; - LoadResource(resource); - } else { - *releaseIt = 0; - } - - SetResLoad(true); - - - if (limitSearch) { - UseResFile(saveRef); - } - - return resource; -} - -/* - *---------------------------------------------------------------------- - * - * ResourceInit -- - * - * Initialize the structures used for resource management. - * - * Results: - * None. - * - * Side effects: - * Read the code. - * - *---------------------------------------------------------------------- - */ - -static void -ResourceInit() -{ - - initialized = 1; - Tcl_InitHashTable(&nameTable, TCL_STRING_KEYS); - Tcl_InitHashTable(&resourceTable, TCL_ONE_WORD_KEYS); - resourceForkList = Tcl_NewObj(); - Tcl_IncrRefCount(resourceForkList); - - BuildResourceForkList(); - -} -/***/ - -/*Tcl_RegisterObjType(typePtr) */ - -/* - *---------------------------------------------------------------------- - * - * Tcl_NewOSTypeObj -- - * - * This procedure is used to create a new resource name type object. - * - * Results: - * The newly created object is returned. This object will have a NULL - * string representation. The returned object has ref count 0. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -Tcl_NewOSTypeObj( - OSType newOSType) /* Int used to initialize the new object. */ -{ - register Tcl_Obj *objPtr; - - if (!osTypeInit) { - osTypeInit = 1; - Tcl_RegisterObjType(&osType); - } - - objPtr = Tcl_NewObj(); - objPtr->bytes = NULL; - objPtr->internalRep.longValue = newOSType; - objPtr->typePtr = &osType; - return objPtr; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_SetOSTypeObj -- - * - * Modify an object to be a resource type and to have the - * specified long value. - * - * Results: - * None. - * - * Side effects: - * The object's old string rep, if any, is freed. Also, any old - * internal rep is freed. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_SetOSTypeObj( - Tcl_Obj *objPtr, /* Object whose internal rep to init. */ - OSType newOSType) /* Integer used to set object's value. */ -{ - register Tcl_ObjType *oldTypePtr = objPtr->typePtr; - - if (!osTypeInit) { - osTypeInit = 1; - Tcl_RegisterObjType(&osType); - } - - if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) { - oldTypePtr->freeIntRepProc(objPtr); - } - - objPtr->internalRep.longValue = newOSType; - objPtr->typePtr = &osType; - - Tcl_InvalidateStringRep(objPtr); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_GetOSTypeFromObj -- - * - * Attempt to return an int from the Tcl object "objPtr". If the object - * is not already an int, an attempt will be made to convert it to one. - * - * Results: - * The return value is a standard Tcl object result. If an error occurs - * during conversion, an error message is left in interp->objResult - * unless "interp" is NULL. - * - * Side effects: - * If the object is not already an int, the conversion will free - * any old internal representation. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_GetOSTypeFromObj( - Tcl_Interp *interp, /* Used for error reporting if not NULL. */ - Tcl_Obj *objPtr, /* The object from which to get a int. */ - OSType *osTypePtr) /* Place to store resulting int. */ -{ - register int result; - - if (!osTypeInit) { - osTypeInit = 1; - Tcl_RegisterObjType(&osType); - } - - if (objPtr->typePtr == &osType) { - *osTypePtr = objPtr->internalRep.longValue; - return TCL_OK; - } - - result = SetOSTypeFromAny(interp, objPtr); - if (result == TCL_OK) { - *osTypePtr = objPtr->internalRep.longValue; - } - return result; -} - -/* - *---------------------------------------------------------------------- - * - * DupOSTypeInternalRep -- - * - * Initialize the internal representation of an int Tcl_Obj to a - * copy of the internal representation of an existing int object. - * - * Results: - * None. - * - * Side effects: - * "copyPtr"s internal rep is set to the integer corresponding to - * "srcPtr"s internal rep. - * - *---------------------------------------------------------------------- - */ - -static void -DupOSTypeInternalRep( - Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ - Tcl_Obj *copyPtr) /* Object with internal rep to set. */ -{ - copyPtr->internalRep.longValue = srcPtr->internalRep.longValue; - copyPtr->typePtr = &osType; -} - -/* - *---------------------------------------------------------------------- - * - * SetOSTypeFromAny -- - * - * Attempt to generate an integer internal form for the Tcl object - * "objPtr". - * - * Results: - * The return value is a standard object Tcl result. If an error occurs - * during conversion, an error message is left in interp->objResult - * unless "interp" is NULL. - * - * Side effects: - * If no error occurs, an int is stored as "objPtr"s internal - * representation. - * - *---------------------------------------------------------------------- - */ - -static int -SetOSTypeFromAny( - Tcl_Interp *interp, /* Used for error reporting if not NULL. */ - Tcl_Obj *objPtr) /* The object to convert. */ -{ - Tcl_ObjType *oldTypePtr = objPtr->typePtr; - char *string; - int length; - long newOSType; - - /* - * Get the string representation. Make it up-to-date if necessary. - */ - - string = Tcl_GetStringFromObj(objPtr, &length); - - if (length != 4) { - if (interp != NULL) { - Tcl_ResetResult(interp); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "expected Macintosh OS type but got \"", string, "\"", - (char *) NULL); - } - return TCL_ERROR; - } - newOSType = *((long *) string); - - /* - * The conversion to resource type succeeded. Free the old internalRep - * before setting the new one. - */ - - if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) { - oldTypePtr->freeIntRepProc(objPtr); - } - - objPtr->internalRep.longValue = newOSType; - objPtr->typePtr = &osType; - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * UpdateStringOfOSType -- - * - * Update the string representation for an resource type object. - * Note: This procedure does not free an existing old string rep - * so storage will be lost if this has not already been done. - * - * Results: - * None. - * - * Side effects: - * The object's string is set to a valid string that results from - * the int-to-string conversion. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateStringOfOSType( - register Tcl_Obj *objPtr) /* Int object whose string rep to update. */ -{ - objPtr->bytes = ckalloc(5); - sprintf(objPtr->bytes, "%-4.4s", &(objPtr->internalRep.longValue)); - objPtr->length = 4; -} - -/* - *---------------------------------------------------------------------- - * - * GetRsrcRefFromObj -- - * - * Given a String object containing a resource file token, return - * the OpenResourceFork structure that it represents, or NULL if - * the token cannot be found. If okayOnReadOnly is false, it will - * also check whether the token corresponds to a read-only file, - * and return NULL if it is. - * - * Results: - * A pointer to an OpenResourceFork structure, or NULL. - * - * Side effects: - * An error message may be left in resultPtr. - * - *---------------------------------------------------------------------- - */ - -static OpenResourceFork * -GetRsrcRefFromObj( - register Tcl_Obj *objPtr, /* String obj containing file token */ - int okayOnReadOnly, /* Whether this operation is okay for a * - * read only file. */ - const char *operation, /* String containing the operation we * - * were trying to perform, used for errors */ - Tcl_Obj *resultPtr) /* Tcl_Obj to contain error message */ -{ - char *stringPtr; - Tcl_HashEntry *nameHashPtr; - OpenResourceFork *resourceRef; - int length; - OSErr err; - - stringPtr = Tcl_GetStringFromObj(objPtr, &length); - nameHashPtr = Tcl_FindHashEntry(&nameTable, stringPtr); - if (nameHashPtr == NULL) { - Tcl_AppendStringsToObj(resultPtr, - "invalid resource file reference \"", - stringPtr, "\"", (char *) NULL); - return NULL; - } - - resourceRef = (OpenResourceFork *) Tcl_GetHashValue(nameHashPtr); - - if (!okayOnReadOnly) { - err = GetResFileAttrs((short) resourceRef->fileRef); - if (err & mapReadOnly) { - Tcl_AppendStringsToObj(resultPtr, "cannot ", operation, - " resource file \"", - stringPtr, "\", it was opened read only", - (char *) NULL); - return NULL; - } - } - return resourceRef; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacRegisterResourceFork -- - * - * Register an open resource fork in the table of open resources - * managed by the procedures in this file. If the resource file - * is already registered with the table, then no new token is made. - * - * The behavior is controlled by the value of tokenPtr, and of the - * flags variable. For tokenPtr, the possibilities are: - * - NULL: The new token is auto-generated, but not returned. - * - The string value of tokenPtr is the empty string: Then - * the new token is auto-generated, and returned in tokenPtr - * - tokenPtr has a value: The string value will be used for the token, - * unless it is already in use, in which case a new token will - * be generated, and returned in tokenPtr. - * - * For the flags variable: it can be one of: - * - TCL_RESOURCE__INSERT_TAIL: The element is inserted at the - * end of the list of open resources. Used only in Resource_Init. - * - TCL_RESOURCE_DONT_CLOSE: The resource close command will not close - * this resource. - * - TCL_RESOURCE_CHECK_IF_OPEN: This will check to see if this file's - * resource fork is already opened by this Tcl shell, and return - * an error without registering the resource fork. - * - * Results: - * Standard Tcl Result - * - * Side effects: - * An entry may be added to the resource name table. - * - *---------------------------------------------------------------------- - */ - -int -TclMacRegisterResourceFork( - short fileRef, /* File ref for an open resource fork. */ - Tcl_Obj *tokenPtr, /* A Tcl Object to which to write the * - * new token */ - int flags) /* 1 means insert at the head of the resource - * fork list, 0 means at the tail */ - -{ - Tcl_HashEntry *resourceHashPtr; - Tcl_HashEntry *nameHashPtr; - OpenResourceFork *resourceRef; - int new; - char *resourceId = NULL; - - if (!initialized) { - ResourceInit(); - } - - /* - * If we were asked to, check that this file has not been opened - * already with a different permission. It it has, then return an error. - */ - - new = 1; - - if (flags & TCL_RESOURCE_CHECK_IF_OPEN) { - Tcl_HashSearch search; - short oldFileRef, filePermissionFlag; - FCBPBRec newFileRec, oldFileRec; - OSErr err; - - oldFileRec.ioCompletion = NULL; - oldFileRec.ioFCBIndx = 0; - oldFileRec.ioNamePtr = NULL; - - newFileRec.ioCompletion = NULL; - newFileRec.ioFCBIndx = 0; - newFileRec.ioNamePtr = NULL; - newFileRec.ioVRefNum = 0; - newFileRec.ioRefNum = fileRef; - err = PBGetFCBInfo(&newFileRec, false); - filePermissionFlag = ( newFileRec.ioFCBFlags >> 12 ) & 0x1; - - - resourceHashPtr = Tcl_FirstHashEntry(&resourceTable, &search); - while (resourceHashPtr != NULL) { - oldFileRef = (short) Tcl_GetHashKey(&resourceTable, - resourceHashPtr); - if (oldFileRef == fileRef) { - new = 0; - break; - } - oldFileRec.ioVRefNum = 0; - oldFileRec.ioRefNum = oldFileRef; - err = PBGetFCBInfo(&oldFileRec, false); - - /* - * err might not be noErr either because the file has closed - * out from under us somehow, which is bad but we're not going - * to fix it here, OR because it is the ROM MAP, which has a - * fileRef, but can't be gotten to by PBGetFCBInfo. - */ - if ((err == noErr) - && (newFileRec.ioFCBVRefNum == oldFileRec.ioFCBVRefNum) - && (newFileRec.ioFCBFlNm == oldFileRec.ioFCBFlNm)) { - /* - * In MacOS 8.1 it seems like we get different file refs even - * though we pass the same file & permissions. This is not - * what Inside Mac says should happen, but it does, so if it - * does, then close the new res file and return the original - * one... - */ - - if (filePermissionFlag == ((oldFileRec.ioFCBFlags >> 12) & 0x1)) { - CloseResFile(fileRef); - new = 0; - break; - } else { - if (tokenPtr != NULL) { - Tcl_SetStringObj(tokenPtr, "Resource already open with different permissions.", -1); - } - return TCL_ERROR; - } - } - resourceHashPtr = Tcl_NextHashEntry(&search); - } - } - - - /* - * If the file has already been opened with these same permissions, then it - * will be in our list and we will have set new to 0 above. - * So we will just return the token (if tokenPtr is non-null) - */ - - if (new) { - resourceHashPtr = Tcl_CreateHashEntry(&resourceTable, - (char *) fileRef, &new); - } - - if (!new) { - if (tokenPtr != NULL) { - resourceId = (char *) Tcl_GetHashValue(resourceHashPtr); - Tcl_SetStringObj(tokenPtr, resourceId, -1); - } - return TCL_OK; - } - - /* - * If we were passed in a result pointer which is not an empty - * string, attempt to use that as the key. If the key already - * exists, silently fall back on resource%d... - */ - - if (tokenPtr != NULL) { - char *tokenVal; - int length; - tokenVal = (char *) Tcl_GetStringFromObj(tokenPtr, &length); - if (length > 0) { - nameHashPtr = Tcl_FindHashEntry(&nameTable, tokenVal); - if (nameHashPtr == NULL) { - resourceId = ckalloc(length + 1); - memcpy(resourceId, tokenVal, length); - resourceId[length] = '\0'; - } - } - } - - if (resourceId == NULL) { - resourceId = (char *) ckalloc(15); - sprintf(resourceId, "resource%d", newId); - } - - Tcl_SetHashValue(resourceHashPtr, resourceId); - newId++; - - nameHashPtr = Tcl_CreateHashEntry(&nameTable, resourceId, &new); - if (!new) { - panic("resource id has repeated itself"); - } - - resourceRef = (OpenResourceFork *) ckalloc(sizeof(OpenResourceFork)); - resourceRef->fileRef = fileRef; - resourceRef->flags = flags; - - Tcl_SetHashValue(nameHashPtr, (ClientData) resourceRef); - if (tokenPtr != NULL) { - Tcl_SetStringObj(tokenPtr, resourceId, -1); - } - - if (flags & TCL_RESOURCE_INSERT_TAIL) { - Tcl_ListObjAppendElement(NULL, resourceForkList, tokenPtr); - } else { - Tcl_ListObjReplace(NULL, resourceForkList, 0, 0, 1, &tokenPtr); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TclMacUnRegisterResourceFork -- - * - * Removes the entry for an open resource fork from the table of - * open resources managed by the procedures in this file. - * If resultPtr is not NULL, it will be used for error reporting. - * - * Results: - * The fileRef for this token, or -1 if an error occured. - * - * Side effects: - * An entry is removed from the resource name table. - * - *---------------------------------------------------------------------- - */ - -short -TclMacUnRegisterResourceFork( - char *tokenPtr, - Tcl_Obj *resultPtr) - -{ - Tcl_HashEntry *resourceHashPtr; - Tcl_HashEntry *nameHashPtr; - OpenResourceFork *resourceRef; - char *resourceId = NULL; - short fileRef; - char *bytes; - int i, match, index, listLen, length, elemLen; - Tcl_Obj **elemPtrs; - - - nameHashPtr = Tcl_FindHashEntry(&nameTable, tokenPtr); - if (nameHashPtr == NULL) { - if (resultPtr != NULL) { - Tcl_AppendStringsToObj(resultPtr, - "invalid resource file reference \"", - tokenPtr, "\"", (char *) NULL); - } - return -1; - } - - resourceRef = (OpenResourceFork *) Tcl_GetHashValue(nameHashPtr); - fileRef = resourceRef->fileRef; - - if ( resourceRef->flags & TCL_RESOURCE_DONT_CLOSE ) { - if (resultPtr != NULL) { - Tcl_AppendStringsToObj(resultPtr, - "can't close \"", tokenPtr, "\" resource file", - (char *) NULL); - } - return -1; - } - - Tcl_DeleteHashEntry(nameHashPtr); - ckfree((char *) resourceRef); - - - /* - * Now remove the resource from the resourceForkList object - */ - - Tcl_ListObjGetElements(NULL, resourceForkList, &listLen, &elemPtrs); - - - index = -1; - length = strlen(tokenPtr); - - for (i = 0; i < listLen; i++) { - match = 0; - bytes = Tcl_GetStringFromObj(elemPtrs[i], &elemLen); - if (length == elemLen) { - match = (memcmp(bytes, tokenPtr, - (size_t) length) == 0); - } - if (match) { - index = i; - break; - } - } - if (!match) { - panic("the resource Fork List is out of synch!"); - } - - Tcl_ListObjReplace(NULL, resourceForkList, index, 1, 0, NULL); - - resourceHashPtr = Tcl_FindHashEntry(&resourceTable, (char *) fileRef); - - if (resourceHashPtr == NULL) { - panic("Resource & Name tables are out of synch in resource command."); - } - ckfree(Tcl_GetHashValue(resourceHashPtr)); - Tcl_DeleteHashEntry(resourceHashPtr); - - return fileRef; - -} - - -/* - *---------------------------------------------------------------------- - * - * BuildResourceForkList -- - * - * Traverses the list of open resource forks, and builds the - * list of resources forks. Also creates a resource token for any that - * are opened but not registered with our resource system. - * This is based on code from Apple DTS. - * - * Results: - * None. - * - * Side effects: - * The list of resource forks is updated. - * The resource name table may be augmented. - * - *---------------------------------------------------------------------- - */ - -void -BuildResourceForkList() -{ - Handle currentMapHandle, mSysMapHandle; - Ptr tempPtr; - FCBPBRec fileRec; - char fileName[256]; - char appName[62]; - Tcl_Obj *nameObj; - OSErr err; - ProcessSerialNumber psn; - ProcessInfoRec info; - FSSpec fileSpec; - - /* - * Get the application name, so we can substitute - * the token "application" for the application's resource. - */ - - GetCurrentProcess(&psn); - info.processInfoLength = sizeof(ProcessInfoRec); - info.processName = (StringPtr) &appName; - info.processAppSpec = &fileSpec; - GetProcessInformation(&psn, &info); - p2cstr((StringPtr) appName); - - - fileRec.ioCompletion = NULL; - fileRec.ioVRefNum = 0; - fileRec.ioFCBIndx = 0; - fileRec.ioNamePtr = (StringPtr) &fileName; - - - currentMapHandle = LMGetTopMapHndl(); - mSysMapHandle = LMGetSysMapHndl(); - - while (1) { - /* - * Now do the ones opened after the application. - */ - - nameObj = Tcl_NewObj(); - - tempPtr = *currentMapHandle; - - fileRec.ioRefNum = *((short *) (tempPtr + 20)); - err = PBGetFCBInfo(&fileRec, false); - - if (err != noErr) { - /* - * The ROM resource map does not correspond to an opened file... - */ - Tcl_SetStringObj(nameObj, "ROM Map", -1); - } else { - p2cstr((StringPtr) fileName); - if (strcmp(fileName,(char *) appName) == 0) { - Tcl_SetStringObj(nameObj, "application", -1); - } else { - Tcl_SetStringObj(nameObj, fileName, -1); - } - c2pstr(fileName); - } - - TclMacRegisterResourceFork(fileRec.ioRefNum, nameObj, - TCL_RESOURCE_DONT_CLOSE | TCL_RESOURCE_INSERT_TAIL); - - if (currentMapHandle == mSysMapHandle) { - break; - } - - currentMapHandle = *((Handle *) (tempPtr + 16)); - } -} diff --git a/mac/tclMacResource.r b/mac/tclMacResource.r deleted file mode 100644 index acfae99..0000000 --- a/mac/tclMacResource.r +++ /dev/null @@ -1,90 +0,0 @@ -/* - * tclMacResource.r -- - * - * This file creates resources for use in a simple shell. - * This is designed to be an example of using the Tcl libraries - * statically in a Macintosh Application. For an example of - * of using the dynamic libraries look at tclMacApplication.r. - * - * Copyright (c) 1993-94 Lockheed Missle & Space Company - * Copyright (c) 1994-97 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacResource.r,v 1.4 1999/08/16 00:09:30 jingham Exp $ - */ - -#include <Types.r> -#include <SysTypes.r> - -/* - * The folowing include and defines help construct - * the version string for Tcl. - */ - -#define RESOURCE_INCLUDED -#include "tcl.h" - -#if (TCL_RELEASE_LEVEL == 0) -# define RELEASE_LEVEL alpha -#elif (TCL_RELEASE_LEVEL == 1) -# define RELEASE_LEVEL beta -#elif (TCL_RELEASE_LEVEL == 2) -# define RELEASE_LEVEL final -#endif - -#if (TCL_RELEASE_LEVEL == 2) -# define MINOR_VERSION (TCL_MINOR_VERSION * 16) + TCL_RELEASE_SERIAL -#else -# define MINOR_VERSION TCL_MINOR_VERSION * 16 -#endif - -resource 'vers' (1) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - TCL_PATCH_LEVEL ", by Ray Johnson & Jim Ingham © Scriptics Inc." -}; - -resource 'vers' (2) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - "Simple Tcl Shell " TCL_PATCH_LEVEL " © 1996 - 1999" -}; - - -/* - * The mechanisim below loads Tcl source into the resource fork of the - * application. The example below creates a TEXT resource named - * "Init" from the file "init.tcl". This allows applications to use - * Tcl to define the behavior of the application without having to - * require some predetermined file structure - all needed Tcl "files" - * are located within the application. To source a file for the - * resource fork the source command has been modified to support - * sourcing from resources. In the below case "source -rsrc {Init}" - * will load the TEXT resource named "Init". - */ - -#include "tclMacTclCode.r" - -/* - * The following resource is used when creating the 'env' variable in - * the Macintosh environment. The creation mechanisim looks for the - * 'STR#' resource named "Tcl Environment Variables" rather than a - * specific resource number. (In other words, feel free to change the - * resource id if it conflicts with your application.) Each string in - * the resource must be of the form "KEYWORD=SOME STRING". See Tcl - * documentation for futher information about the env variable. - * - * A good example of something you may want to set is: "TCL_LIBRARY=My - * disk:etc." - */ - -resource 'STR#' (128, "Tcl Environment Variables") { - { "SCHEDULE_NAME=Agent Controller Schedule", - "SCHEDULE_PATH=Lozoya:System Folder:Tcl Lib:Tcl-Scheduler" - }; -}; - diff --git a/mac/tclMacShLib.exp b/mac/tclMacShLib.exp deleted file mode 100644 index 020380f..0000000 --- a/mac/tclMacShLib.exp +++ /dev/null @@ -1,1066 +0,0 @@ -AddrToName -AddrToStr -BuildAFPVolMountInfo -BumpDate -ChangeCreatorType -ChangeFDFlags -CheckObjectLock -CheckVolLock -ClearHasBeenInited -ClearHasCustomIcon -ClearIsInvisible -ClearIsStationery -ClearNameLocked -CloseResolver -ConfigureMemory -CopyDirectoryAccess -CopyFileMgrAttributes -CopyFork -CreateFileIDRef -DTCopyComment -DTGetIcon -DTOpen -DTSetComment -DeleteDirectory -DeleteDirectoryContents -DeleteFileIDRef -DetermineVRefNum -DirectoryCopy -EnumCache -##EnvStr -ExchangeFiles -FSMakeFSSpecCompat -FSReadNoCache -FSWriteNoCache -FSWriteVerify -FSpBumpDate -FSpCatMoveCompat -FSpChangeCreatorType -FSpChangeFDFlags -FSpCheckObjectLock -FSpClearHasBeenInited -FSpClearHasCustomIcon -FSpClearIsInvisible -FSpClearIsStationery -FSpClearNameLocked -FSpCopyDirectoryAccess -FSpCopyFile -FSpCopyFileMgrAttributes -FSpCreateCompat -FSpCreateFileIDRef -FSpCreateMinimum -FSpCreateResFileCompat -FSpDTCopyComment -FSpDTSetComment -FSpDeleteCompat -FSpDirCreateCompat -FSpDirectoryCopy -FSpExchangeFilesCompat -FSpFileCopy -FSpFilteredDirectoryCopy -FSpFindFolder -FSpGetDInfo -FSpGetDefaultDir -FSpGetDirAccess -FSpGetDirectoryID -FSpGetFInfoCompat -FSpGetFLockCompat -FSpGetFileLocation -FSpGetFileSize -FSpGetForeignPrivs -FSpGetFullPath -FSpGetIOACUser -FSpLocationFromFullPath -FSpLocationFromPath -FSpMoveRename -FSpMoveRenameCompat -FSpOpenAware -FSpOpenDFCompat -FSpOpenRFAware -FSpOpenRFCompat -FSpOpenResFileCompat -FSpPathFromLocation -FSpRenameCompat -FSpResolveFileIDRef -FSpRstFLockCompat -FSpSetDInfo -FSpSetDefaultDir -FSpSetDirAccess -FSpSetFInfoCompat -FSpSetFLockCompat -FSpSetForeignPrivs -FSpSetHasCustomIcon -FSpSetIsInvisible -FSpSetIsStationery -FSpSetNameLocked -FSpShare -FSpUnshare -FileCopy -FilteredDirectoryCopy -FindDrive -FlushFile -FreeAllMemory -GetCPanelFolder -GetCatInfoNoName -GetDInfo -GetDirItems -GetDirName -GetDirectoryID -GetDiskBlocks -GetDriverName -GetFileLocation -GetFileSize -GetFilenameFromPathname -GetForeignPrivs -GetFullPath -GetGlobalMouse -GetIOACUser -GetObjectLocation -GetParentID -GetSystemFolder -GetTempBuffer -GetTrapType -GetUGEntries -GetUGEntry -GetVolMountInfo -GetVolMountInfoSize -GetVolumeInfoNoName -HCopyFile -HCreateMinimum -HGetDirAccess -HGetLogInInfo -HGetVInfo -HGetVolParms -HInfo -HMapID -HMapName -HMoveRename -HMoveRenameCompat -HOpenAware -HOpenRFAware -hypotd -HSetDirAccess -InstallConsole -LocationFromFullPath -LockRange -MXInfo -NumToolboxTraps -OnLine -OpenOurRF -OpenResolver -PBXGetVolInfoSync -ReadCharsFromConsole -RemoveConsole -ResolveFileIDRef -RestoreDefault -RetrieveAFPVolMountInfo -SIOUXBigRect -SIOUXCantSaveAlert -SIOUXDoAboutBox -SIOUXDoContentClick -SIOUXDoEditClear -SIOUXDoEditCopy -SIOUXDoEditCut -SIOUXDoEditPaste -SIOUXDoEditSelectAll -SIOUXDoMenuChoice -SIOUXDoPageSetup -SIOUXDoPrintText -SIOUXDoSaveText -SIOUXDragRect -SIOUXDrawGrowBox -SIOUXHandleOneEvent -SIOUXIsAppWindow -SIOUXMyGrowWindow -SIOUXQuitting -SIOUXSetTitle -SIOUXSettings -SIOUXSetupMenus -SIOUXSetupTextWindow -SIOUXState -SIOUXTextWindow -SIOUXUpdateMenuItems -SIOUXUpdateScrollbar -SIOUXUpdateStatusLine -SIOUXUpdateWindow -SIOUXUseWaitNextEvent -SIOUXYesNoCancelAlert -SIOUXisinrange -SIOUXselstart -SearchFolderForDNRP -SetDInfo -SetDefault -SetForeignPrivs -SetHasCustomIcon -SetIsInvisible -SetIsStationery -SetNameLocked -Share -StrToAddr -TclAccess -TclAllocateFreeObjects -TclChdir -TclCleanupByteCode -TclCleanupCommand -TclCompileBreakCmd -TclCompileCatchCmd -TclCompileContinueCmd -TclCompileDollarVar -TclCompileExpr -TclCompileExprCmd -TclCompileForCmd -TclCompileForeachCmd -TclCompileIfCmd -TclCompileIncrCmd -TclCompileQuotes -TclCompileSetCmd -TclCompileString -TclCompileWhileCmd -TclCopyAndCollapse -TclCopyChannel -TclCreateAuxData -TclCreateExecEnv -TclDate_TclDates -TclDate_TclDatev -TclDateact -TclDatechar -TclDatechk -TclDatedebug -TclDatedef -TclDateerrflag -TclDateexca -TclDatelval -TclDatenerrs -TclDatepact -TclDateparse -TclDatepgo -TclDateps -TclDatepv -TclDater1 -TclDater2 -TclDates -TclDatestate -TclDatetmp -TclDatev -TclDateval -TclDeleteCompiledLocalVars -TclDeleteExecEnv -TclDeleteVars -TclDoGlob -TclEmitForwardJump -TclExecuteByteCode -TclExpandCodeArray -TclExpandJumpFixupArray -TclExprFloatError -TclFileAttrsCmd -TclFileCopyCmd -TclFileDeleteCmd -TclFileMakeDirsCmd -TclFileRenameCmd -TclFindElement -TclFindProc -TclFixupForwardJump -TclFormatInt -TclFreeCompileEnv -TclFreeJumpFixupArray -TclFreeObj -TclFreePackageInfo -TclGetCwd -TclGetDate -TclGetDefaultStdChannel -TclGetElementOfIndexedArray -TclGetEnv -TclGetExceptionRangeForPc -TclGetExtension -TclGetFrame -TclGetIndexedScalar -TclGetIntForIndex -TclGetLoadedPackages -TclGetLong -TclGetNamespaceForQualName -TclGetOpenMode -TclGetOriginalCommand -TclGetRegError -TclGetSrcInfoForPc -TclGetUserHome -TclGlobalInvoke -TclGuessPackageName -TclHasSockets -TclHideUnsafeCommands -TclInExit -TclIncrElementOfIndexedArray -TclIncrIndexedScalar -TclIncrVar2 -TclInitByteCodeObj -TclInitCompileEnv -TclInitJumpFixupArray -TclInitNamespaces -TclInterpInit -TclInvoke -TclInvokeObjectCommand -TclInvokeStringCommand -TclIsProc -TclLoadFile -TclLooksLikeInt -TclLookupVar -TclpAccess -TclMacCreateEnv -TclMacExitHandler -TclMacFOpenHack -TclMacInitExitToShell -TclMacInstallExitToShellPatch -TclMacOSErrorToPosixError -TclMacReadlink -TclMacRemoveTimer -TclMacStartTimer -TclpStat -TclMacTimerExpired -TclMatchFiles -TclNeedSpace -TclObjIndexForString -TclObjInterpProc -TclObjInvoke -TclObjInvokeGlobal -TclPlatformExit -TclPlatformInit -TclPreventAliasLoop -TclPrintByteCodeObj -TclPrintInstruction -TclPrintSource -TclRegComp -TclRegError -TclRegExec -TclRenameCommand -TclResetShadowedCmdRefs -TclServiceIdle -TclSetElementOfIndexedArray -TclSetEnv -TclSetIndexedScalar -TclSetupEnv -TclSockGetPort -TclStat -TclTeardownNamespace -TclTestChannelCmd -TclTestChannelEventCmd -TclUnsetEnv -TclUpdateReturnInfo -TclWordEnd -Tcl_AddErrorInfo -Tcl_AddObjErrorInfo -Tcl_AfterCmd -Tcl_Alloc -Tcl_AllowExceptions -Tcl_AppendAllObjTypes -Tcl_AppendElement -Tcl_AppendObjCmd -Tcl_AppendResult -Tcl_AppendStringsToObj -Tcl_AppendToObj -Tcl_ArrayObjCmd -Tcl_AsyncCreate -Tcl_AsyncDelete -Tcl_AsyncInvoke -Tcl_AsyncMark -Tcl_AsyncReady -Tcl_BackgroundError -Tcl_Backslash -Tcl_BeepObjCmd -Tcl_BinaryObjCmd -Tcl_BreakCmd -Tcl_CallWhenDeleted -Tcl_CancelIdleCall -Tcl_CaseObjCmd -Tcl_CatchObjCmd -Tcl_ClockObjCmd -Tcl_Close -Tcl_CommandComplete -Tcl_Concat -Tcl_ConcatObj -Tcl_ConcatObjCmd -Tcl_ContinueCmd -Tcl_ConvertCountedElement -Tcl_ConvertElement -Tcl_ConvertToType -Tcl_CreateAlias -Tcl_CreateAliasObj -Tcl_CreateChannel -Tcl_CreateChannelHandler -Tcl_CreateCloseHandler -Tcl_CreateCommand -Tcl_CreateEventSource -Tcl_CreateExitHandler -Tcl_CreateInterp -Tcl_CreateMathFunc -Tcl_CreateNamespace -Tcl_CreateObjCommand -Tcl_CreateSlave -Tcl_CreateTimerHandler -Tcl_CreateTrace -Tcl_DStringAppend -Tcl_DStringAppendElement -Tcl_DStringEndSublist -Tcl_DStringFree -Tcl_DStringGetResult -Tcl_DStringInit -Tcl_DStringResult -Tcl_DStringSetLength -Tcl_DStringStartSublist -Tcl_DbCkalloc -Tcl_DbCkfree -Tcl_DbCkrealloc -Tcl_DbDecrRefCount -Tcl_DbIsShared -Tcl_DbIncrRefCount -Tcl_DbNewBooleanObj -Tcl_DbNewDoubleObj -Tcl_DbNewListObj -Tcl_DbNewLongObj -Tcl_DbNewObj -Tcl_DbNewStringObj -Tcl_DeleteAssocData -Tcl_DeleteChannelHandler -Tcl_DeleteCloseHandler -Tcl_DeleteCommand -Tcl_DeleteCommandFromToken -Tcl_DeleteEventSource -Tcl_DeleteEvents -Tcl_DeleteExitHandler -Tcl_DeleteHashEntry -Tcl_DeleteHashTable -Tcl_DeleteInterp -Tcl_DeleteNamespace -Tcl_DeleteTimerHandler -Tcl_DeleteTrace -Tcl_DoOneEvent -Tcl_DoWhenIdle -Tcl_DontCallWhenDeleted -Tcl_DumpActiveMemory -Tcl_DuplicateObj -Tcl_EchoCmd -Tcl_Eof -Tcl_ErrnoId -Tcl_ErrnoMsg -Tcl_ErrorObjCmd -Tcl_Eval -Tcl_EvalFile -Tcl_EvalObj -Tcl_EvalObjCmd -Tcl_EventuallyFree -Tcl_ExecCmd -Tcl_Exit -Tcl_ExitObjCmd -Tcl_ExposeCommand -Tcl_ExprBoolean -Tcl_ExprBooleanObj -Tcl_ExprDouble -Tcl_ExprDoubleObj -Tcl_ExprLong -Tcl_ExprLongObj -Tcl_ExprObjCmd -Tcl_ExprString -Tcl_FconfigureCmd -Tcl_FcopyObjCmd -Tcl_FileEventCmd -Tcl_FileObjCmd -Tcl_Finalize -Tcl_FindCommand -Tcl_FindExecutable -Tcl_FindNamespace -Tcl_FindNamespaceVar -Tcl_FirstHashEntry -Tcl_Flush -Tcl_FlushObjCmd -Tcl_ForCmd -Tcl_ForeachObjCmd -Tcl_ForgetImport -Tcl_FormatCmd -Tcl_Free -Tcl_FreeResult -Tcl_GetAlias -Tcl_GetAliasObj -Tcl_GetAssocData -Tcl_GetBoolean -Tcl_GetBooleanFromObj -Tcl_GetChannel -Tcl_GetChannelBufferSize -Tcl_GetChannelHandle -Tcl_GetChannelInstanceData -Tcl_GetChannelMode -Tcl_GetChannelName -Tcl_GetChannelOption -Tcl_GetChannelType -Tcl_GetCommandFromObj -Tcl_GetCommandFullName -Tcl_GetCommandInfo -Tcl_GetCommandName -Tcl_GetCurrentNamespace -Tcl_GetDouble -Tcl_GetDoubleFromObj -Tcl_GetErrno -Tcl_GetGlobalNamespace -Tcl_GetHostName -Tcl_GetIndexFromObj -Tcl_GetInt -Tcl_GetIntFromObj -Tcl_GetInterpPath -Tcl_GetLongFromObj -Tcl_GetMaster -Tcl_GetOSTypeFromObj -Tcl_GetObjResult -Tcl_GetObjType -Tcl_GetPathType -Tcl_GetServiceMode -Tcl_GetSlave -Tcl_GetStdChannel -Tcl_GetStringFromObj -Tcl_GetStringResult -Tcl_GetVar -Tcl_GetVar2 -Tcl_GetVariableFullName -Tcl_Gets -Tcl_GetsObj -Tcl_GetsObjCmd -Tcl_GlobCmd -Tcl_GlobalEval -Tcl_GlobalEvalObj -Tcl_GlobalObjCmd -Tcl_HashStats -Tcl_HideCommand -Tcl_IfCmd -Tcl_Import -Tcl_IncrCmd -Tcl_InfoObjCmd -Tcl_Init -Tcl_InitHashTable -Tcl_InitMemory -Tcl_InputBlocked -Tcl_InputBuffered -Tcl_InterpDeleted -Tcl_InterpObjCmd -Tcl_IsSafe -Tcl_JoinObjCmd -Tcl_JoinPath -Tcl_LappendObjCmd -Tcl_LindexObjCmd -Tcl_LinkVar -Tcl_LinsertObjCmd -Tcl_ListObjAppendElement -Tcl_ListObjAppendList -Tcl_ListObjCmd -Tcl_ListObjGetElements -Tcl_ListObjIndex -Tcl_ListObjLength -Tcl_ListObjReplace -Tcl_LlengthObjCmd -Tcl_LoadCmd -Tcl_LrangeObjCmd -Tcl_LreplaceObjCmd -Tcl_LsCmd -Tcl_LsearchObjCmd -Tcl_LsortObjCmd -Tcl_MacConvertTextResource -Tcl_MacEvalResource -Tcl_MacFindResource -Tcl_MacSetEventProc -Tcl_MacSourceObjCmd -Tcl_Main -Tcl_MakeSafe -Tcl_MakeTcpClientChannel -Tcl_Merge -Tcl_NamespaceObjCmd -Tcl_NewBooleanObj -Tcl_NewDoubleObj -Tcl_NewIntObj -Tcl_NewListObj -Tcl_NewLongObj -Tcl_NewOSTypeObj -Tcl_NewObj -Tcl_NewStringObj -Tcl_NextHashEntry -Tcl_NotifyChannel -Tcl_ObjGetVar2 -Tcl_ObjSetVar2 -Tcl_OpenCmd -Tcl_OpenFileChannel -Tcl_OpenTcpClient -Tcl_OpenTcpServer -Tcl_PackageCmd -Tcl_ParseVar -Tcl_PidObjCmd -Tcl_PkgProvide -Tcl_PkgRequire -Tcl_PopCallFrame -Tcl_PosixError -Tcl_Preserve -Tcl_PrintDouble -Tcl_ProcObjCmd -Tcl_PushCallFrame -Tcl_PutEnv -Tcl_PutsObjCmd -Tcl_PwdCmd -Tcl_QueueEvent -Tcl_Read -Tcl_ReadObjCmd -Tcl_Realloc -Tcl_RecordAndEval -Tcl_RegExpCompile -Tcl_RegExpExec -Tcl_RegExpMatch -Tcl_RegExpRange -Tcl_RegexpCmd -Tcl_RegisterChannel -Tcl_RegisterObjType -Tcl_RegsubCmd -Tcl_Release -Tcl_RenameObjCmd -Tcl_ResetResult -Tcl_ResourceObjCmd -Tcl_ReturnObjCmd -Tcl_ScanCmd -Tcl_ScanCountedElement -Tcl_ScanElement -Tcl_Seek -Tcl_SeekCmd -Tcl_ServiceAll -Tcl_ServiceEvent -Tcl_SetAssocData -Tcl_SetBooleanObj -Tcl_SetChannelBufferSize -Tcl_SetChannelOption -Tcl_SetCmd -Tcl_SetCommandInfo -Tcl_SetDoubleObj -Tcl_SetErrno -Tcl_SetErrorCode -Tcl_SetIntObj -Tcl_SetListObj -Tcl_SetLongObj -Tcl_SetMaxBlockTime -Tcl_SetOSTypeObj -Tcl_SetObjErrorCode -Tcl_SetObjLength -Tcl_SetObjResult -Tcl_SetPanicProc -Tcl_SetRecursionLimit -Tcl_SetResult -Tcl_SetServiceMode -Tcl_SetStdChannel -Tcl_SetStringObj -Tcl_SetTimer -Tcl_SetVar -Tcl_SetVar2 -Tcl_SignalId -Tcl_SignalMsg -Tcl_Sleep -Tcl_SocketCmd -Tcl_SourceObjCmd -Tcl_SourceRCFile -Tcl_SplitList -Tcl_SplitPath -Tcl_StaticPackage -Tcl_StringMatch -Tcl_StringObjCmd -Tcl_SubstCmd -Tcl_SwitchObjCmd -Tcl_Tell -Tcl_TellCmd -Tcl_TimeObjCmd -Tcl_TraceCmd -Tcl_TraceVar -Tcl_TraceVar2 -Tcl_TranslateFileName -Tcl_Ungets -Tcl_UnlinkVar -Tcl_UnregisterChannel -Tcl_UnsetObjCmd -Tcl_UnsetVar -Tcl_UnsetVar2 -Tcl_UntraceVar -Tcl_UntraceVar2 -Tcl_UpVar -Tcl_UpVar2 -Tcl_UpdateCmd -Tcl_UpdateLinkedVar -Tcl_UplevelObjCmd -Tcl_UpvarObjCmd -Tcl_ValidateAllMemory -Tcl_VarEval -Tcl_VarTraceInfo -Tcl_VarTraceInfo2 -Tcl_VariableObjCmd -Tcl_VwaitCmd -Tcl_WaitForEvent -Tcl_WaitPid -Tcl_WhileCmd -Tcl_Write -Tcl_WrongNumArgs -TclpAlloc -TclpCopyDirectory -TclpCopyFile -TclpCreateDirectory -TclpDeleteFile -TclpFree -TclpGetClicks -TclpGetDate -TclpGetSeconds -TclpGetTime -TclpGetTimeZone -TclpListVolumes -TclpRealloc -TclpRemoveDirectory -TclpRenameFile -TrapExists -TruncPString -UnlockRange -UnmountAndEject -Unshare -VolumeMount -WriteCharsToConsole -XGetVInfo -_Ctype -_Stderr -_Stoul -abort -abs -acosf -appMemory -asctime -asinf -atan -atan2 -atan2_d_dd -atan2_d_pdpd -atan2_r_prpr -atan2_r_rr -atan2f -atan_d_d -atan_d_pd -atan_r_pr -atan_r_r -atanf -atexit -atof -atoi -atol -bsearch -builtinFuncTable -calloc -ccommand -ceilf -chdir -clearerr -clock -close -closeUPP -completeUPP -cos -cos_d_d -cos_d_pd -cos_r_pr -cos_r_r -cosf -coshf -creat -ctime -cuserid -difftime -div -environ -errno -exec -exit -exp -exp_d_d -exp_d_pd -exp_r_pr -exp_r_r -expf -fabsf -fclose -fcntl -fdopen -feof -ferror -fflush -fgetc -fgetpos -fgets -fileno -floorf -fmodf -fopen -fprintf -fputc -fputs -fread -free -freopen -frexpf -fscanf -fseek -fsetpos -fstat -ftell -fwrite -getStdChannelsProc -getc -getchar -getcwd -getenv -getlogin -gets -gmtime -instructionTable -isalnum -isalpha -isatty -iscntrl -isdigit -isgraph -islower -isprint -ispunct -isspace -isupper -isxdigit -labs -ldexpf -ldiv -localeconv -localtime -log -log10 -log10_d_d -log10_d_pd -log10f -log_d_d -log_d_pd -logf -longjmp -lseek -malloc -mblen -mbstowcs -mbtowc -memchr -memcmp -memcpy -memmove -memset -mkdir -mktime -open -panic -panicProc -perror -pow -power_d_dd -powf -printf -putc -putchar -puts -qsort -raise -rand -read -realloc -remove -rename -resultUPP -rewind -rmdir -scanf -setbuf -setlocale -setvbuf -signal -sin -sin_d_d -sin_d_pd -sin_r_pr -sin_r_r -sinf -sinhf -sleep -sprintf -sqrt -sqrt_d_d -sqrt_d_pd -sqrt_r_pr -sqrt_r_r -sqrtf -srand -sscanf -stat -strcasecmp -strcat -strchr -strcmp -strcoll -strcpy -strcspn -strerror -strftime -strlen -strncasecmp -strncat -strncmp -strncpy -strpbrk -strrchr -strspn -strstr -strtod -strtok -strtol -strtoul -strxfrm -system -systemMemory -tanf -tanhf -tclBooleanType -tclByteCodeType -tclCmdNameType -tclDoubleType -tclDummyLinkVarPtr -tclExecutableName -tclFreeObjList -tclIndexType -tclIntType -tclListType -tclMemDumpFileName -tclNsNameType -tclPlatform -tclStringType -tclTraceCompile -tclTraceExec -tclTypeTable -tcl_MathInProgress -tclpFileAttrProcs -tclpFileAttrStrings -tell -time -tmpfile -tmpnam -tolower -toupper -ttyname -uname -ungetc -unlink -utime -utimes -vfprintf -vprintf -vsprintf -wcstombs -wctob -wctomb -write -#DTGetAPPL -#DTGetComment -#FSpDTGetAPPL -#FSpDTGetComment -#TclMacInitializeFragment -#TclMacTerminateFragment -#_Aldata -#_Assert -#_Atcount -#_Atfuns -#_Clocale -#_Closreg -#_Costate -#_Daysto -#_Dbl -#_Defloc -#_Environ -#_Environ1 -#_Fgpos -#_Files -#_Flt -#_Fopen -#_Foprep -#_Fread -#_Freeloc -#_Frprep -#_Fspos -#_Fwprep -#_Fwrite -#_Genld -#_Gentime -#_Getdst -#_Getfld -#_Getfloat -#_Getint -#_Getloc -#_Getmem -#_Getstr -#_Gettime -#_Getzone -#_Isdst -#_Ldbl -#_Ldtob -#_Litob -#_Locale -#_Locsum -#_Loctab -#_Locterm -#_Locvar -#_MWERKS_Atcount -#_MWERKS_Atfuns -#_Makeloc -#_Makestab -#_Makewct -#_Mbcurmax -#_Mbstate -#_Mbtowc -#_Nnl -#_PJP_C_Copyright -#_Printf -#_Putfld -#_Putstr -#_Puttxt -#_Randseed -#_Readloc -#_Scanf -#_Setloc -#_Skip -#_Stdin -#_Stdout -#_Stod -#_Stof -#_Stoflt -#_Stold -#_Strerror -#_Strftime -#_Strxfrm -#_Times -#_Tolower -#_Toupper -#_Ttotm -#_WCostate -#_Wcstate -#_Wctob -#_Wctomb -#_Wctrans -#_Wctype -#__CheckForSystem7 -#__RemoveConsoleHandler__ -#__aborting -#__ctopstring -#__cvt_fp2unsigned -#__getcreator -#__gettype -#__initialize -#__myraise -#__ptmf_null -#__ptr_glue -#__system7present -#__terminate -#__ttyname -#_atexit -#_exit -#_fcreator -#_ftype diff --git a/mac/tclMacSock.c b/mac/tclMacSock.c deleted file mode 100644 index ff627ec..0000000 --- a/mac/tclMacSock.c +++ /dev/null @@ -1,2665 +0,0 @@ -/* - * tclMacSock.c - * - * Channel drivers for Macintosh sockets. - * - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacSock.c,v 1.5 1999/08/10 04:21:55 jingham Exp $ - */ - -#include "tclInt.h" -#include "tclPort.h" -#include "tclMacInt.h" -#include <AddressXlation.h> -#include <Aliases.h> -#undef Status -#include <Devices.h> -#include <Errors.h> -#include <Events.h> -#include <Files.h> -#include <Gestalt.h> -#include <MacTCP.h> -#include <Processes.h> -#include <Strings.h> - -/* - * The following variable is used to tell whether this module has been - * initialized. - */ - -static int initialized = 0; - -/* - * If debugging is on we may drop into the debugger to handle certain cases - * that are not supposed to happen. Otherwise, we change ignore the error - * and most code should handle such errors ok. - */ - -#ifndef TCL_DEBUG - #define Debugger() -#endif - -/* - * The preferred buffer size for Macintosh channels. - */ - -#define CHANNEL_BUF_SIZE 8192 - -/* - * Port information structure. Used to match service names - * to a Tcp/Ip port number. - */ - -typedef struct { - char *name; /* Name of service. */ - int port; /* Port number. */ -} PortInfo; - -/* - * This structure describes per-instance state of a tcp based channel. - */ - -typedef struct TcpState { - TCPiopb pb; /* Parameter block used by this stream. - * This must be in the first position. */ - ProcessSerialNumber psn; /* PSN used to wake up process. */ - StreamPtr tcpStream; /* Macintosh tcp stream pointer. */ - int port; /* The port we are connected to. */ - int flags; /* Bit field comprised of the flags - * described below. */ - int checkMask; /* OR'ed combination of TCL_READABLE and - * TCL_WRITABLE as set by an asynchronous - * event handler. */ - int watchMask; /* OR'ed combination of TCL_READABLE and - * TCL_WRITABLE as set by Tcl_WatchFile. */ - Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */ - ClientData acceptProcData; /* The data for the accept proc. */ - wdsEntry dataSegment[2]; /* List of buffers to be written async. */ - rdsEntry rdsarray[5+1]; /* Array used when cleaning out recieve - * buffers on a closing socket. */ - Tcl_Channel channel; /* Channel associated with this socket. */ - int writeBufferSize; /* Size of buffer to hold data for - * asynchronous writes. */ - void *writeBuffer; /* Buffer for async write data. */ - struct TcpState *nextPtr; /* The next socket on the global socket - * list. */ -} TcpState; - -/* - * This structure is used by domain name resolver callback. - */ - -typedef struct DNRState { - struct hostInfo hostInfo; /* Data structure used by DNR functions. */ - int done; /* Flag to determine when we are done. */ - ProcessSerialNumber psn; /* Process to wake up when we are done. */ -} DNRState; - -/* - * The following macros may be used to set the flags field of - * a TcpState structure. - */ - -#define TCP_ASYNC_SOCKET (1<<0) /* The socket is in async mode. */ -#define TCP_ASYNC_CONNECT (1<<1) /* The socket is trying to connect. */ -#define TCP_CONNECTED (1<<2) /* The socket is connected. */ -#define TCP_PENDING (1<<3) /* A SocketEvent is on the queue. */ -#define TCP_LISTENING (1<<4) /* This socket is listening for - * a connection. */ -#define TCP_LISTEN_CONNECT (1<<5) /* Someone has connect to the - * listening port. */ -#define TCP_REMOTE_CLOSED (1<<6) /* The remote side has closed - * the connection. */ -#define TCP_RELEASE (1<<7) /* The socket may now be released. */ -#define TCP_WRITING (1<<8) /* A background write is in progress. */ -#define TCP_SERVER_ZOMBIE (1<<9) /* The server can no longer accept connects. */ - -/* - * The following structure is what is added to the Tcl event queue when - * a socket event occurs. - */ - -typedef struct SocketEvent { - Tcl_Event header; /* Information that is standard for - * all events. */ - TcpState *statePtr; /* Socket descriptor that is ready. */ - StreamPtr tcpStream; /* Low level Macintosh stream. */ -} SocketEvent; - -/* - * Static routines for this file: - */ - -static pascal void CleanUpExitProc _ANSI_ARGS_((void)); -static void ClearZombieSockets _ANSI_ARGS_((void)); -static void CloseCompletionRoutine _ANSI_ARGS_((TCPiopb *pb)); -static TcpState * CreateSocket _ANSI_ARGS_((Tcl_Interp *interp, - int port, char *host, char *myAddr, int myPort, - int server, int async)); -static pascal void DNRCompletionRoutine _ANSI_ARGS_(( - struct hostInfo *hostinfoPtr, - DNRState *dnrStatePtr)); -static void FreeSocketInfo _ANSI_ARGS_((TcpState *statePtr)); -static long GetBufferSize _ANSI_ARGS_((void)); -static OSErr GetHostFromString _ANSI_ARGS_((char *name, - ip_addr *address)); -static OSErr GetLocalAddress _ANSI_ARGS_((unsigned long *addr)); -static void IOCompletionRoutine _ANSI_ARGS_((TCPiopb *pb)); -static void InitMacTCPParamBlock _ANSI_ARGS_((TCPiopb *pBlock, - int csCode)); -static void InitSockets _ANSI_ARGS_((void)); -static TcpState * NewSocketInfo _ANSI_ARGS_((StreamPtr stream)); -static OSErr ResolveAddress _ANSI_ARGS_((ip_addr tcpAddress, - Tcl_DString *dsPtr)); -static void SocketCheckProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static int SocketEventProc _ANSI_ARGS_((Tcl_Event *evPtr, - int flags)); -static void SocketExitHandler _ANSI_ARGS_((ClientData clientData)); -static void SocketFreeProc _ANSI_ARGS_((ClientData clientData)); -static int SocketReady _ANSI_ARGS_((TcpState *statePtr)); -static void SocketSetupProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static void TcpAccept _ANSI_ARGS_((TcpState *statePtr)); -static int TcpBlockMode _ANSI_ARGS_((ClientData instanceData, int mode)); -static int TcpClose _ANSI_ARGS_((ClientData instanceData, - Tcl_Interp *interp)); -static int TcpGetHandle _ANSI_ARGS_((ClientData instanceData, - int direction, ClientData *handlePtr)); -static int TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData, - Tcl_Interp *interp, char *optionName, - Tcl_DString *dsPtr)); -static int TcpInput _ANSI_ARGS_((ClientData instanceData, - char *buf, int toRead, int *errorCodePtr)); -static int TcpOutput _ANSI_ARGS_((ClientData instanceData, - char *buf, int toWrite, int *errorCodePtr)); -static void TcpWatch _ANSI_ARGS_((ClientData instanceData, - int mask)); -static int WaitForSocketEvent _ANSI_ARGS_((TcpState *infoPtr, - int mask, int *errorCodePtr)); - -/* - * This structure describes the channel type structure for TCP socket - * based IO: - */ - -static Tcl_ChannelType tcpChannelType = { - "tcp", /* Type name. */ - TcpBlockMode, /* Set blocking or - * non-blocking mode.*/ - TcpClose, /* Close proc. */ - TcpInput, /* Input proc. */ - TcpOutput, /* Output proc. */ - NULL, /* Seek proc. */ - NULL, /* Set option proc. */ - TcpGetOptionProc, /* Get option proc. */ - TcpWatch, /* Initialize notifier. */ - TcpGetHandle /* Get handles out of channel. */ -}; - -/* - * Universal Procedure Pointers (UPP) for various callback - * routines used by MacTcp code. - */ - -ResultUPP resultUPP = NULL; -TCPIOCompletionUPP completeUPP = NULL; -TCPIOCompletionUPP closeUPP = NULL; - -/* - * Built-in commands, and the procedures associated with them: - */ - -static PortInfo portServices[] = { - {"echo", 7}, - {"discard", 9}, - {"systat", 11}, - {"daytime", 13}, - {"netstat", 15}, - {"chargen", 19}, - {"ftp-data", 20}, - {"ftp", 21}, - {"telnet", 23}, - {"telneto", 24}, - {"smtp", 25}, - {"time", 37}, - {"whois", 43}, - {"domain", 53}, - {"gopher", 70}, - {"finger", 79}, - {"hostnames", 101}, - {"sunrpc", 111}, - {"nntp", 119}, - {"exec", 512}, - {"login", 513}, - {"shell", 514}, - {"printer", 515}, - {"courier", 530}, - {"uucp", 540}, - {NULL, 0}, -}; - -typedef struct ThreadSpecificData { - /* - * Every open socket has an entry on the following list. - */ - - TcpState *socketList; -} ThreadSpecificData; - -static Tcl_ThreadDataKey dataKey; - -/* - * Globals for holding information about OS support for sockets. - */ - -static int socketsTestInited = false; -static int hasSockets = false; -static short driverRefNum = 0; -static int socketNumber = 0; -static int socketBufferSize = CHANNEL_BUF_SIZE; -static ProcessSerialNumber applicationPSN; - -/* - *---------------------------------------------------------------------- - * - * InitSockets -- - * - * Load the MacTCP driver and open the name resolver. We also - * create several UPP's used by our code. Lastly, we install - * a patch to ExitToShell to clean up socket connections if - * we are about to exit. - * - * Results: - * 1 if successful, 0 on failure. - * - * Side effects: - * Creates a new event source, loads the MacTCP driver, - * registers an exit to shell callback. - * - *---------------------------------------------------------------------- - */ - -#define gestaltMacTCPVersion 'mtcp' -static void -InitSockets() -{ - ParamBlockRec pb; - OSErr err; - long response; - ThreadSpecificData *tsdPtr; - - if (! initialized) { - /* - * Do process wide initialization. - */ - - initialized = 1; - - if (Gestalt(gestaltMacTCPVersion, &response) == noErr) { - hasSockets = true; - } else { - hasSockets = false; - } - - if (!hasSockets) { - return; - } - - /* - * Load MacTcp driver and name server resolver. - */ - - - pb.ioParam.ioCompletion = 0L; - pb.ioParam.ioNamePtr = "\p.IPP"; - pb.ioParam.ioPermssn = fsCurPerm; - err = PBOpenSync(&pb); - if (err != noErr) { - hasSockets = 0; - return; - } - driverRefNum = pb.ioParam.ioRefNum; - - socketBufferSize = GetBufferSize(); - err = OpenResolver(NULL); - if (err != noErr) { - hasSockets = 0; - return; - } - - GetCurrentProcess(&applicationPSN); - /* - * Create UPP's for various callback routines. - */ - - resultUPP = NewResultProc(DNRCompletionRoutine); - completeUPP = NewTCPIOCompletionProc(IOCompletionRoutine); - closeUPP = NewTCPIOCompletionProc(CloseCompletionRoutine); - - /* - * Install an ExitToShell patch. We use this patch instead - * of the Tcl exit mechanism because we need to ensure that - * these routines are cleaned up even if we crash or are forced - * to quit. There are some circumstances when the Tcl exit - * handlers may not fire. - */ - - TclMacInstallExitToShellPatch(CleanUpExitProc); - } - - /* - * Do per-thread initialization. - */ - - tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey); - if (tsdPtr == NULL) { - tsdPtr->socketList = NULL; - Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL); - Tcl_CreateThreadExitHandler(SocketExitHandler, (ClientData) NULL); - } -} - -/* - *---------------------------------------------------------------------- - * - * SocketExitHandler -- - * - * Callback invoked during exit clean up to deinitialize the - * socket module. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -SocketExitHandler( - ClientData clientData) /* Not used. */ -{ - if (hasSockets) { - Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL); - /* CleanUpExitProc(); - TclMacDeleteExitToShellPatch(CleanUpExitProc); */ - } -} - -/* - *---------------------------------------------------------------------- - * - * TclpHasSockets -- - * - * This function determines whether sockets are available on the - * current system and returns an error in interp if they are not. - * Note that interp may be NULL. - * - * Results: - * Returns TCL_OK if the system supports sockets, or TCL_ERROR with - * an error in interp. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclpHasSockets( - Tcl_Interp *interp) /* Interp for error messages. */ -{ - InitSockets(); - - if (hasSockets) { - return TCL_OK; - } - if (interp != NULL) { - Tcl_AppendResult(interp, "sockets are not available on this system", - NULL); - } - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * SocketSetupProc -- - * - * This procedure is invoked before Tcl_DoOneEvent blocks waiting - * for an event. - * - * Results: - * None. - * - * Side effects: - * Adjusts the block time if needed. - * - *---------------------------------------------------------------------- - */ - -static void -SocketSetupProc( - ClientData data, /* Not used. */ - int flags) /* Event flags as passed to Tcl_DoOneEvent. */ -{ - TcpState *statePtr; - Tcl_Time blockTime = { 0, 0 }; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - if (!(flags & TCL_FILE_EVENTS)) { - return; - } - - /* - * Check to see if there is a ready socket. If so, poll. - */ - - for (statePtr = tsdPtr->socketList; statePtr != NULL; - statePtr = statePtr->nextPtr) { - if (statePtr->flags & TCP_RELEASE) { - continue; - } - if (SocketReady(statePtr)) { - Tcl_SetMaxBlockTime(&blockTime); - break; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * SocketCheckProc -- - * - * This procedure is called by Tcl_DoOneEvent to check the socket - * event source for events. - * - * Results: - * None. - * - * Side effects: - * May queue an event. - * - *---------------------------------------------------------------------- - */ - -static void -SocketCheckProc( - ClientData data, /* Not used. */ - int flags) /* Event flags as passed to Tcl_DoOneEvent. */ -{ - TcpState *statePtr; - SocketEvent *evPtr; - TcpState dummyState; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - if (!(flags & TCL_FILE_EVENTS)) { - return; - } - - /* - * Queue events for any ready sockets that don't already have events - * queued (caused by persistent states that won't generate WinSock - * events). - */ - - for (statePtr = tsdPtr->socketList; statePtr != NULL; - statePtr = statePtr->nextPtr) { - /* - * Check to see if this socket is dead and needs to be cleaned - * up. We use a dummy statePtr whose only valid field is the - * nextPtr to allow the loop to continue even if the element - * is deleted. - */ - - if (statePtr->flags & TCP_RELEASE) { - if (!(statePtr->flags & TCP_PENDING)) { - dummyState.nextPtr = statePtr->nextPtr; - SocketFreeProc(statePtr); - statePtr = &dummyState; - } - continue; - } - - if (!(statePtr->flags & TCP_PENDING) && SocketReady(statePtr)) { - statePtr->flags |= TCP_PENDING; - evPtr = (SocketEvent *) ckalloc(sizeof(SocketEvent)); - evPtr->header.proc = SocketEventProc; - evPtr->statePtr = statePtr; - evPtr->tcpStream = statePtr->tcpStream; - Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * SocketReady -- - * - * This function checks the current state of a socket to see - * if any interesting conditions are present. - * - * Results: - * Returns 1 if an event that someone is watching is present, else - * returns 0. - * - * Side effects: - * Updates the checkMask for the socket to reflect any newly - * detected events. - * - *---------------------------------------------------------------------- - */ - -static int -SocketReady( - TcpState *statePtr) -{ - TCPiopb statusPB; - int foundSomething = 0; - int didStatus = 0; - int amount; - OSErr err; - - if (statePtr->flags & TCP_LISTEN_CONNECT) { - foundSomething = 1; - statePtr->checkMask |= TCL_READABLE; - } - if (statePtr->watchMask & TCL_READABLE) { - if (statePtr->checkMask & TCL_READABLE) { - foundSomething = 1; - } else if (statePtr->flags & TCP_CONNECTED) { - statusPB.ioCRefNum = driverRefNum; - statusPB.tcpStream = statePtr->tcpStream; - statusPB.csCode = TCPStatus; - err = PBControlSync((ParmBlkPtr) &statusPB); - didStatus = 1; - - /* - * We make the fchannel readable if 1) we get an error, - * 2) there is more data available, or 3) we detect - * that a close from the remote connection has arrived. - */ - - if ((err != noErr) || - (statusPB.csParam.status.amtUnreadData > 0) || - (statusPB.csParam.status.connectionState == 14)) { - statePtr->checkMask |= TCL_READABLE; - foundSomething = 1; - } - } - } - if (statePtr->watchMask & TCL_WRITABLE) { - if (statePtr->checkMask & TCL_WRITABLE) { - foundSomething = 1; - } else if (statePtr->flags & TCP_CONNECTED) { - if (!didStatus) { - statusPB.ioCRefNum = driverRefNum; - statusPB.tcpStream = statePtr->tcpStream; - statusPB.csCode = TCPStatus; - err = PBControlSync((ParmBlkPtr) &statusPB); - } - - /* - * If there is an error or there if there is room to - * send more data we make the channel writeable. - */ - - amount = statusPB.csParam.status.sendWindow - - statusPB.csParam.status.amtUnackedData; - if ((err != noErr) || (amount > 0)) { - statePtr->checkMask |= TCL_WRITABLE; - foundSomething = 1; - } - } - } - return foundSomething; -} - -/* - *---------------------------------------------------------------------- - * - * InitMacTCPParamBlock-- - * - * Initialize a MacTCP parameter block. - * - * Results: - * None. - * - * Side effects: - * Initializes the parameter block. - * - *---------------------------------------------------------------------- - */ - -static void -InitMacTCPParamBlock( - TCPiopb *pBlock, /* Tcp parmeter block. */ - int csCode) /* Tcp operation code. */ -{ - memset(pBlock, 0, sizeof(TCPiopb)); - pBlock->ioResult = 1; - pBlock->ioCRefNum = driverRefNum; - pBlock->csCode = (short) csCode; -} - -/* - *---------------------------------------------------------------------- - * - * TcpBlockMode -- - * - * Set blocking or non-blocking mode on channel. - * - * Results: - * 0 if successful, errno when failed. - * - * Side effects: - * Sets the device into blocking or non-blocking mode. - * - *---------------------------------------------------------------------- - */ - -static int -TcpBlockMode( - ClientData instanceData, /* Channel state. */ - int mode) /* The mode to set. */ -{ - TcpState *statePtr = (TcpState *) instanceData; - - if (mode == TCL_MODE_BLOCKING) { - statePtr->flags &= ~TCP_ASYNC_SOCKET; - } else { - statePtr->flags |= TCP_ASYNC_SOCKET; - } - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * TcpClose -- - * - * Close the socket. - * - * Results: - * 0 if successful, the value of errno if failed. - * - * Side effects: - * Closes the socket. - * - *---------------------------------------------------------------------- - */ - -static int -TcpClose( - ClientData instanceData, /* The socket to close. */ - Tcl_Interp *interp) /* Interp for error messages. */ -{ - TcpState *statePtr = (TcpState *) instanceData; - StreamPtr tcpStream; - TCPiopb closePB; - OSErr err; - - tcpStream = statePtr->tcpStream; - statePtr->flags &= ~TCP_CONNECTED; - - /* - * If this is a server socket we can't use the statePtr - * param block because it is in use. However, we can - * close syncronously. - */ - - if ((statePtr->flags & TCP_LISTENING) || - (statePtr->flags & TCP_LISTEN_CONNECT)) { - InitMacTCPParamBlock(&closePB, TCPClose); - closePB.tcpStream = tcpStream; - closePB.ioCompletion = NULL; - err = PBControlSync((ParmBlkPtr) &closePB); - if (err != noErr) { - Debugger(); - panic("error closing server socket"); - } - statePtr->flags |= TCP_RELEASE; - - /* - * Server sockets are closed sync. Therefor, we know it is OK to - * release the socket now. - */ - - InitMacTCPParamBlock(&statePtr->pb, TCPRelease); - statePtr->pb.tcpStream = statePtr->tcpStream; - err = PBControlSync((ParmBlkPtr) &statePtr->pb); - if (err != noErr) { - panic("error releasing server socket"); - } - - /* - * Free the buffer space used by the socket and the - * actual socket state data structure. - */ - - ckfree((char *) statePtr->pb.csParam.create.rcvBuff); - FreeSocketInfo(statePtr); - return 0; - } - - /* - * If this socket is in the midddle on async connect we can just - * abort the connect and release the stream right now. - */ - - if (statePtr->flags & TCP_ASYNC_CONNECT) { - InitMacTCPParamBlock(&closePB, TCPClose); - closePB.tcpStream = tcpStream; - closePB.ioCompletion = NULL; - err = PBControlSync((ParmBlkPtr) &closePB); - if (err != noErr) { - panic("error closing async connect socket"); - } - statePtr->flags |= TCP_RELEASE; - - InitMacTCPParamBlock(&statePtr->pb, TCPRelease); - statePtr->pb.tcpStream = statePtr->tcpStream; - err = PBControlSync((ParmBlkPtr) &statePtr->pb); - if (err != noErr) { - panic("error releasing async connect socket"); - } - - /* - * Free the buffer space used by the socket and the - * actual socket state data structure. - */ - - ckfree((char *) statePtr->pb.csParam.create.rcvBuff); - FreeSocketInfo(statePtr); - return 0; - } - - /* - * Client sockets: - * If a background write is in progress, don't close - * the socket yet. The completion routine for the - * write will take care of it. - */ - - if (!(statePtr->flags & TCP_WRITING)) { - InitMacTCPParamBlock(&statePtr->pb, TCPClose); - statePtr->pb.tcpStream = tcpStream; - statePtr->pb.ioCompletion = closeUPP; - statePtr->pb.csParam.close.userDataPtr = (Ptr) statePtr; - err = PBControlAsync((ParmBlkPtr) &statePtr->pb); - if (err != noErr) { - Debugger(); - statePtr->flags |= TCP_RELEASE; - /* return 0; */ - } - } - - SocketFreeProc(instanceData); - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * CloseCompletionRoutine -- - * - * Handles the close protocol for a Tcp socket. This will do - * a series of calls to release all data currently buffered for - * the socket. This is important to do to as it allows the remote - * connection to recieve and issue it's own close on the socket. - * Note that this function is running at interupt time and can't - * allocate memory or do much else except set state. - * - * Results: - * None. - * - * Side effects: - * The buffers for the socket are flushed. - * - *---------------------------------------------------------------------- - */ - -static void -CloseCompletionRoutine( - TCPiopb *pbPtr) /* Tcp parameter block. */ -{ - TcpState *statePtr; - OSErr err; - - if (pbPtr->csCode == TCPClose) { - statePtr = (TcpState *) (pbPtr->csParam.close.userDataPtr); - } else { - statePtr = (TcpState *) (pbPtr->csParam.receive.userDataPtr); - } - - /* - * It's very bad if the statePtr is nNULL - we should probably panic... - */ - - if (statePtr == NULL) { - Debugger(); - return; - } - - WakeUpProcess(&statePtr->psn); - - /* - * If there is an error we assume the remote side has already - * close. We are done closing as soon as we decide that the - * remote connection has closed. - */ - - if (pbPtr->ioResult != noErr) { - statePtr->flags |= TCP_RELEASE; - return; - } - if (statePtr->flags & TCP_REMOTE_CLOSED) { - statePtr->flags |= TCP_RELEASE; - return; - } - - /* - * If we just did a recieve we need to return the buffers. - * Otherwise, attempt to recieve more data until we recieve an - * error (usually because we have no more data). - */ - - if (statePtr->pb.csCode == TCPNoCopyRcv) { - InitMacTCPParamBlock(&statePtr->pb, TCPRcvBfrReturn); - statePtr->pb.tcpStream = statePtr->tcpStream; - statePtr->pb.ioCompletion = closeUPP; - statePtr->pb.csParam.receive.rdsPtr = (Ptr) statePtr->rdsarray; - statePtr->pb.csParam.receive.userDataPtr = (Ptr) statePtr; - err = PBControlAsync((ParmBlkPtr) &statePtr->pb); - } else { - InitMacTCPParamBlock(&statePtr->pb, TCPNoCopyRcv); - statePtr->pb.tcpStream = statePtr->tcpStream; - statePtr->pb.ioCompletion = closeUPP; - statePtr->pb.csParam.receive.commandTimeoutValue = 1; - statePtr->pb.csParam.receive.rdsPtr = (Ptr) statePtr->rdsarray; - statePtr->pb.csParam.receive.rdsLength = 5; - statePtr->pb.csParam.receive.userDataPtr = (Ptr) statePtr; - err = PBControlAsync((ParmBlkPtr) &statePtr->pb); - } - - if (err != noErr) { - statePtr->flags |= TCP_RELEASE; - } -} -/* - *---------------------------------------------------------------------- - * - * SocketFreeProc -- - * - * This callback is invoked in order to delete - * the notifier data associated with a file handle. - * - * Results: - * None. - * - * Side effects: - * Removes the SocketInfo from the global socket list. - * - *---------------------------------------------------------------------- - */ - -static void -SocketFreeProc( - ClientData clientData) /* Channel state. */ -{ - TcpState *statePtr = (TcpState *) clientData; - OSErr err; - TCPiopb statusPB; - - /* - * Get the status of this connection. We need to do a - * few tests to see if it's OK to release the stream now. - */ - - if (!(statePtr->flags & TCP_RELEASE)) { - return; - } - statusPB.ioCRefNum = driverRefNum; - statusPB.tcpStream = statePtr->tcpStream; - statusPB.csCode = TCPStatus; - err = PBControlSync((ParmBlkPtr) &statusPB); - if ((statusPB.csParam.status.connectionState == 0) || - (statusPB.csParam.status.connectionState == 2)) { - /* - * If the conection state is 0 then this was a client - * connection and it's closed. If it is 2 then this a - * server client and we may release it. If it isn't - * one of those values then we return and we'll try to - * clean up later. - */ - - } else { - return; - } - - /* - * The Close request is made async. We know it's - * OK to release the socket when the TCP_RELEASE flag - * gets set. - */ - - InitMacTCPParamBlock(&statePtr->pb, TCPRelease); - statePtr->pb.tcpStream = statePtr->tcpStream; - err = PBControlSync((ParmBlkPtr) &statePtr->pb); - if (err != noErr) { - Debugger(); /* Ignoreing leaves stranded stream. Is there an - alternative? */ - } - - /* - * Free the buffer space used by the socket and the - * actual socket state data structure. - */ - - ckfree((char *) statePtr->pb.csParam.create.rcvBuff); - FreeSocketInfo(statePtr); -} - -/* - *---------------------------------------------------------------------- - * - * TcpInput -- - * - * Reads input from the IO channel into the buffer given. Returns - * count of how many bytes were actually read, and an error - * indication. - * - * Results: - * A count of how many bytes were read is returned. A value of -1 - * implies an error occured. A value of zero means we have reached - * the end of data (EOF). - * - * Side effects: - * Reads input from the actual channel. - * - *---------------------------------------------------------------------- - */ - -int -TcpInput( - ClientData instanceData, /* Channel state. */ - char *buf, /* Where to store data read. */ - int bufSize, /* How much space is available - * in the buffer? */ - int *errorCodePtr) /* Where to store error code. */ -{ - TcpState *statePtr = (TcpState *) instanceData; - StreamPtr tcpStream; - OSErr err; - TCPiopb statusPB; - int toRead, dataAvail; - - *errorCodePtr = 0; - errno = 0; - tcpStream = statePtr->tcpStream; - - if (bufSize == 0) { - return 0; - } - toRead = bufSize; - - /* - * First check to see if EOF was already detected, to prevent - * calling the socket stack after the first time EOF is detected. - */ - - if (statePtr->flags & TCP_REMOTE_CLOSED) { - return 0; - } - - /* - * If an asynchronous connect is in progress, attempt to wait for it - * to complete before reading. - */ - - if ((statePtr->flags & TCP_ASYNC_CONNECT) - && ! WaitForSocketEvent(statePtr, TCL_READABLE, errorCodePtr)) { - return -1; - } - - /* - * No EOF, and it is connected, so try to read more from the socket. - * If the socket is blocking, we keep trying until there is data - * available or the socket is closed. - */ - - while (1) { - - statusPB.ioCRefNum = driverRefNum; - statusPB.tcpStream = tcpStream; - statusPB.csCode = TCPStatus; - err = PBControlSync((ParmBlkPtr) &statusPB); - if (err != noErr) { - Debugger(); - statePtr->flags |= TCP_REMOTE_CLOSED; - return 0; /* EOF */ - } - dataAvail = statusPB.csParam.status.amtUnreadData; - if (dataAvail < bufSize) { - toRead = dataAvail; - } else { - toRead = bufSize; - } - if (toRead != 0) { - /* - * Try to read the data. - */ - - InitMacTCPParamBlock(&statusPB, TCPRcv); - statusPB.tcpStream = tcpStream; - statusPB.csParam.receive.rcvBuff = buf; - statusPB.csParam.receive.rcvBuffLen = toRead; - err = PBControlSync((ParmBlkPtr) &statusPB); - - statePtr->checkMask &= ~TCL_READABLE; - switch (err) { - case noErr: - /* - * The channel remains readable only if this read succeds - * and we had more data then the size of the buffer we were - * trying to fill. Use the info from the call to status to - * determine this. - */ - - if (dataAvail > bufSize) { - statePtr->checkMask |= TCL_READABLE; - } - return statusPB.csParam.receive.rcvBuffLen; - case connectionClosing: - *errorCodePtr = errno = ESHUTDOWN; - statePtr->flags |= TCP_REMOTE_CLOSED; - return 0; - case connectionDoesntExist: - case connectionTerminated: - *errorCodePtr = errno = ENOTCONN; - statePtr->flags |= TCP_REMOTE_CLOSED; - return 0; - case invalidStreamPtr: - default: - *errorCodePtr = EINVAL; - return -1; - } - } - - /* - * No data is available, so check the connection state to - * see why this is the case. - */ - - if (statusPB.csParam.status.connectionState == 14) { - statePtr->flags |= TCP_REMOTE_CLOSED; - return 0; - } - if (statusPB.csParam.status.connectionState != 8) { - Debugger(); - } - statePtr->checkMask &= ~TCL_READABLE; - if (statePtr->flags & TCP_ASYNC_SOCKET) { - *errorCodePtr = EWOULDBLOCK; - return -1; - } - - /* - * In the blocking case, wait until the file becomes readable - * or closed and try again. - */ - - if (!WaitForSocketEvent(statePtr, TCL_READABLE, errorCodePtr)) { - return -1; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TcpGetHandle -- - * - * Called from Tcl_GetChannelHandle to retrieve handles from inside - * a file based channel. - * - * Results: - * The appropriate handle or NULL if not present. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -TcpGetHandle( - ClientData instanceData, /* The file state. */ - int direction, /* Which handle to retrieve? */ - ClientData *handlePtr) -{ - TcpState *statePtr = (TcpState *) instanceData; - - *handlePtr = (ClientData) statePtr->tcpStream; - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TcpOutput-- - * - * Writes the given output on the IO channel. Returns count of how - * many characters were actually written, and an error indication. - * - * Results: - * A count of how many characters were written is returned and an - * error indication is returned in an output argument. - * - * Side effects: - * Writes output on the actual channel. - * - *---------------------------------------------------------------------- - */ - -static int -TcpOutput( - ClientData instanceData, /* Channel state. */ - char *buf, /* The data buffer. */ - int toWrite, /* How many bytes to write? */ - int *errorCodePtr) /* Where to store error code. */ -{ - TcpState *statePtr = (TcpState *) instanceData; - StreamPtr tcpStream; - OSErr err; - int amount; - TCPiopb statusPB; - - *errorCodePtr = 0; - tcpStream = statePtr->tcpStream; - - /* - * If an asynchronous connect is in progress, attempt to wait for it - * to complete before writing. - */ - - if ((statePtr->flags & TCP_ASYNC_CONNECT) - && ! WaitForSocketEvent(statePtr, TCL_WRITABLE, errorCodePtr)) { - return -1; - } - - /* - * Loop until we have written some data, or an error occurs. - */ - - while (1) { - statusPB.ioCRefNum = driverRefNum; - statusPB.tcpStream = tcpStream; - statusPB.csCode = TCPStatus; - err = PBControlSync((ParmBlkPtr) &statusPB); - if ((err == connectionDoesntExist) || ((err == noErr) && - (statusPB.csParam.status.connectionState == 14))) { - /* - * The remote connection is gone away. Report an error - * and don't write anything. - */ - - *errorCodePtr = errno = EPIPE; - return -1; - } else if (err != noErr) { - return -1; - } - amount = statusPB.csParam.status.sendWindow - - statusPB.csParam.status.amtUnackedData; - - /* - * Attempt to write the data to the socket if a background - * write isn't in progress and there is room in the output buffers. - */ - - if (!(statePtr->flags & TCP_WRITING) && amount > 0) { - if (toWrite < amount) { - amount = toWrite; - } - - /* We need to copy the data, otherwise the caller may overwrite - * the buffer in the middle of our asynchronous call - */ - - if (amount > statePtr->writeBufferSize) { - /* - * need to grow write buffer - */ - - if (statePtr->writeBuffer != (void *) NULL) { - ckfree(statePtr->writeBuffer); - } - statePtr->writeBuffer = (void *) ckalloc(amount); - statePtr->writeBufferSize = amount; - } - memcpy(statePtr->writeBuffer, buf, amount); - statePtr->dataSegment[0].ptr = statePtr->writeBuffer; - - statePtr->dataSegment[0].length = amount; - statePtr->dataSegment[1].length = 0; - InitMacTCPParamBlock(&statePtr->pb, TCPSend); - statePtr->pb.ioCompletion = completeUPP; - statePtr->pb.tcpStream = tcpStream; - statePtr->pb.csParam.send.wdsPtr = (Ptr) statePtr->dataSegment; - statePtr->pb.csParam.send.pushFlag = 1; - statePtr->pb.csParam.send.userDataPtr = (Ptr) statePtr; - statePtr->flags |= TCP_WRITING; - err = PBControlAsync((ParmBlkPtr) &(statePtr->pb)); - switch (err) { - case noErr: - return amount; - case connectionClosing: - *errorCodePtr = errno = ESHUTDOWN; - statePtr->flags |= TCP_REMOTE_CLOSED; - return -1; - case connectionDoesntExist: - case connectionTerminated: - *errorCodePtr = errno = ENOTCONN; - statePtr->flags |= TCP_REMOTE_CLOSED; - return -1; - case invalidStreamPtr: - default: - return -1; - } - - } - - /* - * The socket wasn't writable. In the non-blocking case, return - * immediately, otherwise wait until the file becomes writable - * or closed and try again. - */ - - if (statePtr->flags & TCP_ASYNC_SOCKET) { - statePtr->checkMask &= ~TCL_WRITABLE; - *errorCodePtr = EWOULDBLOCK; - return -1; - } else if (!WaitForSocketEvent(statePtr, TCL_WRITABLE, errorCodePtr)) { - return -1; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TcpGetOptionProc -- - * - * Computes an option value for a TCP socket based channel, or a - * list of all options and their values. - * - * Note: This code is based on code contributed by John Haxby. - * - * Results: - * A standard Tcl result. The value of the specified option or a - * list of all options and their values is returned in the - * supplied DString. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -TcpGetOptionProc( - ClientData instanceData, /* Socket state. */ - Tcl_Interp *interp, /* For error reporting - can be NULL.*/ - char *optionName, /* Name of the option to - * retrieve the value for, or - * NULL to get all options and - * their values. */ - Tcl_DString *dsPtr) /* Where to store the computed - * value; initialized by caller. */ -{ - TcpState *statePtr = (TcpState *) instanceData; - int doPeerName = false, doSockName = false, doAll = false; - ip_addr tcpAddress; - char buffer[128]; - OSErr err; - Tcl_DString dString; - TCPiopb statusPB; - int errorCode; - - /* - * If an asynchronous connect is in progress, attempt to wait for it - * to complete before accessing the socket state. - */ - - if ((statePtr->flags & TCP_ASYNC_CONNECT) - && ! WaitForSocketEvent(statePtr, TCL_WRITABLE, &errorCode)) { - if (interp) { - /* - * fix the error message. - */ - - Tcl_AppendResult(interp, "connect is in progress and can't wait", - NULL); - } - return TCL_ERROR; - } - - /* - * Determine which options we need to do. Do all of them - * if optionName is NULL. - */ - - if (optionName == (char *) NULL || optionName[0] == '\0') { - doAll = true; - } else { - if (!strcmp(optionName, "-peername")) { - doPeerName = true; - } else if (!strcmp(optionName, "-sockname")) { - doSockName = true; - } else { - return Tcl_BadChannelOption(interp, optionName, - "peername sockname"); - } - } - - /* - * Get status on the stream. Make sure to use a new pb struct because - * the struct in the statePtr may be part of an asyncronous call. - */ - - statusPB.ioCRefNum = driverRefNum; - statusPB.tcpStream = statePtr->tcpStream; - statusPB.csCode = TCPStatus; - err = PBControlSync((ParmBlkPtr) &statusPB); - if ((err == connectionDoesntExist) || - ((err == noErr) && (statusPB.csParam.status.connectionState == 14))) { - /* - * The socket was probably closed on the other side of the connection. - */ - - if (interp) { - Tcl_AppendResult(interp, "can't access socket info: ", - "connection reset by peer", NULL); - } - return TCL_ERROR; - } else if (err != noErr) { - if (interp) { - Tcl_AppendResult(interp, "unknown socket error", NULL); - } - Debugger(); - return TCL_ERROR; - } - - - /* - * Get the sockname for the socket. - */ - - Tcl_DStringInit(&dString); - if (doAll || doSockName) { - if (doAll) { - Tcl_DStringAppendElement(dsPtr, "-sockname"); - Tcl_DStringStartSublist(dsPtr); - } - tcpAddress = statusPB.csParam.status.localHost; - sprintf(buffer, "%d.%d.%d.%d", tcpAddress>>24, - tcpAddress>>16 & 0xff, tcpAddress>>8 & 0xff, - tcpAddress & 0xff); - Tcl_DStringAppendElement(dsPtr, buffer); - if (ResolveAddress(tcpAddress, &dString) == noErr) { - Tcl_DStringAppendElement(dsPtr, dString.string); - } else { - Tcl_DStringAppendElement(dsPtr, "<unknown>"); - } - sprintf(buffer, "%d", statusPB.csParam.status.localPort); - Tcl_DStringAppendElement(dsPtr, buffer); - if (doAll) { - Tcl_DStringEndSublist(dsPtr); - } - } - - /* - * Get the peername for the socket. - */ - - if ((doAll || doPeerName) && (statePtr->flags & TCP_CONNECTED)) { - if (doAll) { - Tcl_DStringAppendElement(dsPtr, "-peername"); - Tcl_DStringStartSublist(dsPtr); - } - tcpAddress = statusPB.csParam.status.remoteHost; - sprintf(buffer, "%d.%d.%d.%d", tcpAddress>>24, - tcpAddress>>16 & 0xff, tcpAddress>>8 & 0xff, - tcpAddress & 0xff); - Tcl_DStringAppendElement(dsPtr, buffer); - Tcl_DStringSetLength(&dString, 0); - if (ResolveAddress(tcpAddress, &dString) == noErr) { - Tcl_DStringAppendElement(dsPtr, dString.string); - } else { - Tcl_DStringAppendElement(dsPtr, "<unknown>"); - } - sprintf(buffer, "%d", statusPB.csParam.status.remotePort); - Tcl_DStringAppendElement(dsPtr, buffer); - if (doAll) { - Tcl_DStringEndSublist(dsPtr); - } - } - - Tcl_DStringFree(&dString); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TcpWatch -- - * - * Initialize the notifier to watch this channel. - * - * Results: - * None. - * - * Side effects: - * Sets the watchMask for the channel. - * - *---------------------------------------------------------------------- - */ - -static void -TcpWatch(instanceData, mask) - ClientData instanceData; /* The file state. */ - int mask; /* Events of interest; an OR-ed - * combination of TCL_READABLE, - * TCL_WRITABLE and TCL_EXCEPTION. */ -{ - TcpState *statePtr = (TcpState *) instanceData; - - statePtr->watchMask = mask; -} - -/* - *---------------------------------------------------------------------- - * - * NewSocketInfo -- - * - * This function allocates and initializes a new SocketInfo - * structure. - * - * Results: - * Returns a newly allocated SocketInfo. - * - * Side effects: - * Adds the socket to the global socket list, allocates memory. - * - *---------------------------------------------------------------------- - */ - -static TcpState * -NewSocketInfo( - StreamPtr tcpStream) -{ - TcpState *statePtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState)); - statePtr->tcpStream = tcpStream; - statePtr->psn = applicationPSN; - statePtr->flags = 0; - statePtr->checkMask = 0; - statePtr->watchMask = 0; - statePtr->acceptProc = (Tcl_TcpAcceptProc *) NULL; - statePtr->acceptProcData = (ClientData) NULL; - statePtr->writeBuffer = (void *) NULL; - statePtr->writeBufferSize = 0; - statePtr->nextPtr = tsdPtr->socketList; - tsdPtr->socketList = statePtr; - return statePtr; -} - -/* - *---------------------------------------------------------------------- - * - * FreeSocketInfo -- - * - * This function deallocates a SocketInfo structure that is no - * longer needed. - * - * Results: - * None. - * - * Side effects: - * Removes the socket from the global socket list, frees memory. - * - *---------------------------------------------------------------------- - */ - -static void -FreeSocketInfo( - TcpState *statePtr) /* The state pointer to free. */ -{ - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - if (statePtr == tsdPtr->socketList) { - tsdPtr->socketList = statePtr->nextPtr; - } else { - TcpState *p; - for (p = tsdPtr->socketList; p != NULL; p = p->nextPtr) { - if (p->nextPtr == statePtr) { - p->nextPtr = statePtr->nextPtr; - break; - } - } - } - - if (statePtr->writeBuffer != (void *) NULL) { - ckfree(statePtr->writeBuffer); - } - - ckfree((char *) statePtr); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_MakeTcpClientChannel -- - * - * Creates a Tcl_Channel from an existing client TCP socket. - * - * Results: - * The Tcl_Channel wrapped around the preexisting TCP socket. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Channel -Tcl_MakeTcpClientChannel( - ClientData sock) /* The socket to wrap up into a channel. */ -{ - TcpState *statePtr; - char channelName[20]; - - if (TclpHasSockets(NULL) != TCL_OK) { - return NULL; - } - - statePtr = NewSocketInfo((StreamPtr) sock); - /* TODO: do we need to set the port??? */ - - sprintf(channelName, "sock%d", socketNumber++); - - statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, - (ClientData) statePtr, (TCL_READABLE | TCL_WRITABLE)); - Tcl_SetChannelBufferSize(statePtr->channel, socketBufferSize); - Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", "auto crlf"); - return statePtr->channel; -} - -/* - *---------------------------------------------------------------------- - * - * CreateSocket -- - * - * This function opens a new socket and initializes the - * SocketInfo structure. - * - * Results: - * Returns a new SocketInfo, or NULL with an error in interp. - * - * Side effects: - * Adds a new socket to the socketList. - * - *---------------------------------------------------------------------- - */ - -static TcpState * -CreateSocket( - Tcl_Interp *interp, /* For error reporting; can be NULL. */ - int port, /* Port number to open. */ - char *host, /* Name of host on which to open port. */ - char *myaddr, /* Optional client-side address */ - int myport, /* Optional client-side port */ - int server, /* 1 if socket should be a server socket, - * else 0 for a client socket. */ - int async) /* 1 create async, 0 do sync. */ -{ - ip_addr macAddr; - OSErr err; - TCPiopb pb; - StreamPtr tcpStream; - TcpState *statePtr; - char * buffer; - - /* - * Figure out the ip address from the host string. - */ - - if (host == NULL) { - err = GetLocalAddress(&macAddr); - } else { - err = GetHostFromString(host, &macAddr); - } - if (err != noErr) { - Tcl_SetErrno(EHOSTUNREACH); - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, "couldn't open socket: ", - Tcl_PosixError(interp), (char *) NULL); - } - return (TcpState *) NULL; - } - - /* - * Create a MacTCP stream and create the state used for socket - * transactions from here on out. - */ - - ClearZombieSockets(); - buffer = ckalloc(socketBufferSize); - InitMacTCPParamBlock(&pb, TCPCreate); - pb.csParam.create.rcvBuff = buffer; - pb.csParam.create.rcvBuffLen = socketBufferSize; - err = PBControlSync((ParmBlkPtr) &pb); - if (err != noErr) { - Tcl_SetErrno(0); /* TODO: set to ENOSR - maybe?*/ - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, "couldn't open socket: ", - Tcl_PosixError(interp), (char *) NULL); - } - return (TcpState *) NULL; - } - - tcpStream = pb.tcpStream; - statePtr = NewSocketInfo(tcpStream); - statePtr->port = port; - - if (server) { - /* - * Set up server connection. - */ - - InitMacTCPParamBlock(&statePtr->pb, TCPPassiveOpen); - statePtr->pb.tcpStream = tcpStream; - statePtr->pb.csParam.open.localPort = statePtr->port; - statePtr->pb.ioCompletion = completeUPP; - statePtr->pb.csParam.open.userDataPtr = (Ptr) statePtr; - statePtr->flags |= TCP_LISTENING; - err = PBControlAsync((ParmBlkPtr) &(statePtr->pb)); - - /* - * If this is a server on port 0 then we need to wait until - * the dynamic port allocation is made by the MacTcp driver. - */ - - if (statePtr->port == 0) { - EventRecord dummy; - - while (statePtr->pb.csParam.open.localPort == 0) { - WaitNextEvent(0, &dummy, 1, NULL); - if (statePtr->pb.ioResult != 0) { - break; - } - } - statePtr->port = statePtr->pb.csParam.open.localPort; - } - Tcl_SetErrno(EINPROGRESS); - } else { - /* - * Attempt to connect. The connect may fail at present with an - * EINPROGRESS but at a later time it will complete. The caller - * will set up a file handler on the socket if she is interested in - * being informed when the connect completes. - */ - - InitMacTCPParamBlock(&statePtr->pb, TCPActiveOpen); - statePtr->pb.tcpStream = tcpStream; - statePtr->pb.csParam.open.remoteHost = macAddr; - statePtr->pb.csParam.open.remotePort = port; - statePtr->pb.csParam.open.localHost = 0; - statePtr->pb.csParam.open.localPort = myport; - statePtr->pb.csParam.open.userDataPtr = (Ptr) statePtr; - statePtr->pb.ioCompletion = completeUPP; - if (async) { - statePtr->flags |= TCP_ASYNC_CONNECT; - err = PBControlAsync((ParmBlkPtr) &(statePtr->pb)); - Tcl_SetErrno(EINPROGRESS); - } else { - err = PBControlSync((ParmBlkPtr) &(statePtr->pb)); - } - } - - switch (err) { - case noErr: - if (!async) { - statePtr->flags |= TCP_CONNECTED; - } - return statePtr; - case duplicateSocket: - Tcl_SetErrno(EADDRINUSE); - break; - case openFailed: - case connectionTerminated: - Tcl_SetErrno(ECONNREFUSED); - break; - case invalidStreamPtr: - case connectionExists: - default: - /* - * These cases should never occur. However, we will fail - * gracefully and hope Tcl can resume. The alternative is to panic - * which is probably a bit drastic. - */ - - Debugger(); - Tcl_SetErrno(err); - } - - /* - * We had error during the connection. Release the stream - * and file handle. Also report to the interp. - */ - - pb.ioCRefNum = driverRefNum; - pb.csCode = TCPRelease; - pb.tcpStream = tcpStream; - pb.ioCompletion = NULL; - err = PBControlSync((ParmBlkPtr) &pb); - - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, "couldn't open socket: ", - Tcl_PosixError(interp), (char *) NULL); - } - - ckfree(buffer); - FreeSocketInfo(statePtr); - return (TcpState *) NULL; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_OpenTcpClient -- - * - * Opens a TCP client socket and creates a channel around it. - * - * Results: - * The channel or NULL if failed. On failure, the routine also - * sets the output argument errorCodePtr to the error code. - * - * Side effects: - * Opens a client socket and creates a new channel. - * - *---------------------------------------------------------------------- - */ - -Tcl_Channel -Tcl_OpenTcpClient( - Tcl_Interp *interp, /* For error reporting; can be NULL. */ - int port, /* Port number to open. */ - char *host, /* Host on which to open port. */ - char *myaddr, /* Client-side address */ - int myport, /* Client-side port */ - int async) /* If nonzero, attempt to do an - * asynchronous connect. Otherwise - * we do a blocking connect. - * - currently ignored */ -{ - TcpState *statePtr; - char channelName[20]; - - if (TclpHasSockets(interp) != TCL_OK) { - return NULL; - } - - /* - * Create a new client socket and wrap it in a channel. - */ - - statePtr = CreateSocket(interp, port, host, myaddr, myport, 0, async); - if (statePtr == NULL) { - return NULL; - } - - sprintf(channelName, "sock%d", socketNumber++); - - statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, - (ClientData) statePtr, (TCL_READABLE | TCL_WRITABLE)); - Tcl_SetChannelBufferSize(statePtr->channel, socketBufferSize); - Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", "auto crlf"); - return statePtr->channel; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_OpenTcpServer -- - * - * Opens a TCP server socket and creates a channel around it. - * - * Results: - * The channel or NULL if failed. - * - * Side effects: - * Opens a server socket and creates a new channel. - * - *---------------------------------------------------------------------- - */ - -Tcl_Channel -Tcl_OpenTcpServer( - Tcl_Interp *interp, /* For error reporting - may be - * NULL. */ - int port, /* Port number to open. */ - char *host, /* Name of local host. */ - Tcl_TcpAcceptProc *acceptProc, /* Callback for accepting connections - * from new clients. */ - ClientData acceptProcData) /* Data for the callback. */ -{ - TcpState *statePtr; - char channelName[20]; - - if (TclpHasSockets(interp) != TCL_OK) { - return NULL; - } - - /* - * Create a new client socket and wrap it in a channel. - */ - - statePtr = CreateSocket(interp, port, host, NULL, 0, 1, 1); - if (statePtr == NULL) { - return NULL; - } - - statePtr->acceptProc = acceptProc; - statePtr->acceptProcData = acceptProcData; - - sprintf(channelName, "sock%d", socketNumber++); - - statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, - (ClientData) statePtr, 0); - Tcl_SetChannelBufferSize(statePtr->channel, socketBufferSize); - Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", "auto crlf"); - return statePtr->channel; -} - -/* - *---------------------------------------------------------------------- - * - * SocketEventProc -- - * - * This procedure is called by Tcl_ServiceEvent when a socket event - * reaches the front of the event queue. This procedure is - * responsible for notifying the generic channel code. - * - * Results: - * Returns 1 if the event was handled, meaning it should be removed - * from the queue. Returns 0 if the event was not handled, meaning - * it should stay on the queue. The only time the event isn't - * handled is if the TCL_FILE_EVENTS flag bit isn't set. - * - * Side effects: - * Whatever the channel callback procedures do. - * - *---------------------------------------------------------------------- - */ - -static int -SocketEventProc( - Tcl_Event *evPtr, /* Event to service. */ - int flags) /* Flags that indicate what events to - * handle, such as TCL_FILE_EVENTS. */ -{ - TcpState *statePtr; - SocketEvent *eventPtr = (SocketEvent *) evPtr; - int mask = 0; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - if (!(flags & TCL_FILE_EVENTS)) { - return 0; - } - - /* - * Find the specified socket on the socket list. - */ - - for (statePtr = tsdPtr->socketList; statePtr != NULL; - statePtr = statePtr->nextPtr) { - if ((statePtr == eventPtr->statePtr) && - (statePtr->tcpStream == eventPtr->tcpStream)) { - break; - } - } - - /* - * Discard events that have gone stale. - */ - - if (!statePtr) { - return 1; - } - statePtr->flags &= ~(TCP_PENDING); - if (statePtr->flags & TCP_RELEASE) { - SocketFreeProc(statePtr); - return 1; - } - - - /* - * Handle connection requests directly. - */ - - if (statePtr->flags & TCP_LISTEN_CONNECT) { - if (statePtr->checkMask & TCL_READABLE) { - TcpAccept(statePtr); - } - return 1; - } - - /* - * Mask off unwanted events then notify the channel. - */ - - mask = statePtr->checkMask & statePtr->watchMask; - if (mask) { - Tcl_NotifyChannel(statePtr->channel, mask); - } - return 1; -} - -/* - *---------------------------------------------------------------------- - * - * WaitForSocketEvent -- - * - * Waits until one of the specified events occurs on a socket. - * - * Results: - * Returns 1 on success or 0 on failure, with an error code in - * errorCodePtr. - * - * Side effects: - * Processes socket events off the system queue. - * - *---------------------------------------------------------------------- - */ - -static int -WaitForSocketEvent( - TcpState *statePtr, /* Information about this socket. */ - int mask, /* Events to look for. */ - int *errorCodePtr) /* Where to store errors? */ -{ - OSErr err; - TCPiopb statusPB; - EventRecord dummy; - - /* - * Loop until we get the specified condition, unless the socket is - * asynchronous. - */ - - do { - statusPB.ioCRefNum = driverRefNum; - statusPB.tcpStream = statePtr->tcpStream; - statusPB.csCode = TCPStatus; - err = PBControlSync((ParmBlkPtr) &statusPB); - if (err != noErr) { - statePtr->checkMask |= (TCL_READABLE | TCL_WRITABLE); - return 1; - } - statePtr->checkMask = 0; - if (statusPB.csParam.status.amtUnreadData > 0) { - statePtr->checkMask |= TCL_READABLE; - } - if (!(statePtr->flags & TCP_WRITING) - && (statusPB.csParam.status.sendWindow - - statusPB.csParam.status.amtUnackedData) > 0) { - statePtr->flags &= ~(TCP_ASYNC_CONNECT); - statePtr->checkMask |= TCL_WRITABLE; - } - if (mask & statePtr->checkMask) { - return 1; - } - - /* - * Call the system to let other applications run while we - * are waiting for this event to occur. - */ - - WaitNextEvent(0, &dummy, 1, NULL); - } while (!(statePtr->flags & TCP_ASYNC_SOCKET)); - *errorCodePtr = EWOULDBLOCK; - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * TcpAccept -- - * Accept a TCP socket connection. This is called by the event - * loop, and it in turns calls any registered callbacks for this - * channel. - * - * Results: - * None. - * - * Side effects: - * Evals the Tcl script associated with the server socket. - * - *---------------------------------------------------------------------- - */ - -static void -TcpAccept( - TcpState *statePtr) -{ - TcpState *newStatePtr; - StreamPtr tcpStream; - char remoteHostname[255]; - OSErr err; - ip_addr remoteAddress; - long remotePort; - char channelName[20]; - - statePtr->flags &= ~TCP_LISTEN_CONNECT; - statePtr->checkMask &= ~TCL_READABLE; - - /* - * Transfer sever stream to new connection. - */ - - tcpStream = statePtr->tcpStream; - newStatePtr = NewSocketInfo(tcpStream); - newStatePtr->tcpStream = tcpStream; - sprintf(channelName, "sock%d", socketNumber++); - - - newStatePtr->flags |= TCP_CONNECTED; - newStatePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, - (ClientData) newStatePtr, (TCL_READABLE | TCL_WRITABLE)); - Tcl_SetChannelBufferSize(newStatePtr->channel, socketBufferSize); - Tcl_SetChannelOption(NULL, newStatePtr->channel, "-translation", - "auto crlf"); - - remoteAddress = statePtr->pb.csParam.open.remoteHost; - remotePort = statePtr->pb.csParam.open.remotePort; - - /* - * Reopen passive connect. Make new tcpStream the server. - */ - - ClearZombieSockets(); - InitMacTCPParamBlock(&statePtr->pb, TCPCreate); - statePtr->pb.csParam.create.rcvBuff = ckalloc(socketBufferSize); - statePtr->pb.csParam.create.rcvBuffLen = socketBufferSize; - err = PBControlSync((ParmBlkPtr) &statePtr->pb); - if (err != noErr) { - /* - * Hmmm... We can't reopen the server. We'll go ahead - * an continue - but we are kind of broken now... - */ - Debugger(); - statePtr->tcpStream = -1; - statePtr->flags |= TCP_SERVER_ZOMBIE; - } - - tcpStream = statePtr->tcpStream = statePtr->pb.tcpStream; - - InitMacTCPParamBlock(&statePtr->pb, TCPPassiveOpen); - statePtr->pb.tcpStream = tcpStream; - statePtr->pb.csParam.open.localHost = 0; - statePtr->pb.csParam.open.localPort = statePtr->port; - statePtr->pb.ioCompletion = completeUPP; - statePtr->pb.csParam.open.userDataPtr = (Ptr) statePtr; - statePtr->flags |= TCP_LISTENING; - err = PBControlAsync((ParmBlkPtr) &(statePtr->pb)); - /* - * TODO: deal with case where we can't recreate server socket... - */ - - /* - * Finally we run the accept procedure. We must do this last to make - * sure we are in a nice clean state. This Tcl code can do anything - * including closing the server or client sockets we've just delt with. - */ - - if (statePtr->acceptProc != NULL) { - sprintf(remoteHostname, "%d.%d.%d.%d", remoteAddress>>24, - remoteAddress>>16 & 0xff, remoteAddress>>8 & 0xff, - remoteAddress & 0xff); - - (statePtr->acceptProc)(statePtr->acceptProcData, newStatePtr->channel, - remoteHostname, remotePort); - } -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_GetHostName -- - * - * Returns the name of the local host. - * - * Results: - * A string containing the network name for this machine, or - * an empty string if we can't figure out the name. The caller - * must not modify or free this string. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -char * -Tcl_GetHostName() -{ - static int hostnameInited = 0; - static char hostname[255]; - ip_addr ourAddress; - Tcl_DString dString; - OSErr err; - - if (hostnameInited) { - return hostname; - } - - if (TclpHasSockets(NULL) == TCL_OK) { - err = GetLocalAddress(&ourAddress); - if (err == noErr) { - /* - * Search for the doman name and return it if found. Otherwise, - * just print the IP number to a string and return that. - */ - - Tcl_DStringInit(&dString); - err = ResolveAddress(ourAddress, &dString); - if (err == noErr) { - strcpy(hostname, dString.string); - } else { - sprintf(hostname, "%d.%d.%d.%d", ourAddress>>24, ourAddress>>16 & 0xff, - ourAddress>>8 & 0xff, ourAddress & 0xff); - } - Tcl_DStringFree(&dString); - - hostnameInited = 1; - return hostname; - } - } - - hostname[0] = '\0'; - hostnameInited = 1; - return hostname; -} - -/* - *---------------------------------------------------------------------- - * - * ResolveAddress -- - * - * This function is used to resolve an ip address to it's full - * domain name address. - * - * Results: - * An os err value. - * - * Side effects: - * Treats client data as int we set to true. - * - *---------------------------------------------------------------------- - */ - -static OSErr -ResolveAddress( - ip_addr tcpAddress, /* Address to resolve. */ - Tcl_DString *dsPtr) /* Returned address in string. */ -{ - int i; - EventRecord dummy; - DNRState dnrState; - OSErr err; - - /* - * Call AddrToName to resolve our ip address to our domain name. - * The call is async, so we must wait for a callback to tell us - * when to continue. - */ - - for (i = 0; i < NUM_ALT_ADDRS; i++) { - dnrState.hostInfo.addr[i] = 0; - } - dnrState.done = 0; - GetCurrentProcess(&(dnrState.psn)); - err = AddrToName(tcpAddress, &dnrState.hostInfo, resultUPP, (Ptr) &dnrState); - if (err == cacheFault) { - while (!dnrState.done) { - WaitNextEvent(0, &dummy, 1, NULL); - } - } - - /* - * If there is no error in finding the domain name we set the - * result into the dynamic string. We also work around a bug in - * MacTcp where an extranious '.' may be found at the end of the name. - */ - - if (dnrState.hostInfo.rtnCode == noErr) { - i = strlen(dnrState.hostInfo.cname) - 1; - if (dnrState.hostInfo.cname[i] == '.') { - dnrState.hostInfo.cname[i] = '\0'; - } - Tcl_DStringAppend(dsPtr, dnrState.hostInfo.cname, -1); - } - - return dnrState.hostInfo.rtnCode; -} - -/* - *---------------------------------------------------------------------- - * - * DNRCompletionRoutine -- - * - * This function is called when the Domain Name Server is done - * seviceing our request. It just sets a flag that we can poll - * in functions like Tcl_GetHostName to let them know to continue. - * - * Results: - * None. - * - * Side effects: - * Treats client data as int we set to true. - * - *---------------------------------------------------------------------- - */ - -static pascal void -DNRCompletionRoutine( - struct hostInfo *hostinfoPtr, /* Host infor struct. */ - DNRState *dnrStatePtr) /* Completetion state. */ -{ - dnrStatePtr->done = true; - WakeUpProcess(&(dnrStatePtr->psn)); -} - -/* - *---------------------------------------------------------------------- - * - * CleanUpExitProc -- - * - * This procedure is invoked as an exit handler when ExitToShell - * is called. It aborts any lingering socket connections. This - * must be called or the Mac OS will more than likely crash. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static pascal void -CleanUpExitProc() -{ - TCPiopb exitPB; - TcpState *statePtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - while (tsdPtr->socketList != NULL) { - statePtr = tsdPtr->socketList; - tsdPtr->socketList = statePtr->nextPtr; - - /* - * Close and Release the connection. - */ - - exitPB.ioCRefNum = driverRefNum; - exitPB.csCode = TCPClose; - exitPB.tcpStream = statePtr->tcpStream; - exitPB.csParam.close.ulpTimeoutValue = 60 /* seconds */; - exitPB.csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */; - exitPB.csParam.close.validityFlags = timeoutValue | timeoutAction; - exitPB.ioCompletion = NULL; - PBControlSync((ParmBlkPtr) &exitPB); - - exitPB.ioCRefNum = driverRefNum; - exitPB.csCode = TCPRelease; - exitPB.tcpStream = statePtr->tcpStream; - exitPB.ioCompletion = NULL; - PBControlSync((ParmBlkPtr) &exitPB); - } -} - -/* - *---------------------------------------------------------------------- - * - * GetHostFromString -- - * - * Looks up the passed in domain name in the domain resolver. It - * can accept strings of two types: 1) the ip number in string - * format, or 2) the domain name. - * - * Results: - * We return a ip address or 0 if there was an error or the - * domain does not exist. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static OSErr -GetHostFromString( - char *name, /* Host in string form. */ - ip_addr *address) /* Returned IP address. */ -{ - OSErr err; - int i; - EventRecord dummy; - DNRState dnrState; - - if (TclpHasSockets(NULL) != TCL_OK) { - return 0; - } - - /* - * Call StrToAddr to get the ip number for the passed in domain - * name. The call is async, so we must wait for a callback to - * tell us when to continue. - */ - - for (i = 0; i < NUM_ALT_ADDRS; i++) { - dnrState.hostInfo.addr[i] = 0; - } - dnrState.done = 0; - GetCurrentProcess(&(dnrState.psn)); - err = StrToAddr(name, &dnrState.hostInfo, resultUPP, (Ptr) &dnrState); - if (err == cacheFault) { - while (!dnrState.done) { - WaitNextEvent(0, &dummy, 1, NULL); - } - } - - /* - * For some reason MacTcp may return a cachFault a second time via - * the hostinfo block. This seems to be a bug in MacTcp. In this case - * we run StrToAddr again - which seems to then work just fine. - */ - - if (dnrState.hostInfo.rtnCode == cacheFault) { - dnrState.done = 0; - err = StrToAddr(name, &dnrState.hostInfo, resultUPP, (Ptr) &dnrState); - if (err == cacheFault) { - while (!dnrState.done) { - WaitNextEvent(0, &dummy, 1, NULL); - } - } - } - - if (dnrState.hostInfo.rtnCode == noErr) { - *address = dnrState.hostInfo.addr[0]; - } - - return dnrState.hostInfo.rtnCode; -} - -/* - *---------------------------------------------------------------------- - * - * IOCompletionRoutine -- - * - * This function is called when an asynchronous socket operation - * completes. Since this routine runs as an interrupt handler, - * it will simply set state to tell the notifier that this socket - * is now ready for action. Note that this function is running at - * interupt time and can't allocate memory or do much else except - * set state. - * - * Results: - * None. - * - * Side effects: - * Sets some state in the socket state. May also wake the process - * if we are not currently running. - * - *---------------------------------------------------------------------- - */ - -static void -IOCompletionRoutine( - TCPiopb *pbPtr) /* Tcp parameter block. */ -{ - TcpState *statePtr; - - if (pbPtr->csCode == TCPSend) { - statePtr = (TcpState *) pbPtr->csParam.send.userDataPtr; - } else { - statePtr = (TcpState *) pbPtr->csParam.open.userDataPtr; - } - - /* - * Always wake the process in case it's in WaitNextEvent. - * If an error has a occured - just return. We will deal - * with the problem later. - */ - - WakeUpProcess(&statePtr->psn); - if (pbPtr->ioResult != noErr) { - return; - } - - if (statePtr->flags & TCP_ASYNC_CONNECT) { - statePtr->flags &= ~TCP_ASYNC_CONNECT; - statePtr->flags |= TCP_CONNECTED; - statePtr->checkMask |= TCL_READABLE & TCL_WRITABLE; - } else if (statePtr->flags & TCP_LISTENING) { - if (statePtr->port == 0) { - Debugger(); - } - statePtr->flags &= ~TCP_LISTENING; - statePtr->flags |= TCP_LISTEN_CONNECT; - statePtr->checkMask |= TCL_READABLE; - } else if (statePtr->flags & TCP_WRITING) { - statePtr->flags &= ~TCP_WRITING; - statePtr->checkMask |= TCL_WRITABLE; - if (!(statePtr->flags & TCP_CONNECTED)) { - InitMacTCPParamBlock(&statePtr->pb, TCPClose); - statePtr->pb.tcpStream = statePtr->tcpStream; - statePtr->pb.ioCompletion = closeUPP; - statePtr->pb.csParam.close.userDataPtr = (Ptr) statePtr; - if (PBControlAsync((ParmBlkPtr) &statePtr->pb) != noErr) { - statePtr->flags |= TCP_RELEASE; - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * GetLocalAddress -- - * - * Get the IP address for this machine. The result is cached so - * the result is returned quickly after the first call. - * - * Results: - * Macintosh error code. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static OSErr -GetLocalAddress( - unsigned long *addr) /* Returns host IP address. */ -{ - struct GetAddrParamBlock pBlock; - OSErr err = noErr; - static unsigned long localAddress = 0; - - if (localAddress == 0) { - memset(&pBlock, 0, sizeof(pBlock)); - pBlock.ioResult = 1; - pBlock.csCode = ipctlGetAddr; - pBlock.ioCRefNum = driverRefNum; - err = PBControlSync((ParmBlkPtr) &pBlock); - - if (err != noErr) { - return err; - } - localAddress = pBlock.ourAddress; - } - - *addr = localAddress; - return noErr; -} - -/* - *---------------------------------------------------------------------- - * - * GetBufferSize -- - * - * Get the appropiate buffer size for our machine & network. This - * value will be used by the rest of Tcl & the MacTcp driver for - * the size of its buffers. If out method for determining the - * optimal buffer size fails for any reason - we return a - * reasonable default. - * - * Results: - * Size of optimal buffer in bytes. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static long -GetBufferSize() -{ - UDPiopb iopb; - OSErr err = noErr; - long bufferSize; - - memset(&iopb, 0, sizeof(iopb)); - err = GetLocalAddress(&iopb.csParam.mtu.remoteHost); - if (err != noErr) { - return CHANNEL_BUF_SIZE; - } - iopb.ioCRefNum = driverRefNum; - iopb.csCode = UDPMaxMTUSize; - err = PBControlSync((ParmBlkPtr)&iopb); - if (err != noErr) { - return CHANNEL_BUF_SIZE; - } - bufferSize = (iopb.csParam.mtu.mtuSize * 4) + 1024; - if (bufferSize < CHANNEL_BUF_SIZE) { - bufferSize = CHANNEL_BUF_SIZE; - } - return bufferSize; -} - -/* - *---------------------------------------------------------------------- - * - * TclSockGetPort -- - * - * Maps from a string, which could be a service name, to a port. - * Used by socket creation code to get port numbers and resolve - * registered service names to port numbers. - * - * Results: - * A standard Tcl result. On success, the port number is - * returned in portPtr. On failure, an error message is left in - * the interp's result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclSockGetPort( - Tcl_Interp *interp, /* Interp for error messages. */ - char *string, /* Integer or service name */ - char *proto, /* "tcp" or "udp", typically - - * ignored on Mac - assumed to be tcp */ - int *portPtr) /* Return port number */ -{ - PortInfo *portInfoPtr = NULL; - - if (Tcl_GetInt(interp, string, portPtr) == TCL_OK) { - if (*portPtr > 0xFFFF) { - Tcl_AppendResult(interp, "couldn't open socket: port number too high", - (char *) NULL); - return TCL_ERROR; - } - if (*portPtr < 0) { - Tcl_AppendResult(interp, "couldn't open socket: negative port number", - (char *) NULL); - return TCL_ERROR; - } - return TCL_OK; - } - for (portInfoPtr = portServices; portInfoPtr->name != NULL; portInfoPtr++) { - if (!strcmp(portInfoPtr->name, string)) { - break; - } - } - if (portInfoPtr != NULL && portInfoPtr->name != NULL) { - *portPtr = portInfoPtr->port; - Tcl_ResetResult(interp); - return TCL_OK; - } - - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * ClearZombieSockets -- - * - * This procedure looks through the socket list and removes the - * first stream it finds that is ready for release. This procedure - * should be called before we ever try to create new Tcp streams - * to ensure we can least allocate one stream. - * - * Results: - * None. - * - * Side effects: - * Tcp streams may be released. - * - *---------------------------------------------------------------------- - */ - -static void -ClearZombieSockets() -{ - TcpState *statePtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - for (statePtr = tsdPtr->socketList; statePtr != NULL; - statePtr = statePtr->nextPtr) { - if (statePtr->flags & TCP_RELEASE) { - SocketFreeProc(statePtr); - return; - } - } -} diff --git a/mac/tclMacTclCode.r b/mac/tclMacTclCode.r deleted file mode 100644 index c3a0c22..0000000 --- a/mac/tclMacTclCode.r +++ /dev/null @@ -1,37 +0,0 @@ -/* - * tclMacTclCode.r -- - * - * This file creates resources from the Tcl code that is - * usually stored in the TCL_LiBRARY - * - * Copyright (c) 1996-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * SCCS: @(#) tclMacTclCode.r 1.1 98/01/21 22:22:38 - */ - -#include <Types.r> -#include <SysTypes.r> - -#define TCL_LIBRARY_RESOURCES 2000 - -/* - * The mechanisim below loads Tcl source into the resource fork of the - * application. The example below creates a TEXT resource named - * "Init" from the file "init.tcl". This allows applications to use - * Tcl to define the behavior of the application without having to - * require some predetermined file structure - all needed Tcl "files" - * are located within the application. To source a file for the - * resource fork the source command has been modified to support - * sourcing from resources. In the below case "source -rsrc {Init}" - * will load the TEXT resource named "Init". - */ - -read 'TEXT' (TCL_LIBRARY_RESOURCES, "Init", purgeable) "::library:init.tcl"; -read 'TEXT' (TCL_LIBRARY_RESOURCES + 1, "Auto", purgeable) "::library:auto.tcl"; -read 'TEXT' (TCL_LIBRARY_RESOURCES + 2, "Package", purgeable,preload) "::library:package.tcl"; -read 'TEXT' (TCL_LIBRARY_RESOURCES + 3, "History", purgeable) "::library:history.tcl"; -read 'TEXT' (TCL_LIBRARY_RESOURCES + 4, "Word", purgeable,preload) "::library:word.tcl"; -read 'TEXT' (TCL_LIBRARY_RESOURCES + 5, "Parray", purgeable,preload) "::library:parray.tcl"; diff --git a/mac/tclMacTest.c b/mac/tclMacTest.c deleted file mode 100644 index 9598848..0000000 --- a/mac/tclMacTest.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * tclMacTest.c -- - * - * Contains commands for platform specific tests for - * the Macintosh platform. - * - * Copyright (c) 1996 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacTest.c,v 1.4 1999/05/11 07:13:36 jingham Exp $ - */ - -#define TCL_TEST - -#include "tclInt.h" -#include "tclMacInt.h" -#include "tclMacPort.h" -#include "Files.h" -#include <Errors.h> -#include <Resources.h> -#include <Script.h> -#include <Strings.h> -#include <FSpCompat.h> - -/* - * Forward declarations of procedures defined later in this file: - */ - -int TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp)); -static int DebuggerCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -static int WriteTextResource _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); - - -/* - *---------------------------------------------------------------------- - * - * TclplatformtestInit -- - * - * Defines commands that test platform specific functionality for - * Unix platforms. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Defines new commands. - * - *---------------------------------------------------------------------- - */ - -int -TclplatformtestInit( - Tcl_Interp *interp) /* Interpreter to add commands to. */ -{ - /* - * Add commands for platform specific tests on MacOS here. - */ - - Tcl_CreateCommand(interp, "debugger", DebuggerCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); - Tcl_CreateCommand(interp, "testWriteTextResource", WriteTextResource, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * DebuggerCmd -- - * - * This procedure simply calls the low level debugger. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -DebuggerCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Not used. */ - int argc, /* Not used. */ - char **argv) /* Not used. */ -{ - Debugger(); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WriteTextResource -- - * - * This procedure will write a text resource out to the - * application or a given file. The format for this command is - * textwriteresource - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -WriteTextResource( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - char **argv) /* Argument strings. */ -{ - char *errNum = "wrong # args: "; - char *errBad = "bad argument: "; - char *errStr; - char *fileName = NULL, *rsrcName = NULL; - char *data = NULL; - int rsrcID = -1, i, protectIt = 0; - short fileRef = -1; - OSErr err; - Handle dataHandle; - Str255 resourceName; - FSSpec fileSpec; - - /* - * Process the arguments. - */ - for (i = 1 ; i < argc ; i++) { - if (!strcmp(argv[i], "-rsrc")) { - rsrcName = argv[i + 1]; - i++; - } else if (!strcmp(argv[i], "-rsrcid")) { - rsrcID = atoi(argv[i + 1]); - i++; - } else if (!strcmp(argv[i], "-file")) { - fileName = argv[i + 1]; - i++; - } else if (!strcmp(argv[i], "-protected")) { - protectIt = 1; - } else { - data = argv[i]; - } - } - - if ((rsrcName == NULL && rsrcID < 0) || - (fileName == NULL) || (data == NULL)) { - errStr = errBad; - goto sourceFmtErr; - } - - /* - * Open the resource file. - */ - err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec); - if (!(err == noErr || err == fnfErr)) { - Tcl_AppendResult(interp, "couldn't validate file name", (char *) NULL); - return TCL_ERROR; - } - - if (err == fnfErr) { - FSpCreateResFile(&fileSpec, 'WIsH', 'rsrc', smSystemScript); - } - fileRef = FSpOpenResFile(&fileSpec, fsRdWrPerm); - if (fileRef == -1) { - Tcl_AppendResult(interp, "couldn't open resource file", (char *) NULL); - return TCL_ERROR; - } - - UseResFile(fileRef); - - /* - * Prepare data needed to create resource. - */ - if (rsrcID < 0) { - rsrcID = UniqueID('TEXT'); - } - - strcpy((char *) resourceName, rsrcName); - c2pstr((char *) resourceName); - - dataHandle = NewHandle(strlen(data)); - HLock(dataHandle); - strcpy(*dataHandle, data); - HUnlock(dataHandle); - - /* - * Add the resource to the file and close it. - */ - AddResource(dataHandle, 'TEXT', rsrcID, resourceName); - - UpdateResFile(fileRef); - if (protectIt) { - SetResAttrs(Get1Resource('TEXT', rsrcID), resProtected); - } - - CloseResFile(fileRef); - return TCL_OK; - - sourceFmtErr: - Tcl_AppendResult(interp, errStr, "error in \"", argv[0], "\"", - (char *) NULL); - return TCL_ERROR; -} diff --git a/mac/tclMacThrd.c b/mac/tclMacThrd.c deleted file mode 100644 index 75f5e35..0000000 --- a/mac/tclMacThrd.c +++ /dev/null @@ -1,822 +0,0 @@ -/* - * tclMacThrd.c -- - * - * This file implements the Mac-specific thread support. - * - * Copyright (c) 1991-1994 The Regents of the University of California. - * Copyright (c) 1994-1998 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * SCCS: @(#) tclMacThrd.c 1.2 98/02/23 16:48:07 - */ - -#include "tclInt.h" -#include "tclPort.h" -#include "tclMacInt.h" -#include <Threads.h> -#include <Gestalt.h> - -#define TCL_MAC_THRD_DEFAULT_STACK (256*1024) - - -typedef struct TclMacThrdData { - ThreadID threadID; - VOID *data; - struct TclMacThrdData *next; -} TclMacThrdData; - -/* - * This is an array of the Thread Data Keys. It is a process-wide table. - * Its size is originally set to 32, but it can grow if needed. - */ - -static TclMacThrdData **tclMacDataKeyArray; -#define TCL_MAC_INITIAL_KEYSIZE 32 - -/* - * These two bits of data store the current maximum number of keys - * and the keyCounter (which is the number of occupied slots in the - * KeyData array. - * - */ - -static int maxNumKeys = 0; -static int keyCounter = 0; - -/* - * Prototypes for functions used only in this file - */ - -TclMacThrdData *GetThreadDataStruct(Tcl_ThreadDataKey keyVal); -TclMacThrdData *RemoveThreadDataStruct(Tcl_ThreadDataKey keyVal); - -/* - *---------------------------------------------------------------------- - * - * TclMacHaveThreads -- - * - * Do we have the Thread Manager? - * - * Results: - * 1 if the ThreadManager is present, 0 otherwise. - * - * Side effects: - * If this is the first time this is called, the return is cached. - * - *---------------------------------------------------------------------- - */ - -int -TclMacHaveThreads(void) -{ - static initialized = false; - static int tclMacHaveThreads = false; - long response = 0; - OSErr err = noErr; - - if (!initialized) { - err = Gestalt(gestaltThreadMgrAttr, &response); - if (err == noErr) { - tclMacHaveThreads = response | (1 << gestaltThreadMgrPresent); - } - } - - return tclMacHaveThreads; -} - -/* - *---------------------------------------------------------------------- - * - * TclpThreadCreate -- - * - * This procedure creates a new thread. - * - * Results: - * TCL_OK if the thread could be created. The thread ID is - * returned in a parameter. - * - * Side effects: - * A new thread is created. - * - *---------------------------------------------------------------------- - */ - -int -TclpThreadCreate(idPtr, proc, clientData) - Tcl_ThreadId *idPtr; /* Return, the ID of the thread */ - Tcl_ThreadCreateProc proc; /* Main() function of the thread */ - ClientData clientData; /* The one argument to Main() */ -{ - - if (!TclMacHaveThreads()) { - return TCL_ERROR; - } - -#if TARGET_CPU_68K && TARGET_RT_MAC_CFM - { - ThreadEntryProcPtr entryProc; - entryProc = NewThreadEntryProc(proc); - - NewThread(kCooperativeThread, entryProc, (void *) clientData, - TCL_MAC_THRD_DEFAULT_STACK, kCreateIfNeeded, NULL, (ThreadID *) idPtr); - } -#else - NewThread(kCooperativeThread, proc, (void *) clientData, - TCL_MAC_THRD_DEFAULT_STACK, kCreateIfNeeded, NULL, (ThreadID *) idPtr); -#endif - if ((ThreadID) *idPtr == kNoThreadID) { - return TCL_ERROR; - } else { - return TCL_OK; - } - -} - -/* - *---------------------------------------------------------------------- - * - * TclpThreadExit -- - * - * This procedure terminates the current thread. - * - * Results: - * None. - * - * Side effects: - * This procedure terminates the current thread. - * - *---------------------------------------------------------------------- - */ - -void -TclpThreadExit(status) - int status; -{ - ThreadID curThread; - - if (!TclMacHaveThreads()) { - return; - } - - GetCurrentThread(&curThread); - DisposeThread(curThread, NULL, false); -} - - -/* - *---------------------------------------------------------------------- - * - * Tcl_GetCurrentThread -- - * - * This procedure returns the ID of the currently running thread. - * - * Results: - * A thread ID. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_ThreadId -Tcl_GetCurrentThread() -{ -#ifdef TCL_THREADS - ThreadID curThread; - - if (!TclMacHaveThreads()) { - return (Tcl_ThreadId) 0; - } else { - GetCurrentThread(&curThread); - return (Tcl_ThreadId) curThread; - } -#else - return (Tcl_ThreadId) 0; -#endif -} - - -/* - *---------------------------------------------------------------------- - * - * TclpInitLock - * - * This procedure is used to grab a lock that serializes initialization - * and finalization of Tcl. On some platforms this may also initialize - * the mutex used to serialize creation of more mutexes and thread - * local storage keys. - * - * Results: - * None. - * - * Side effects: - * Acquire the initialization mutex. - * - *---------------------------------------------------------------------- - */ - -void -TclpInitLock() -{ -#ifdef TCL_THREADS - /* There is nothing to do on the Mac. */; -#endif -} - - -/* - *---------------------------------------------------------------------- - * - * TclpInitUnlock - * - * This procedure is used to release a lock that serializes initialization - * and finalization of Tcl. - * - * Results: - * None. - * - * Side effects: - * Release the initialization mutex. - * - *---------------------------------------------------------------------- - */ - -void -TclpInitUnlock() -{ -#ifdef TCL_THREADS - /* There is nothing to do on the Mac */; -#endif -} - -/* - *---------------------------------------------------------------------- - * - * TclpMasterLock - * - * This procedure is used to grab a lock that serializes creation - * and finalization of serialization objects. This interface is - * only needed in finalization; it is hidden during - * creation of the objects. - * - * This lock must be different than the initLock because the - * initLock is held during creation of syncronization objects. - * - * Results: - * None. - * - * Side effects: - * Acquire the master mutex. - * - *---------------------------------------------------------------------- - */ - -void -TclpMasterLock() -{ -#ifdef TCL_THREADS - /* There is nothing to do on the Mac */; -#endif -} - - -/* - *---------------------------------------------------------------------- - * - * TclpMasterUnlock - * - * This procedure is used to release a lock that serializes creation - * and finalization of synchronization objects. - * - * Results: - * None. - * - * Side effects: - * Release the master mutex. - * - *---------------------------------------------------------------------- - */ - -void -TclpMasterUnlock() -{ -#ifdef TCL_THREADS - /* There is nothing to do on the Mac */ -#endif -} - - -/* - *---------------------------------------------------------------------- - * - * Tcl_GetAllocMutex - * - * This procedure returns a pointer to a statically initialized - * mutex for use by the memory allocator. The alloctor must - * use this lock, because all other locks are allocated... - * - * Results: - * A pointer to a mutex that is suitable for passing to - * Tcl_MutexLock and Tcl_MutexUnlock. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tcl_Mutex * -Tcl_GetAllocMutex() -{ - /* There is nothing to do on the Mac */ - return NULL; -} - -#ifdef TCL_THREADS - -/* - *---------------------------------------------------------------------- - * - * Tcl_MutexLock -- - * - * This procedure is invoked to lock a mutex. This procedure - * handles initializing the mutex, if necessary. The caller - * can rely on the fact that Tcl_Mutex is an opaque pointer. - * This routine will change that pointer from NULL after first use. - * - * Results: - * None. - * - * Side effects: - * May block the current thread. The mutex is aquired when - * this returns. Will allocate memory for a pthread_mutex_t - * and initialize this the first time this Tcl_Mutex is used. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_MutexLock(mutexPtr) - Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ -{ -/* There is nothing to do on the Mac */ -} - - -/* - *---------------------------------------------------------------------- - * - * TclpMutexUnlock -- - * - * This procedure is invoked to unlock a mutex. The mutex must - * have been locked by Tcl_MutexLock. - * - * Results: - * None. - * - * Side effects: - * The mutex is released when this returns. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_MutexUnlock(mutexPtr) - Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ -{ -/* There is nothing to do on the Mac */ -} - - -/* - *---------------------------------------------------------------------- - * - * TclpFinalizeMutex -- - * - * This procedure is invoked to clean up one mutex. This is only - * safe to call at the end of time. - * - * This assumes the Master Lock is held. - * - * Results: - * None. - * - * Side effects: - * The mutex list is deallocated. - * - *---------------------------------------------------------------------- - */ - -void -TclpFinalizeMutex(mutexPtr) - Tcl_Mutex *mutexPtr; -{ -/* There is nothing to do on the Mac */ -} - - -/* - *---------------------------------------------------------------------- - * - * TclpThreadDataKeyInit -- - * - * This procedure initializes a thread specific data block key. - * Each thread has table of pointers to thread specific data. - * all threads agree on which table entry is used by each module. - * this is remembered in a "data key", that is just an index into - * this table. To allow self initialization, the interface - * passes a pointer to this key and the first thread to use - * the key fills in the pointer to the key. The key should be - * a process-wide static. - * - * There is no system-wide support for thread specific data on the - * Mac. So we implement this as an array of pointers. The keys are - * allocated sequentially, and each key maps to a slot in the table. - * The table element points to a linked list of the instances of - * the data for each thread. - * - * Results: - * None. - * - * Side effects: - * Will bump the key counter if this is the first time this key - * has been initialized. May grow the DataKeyArray if that is - * necessary. - * - *---------------------------------------------------------------------- - */ - -void -TclpThreadDataKeyInit(keyPtr) - Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, - * really (pthread_key_t **) */ -{ - - if (*keyPtr == NULL) { - keyCounter += 1; - *keyPtr = (Tcl_ThreadDataKey) keyCounter; - if (keyCounter > maxNumKeys) { - TclMacThrdData **newArray; - int i, oldMax = maxNumKeys; - - maxNumKeys = maxNumKeys + TCL_MAC_INITIAL_KEYSIZE; - - newArray = (TclMacThrdData **) - ckalloc(maxNumKeys * sizeof(TclMacThrdData *)); - - for (i = 0; i < oldMax; i++) { - newArray[i] = tclMacDataKeyArray[i]; - } - for (i = oldMax; i < maxNumKeys; i++) { - newArray[i] = NULL; - } - - if (tclMacDataKeyArray != NULL) { - ckfree((char *) tclMacDataKeyArray); - } - tclMacDataKeyArray = newArray; - - } - /* TclRememberDataKey(keyPtr); */ - } -} - -/* - *---------------------------------------------------------------------- - * - * TclpThreadDataKeyGet -- - * - * This procedure returns a pointer to a block of thread local storage. - * - * Results: - * A thread-specific pointer to the data structure, or NULL - * if the memory has not been assigned to this key for this thread. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -VOID * -TclpThreadDataKeyGet(keyPtr) - Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, - * really (pthread_key_t **) */ -{ - TclMacThrdData *dataPtr; - - dataPtr = GetThreadDataStruct(*keyPtr); - - if (dataPtr == NULL) { - return NULL; - } else { - return dataPtr->data; - } -} - - -/* - *---------------------------------------------------------------------- - * - * TclpThreadDataKeySet -- - * - * This procedure sets the pointer to a block of thread local storage. - * - * Results: - * None. - * - * Side effects: - * Sets up the thread so future calls to TclpThreadDataKeyGet with - * this key will return the data pointer. - * - *---------------------------------------------------------------------- - */ - -void -TclpThreadDataKeySet(keyPtr, data) - Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, - * really (pthread_key_t **) */ - VOID *data; /* Thread local storage */ -{ - TclMacThrdData *dataPtr; - ThreadID curThread; - - dataPtr = GetThreadDataStruct(*keyPtr); - - /* - * Is it legal to reset the thread data like this? - * And if so, who owns the memory? - */ - - if (dataPtr != NULL) { - dataPtr->data = data; - } else { - dataPtr = (TclMacThrdData *) ckalloc(sizeof(TclMacThrdData)); - GetCurrentThread(&curThread); - dataPtr->threadID = curThread; - dataPtr->data = data; - dataPtr->next = tclMacDataKeyArray[(int) *keyPtr - 1]; - tclMacDataKeyArray[(int) *keyPtr - 1] = dataPtr; - } -} - -/* - *---------------------------------------------------------------------- - * - * TclpFinalizeThreadData -- - * - * This procedure cleans up the thread-local storage. This is - * called once for each thread. - * - * Results: - * None. - * - * Side effects: - * Frees up all thread local storage. - * - *---------------------------------------------------------------------- - */ - -void -TclpFinalizeThreadData(keyPtr) - Tcl_ThreadDataKey *keyPtr; -{ - TclMacThrdData *dataPtr; - - if (*keyPtr != NULL) { - dataPtr = RemoveThreadDataStruct(*keyPtr); - - if ((dataPtr != NULL) && (dataPtr->data != NULL)) { - ckfree((char *) dataPtr->data); - ckfree((char *) dataPtr); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TclpFinalizeThreadDataKey -- - * - * This procedure is invoked to clean up one key. This is a - * process-wide storage identifier. The thread finalization code - * cleans up the thread local storage itself. - * - * On the Mac, there is really nothing to do here, since the key - * is just an array index. But we set the key to 0 just in case - * someone else is relying on that. - * - * Results: - * None. - * - * Side effects: - * The keyPtr value is set to 0. - * - *---------------------------------------------------------------------- - */ - -void -TclpFinalizeThreadDataKey(keyPtr) - Tcl_ThreadDataKey *keyPtr; -{ - ckfree((char *) tclMacDataKeyArray[(int) *keyPtr - 1]); - tclMacDataKeyArray[(int) *keyPtr - 1] = NULL; - *keyPtr = NULL; -} - - -/* - *---------------------------------------------------------------------- - * - * GetThreadDataStruct -- - * - * This procedure gets the data structure corresponding to - * keyVal for the current process. - * - * Results: - * The requested key data. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TclMacThrdData * -GetThreadDataStruct(keyVal) - Tcl_ThreadDataKey keyVal; -{ - ThreadID curThread; - TclMacThrdData *dataPtr; - - /* - * The keyPtr will only be greater than keyCounter is someone - * has passed us a key without getting the value from - * TclpInitDataKey. - */ - - if ((int) keyVal <= 0) { - return NULL; - } else if ((int) keyVal > keyCounter) { - panic("illegal data key value"); - } - - GetCurrentThread(&curThread); - - for (dataPtr = tclMacDataKeyArray[(int) keyVal - 1]; dataPtr != NULL; - dataPtr = dataPtr->next) { - if (dataPtr->threadID == curThread) { - break; - } - } - - return dataPtr; -} - - -/* - *---------------------------------------------------------------------- - * - * RemoveThreadDataStruct -- - * - * This procedure removes the data structure corresponding to - * keyVal for the current process from the list kept for keyVal. - * - * Results: - * The requested key data is removed from the list, and a pointer - * to it is returned. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TclMacThrdData * -RemoveThreadDataStruct(keyVal) - Tcl_ThreadDataKey keyVal; -{ - ThreadID curThread; - TclMacThrdData *dataPtr, *prevPtr; - - - if ((int) keyVal <= 0) { - return NULL; - } else if ((int) keyVal > keyCounter) { - panic("illegal data key value"); - } - - GetCurrentThread(&curThread); - - for (dataPtr = tclMacDataKeyArray[(int) keyVal - 1], prevPtr = NULL; - dataPtr != NULL; - prevPtr = dataPtr, dataPtr = dataPtr->next) { - if (dataPtr->threadID == curThread) { - break; - } - } - - if (dataPtr == NULL) { - /* No body */ - } else if ( prevPtr == NULL) { - tclMacDataKeyArray[(int) keyVal - 1] = dataPtr->next; - } else { - prevPtr->next = dataPtr->next; - } - - return dataPtr; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_ConditionWait -- - * - * This procedure is invoked to wait on a condition variable. - * On the Mac, mutexes are no-ops, and we just yield. After - * all, it is the application's job to loop till the condition - * variable is changed... - * - * - * Results: - * None. - * - * Side effects: - * Will block the current thread till someone else yields. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_ConditionWait(condPtr, mutexPtr, timePtr) - Tcl_Condition *condPtr; /* Really (pthread_cond_t **) */ - Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ - Tcl_Time *timePtr; /* Timeout on waiting period */ -{ - if (TclMacHaveThreads()) { - YieldToAnyThread(); - } -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_ConditionNotify -- - * - * This procedure is invoked to signal a condition variable. - * - * The mutex must be held during this call to avoid races, - * but this interface does not enforce that. - * - * Results: - * None. - * - * Side effects: - * May unblock another thread. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_ConditionNotify(condPtr) - Tcl_Condition *condPtr; -{ - if (TclMacHaveThreads()) { - YieldToAnyThread(); - } -} - - -/* - *---------------------------------------------------------------------- - * - * TclpFinalizeCondition -- - * - * This procedure is invoked to clean up a condition variable. - * This is only safe to call at the end of time. - * - * This assumes the Master Lock is held. - * - * Results: - * None. - * - * Side effects: - * The condition variable is deallocated. - * - *---------------------------------------------------------------------- - */ - -void -TclpFinalizeCondition(condPtr) - Tcl_Condition *condPtr; -{ - /* Nothing to do on the Mac */ -} - - - -#endif /* TCL_THREADS */ - diff --git a/mac/tclMacThrd.h b/mac/tclMacThrd.h deleted file mode 100644 index 22f2c83..0000000 --- a/mac/tclMacThrd.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * tclUnixThrd.h -- - * - * This header file defines things for thread support. - * - * Copyright (c) 1998 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * SCCS: @(#) - */ - -#ifndef _TCLMACTHRD -#define _TCLMACTHRD - -#ifdef TCL_THREADS - -#endif /* TCL_THREADS */ -#endif /* _TCLMACTHRD */ diff --git a/mac/tclMacTime.c b/mac/tclMacTime.c deleted file mode 100644 index 1a2d1ed..0000000 --- a/mac/tclMacTime.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * tclMacTime.c -- - * - * Contains Macintosh specific versions of Tcl functions that - * obtain time values from the operating system. - * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacTime.c,v 1.3 1999/03/10 05:52:51 stanton Exp $ - */ - -#include "tclInt.h" -#include "tclPort.h" -#include <OSUtils.h> -#include <Timer.h> -#include <time.h> - -/* - * Static variables used by the TclpGetTime function. - */ - -static int initalized = false; -static unsigned long baseSeconds; -static UnsignedWide microOffset; - -/* - * Prototypes for procedures that are private to this file: - */ - -static void SubtractUnsignedWide _ANSI_ARGS_((UnsignedWide *x, - UnsignedWide *y, UnsignedWide *result)); - -/* - *----------------------------------------------------------------------------- - * - * TclpGetSeconds -- - * - * This procedure returns the number of seconds from the epoch. On - * the Macintosh the epoch is Midnight Jan 1, 1904. Unfortunatly, - * the Macintosh doesn't tie the epoch to a particular time zone. For - * Tcl we tie the epoch to GMT. This makes the time zone date parsing - * code work. The epoch for Mac-Tcl is: Midnight Jan 1, 1904 GMT. - * - * Results: - * Number of seconds from the epoch in GMT. - * - * Side effects: - * None. - * - *----------------------------------------------------------------------------- - */ - -unsigned long -TclpGetSeconds() -{ - unsigned long seconds; - MachineLocation loc; - long int offset; - - ReadLocation(&loc); - offset = loc.u.gmtDelta & 0x00ffffff; - if (offset & 0x00800000) { - offset = offset | 0xff000000; - } - - if (ReadDateTime(&seconds) == noErr) { - return (seconds - offset); - } else { - panic("Can't get time."); - return 0; - } -} - -/* - *----------------------------------------------------------------------------- - * - * TclpGetClicks -- - * - * This procedure returns a value that represents the highest resolution - * clock available on the system. There are no garantees on what the - * resolution will be. In Tcl we will call this value a "click". The - * start time is also system dependant. - * - * Results: - * Number of clicks from some start time. - * - * Side effects: - * None. - * - *----------------------------------------------------------------------------- - */ - -unsigned long -TclpGetClicks() -{ - UnsignedWide micros; - - Microseconds(µs); - return micros.lo; -} - -/* - *---------------------------------------------------------------------- - * - * TclpGetTimeZone -- - * - * Get the current time zone. - * - * Results: - * The return value is the local time zone, measured in - * minutes away from GMT (-ve for east, +ve for west). - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclpGetTimeZone ( - unsigned long currentTime) /* Ignored on Mac. */ -{ - MachineLocation loc; - long int offset; - - ReadLocation(&loc); - offset = loc.u.gmtDelta & 0x00ffffff; - if (offset & 0x00700000) { - offset |= 0xff000000; - } - - /* - * Convert the Mac offset from seconds to minutes and - * add an hour if we have daylight savings time. - */ - offset = -offset; - offset /= 60; - if (loc.u.dlsDelta < 0) { - offset += 60; - } - - return offset; -} - -/* - *---------------------------------------------------------------------- - * - * TclpGetTime -- - * - * Gets the current system time in seconds and microseconds - * since the beginning of the epoch: 00:00 UCT, January 1, 1970. - * - * Results: - * Returns the current time (in the local timezone) in timePtr. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TclpGetTime( - Tcl_Time *timePtr) /* Location to store time information. */ -{ - UnsignedWide micro; -#ifndef NO_LONG_LONG - long long *microPtr; -#endif - - if (initalized == false) { - MachineLocation loc; - long int offset; - - ReadLocation(&loc); - offset = loc.u.gmtDelta & 0x00ffffff; - if (offset & 0x00800000) { - offset = offset | 0xff000000; - } - if (ReadDateTime(&baseSeconds) != noErr) { - /* - * This should never happen! - */ - return; - } - /* - * Remove the local offset that ReadDateTime() adds. - */ - baseSeconds -= offset; - Microseconds(µOffset); - initalized = true; - } - - Microseconds(µ); - -#ifndef NO_LONG_LONG - microPtr = (long long *) µ - *microPtr -= *((long long *) µOffset); - timePtr->sec = baseSeconds + (*microPtr / 1000000); - timePtr->usec = *microPtr % 1000000; -#else - SubtractUnsignedWide(µ, µOffset, µ); - - /* - * This lovely computation is equal to: base + (micro / 1000000) - * For the .hi part the ratio of 0x100000000 / 1000000 has been - * reduced to avoid overflow. This computation certainly has - * problems as the .hi part gets large. However, your application - * would have to run for a long time to make that happen. - */ - - timePtr->sec = baseSeconds + (micro.lo / 1000000) + - (long) (micro.hi * ((double) 33554432.0 / 15625.0)); - timePtr->usec = micro.lo % 1000000; -#endif -} - -/* - *---------------------------------------------------------------------- - * - * TclpGetDate -- - * - * Converts raw seconds to a struct tm data structure. The - * returned time will be for Greenwich Mean Time if the useGMT flag - * is set. Otherwise, the returned time will be for the local - * time zone. This function is meant to be used as a replacement - * for localtime and gmtime which is broken on most ANSI libs - * on the Macintosh. - * - * Results: - * None. - * - * Side effects: - * The passed in struct tm data structure is modified. - * - *---------------------------------------------------------------------- - */ - -struct tm * -TclpGetDate( - TclpTime_t time, /* Time struct to fill. */ - int useGMT) /* True if date should reflect GNT time. */ -{ - const time_t *tp = (const time_t *)time; - DateTimeRec dtr; - MachineLocation loc; - long int offset; - static struct tm statictime; - static const short monthday[12] = - {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - - ReadLocation(&loc); - - if (useGMT) { - SecondsToDate(*tp, &dtr); - } else { - offset = loc.u.gmtDelta & 0x00ffffff; - if (offset & 0x00700000) { - offset |= 0xff000000; - } - - SecondsToDate(*tp + offset, &dtr); - } - - statictime.tm_sec = dtr.second; - statictime.tm_min = dtr.minute; - statictime.tm_hour = dtr.hour; - statictime.tm_mday = dtr.day; - statictime.tm_mon = dtr.month - 1; - statictime.tm_year = dtr.year - 1900; - statictime.tm_wday = dtr.dayOfWeek - 1; - statictime.tm_yday = monthday[statictime.tm_mon] - + statictime.tm_mday - 1; - if (1 < statictime.tm_mon && !(statictime.tm_year & 3)) { - ++statictime.tm_yday; - } - statictime.tm_isdst = loc.u.dlsDelta; - return(&statictime); -} - -#ifdef NO_LONG_LONG -/* - *---------------------------------------------------------------------- - * - * SubtractUnsignedWide -- - * - * Subtracts one UnsignedWide value from another. - * - * Results: - * The subtracted value. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -SubtractUnsignedWide( - UnsignedWide *x, /* Ptr to wide int. */ - UnsignedWide *y, /* Ptr to wide int. */ - UnsignedWide *result) /* Ptr to result. */ -{ - result->hi = x->hi - y->hi; - if (x->lo < y->lo) { - result->hi--; - } - result->lo = x->lo - y->lo; -} -#endif diff --git a/mac/tclMacUnix.c b/mac/tclMacUnix.c deleted file mode 100644 index 483780c..0000000 --- a/mac/tclMacUnix.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * tclMacUnix.c -- - * - * This file contains routines to implement several features - * available to the Unix implementation, but that require - * extra work to do on a Macintosh. These include routines - * Unix Tcl normally hands off to the Unix OS. - * - * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center - * Copyright (c) 1994-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacUnix.c,v 1.3 1999/04/16 00:47:22 stanton Exp $ - */ - -#include <Files.h> -#include <Strings.h> -#include <TextUtils.h> -#include <Finder.h> -#include <FSpCompat.h> -#include <Aliases.h> -#include <Errors.h> - -#include "tclInt.h" -#include "tclMacInt.h" - -/* - * The following two Includes are from the More Files package - */ -#include "FileCopy.h" -#include "MoreFiles.h" -#include "MoreFilesExtras.h" - -/* - * The following may not be defined in some versions of - * MPW header files. - */ -#ifndef kIsInvisible -#define kIsInvisible 0x4000 -#endif -#ifndef kIsAlias -#define kIsAlias 0x8000 -#endif - -/* - * Missing error codes - */ -#define usageErr 500 -#define noSourceErr 501 -#define isDirErr 502 - - -/* - *---------------------------------------------------------------------- - * - * Tcl_EchoCmd -- - * - * Implements the TCL echo command: - * echo ?str ...? - * - * Results: - * Always returns TCL_OK. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_EchoCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - char **argv) /* Argument strings. */ -{ - Tcl_Channel chan; - int mode, result, i; - - chan = Tcl_GetChannel(interp, "stdout", &mode); - if (chan == (Tcl_Channel) NULL) { - return TCL_ERROR; - } - for (i = 1; i < argc; i++) { - result = Tcl_WriteChars(chan, argv[i], -1); - if (result < 0) { - Tcl_AppendResult(interp, "echo: ", Tcl_GetChannelName(chan), - ": ", Tcl_PosixError(interp), (char *) NULL); - return TCL_ERROR; - } - if (i < (argc - 1)) { - Tcl_WriteChars(chan, " ", -1); - } - } - Tcl_WriteChars(chan, "\n", -1); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_LsObjCmd -- - * - * This procedure is invoked to process the "ls" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ -int -Tcl_LsObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument strings. */ -{ -#define STRING_LENGTH 80 -#define CR '\n' - int i, j; - int fieldLength, len = 0, maxLen = 0, perLine; - OSErr err; - CInfoPBRec paramBlock; - HFileInfo *hpb = (HFileInfo *)¶mBlock; - DirInfo *dpb = (DirInfo *)¶mBlock; - char theFile[256]; - char theLine[STRING_LENGTH + 2]; - int fFlag = false, pFlag = false, aFlag = false, lFlag = false, - cFlag = false, hFlag = false; - char *argv; - Tcl_Obj *newObjv[2], *resultObjPtr; - - /* - * Process command flags. End if argument doesn't start - * with a dash or is a dash by itself. The remaining arguments - * should be files. - */ - for (i = 1; i < objc; i++) { - argv = Tcl_GetString(objv[i]); - if (argv[0] != '-') { - break; - } - - if (!strcmp(argv, "-")) { - i++; - break; - } - - for (j = 1 ; argv[j] ; ++j) { - switch(argv[j]) { - case 'a': - case 'A': - aFlag = true; - break; - case '1': - cFlag = false; - break; - case 'C': - cFlag = true; - break; - case 'F': - fFlag = true; - break; - case 'H': - hFlag = true; - break; - case 'p': - pFlag = true; - break; - case 'l': - pFlag = false; - lFlag = true; - break; - default: - Tcl_AppendResult(interp, "error - unknown flag ", - "usage: ls -apCFHl1 ?files? ", NULL); - return TCL_ERROR; - } - } - } - - objv += i; - objc -= i; - - /* - * No file specifications means we search for all files. - * Glob will be doing most of the work. - */ - if (!objc) { - objc = 1; - newObjv[0] = Tcl_NewStringObj("*", -1); - newObjv[1] = NULL; - objv = newObjv; - } - - if (Tcl_GlobObjCmd(NULL, interp, objc + 1, objv - 1) != TCL_OK) { - Tcl_ResetResult(interp); - return TCL_ERROR; - } - - resultObjPtr = Tcl_GetObjResult(interp); - Tcl_IncrRefCount(resultObjPtr); - if (Tcl_ListObjGetElements(interp, resultObjPtr, &objc, &objv) != TCL_OK) { - Tcl_DecrRefCount(resultObjPtr); - return TCL_ERROR; - } - - Tcl_ResetResult(interp); - - /* - * There are two major methods for listing files: the long - * method and the normal method. - */ - if (lFlag) { - char creator[5], type[5], time[16], date[16]; - char lineTag; - long size; - unsigned short flags; - Tcl_Obj *objPtr; - char *string; - int length; - - /* - * Print the header for long listing. - */ - if (hFlag) { - sprintf(theLine, "T %7s %8s %8s %4s %4s %6s %s", - "Size", "ModTime", "ModDate", - "CRTR", "TYPE", "Flags", "Name"); - Tcl_AppendResult(interp, theLine, "\n", NULL); - Tcl_AppendResult(interp, - "-------------------------------------------------------------\n", - NULL); - } - - for (i = 0; i < objc; i++) { - strcpy(theFile, Tcl_GetString(objv[i])); - - c2pstr(theFile); - hpb->ioCompletion = NULL; - hpb->ioVRefNum = 0; - hpb->ioFDirIndex = 0; - hpb->ioNamePtr = (StringPtr) theFile; - hpb->ioDirID = 0L; - err = PBGetCatInfoSync(¶mBlock); - p2cstr((StringPtr) theFile); - - if (hpb->ioFlAttrib & 16) { - /* - * For directories use zero as the size, use no Creator - * type, and use 'DIR ' as the file type. - */ - if ((aFlag == false) && (dpb->ioDrUsrWds.frFlags & 0x1000)) { - continue; - } - lineTag = 'D'; - size = 0; - IUTimeString(dpb->ioDrMdDat, false, (unsigned char *)time); - p2cstr((StringPtr)time); - IUDateString(dpb->ioDrMdDat, shortDate, (unsigned char *)date); - p2cstr((StringPtr)date); - strcpy(creator, " "); - strcpy(type, "DIR "); - flags = dpb->ioDrUsrWds.frFlags; - if (fFlag || pFlag) { - strcat(theFile, ":"); - } - } else { - /* - * All information for files should be printed. This - * includes size, modtime, moddate, creator type, file - * type, flags, anf file name. - */ - if ((aFlag == false) && - (hpb->ioFlFndrInfo.fdFlags & kIsInvisible)) { - continue; - } - lineTag = 'F'; - size = hpb->ioFlLgLen + hpb->ioFlRLgLen; - IUTimeString(hpb->ioFlMdDat, false, (unsigned char *)time); - p2cstr((StringPtr)time); - IUDateString(hpb->ioFlMdDat, shortDate, (unsigned char *)date); - p2cstr((StringPtr)date); - strncpy(creator, (char *) &hpb->ioFlFndrInfo.fdCreator, 4); - creator[4] = 0; - strncpy(type, (char *) &hpb->ioFlFndrInfo.fdType, 4); - type[4] = 0; - flags = hpb->ioFlFndrInfo.fdFlags; - if (fFlag) { - if (hpb->ioFlFndrInfo.fdFlags & kIsAlias) { - strcat(theFile, "@"); - } else if (hpb->ioFlFndrInfo.fdType == 'APPL') { - strcat(theFile, "*"); - } - } - } - - sprintf(theLine, "%c %7ld %8s %8s %-4.4s %-4.4s 0x%4.4X %s", - lineTag, size, time, date, creator, type, flags, theFile); - - Tcl_AppendResult(interp, theLine, "\n", NULL); - - } - - objPtr = Tcl_GetObjResult(interp); - string = Tcl_GetStringFromObj(objPtr, &length); - if ((length > 0) && (string[length - 1] == '\n')) { - Tcl_SetObjLength(objPtr, length - 1); - } - } else { - /* - * Not in long format. We only print files names. If the - * -C flag is set we need to print in multiple coloumns. - */ - int argCount, linePos; - Boolean needNewLine = false; - - /* - * Fiend the field length: the length each string printed - * to the terminal will be. - */ - if (!cFlag) { - perLine = 1; - fieldLength = STRING_LENGTH; - } else { - for (i = 0; i < objc; i++) { - argv = Tcl_GetString(objv[i]); - len = strlen(argv); - if (len > maxLen) { - maxLen = len; - } - } - fieldLength = maxLen + 3; - perLine = STRING_LENGTH / fieldLength; - } - - argCount = 0; - linePos = 0; - memset(theLine, ' ', STRING_LENGTH); - while (argCount < objc) { - strcpy(theFile, Tcl_GetString(objv[argCount])); - - c2pstr(theFile); - hpb->ioCompletion = NULL; - hpb->ioVRefNum = 0; - hpb->ioFDirIndex = 0; - hpb->ioNamePtr = (StringPtr) theFile; - hpb->ioDirID = 0L; - err = PBGetCatInfoSync(¶mBlock); - p2cstr((StringPtr) theFile); - - if (hpb->ioFlAttrib & 16) { - /* - * Directory. If -a show hidden files. If -f or -p - * denote that this is a directory. - */ - if ((aFlag == false) && (dpb->ioDrUsrWds.frFlags & 0x1000)) { - argCount++; - continue; - } - if (fFlag || pFlag) { - strcat(theFile, ":"); - } - } else { - /* - * File: If -a show hidden files, if -f show links - * (aliases) and executables (APPLs). - */ - if ((aFlag == false) && - (hpb->ioFlFndrInfo.fdFlags & kIsInvisible)) { - argCount++; - continue; - } - if (fFlag) { - if (hpb->ioFlFndrInfo.fdFlags & kIsAlias) { - strcat(theFile, "@"); - } else if (hpb->ioFlFndrInfo.fdType == 'APPL') { - strcat(theFile, "*"); - } - } - } - - /* - * Print the item, taking into account multi- - * coloum output. - */ - strncpy(theLine + (linePos * fieldLength), theFile, - strlen(theFile)); - linePos++; - - if (linePos == perLine) { - theLine[STRING_LENGTH] = '\0'; - if (needNewLine) { - Tcl_AppendResult(interp, "\n", theLine, NULL); - } else { - Tcl_AppendResult(interp, theLine, NULL); - needNewLine = true; - } - linePos = 0; - memset(theLine, ' ', STRING_LENGTH); - } - - argCount++; - } - - if (linePos != 0) { - theLine[STRING_LENGTH] = '\0'; - if (needNewLine) { - Tcl_AppendResult(interp, "\n", theLine, NULL); - } else { - Tcl_AppendResult(interp, theLine, NULL); - } - } - } - - Tcl_DecrRefCount(resultObjPtr); - - return TCL_OK; -} diff --git a/mac/tclMacUtil.c b/mac/tclMacUtil.c deleted file mode 100644 index fd981c9..0000000 --- a/mac/tclMacUtil.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * tclMacUtil.c -- - * - * This contains utility functions used to help with - * implementing Macintosh specific portions of the Tcl port. - * - * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center - * Copyright (c) 1995-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclMacUtil.c,v 1.3 1998/11/10 06:49:55 jingham Exp $ - */ - -#include "tcl.h" -#include "tclInt.h" -#include "tclMacInt.h" -#include "tclMath.h" -#include "tclMacPort.h" - -#include <Aliases.h> -#include <Errors.h> -#include <Files.h> -#include <Folders.h> -#include <FSpCompat.h> -#include <Strings.h> -#include <TextUtils.h> -#include <MoreFilesExtras.h> - -/* - * The following two Includes are from the More Files package. - */ -#include <FileCopy.h> -#include <MoreFiles.h> - -/* - *---------------------------------------------------------------------- - * - * hypotd -- - * - * The standard math function hypot is not supported by Think C. - * It is included here so everything works. It is supported by - * CodeWarrior Pro 1, but the 68K version does not support doubles. - * So we hack it in. - * - * Results: - * Result of computation. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -#if defined(THINK_C) || defined(__MWERKS__) -double hypotd(double x, double y); - -double -hypotd( - double x, /* X value */ - double y) /* Y value */ -{ - double sum; - - sum = x*x + y*y; - return sqrt(sum); -} -#endif - -/* - *---------------------------------------------------------------------- - * - * FSpGetDefaultDir -- - * - * This function gets the current default directory. - * - * Results: - * The provided FSSpec is changed to point to the "default" - * directory. The function returns what ever errors - * FSMakeFSSpecCompat may encounter. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -FSpGetDefaultDir( - FSSpecPtr dirSpec) /* On return the default directory. */ -{ - OSErr err; - short vRefNum = 0; - long int dirID = 0; - - err = HGetVol(NULL, &vRefNum, &dirID); - - if (err == noErr) { - err = FSMakeFSSpecCompat(vRefNum, dirID, (ConstStr255Param) NULL, - dirSpec); - } - - return err; -} - -/* - *---------------------------------------------------------------------- - * - * FSpSetDefaultDir -- - * - * This function sets the default directory to the directory - * pointed to by the provided FSSpec. - * - * Results: - * The function returns what ever errors HSetVol may encounter. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -FSpSetDefaultDir( - FSSpecPtr dirSpec) /* The new default directory. */ -{ - OSErr err; - - /* - * The following special case is needed to work around a bug - * in the Macintosh OS. (Acutally PC Exchange.) - */ - - if (dirSpec->parID == fsRtParID) { - err = HSetVol(NULL, dirSpec->vRefNum, fsRtDirID); - } else { - err = HSetVol(dirSpec->name, dirSpec->vRefNum, dirSpec->parID); - } - - return err; -} - -/* - *---------------------------------------------------------------------- - * - * FSpFindFolder -- - * - * This function is a version of the FindFolder function that - * returns the result as a FSSpec rather than a vRefNum and dirID. - * - * Results: - * Results will be simaler to that of the FindFolder function. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -OSErr -FSpFindFolder( - short vRefNum, /* Volume reference number. */ - OSType folderType, /* Folder type taken by FindFolder. */ - Boolean createFolder, /* Should we create it if non-existant. */ - FSSpec *spec) /* Pointer to resulting directory. */ -{ - short foundVRefNum; - long foundDirID; - OSErr err; - - err = FindFolder(vRefNum, folderType, createFolder, - &foundVRefNum, &foundDirID); - if (err != noErr) { - return err; - } - - err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec); - return err; -} - -/* - *---------------------------------------------------------------------- - * - * FSpLocationFromPath -- - * - * This function obtains an FSSpec for a given macintosh path. - * Unlike the More Files function FSpLocationFromFullPath, this - * function will also accept partial paths and resolve any aliases - * along the path. - * - * Results: - * OSErr code. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -FSpLocationFromPath( - int length, /* Length of path. */ - CONST char *path, /* The path to convert. */ - FSSpecPtr fileSpecPtr) /* On return the spec for the path. */ -{ - Str255 fileName; - OSErr err; - short vRefNum; - long dirID; - int pos, cur; - Boolean isDirectory; - Boolean wasAlias; - - /* - * Check to see if this is a full path. If partial - * we assume that path starts with the current working - * directory. (Ie. volume & dir = 0) - */ - vRefNum = 0; - dirID = 0; - cur = 0; - if (length == 0) { - return fnfErr; - } - if (path[cur] == ':') { - cur++; - if (cur >= length) { - /* - * If path = ":", just return current directory. - */ - FSMakeFSSpecCompat(0, 0, NULL, fileSpecPtr); - return noErr; - } - } else { - while (path[cur] != ':' && cur < length) { - cur++; - } - if (cur > 255) { - return bdNamErr; - } - if (cur < length) { - /* - * This is a full path - */ - cur++; - strncpy((char *) fileName + 1, path, cur); - fileName[0] = cur; - err = FSMakeFSSpecCompat(0, 0, fileName, fileSpecPtr); - if (err != noErr) return err; - FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); - vRefNum = fileSpecPtr->vRefNum; - } else { - cur = 0; - } - } - - isDirectory = 1; - while (cur < length) { - if (!isDirectory) { - return dirNFErr; - } - pos = cur; - while (path[pos] != ':' && pos < length) { - pos++; - } - if (pos == cur) { - /* Move up one dir */ - /* cur++; */ - strcpy((char *) fileName + 1, "::"); - fileName[0] = 2; - } else if (pos - cur > 255) { - return bdNamErr; - } else { - strncpy((char *) fileName + 1, &path[cur], pos - cur); - fileName[0] = pos - cur; - } - err = FSMakeFSSpecCompat(vRefNum, dirID, fileName, fileSpecPtr); - if (err != noErr) return err; - err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias); - if (err != noErr) return err; - FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); - vRefNum = fileSpecPtr->vRefNum; - cur = pos; - if (path[cur] == ':') { - cur++; - } - } - - return noErr; -} - -/* - *---------------------------------------------------------------------- - * - * FSpPathFromLocation -- - * - * This function obtains a full path name for a given macintosh - * FSSpec. Unlike the More Files function FSpGetFullPath, this - * function will return a C string in the Handle. It also will - * create paths for FSSpec that do not yet exist. - * - * Results: - * OSErr code. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -OSErr -FSpPathFromLocation( - FSSpec *spec, /* The location we want a path for. */ - int *length, /* Length of the resulting path. */ - Handle *fullPath) /* Handle to path. */ -{ - OSErr err; - FSSpec tempSpec; - CInfoPBRec pb; - - *fullPath = NULL; - - /* - * Make a copy of the input FSSpec that can be modified. - */ - BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); - - if (tempSpec.parID == fsRtParID) { - /* - * The object is a volume. Add a colon to make it a full - * pathname. Allocate a handle for it and we are done. - */ - tempSpec.name[0] += 2; - tempSpec.name[tempSpec.name[0] - 1] = ':'; - tempSpec.name[tempSpec.name[0]] = '\0'; - - err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); - } else { - /* - * The object isn't a volume. Is the object a file or a directory? - */ - pb.dirInfo.ioNamePtr = tempSpec.name; - pb.dirInfo.ioVRefNum = tempSpec.vRefNum; - pb.dirInfo.ioDrDirID = tempSpec.parID; - pb.dirInfo.ioFDirIndex = 0; - err = PBGetCatInfoSync(&pb); - - if ((err == noErr) || (err == fnfErr)) { - /* - * If the file doesn't currently exist we start over. If the - * directory exists everything will work just fine. Otherwise we - * will just fail later. If the object is a directory, append a - * colon so full pathname ends with colon. - */ - if (err == fnfErr) { - BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); - } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) { - tempSpec.name[0] += 1; - tempSpec.name[tempSpec.name[0]] = ':'; - } - - /* - * Create a new Handle for the object - make it a C string. - */ - tempSpec.name[0] += 1; - tempSpec.name[tempSpec.name[0]] = '\0'; - err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); - if (err == noErr) { - /* - * Get the ancestor directory names - loop until we have an - * error or find the root directory. - */ - pb.dirInfo.ioNamePtr = tempSpec.name; - pb.dirInfo.ioVRefNum = tempSpec.vRefNum; - pb.dirInfo.ioDrParID = tempSpec.parID; - do { - pb.dirInfo.ioFDirIndex = -1; - pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; - err = PBGetCatInfoSync(&pb); - if (err == noErr) { - /* - * Append colon to directory name and add - * directory name to beginning of fullPath. - */ - ++tempSpec.name[0]; - tempSpec.name[tempSpec.name[0]] = ':'; - - (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], - tempSpec.name[0]); - err = MemError(); - } - } while ( (err == noErr) && - (pb.dirInfo.ioDrDirID != fsRtDirID) ); - } - } - } - - /* - * On error Dispose the handle, set it to NULL & return the err. - * Otherwise, set the length & return. - */ - if (err == noErr) { - *length = GetHandleSize(*fullPath) - 1; - } else { - if ( *fullPath != NULL ) { - DisposeHandle(*fullPath); - } - *fullPath = NULL; - *length = 0; - } - - return err; -} - -/* - *---------------------------------------------------------------------- - * - * GetGlobalMouse -- - * - * This procedure obtains the current mouse position in global - * coordinates. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -GetGlobalMouse( - Point *mouse) /* Mouse position. */ -{ - EventRecord event; - - OSEventAvail(0, &event); - *mouse = event.where; -} |
