summaryrefslogtreecommitdiffstats
path: root/mac
diff options
context:
space:
mode:
Diffstat (limited to 'mac')
-rw-r--r--mac/AppleScript.html298
-rw-r--r--mac/Background.doc92
-rw-r--r--mac/MW_TclAppleScriptHeader.pch47
-rw-r--r--mac/MW_TclHeader.pch49
-rw-r--r--mac/README78
-rw-r--r--mac/bugs.doc37
-rw-r--r--mac/libmoto.doc39
-rw-r--r--mac/morefiles.doc74
-rw-r--r--mac/porting.notes23
-rw-r--r--mac/tclMac.h38
-rw-r--r--mac/tclMacAETE.r58
-rw-r--r--mac/tclMacAlloc.c348
-rw-r--r--mac/tclMacAppInit.c212
-rw-r--r--mac/tclMacApplication.r75
-rw-r--r--mac/tclMacBOAAppInit.c257
-rw-r--r--mac/tclMacBOAMain.c361
-rw-r--r--mac/tclMacChan.c1394
-rwxr-xr-xmac/tclMacCommonPch.h88
-rw-r--r--mac/tclMacDNR.c23
-rw-r--r--mac/tclMacEnv.c536
-rw-r--r--mac/tclMacExit.c333
-rw-r--r--mac/tclMacFCmd.c1551
-rw-r--r--mac/tclMacFile.c921
-rw-r--r--mac/tclMacInit.c752
-rw-r--r--mac/tclMacInt.h74
-rw-r--r--mac/tclMacInterupt.c289
-rw-r--r--mac/tclMacLibrary.c241
-rw-r--r--mac/tclMacLibrary.r221
-rw-r--r--mac/tclMacLoad.c284
-rw-r--r--mac/tclMacMSLPrefix.h24
-rw-r--r--mac/tclMacMath.h145
-rw-r--r--mac/tclMacNotify.c580
-rw-r--r--mac/tclMacOSA.c2945
-rw-r--r--mac/tclMacOSA.exp1
-rw-r--r--mac/tclMacOSA.r76
-rw-r--r--mac/tclMacPanic.c235
-rw-r--r--mac/tclMacPort.h292
-rw-r--r--mac/tclMacProjects.sea.hqx1
-rw-r--r--mac/tclMacResource.c2210
-rw-r--r--mac/tclMacResource.r90
-rw-r--r--mac/tclMacShLib.exp1066
-rw-r--r--mac/tclMacSock.c2665
-rw-r--r--mac/tclMacTclCode.r37
-rw-r--r--mac/tclMacTest.c213
-rw-r--r--mac/tclMacThrd.c822
-rw-r--r--mac/tclMacThrd.h20
-rw-r--r--mac/tclMacTime.c313
-rw-r--r--mac/tclMacUnix.c425
-rw-r--r--mac/tclMacUtil.c441
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(&currentDir);
- FSpPathFromLocation(&currentDir, &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(&paramBlock, 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(&paramBlock, 0);
- } else {
- err = PBHRstFLock(&paramBlock, 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(&notifier, 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(&currentMouse);
- 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(&currentMouse);
- 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(&notifier.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(&currentMouse);
- 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&LTa"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&#0%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 +$VX&#1NMDr5LMfVd"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&GTeQ+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!+Thi&#6Jl2`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[&#8cH"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*&GTreF*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&#1!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,&GTkF&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(&micros);
- 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(&microOffset);
- initalized = true;
- }
-
- Microseconds(&micro);
-
-#ifndef NO_LONG_LONG
- microPtr = (long long *) &micro;
- *microPtr -= *((long long *) &microOffset);
- timePtr->sec = baseSeconds + (*microPtr / 1000000);
- timePtr->usec = *microPtr % 1000000;
-#else
- SubtractUnsignedWide(&micro, &microOffset, &micro);
-
- /*
- * 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 *)&paramBlock;
- DirInfo *dpb = (DirInfo *)&paramBlock;
- char theFile[256];
- char theLine[STRING_LENGTH + 2];
- int fFlag = false, pFlag = false, aFlag = false, lFlag = false,
- cFlag = false, hFlag = false;
- char *argv;
- Tcl_Obj *newObjv[2], *resultObjPtr;
-
- /*
- * Process command flags. End if argument doesn't start
- * with a dash or is a dash by itself. The remaining arguments
- * should be files.
- */
- for (i = 1; i < objc; i++) {
- argv = Tcl_GetString(objv[i]);
- if (argv[0] != '-') {
- break;
- }
-
- if (!strcmp(argv, "-")) {
- i++;
- break;
- }
-
- for (j = 1 ; argv[j] ; ++j) {
- switch(argv[j]) {
- case 'a':
- case 'A':
- aFlag = true;
- break;
- case '1':
- cFlag = false;
- break;
- 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(&paramBlock);
- 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(&paramBlock);
- 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;
-}