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.doc32
-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.c1535
-rw-r--r--mac/tclMacFile.c918
-rw-r--r--mac/tclMacInit.c752
-rw-r--r--mac/tclMacInt.h61
-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.c554
-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.c2637
-rw-r--r--mac/tclMacTclCode.r36
-rw-r--r--mac/tclMacTest.c213
-rw-r--r--mac/tclMacThrd.c795
-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, 21275 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 c7569cc..0000000
--- a/mac/README
+++ /dev/null
@@ -1,78 +0,0 @@
-Tcl 8.2 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.8 1999/06/25 23:29:53 welch Exp $
-
-1. Introduction
----------------
-
-This is the README file for the Macintosh version of the Tcl
-scripting language. The home page for the Macintosh releases is
- http://www.scriptics.com/mac/
-
-A summary of what's new in this release is at
- http://www.scriptics.com/software/whatsnew82.html
-
-A summary of Macintosh-specific features is at
- http://www.scriptics.com/mac/features.html
-
-
-2. The Distribution
--------------------
-
-Macintosh Tcl is distributed in three different forms. This
-should make it easier to only download what you need. The
-packages are as follows:
-
-mactk8.2.sea.hqx
-
- This distribution is a "binary" only release. It contains an
- installer program that will install a 68k, PowerPC, or Fat
- version of the "Tcl Shell" and "Wish" applications. In addition,
- it installs the Tcl & Tk libraries in the Extensions folder inside
- your System Folder.
-
-mactcltk-full-8.2.sea.hqx
-
- This release contains the full release of Tcl and Tk for the
- Macintosh plus the More Files packages which Macintosh Tcl and Tk
- rely on.
-
-mactcl-source-8.2.sea.hqx
-
- This release contains the complete source for Tcl 8.2. In
- addition, Metrowerks CodeWarrior libraries and project files
- are included. However, you must already have the More Files
- package to compile this code.
-
-The "html" subdirectory contains reference documentation in
-in the HTML format. You may also find these pages at:
-
- http://www.scriptics.com/man/tcl8.2/contents.html
-
-3. Compiling Tcl
-----------------
-
-In order to compile Macintosh Tcl you must have the
-following items:
-
- CodeWarrior Pro 2 or 3
- Mac Tcl 8.1 (source)
- More Files 1.4.3
-
-The included project files should work fine. However, for
-current release notes please check this page:
-
- http://www.scriptics.com/support/howto/compile.html#mac
-
-If you have comments or Bug reports send them to:
-Jim Ingham
-jingham@cygnus.com
-
diff --git a/mac/bugs.doc b/mac/bugs.doc
deleted file mode 100644
index 3e1efb9..0000000
--- a/mac/bugs.doc
+++ /dev/null
@@ -1,32 +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.2 1998/09/14 18:40:04 stanton Exp $
-
-This was a new feature as of Tcl7.6b1 and as such I'll started with
-a clean slate. I currently know of no reproducable bugs. I often
-get vague reports - but nothing I've been able to confirm. Let
-me know what bugs you find!
-
-The Macintosh version of Tcl passes most all tests in the Tcl
-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!
-
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 21e013e..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.2 1998/09/14 18:40:04 stanton 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 © Sun Microsystems"
-};
-
-resource 'vers' (2) {
- TCL_MAJOR_VERSION, MINOR_VERSION,
- RELEASE_LEVEL, 0x00, verUS,
- TCL_PATCH_LEVEL,
- "Tcl Shell " TCL_PATCH_LEVEL " © 1996"
-};
-
-#define TCL_APP_CREATOR 'Tcl '
-
-type TCL_APP_CREATOR as 'STR ';
-resource TCL_APP_CREATOR (0, purgeable) {
- "Tcl Shell " TCL_PATCH_LEVEL " © 1996"
-};
-
-/*
- * 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 dbd0680..0000000
--- a/mac/tclMacFCmd.c
+++ /dev/null
@@ -1,1535 +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.5 1999/05/11 07:12:00 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. */
- Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
-{
- OSErr err;
- FSSpec fileSpec;
- FInfo finfo;
-
- err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);
-
- 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. */
- Tcl_Obj **readOnlyPtrPtr) /* A pointer to return the object with. */
-{
- OSErr err;
- FSSpec fileSpec;
- CInfoPBRec paramBlock;
-
- err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);
-
- 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. */
- Tcl_Obj *attributePtr) /* The command line object. */
-{
- OSErr err;
- FSSpec fileSpec;
- FInfo finfo;
-
- err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);
-
- 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. */
- Tcl_Obj *readOnlyPtr) /* The command line object. */
-{
- OSErr err;
- FSSpec fileSpec;
- HParamBlockRec paramBlock;
- int hidden;
-
- err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec);
-
- 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 45e0181..0000000
--- a/mac/tclMacFile.c
+++ /dev/null
@@ -1,918 +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.7 1999/05/11 07:12:09 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 *dirName, *patternEnd = tail;
- char savedChar;
- int result = TCL_OK;
- int baseLength = Tcl_DStringLength(dirPtr);
- CInfoPBRec pb;
- OSErr err;
- FSSpec dirSpec;
- Boolean isDirectory;
- long dirID;
- short itemIndex;
- Str255 fileName;
- Tcl_DString fileString;
-
- /*
- * Make sure that the directory part of the name really is a
- * directory.
- */
-
- dirName = dirPtr->string;
- FSpLocationFromPath(strlen(dirName), dirName, &dirSpec);
- 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 9e94e61..0000000
--- a/mac/tclMacInt.h
+++ /dev/null
@@ -1,61 +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.5 1999/05/11 07:12:19 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
- */
-
-#define TCL_MAC_68K_STACK_GROWTH (256*1024)
-#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 ea84b9d..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 oepn 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.2 1998/09/14 18:40:05 stanton 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 eda1f7f..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.3 1999/04/16 00:47:20 stanton 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 © Sun Microsystems"
-};
-
-resource 'vers' (2) {
- TCL_MAJOR_VERSION, MINOR_VERSION,
- RELEASE_LEVEL, 0x00, verUS,
- TCL_PATCH_LEVEL,
- "Tcl Library " TCL_PATCH_LEVEL " © 1996"
-};
-
-/*
- * 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"
-};
-
-/*
- * 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 622eb65..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.3 1999/04/16 00:47:20 stanton 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(fileName), fileName, &fileSpec);
- Tcl_DStringFree(&ds);
-
- if (err != noErr) {
- Tcl_SetResult(interp, "could not locate shared library", TCL_STATIC);
- return TCL_ERROR;
- }
-
- /*
- * See if this fragment has a 'cfrg' resource. It will tell us where
- * to look for the fragment in the file. If it doesn't exist we will
- * assume we have a ppc frag using the whole data fork. If it does
- * exist we find the frag that matches the one we are looking for and
- * get the offset and size from the resource.
- */
-
- saveFileRef = CurResFile();
- SetResLoad(false);
- fragFileRef = FSpOpenResFile(&fileSpec, fsRdPerm);
- SetResLoad(true);
- if (fragFileRef != -1) {
- UseResFile(fragFileRef);
- fragResource = Get1Resource(kCFragResourceType, kCFragResourceID);
- 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 773490f..0000000
--- a/mac/tclMacNotify.c
+++ /dev/null
@@ -1,554 +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.3 1999/04/16 00:47:20 stanton Exp $
- */
-
-#include "tclInt.h"
-#include "tclPort.h"
-#include "tclMac.h"
-#include "tclMacInt.h"
-#include <signal.h>
-#include <Events.h>
-#include <LowMem.h>
-#include <Processes.h>
-#include <Timer.h>
-#include <Threads.h>
-
-
-/*
- * This is necessary to work around a bug in Apple's Universal header files
- * for the CFM68K libraries.
- */
-
-#ifdef __CFM68K__
-#undef GetEventQueue
-extern pascal QHdrPtr GetEventQueue(void)
- THREEWORDINLINE(0x2EBC, 0x0000, 0x014A);
-#pragma import list GetEventQueue
-#define GetEvQHdr() GetEventQueue()
-#endif
-
-/*
- * 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. */
-{
- 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;
-
- /*
- * 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 e45c746..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.4 1999/05/11 07:12:36 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.0", 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 6521ac8..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.2 1998/09/14 18:40:05 stanton 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 & Ray Johnson © Sun Microsystems"
-};
-
-resource 'vers' (2) {
- SCRIPT_MAJOR_VERSION, MINOR_VERSION,
- RELEASE_LEVEL, 0x00, verUS,
- SCRIPT_PATCH_LEVEL,
- "Tclapplescript " SCRIPT_PATCH_LEVEL " © 1996-1997"
-};
-
-/*
- * 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 fcc775b..0000000
--- a/mac/tclMacProjects.sea.hqx
+++ /dev/null
@@ -1 +0,0 @@
-(This file must be converted with BinHex 4.0) :#d&bBfKTGQ8ZFf9K!%&38%aKGA0d)!#3!rQX!!"Cp%iX8dP8)3!&!!$jV(*-BA8 #)!#3!aErr`!0$d*239p8Bfa6D'9XE(-ZZ3Gi(9)!N!J(H"p8`cm!N"3fP`#3"2q 3"%e08(*$9dP&!3#[[Qr$XedMi3#3"3)AYJ#3"MB4!!"h(`#3"Y9U"[L1jf,mBT& MYrK*RTILbF+[Sr`@[[#9h6i[4YM#VZAjbYFZ[kK-0re5[T!!K40qq&lQiGRK1q2 iMjrI,pb@ilr`KC-G*i`Xjq@lf$1bbHl9KGpbAT`XjlN`FRaj[TaNX52l#9Y-`RE RaCEM0E!MbiJYI*NB*pZ&BSAhf#VYEG$#[H@iYcd**3YCb(1bN!#&6*BM#aNXJh8 6[(6L0FMEjpP!Hl14fH8Y1ZKGq-+,*bf[bc4[HaEEEfqXGp(V2,F,prEEb'[J0I! cVfR[`1bc!ErPr2bdbmr-Xmr1cP&Rlh9fjMGbd"3B#b$JbJm"IHR9`'cKK(p(0Z& NNeZ-5`$BJJpi"Ejm[fp%8HJicMQ18lM8+ElL#DGilKFFCpPHBMj3+"Ei'hkVSUD rdB[M))VG@KaYpKYT,pD6mRAN[@$HMrfJij4@1mi+k`rZGCCN`CFiVmMq[b"lX6e l0IIdq,IVM8k[&(92Ypk$Xf,T(rer5Q&RiEcLl3[9$'[69A$QjJk'rIGF34qZ)I1 AlcA[FCa[RG023YS1pm,09H[ieeGZr0T!U*iq!Ae-,A`#IA4hpaMR[+qU4Qf[%Cf Z8GDje$Qrm'4a4qprZBM'ZD[`qF+qFbjePP1'kacR6k[p+6U05KQjFTL4ad@r3`G G8RLXX,ric+%1LQT6`,PF0E`2940b*RDTbL0f@4m#4+[L5Z!mKId+pU[B[m$q#IE 2X(q*r4T@1'2`1HbIB[mDqhAXhf#rJIdQpP[B[mAq(IE[XIq!r8IX2f'rMId1pXX N[a)VH4YSPANc9ZTVVX!HJMd8HaKf&(X3p[lB"f!IL$dFqj0BB@4Q$IC)l)1`2id p#LZe0fAX'(BjZCk&24[l"1`6X6q$I6`@,R`ZGJYf-hB6pURBdl%ABbr"RS&p!ID &f01`Mm25eZGKIaCl2RBVPPim%rXSl*1a6m'HLRddpM(Baf,r$I[[f2r!rLIfHpK raIkAB%AlrE[BIl&3+Le[a0@PIFfjf#jX"T[&GQ-&ZFfVX-*&c3ABIYlqCrir(b[ e-p628$XcJRd)pKABil%2a4k$24Cl!PCkhUc(VX+q(2Ydl"UX))8Cakl(2Jal%[C Nl!EX+GL(BcGLAiPp"2D4@+QrSHk'ZTXKl+Z`VmBq%bXBD4l#[Sik[34l"IDPf#Z a,mCHMVd+qc+Xe#(i(ZaP@+PE3)i"Z36N%T!!4d!HJI,i1Hc2Bhm"qhVX'l"[a,i *HbRfDLb-r4VX@l$db!$f2KCEiI(51m(AB2I&cX4+6`Ad@I"e'8S(cMDXp%4!c`9 #6kPP3$m'p'2`@Zcqf!1`"f*RB3HaMPA0aXkaZ!f-5cpE1,i!qe(Xlf)rK[dipX2 Bhm(HJ2d%pT2B$f%rJ[d8p[H`RmDLer`"pM2B2m6q%IDcf-pK2irp![D,f#pKIj[ 8K9QBZl(2a6i2+c8fe-h3EiED'@TRk!G$r3de00638%0$RaMkci#*K[i`e-a36d- p$EeKhS#GKah'cXFZ`#l%5QqE5l#,X8Z`)jRH&"6S0d22'hVHd&1'[MIdZe'r#mB (B(m!*i#,@+i$GL1j#$F)i!3"A#!JT`$-$mJVZ"2lE+cN&pb&K8&*rJ'j"r#(!2i 3`"X#H%-!E`MJ$F+eK,H*&Ii3`"m#kKG3[i$k"G3[H!6l+pKIa9k,I4[fPl$#MB) 2BAmGqeEXfl([`,i6qblXEf$IMAd2pVhBhm5q$hXpp[hB$f"r#bY+8[!`04FqBF! h!qiCF-V!13aF`i"P"KjKi#-'cQ$J*!DqBZ!V"KjMi")'c$28hX"&$28hF"X$Yc& `'`1R-A!D!kFam"3$6c(`&!-q'VL+JDXBZ)U"SaJiLS(6'($6J*Z'(M*JT`%lMA" 6Z%)!9`MJ#)&iSI#)!"i4`"8#H%%!,`MJ%!'m)3$l!cK&!-i%i%`!pJGJ63!A#H" L!9`XJ%-%F)J!$K(!)3)i4!#(#1!D!4`ZJ%X%m)J!,KI!j3+iA-KMr3VIHCh'Mdi 'V8lS6c9#"cXm1HZ(S910dLL13XmG#qUa&fpcUKZYkf`rbGl4`''[hA3Rr#6UaJd LYcA#UYFSGcUMl5!Y0H6Ii#I@)j%j*jjepFdic`RU,G*GfBak[Q#dRIVa*UrKNfB `16UqBET8Ue9+mUledYRXrmE+4,HG"Ldr#cYkrH5S@qQp)L9D)CmNT+Ql)Uf-R@4 f[ZMV'e'V%i5"hh4(I+rTaePp`cD)#ahN49klm5B#`mG@GKUcHZE`dST5-KXH6&B ki*bJiD9"e#CIm5DP@V[4HR'ZMrhM"A#j$Vr*AEPULbZ&1M!9'eC*PUjFGGeP$T' &hZ8GH6*A+ET!RV&G)&9C0jPj`Rk5(+,'@H0GHP@`I&AcXNS[60Y-h-1pD"Yia+& #5)Z01N30MlBk8Cbkq)0V[6#-SME&2+FMh&Le[(,jj9QN10Gl5F-,-qp*rRD(rdF R,@Hk-VjflD%FeJmGGUFjEjfp!YJDG9Ehi'UBlXZrB4XNVS[iJfTYif'hUi`kY6* iiqaYm-PM)%[8#DFGl)3`$T3jCQ`XmqBl+aI[[!8NNiJL0%L)qJYi9dpIhdSbMTq R,+[@9SQ1J8,la,C*'$bk8)N`+NSSJDX`9!&2hl'`4c1'Q&P*VpUpB3T8bEi20j! !F-PhjH1+MFL'Z(1a)4K!@Z,h`LD*RU!q4kMNm41J(Umk,+GD%6d!4p0!KjLmD-Y UBDp3-$)X"KFE)L)&&UP#6#lLFjj@KHQ)Ba-%BR25L)01DKSL$XMPR,cL%SeME$f HH25PT%Vj50YGTC!!!Uq"fBd0`p[NSE&Kdr-*pSi0'eC`4Y41SY![*@QhRSMc2C( hMaXEZY9[TjQIjpGk34ZIHhpXq!K)4%4YE&M3T69B268%U5Uq@H"%iB[kL(AQm#M &a#5eU#$1R6*C)YD96i6SSlPUV5[2*cq-Zm"FLS(&fUA[KpjQpI+TfJCF9cBG5)1 Z+eY#$rX$2J9[YQcaBaX!Up#!9GdNM9VZGIkffk+iQ6MP"JLe&9UdE4CSfK62q+N lkDGTd*j*R,8"bDi&*kahV"Z%6AGSDaTlL62SelXc-hlXQMF$3l*@C4bA0+eEjUf fQ%3fe%KaLamkSa2ZH!HDFICfAU&3X0PMrAEQ1bC)[#6a@h@P%&F4Pl#em,r1ES@ F8V-5NTR,R@UlV2#P@F@YJ-YPSicRB(I-Dmpd[4NrEi*$$1'@E$E('G82VX`,HjK EEMB$43QTT,!#KlC-aiC4hBD%Y5EE8P")(`iff'Y9'S(4L+8)mZ#h,-Arpc&2)(T S0pUj(I2$Arj%b@IU4k4R1aX8rf-f`!F`Qq8"q6,C+&JjaTT`LXP18LAM9[DE55` kIIhV,"*HH08k55@H33YR-*MCB*k$Q3Z#h0b'GV#Gb@$'JhN30a[#2!L0c`b)cq$ ,e8cU-E$1Zp@VK1*H@d[E!ddATGqM4Q[ZZ[,e8Y,&ZEdrU(AAQIK6U@`VAJ32HL, qD)QPkKZaM'332i*GJPf-RBpGJ&f)RB[0B2I$$Q(harCJ"l$pf&%laNE,d9kdTfY ,65dDND&0D8RDPeCfScTH"13+qp2qSc6,X+0BZQ!BQm%Za#l#,XD1U$2%cX81BAZ `$*D!9*10'#DBVlS$+'T!Pp!K9*mZS2Td)je!Cf$p#ap!Z8)&%M[l"4+8!(%*iA1 P#i(kP0TSU42lQ`+046@DK(q'&JLj`m#KN308ZXDEKFCf"#&(6D)bhBh#6+JPNfP -YM"0b!3KcFpNLjY`Sd@BFQ1kMFNCTQQB2Q3UN8P"*JDCFQ+ULHNRTK'C1'-bNCC JHSC*+#CRQ+*K5SCT'5CSQ)4MZT!!b85d$kCTQ)TM)JU`B"U+L65!L-NF*R+BEQ5 +NFNfUXN%&P146&-aYF-8$p12J!l6MdaI-@AP'"@69dc"-6(&0"!63N`,!9"-D$' p!kJaKF9N$qhT*V#BZQ*5b%hh-1h$0"C6A8aX-H8&'$+j"98!+CLLBm+1#6fQZCJ 5BrU)MbP!TSQBd'4LN!!*3DB*QIjMHT!!b6)Q#jR#Bk+2D6eS$"1)6)3bZFRd(e0 K6$JadF38'5$,4"R6B8ae-ZRR@#666Nb-!BC-r6(Ya'38djj-L6**bY3RNkG-K6) eb#39dkF!2&1P6!Sb33V+Z#P5*K)"IUB3Q4i&Cb%"6+Xb(CIlT!ZRCi"hI%Ia(9f VD3,dSZPMdmIhj"-jbl2'Y)iA)-XLaRGAI869iI(rlS5S#b!'(B0M`p10,8&6@ZI '5@K&AU)3l5'N)5Qj52NbNAd6iq1#T1MV(*lBF"#[c(Rj8*PdqjV4X5%4D2fra2k IErm[Y2p(l2r&p[qbqBcDPKiE6T-J(K,mk,32lMIrB2Z5`m0VJM(k5)rp[lpp[0r q[krq3fiehXC"H08r-*pFa`@UEfkL3p,99paVVZDMmkpQAR9SXNbbd$GXaY"TV85 IM4[H[hpri@+D62kR0Tb9,dJBV5q[4bN0E-2ZKcd!filY`"kSh-A1`!kUVF4fB62 BER8+AH)8)q-%ASKSr8-m1ZfQ*2@b2qIr&k+GaTaJ%,5pp$r6$p(XpJBUS0qGDe$ bi*US"&AYd#q`pX!IX+$"b4(l(*)MG%#Lp&MTQe429*GJNF'ZG6&[+Ia5iGRLAaa Hj3#4KV6c2r[BM4GrIQlZJ-K`qMNpe22fKBZ-iXm,-m(J!IKqc11m!Cr*"#3rc5H U`J'RjK(eNjJ6M%6@bf+(GKEGJ)SEY-6"Hp#eXCM@UFeX"6im$Xj*j)p%GKq#V"D @N`dhb+Z@HlMY%0%XL&X6%3@JGMq5*iI3$@b!@aJ4[R#hJ-p1(36X1l*2!QcfiTb APF-M-r5PkSrA3`%6AM$FPf+pQQqL)RcGl"'U6f6[rK+'0E-[!+rD1B3!Li[8AMr !*mLrlh2l(2*9(Ml#)e%U(p&[J8H@baf13R9SceKj3U[d-H`5`FKiaX@!(j(3I$T NiE*QiJC"NimfFp)9Nd'1R$&Ai(40*U2F,#F62di3B9+,D5BqTU)F-$+aaH36(p0 %iDl2F)HB'd"Npj1V,(ZHQ,6LBhHADa4fF$(4`mIH2+D-q0MlaL36jD@162[JBc+ *+50m6*!!iFI(Y",66rLBLU,qq*MdBSS)(pb9+5pm6()a-B@2b6)QRr!arF8%&$i QeTKi`XGq+r,&aliU+$NqDXQ8%clfrd'@mE(MM`NTI1bVBm+-pU5@6(rKSaC-Xq& M#ScT-Aa-5ZP)C*[SYF*NQbDQQ2E#ap5E(639(e0Q6($K3i$A+DJf6D8a"BD2(Q9 U$KqlZCL8`dFYQDV$acieTYM`bHj"1jQ'Mef&6*hKBcFIr3@mJ"(J#6lkN!$T0Ac 8PbNfI'jb$4pb2j0Yq*MmBTS0(a0I6-$KBfU10r'"-8c*i@2APS*dZfUQ1krDYHX YP#U#Fl5,N5P!I1a3e)(($Z%Ddh6ik&[k#are!Kr`-CR'9"XqC!fQh2#"%m6LBpU 3!!NqI%c4kIK#KkBEQHl$"ria9)#2[@G-rZ&MIae6MIMB2kFc24h##A39I,+A-04 A"+,"DqU!$kc88DP1B4-U#ck`J!P+I239BJXqkQJP(r%aP@F9'I%a)BFI(j126-r KBpL"U6ame*,Ha!G1-$@*$raQDJmIZrAJ#rM!E($*83RG,0%P('H#$apeBX)2(hf ZNN1AkN4riD-@e!FIH-"8)$k)+41Jq-!cZ!NqpKMb$Mlfd$%RKSmk-@'+McU"NrM BekQ6,&hL&LTlCF4YQ$$%"fGJbK!I0@-Z#apiT#T,4Vd0Am"(Rc#CLSrrF#9m6&3 UGFYS,`+c@[M!!c!%(hLJT$XMV!A$mE%M&!c%abj-TNhPbiTVdE2ii#dkD*-96f! 5&4qB#hr""kiaTBS2()'liD-RQ@c&4kfCB-9($[3A2UC#Q46&"fm!kr#a)j+T8Ac Xmq-GI&"dDSk2ZZV`6&Bl&jNJaFHZ9#CpmE(c&'c(4ifCqT@[@c9QqKFII)+*@ha `+LD*mF'&Q#M'4eq#9rM!9[JD2M#1ZZ'MjqhiN!$ik!%QJI%4`e3X2RCH-Jf-Maf &p9d@PBmj2INlD0H#kj!!A25CJV)*hl($qEPh($AAKh,[`*H22[P1P*bm!jGqd1) lF1AHaAISYrl&Gq!IqjbUGr`1[2PejjVef--,q5KHDDa`Te`qGG&%SZ$BfF@m`BV -iMY`mql&Gq#bfdkqNp3((Vpem4dirPQ,li"cjbbq!dpjr%[[j!#*hFbj2Fhqk(I X*dbbY'l0ZrS99b&k@$jKm#U3!2[H[RXh10fehL1D%mVRiK0B*G('Y%-i-ZZ"'Ik F19!C(a`DF!F'be0PrUiIV8cCX4pIbPGCSD#M9&kIca1a3Z(@FIZE)L%ZlQb&m"@ C,')@-$H%,J&p"`IFG`fK4`(CPrIfq&8qEma`[JpKVm01q*%AHYD2VbpAKdT$dhC DXIMGYX8Tpc@*IRMkLjILme'X&r$0+4Pq!(3Uk5%rqN)3pa#X+VL$+c-,ZHQjP6+ qQFmYf-%192ddMQlcibf*Uldm`j0I2q&H9PMa`3m89QbkCX1i1c%bkecL6ZVIf-" &9h1%MPc1-[rM5bpDjmbi'ma%ZICkfd@IYP2"EAZ,9crbfmlpppprd*Srq2'EMkf "I!f,p4,rfhI[2[E'AECDdpTEaGcp$rCpHrEd5FM6IIk)ZS-2c9J[!6lFQRZ1dYL 2HAI(3jKaGc)'Za)FIh*EJrQBEhGl6GJEiIDDF#H3!0YV`Ke!EUm*-rHU%A"(NYY V`VdqEUm*0c1j[5EFEq6fQYMG)EVAK,Yp(+XbfNQJHdf-lKI5[5C'Fr"ZV`Nh,HP HNcE9@2HDY'NhKqieDG1q#GeVdUBp#,VAT%ecrVVAa1lfd,dQEEUp4rHDY1NH)Ye VdUCe1VVAK(@YEUp*ZqDPGDp*ZhBcU"MI,Ve8pjUdDcq#lM9Tebi!h@[5V[Z4G+p *ZqlfdEdQlEU&5[HDY1ZZ+C8&)+CZVdQ(kU*l66V8dlVAT%2LVHiekG$X[ZieXIX fG+p*Kr,@[5BGfMfJHddkG014lMATd#e9ZYHN8hfVHddkPE2Z0HR8rJ$GDp+T24U kek46XTrZ0HR8AJ2GDp+TQjPdVdQREKI5[5DGfR1JBeZGfQfJHdfkK#1kek4,rD" l6H`1$0eVdLAP@[HDG+QrGDp*P`4`h@[5TCd)ZYHN5hYSG!bS5cF[k9k6,Y9!PF) Zl8(4[5CGh%RPpTTNK%fkeb5M2Y#p*KRPVhY0-ZSrh@Z5dDi0h@Z5dHi%h@Z5%Gl SAT1-lN$5[5BChH@NHdhX6J[GDj,4R9Zkeb3V$0#p*PPKJ1iebDT[GDp*9RAA[5C CrGHp*PN0"1THNkc`6rHDC,A(3IHDC)9rZYFN+rc6[5CChGfPHdfkKI'kek4EQ+K l6EV9jlVAT&Zed,dQhGS$SRY0ZV8A3rHDG#Y[h@YLpdESAT0Zh4ZPHdfkK81kek4 (A%,hQ[3)%h@[5BrUVAY0HT5rlMATdGi3(B,Xd5i-h@[5ScZEG+p*MfUXHdeke2H U[I6SILlGDp)V2U#ca,h#1peVdUZH9iQl9hA8[5DpfM1LHdekY5p$pjU`PX[Y0HN 9hZKHNelG1UCl6IV%f95!lP2HZYHN6eLXHdhkK!Xkh0'R@ZYHNcjKM#SBIGV2SAX LqT5hlMATdheAZYHN6hHAk9k62Ye,TRY0CSL2k9k6'H)9ZYGNKV"5pjV-%&lSAT- CUThZ0CQKRYDp*M0dSj6Z0CQK1l&dVmN-h51QHdhkaFedVdQrHN[hQ[3,Yh5[5Ep k6rHDp1XYh@[5VpZTG+p*[rBBk9k6IYf,TRY0"X4TGDr*J$LBlM8C%%r3[5B$`N( GDc+JIY1p*J2DBk*l63Cd@jAZ04R3A@VF!SD2'm[BT52IIF3RZ3d-(h`*[S-2I)G ci31$i06ik"0f`Z#$Pl$l#"mlB0LTJSplf0JM*0ppK3hFLS82l*FEVkb2[Z&@,(c N5Lli`%TZcF)(,X!em0%2m'Yml"LMMr"a(aMBL)pp2pbLKBmG-r!#qIB4hqC0I(! bG[,JJiqad`BIf+mE@IC4[EPC#ame!)[`d8[J!cjLi)2i`(jf%1'$Fl#V5VjpaEQ jF3XIYDFImF&GiFlii'bklQjIm42d#RaJ-AH2i3-Mj1B5kk1qF%"ml$U#Iq'$Eh% hQA`cTA'J2q#$Up1Eq-"#qJ8IZE,($"qBcKi`I23CpjAKScIJ'[L)"iIaJ99JPhc FXf([,X1([X$pCIMJeGaKKJpFT%I``6IJ%IM!3Hic`dFrSmrJ)cIfCH&$Ti(MbfI P%AE(iB0RJ-rii($J'cji*PS%2ML2kNVl#k1jb`iIH-(H0Rc8&0c!aeiZY"Vj$T! !IJ5h`SGq!Hr!"`m(hr$")GQ&K3pZ!bI#"dl3)rM!'VYB8Acd"[A%4lq#&I)G+"f +h2'"pqaH`dHrmJiqZ"Sk!cli$rIMi31ld9[`J4e`6hcd!(IPiB-RX4Y0[PR5!r$ M3eYK6adqH#%lX[#"Iq`P``Ir38r!4pr!Jr"45c!@(cQc)dkq3H8($m8(aX-em+% &S(hKJk2UISa"H*'6r!E"'cI$-!J'Z-9!Jp6D,41DM3CRp6Tmh-QRqYpXhA'RqYp XhALQqYpXhG+QqYpXHT(lm+a2m)JlmDa2DXfpH(acG2qEkRpcG(qIkRpcG1qGkRp cG$qDkRpcG,HEkRpc`$"ZHE-q`9"ZJl-qk@GZL11E5mlF'@Gph2qQqYpFF-AZ1F3 R[FlYFGE(l@QUrmf&ih'$R28*pq!@1HX6616q11X6,1!11EiKDXFpFYE([B#Ur`h TKMh9riCd5j[UId1kKdle[b&`KE[PV%ri#II,@CrJ#MI-@Crd0VI-mFfM4Y`dChh dMHTrmh4&KHTrmh52QqTrmh5$RqTrmq#+GTFM2Z%ch$9SIB+Rh$h)ah8Th%9SI9) ,lL1d2QiD92e[@,I#UIihV2[I92mE9YqSrMF-6q0q3ZX6cQ$h4Z)6I1513Vljp$$ h&&SI'+2khhc98[@rqET$6[@rqETC6[@rqETK6[@rqI!VlLqd2Z%$h'()Y`!-XYS b2ZNIlM+d2SQhC`hJieC!eIm@k#BmeIm@k'j!eIm@U*DUrbe3AkVq4kYb`k$e53p cjk$eJ6'Urbh86A@Urbe8r96r@kKH92e[)4b5'`LY6lJ+Ya$b,4+ZU2khL0lQ$N, V!i09reZNAPIpEj&ZZ92pEa%D!AF5@KmBUIVI)Z'@kRq,GBHIkRq,k99Z+,3qlLK 8r@qaEZj6r@qaEM08r@qa-&le[m9`5ql#XclK0Yb0alG%0rZTrVF%h1&H21Z6RZ' Z21Z6rpbHChhFIDMkha,GjDIkha,K[HTr5q$HGVmS2Z'Ch+9RIF+AZ%q2Ed4e9Ie [40L[qYq)-%ce[a&UcDekeXGpHUVrMHKZ4GAr4Y"LZ'(2qN4(i*Bpk`2292mE%Ck TrVG80`bUrVG8HD[qYa6-XV--q+3rZA[2qL4rEKZd2[*@r@mT@Jrh#9SIHD[qYa3 qc%f-I+1k`9(e[e(G1+MkhkMiNqTrSp5DQrUXMrX,9ImEeAepU[q0UTp8ra[9HRR 9rjETlNI9rjB*He6r@`B'FGHMp8NGZHr4qVMY8I@rCHJ[h"CSII5SkRr,i+[F'XL hA,FHU[khA0LMqYpbF)Vl$Dd22&$pElPZ"&6pElRb8re[1GS%0aaD(cG-U[jhN!$ Z4e6plb$GEDRkhd(#HpAr$U+qGJmY2Y'rZ"25qN4Ri9C)k`-[9IpESEX89IpES4X `9IpE)5a4r@m&IFkYJpBRHA,ES2@*cX@0JpBRHJeh$PSIH+rkhdVG8URkhdVa#GA r[%0IY!XX2Lr-ZrT9ljAcV(cqZ&eJAYLpN!$*5BUHPXmIa`9p-4H0qFc1-)SZSpP 6armYTR$0Y9lfjibKV8%k`UA#h2PjqqHe158T13%QZMFerTiD*,2(6dRb!j`mXq0 ,6S$abqeimm*JJ$IQBall3VYjkL,,mCjM0dXpefkRHTlG329mLaSAfie4PpLi&pR r,lEaVl(r,l9jA'EcZYbqma+EeaAfrd[Y1eIDGepVrepPiejQ0eUp[(H$SrXm&EX +%hILeDY!E!rFHR,@kqc"@cD4r,CIqGcjm`6`JVYTkii%iqF,0fe9%p4paEN%TrF 9Pa1FU1#XNhHDl%dQh&ALMp0YI()ii)2lGQibVae)`#R6mRIkaLYj*hrM9GIc0el *1qcK1ZEN1e&bmJilZPB[[X2qVM@pGc,2Di,b$TVJp1e@+Sj1DiIb$PVIY(BSll! ME&SlP(I3"+He3hN(V@pD`j0hf$8fV3R+1fL#daUM[)-Q1+eCkJ(J([#EV2`"lh! VXraYm4r(#q8GHi$`6Hm`Kp2L5I%lM)rd,,iMC[a'Z2JGH2$d$A2b$P0)V9[LiRI BVARINqmmCriGTUKD[$9qKjfF2rA5$A2f"QRC[hl61mc`620JHBHpR8hqQ16$(Xm Q(dhHBFGRNfFQll$cXmQ$NhIB"rVi(Nieh['[i,+(q4e[R!E[*6KXb0rfq5iQh(d #@"FUJdmQ)6F3lZVp&-k9rr1jZIID,GfHYZrTGN)T`B@RQ62f[fXhER[D[QID5B% %&jjKF1%'Hh''PqhcaHf4p(rYU!YRIqlH4r8+qrq9p[qVl2pAprC9KGH1A'*ji`Y Xh![YraICI0hqUY[h9SAAQ,Lp9Dep94i+8GG2F&&E,VN[8rDH2P"AX`f2f*Z"p'S f0m-Lrqh9E,%rXNAr90b1q'T0Th1ZqT0[XJj6Y@VQ-K9Ac1Z121kZh`rcDpErj[H UH6IIZEY[lZMCm6cmFTY,r3AIAJ3#@cf[dl$(RBM5HS51BphF50eUN!!d&N)h"Zf *LPZ*@Te!LpMc`4HX@NRSQIk`hci4UGGbP!-eh@)40L80,cb9UNC[p1*fd*j*&U* A0i-d1[VNQUKp0%G,!"VTD`qXhTV'hY(m9R@60'UjerREES[LjY(SSaX02dRFQTI 1(JdGk`CKmrQF1#kRhMa%(K-NAT,iVIVa9SL[dLN(eSZlDRRPmXY2Y9BBh1LXm"# BBUr),56edK%j8EViL**bi2UKYFp&eEYeID@FY'Lj,Aki%(U5[re8T6GiA*DlcCh ddr4%UGI`iR$9kh5bf1JDmK*!TT%&I%aM%hJX"@SEP1*F[I2j&l#a'K`eF"UXb*M '@'"-)e*FV&9H)5b0,D*L'Tb#BKUCBQ)DQ8"L+6#&P9*dYCd52-`A,Jq(PGKk-bN BjKXNaX*5i(M0BL3Xa3'%jD"DGbB`Q%DQ+*K'&N%`$`dT"NU%2IXNMhp49!(lSVJ %pp)J,AJDiqUDbl@!GFA!U$@M3-@ib'ra,I+Qf&DUU-*3&&I%Y#J`aE-S+X@b+#V "X63SaB-dXYJD#AEPLT2(V8*FZ6%8Vh*&Ml%U$DVA*FDS0!CmbJH8ZL["T5JUaD3 SUSK(Z6C1XHJ"UlDF)Q6jd!)UjB-6D#T(DV(,JDl!K5)8N!#U&KeeC6jD-5XIC)% V(j+L9ld(&(hb`88FbdHRB*B264%Y(jV!@MNbaC!!FRLYYa+8+p3[$hA9i%CR+HJ 9HL9'[R,N41PL$#`(!S59U(Uh*T!!Q!p0F6%I@J6(!PkN#1R``%DG%#4(0C1(6,M MR64S"GZ2#5-@CH6Ll[1iEDB5qI$U3P4i%P0iU(H&I+DCPS8'6E3F+(QQ3H8d)h+ 3!+DBjhUDAMj)8SX#bQRPfbV0V3,(QQ!P8V,-4j9665rVUL*ekB%8V%[44B3S2C! !"iP5H)VhTHJ%mQ["+A6@AP$dV-8kU#`h44lq'r%4!bM(Kb5J&*HfGLNkkHjkF+Y JV[e,J6FK3*&(0KmB,hG#EfV"0lCT6(*UXI#FHQ#c(9+f8iT1#8mTZN$J5r%*Kkm &0dYCN!#EaSEr@I*aS8A4am990!XA@P,3A'"4+R*a"E%S#5[+-NPX6TK*SUVP,BP 'qFK%0SSL)q()446jPSXV-+idV&+-Q)ZjN!!DbA2"&6'`%&SYAd(R5X+D,CAAZT) S9E[5N!"bBBZ+PiZVkl"M`fIdmc#mVU#(X5d40`a[M$+%`AAp2BbY+I#jd,UHRBX [+YUjb**mV5h381+6k,)@Vp%&06k-UQX2B@a0IBK$'d8UD40Kf)3)%Ml3QYT)`j[ PV3d@j%)R@l%kA*!!Ldc(#q+`H[(V)`CKE%1iUU0E-EkK3GEaV4MIe)BV#&F-VUZ B$BbV2P#5!mXS9qU&TTTC`lP5H&(4V#"G-EJZ9&@`VKDFkPK0Y#Zq-#k(er'Z&&r 6D"Z)9hfJdCKPTEB-HTABUPTEJEhmTB`ej+Xm-DlTeI'[mX5%VPG"`8Tm5pYVB'( MMDVD8NE%DTY-D(`eA+bq80(j+ZKBL@pTI4@-E-BApEiQ8PBHfDljeI'bqN46pfZ JCZ10m4DZUApPq+b(0a6!#SMQH+8p0A0#'3RM'p*)'$bZMB6a6A%NM'kS)f&`A4l *a6C)HHk"%L[2KCEjYrC#8b**`LXLJSBA4C)`V+'5K-&eQ551ECDU,*5%FC0+5IM #Z&55aVI+A"G,FV(E'l-QPq4#mhT*(0ISJSCL%JBh*C-klT8HD)SQGH3V2G#565V B9iTZ##F0p+Zp8'ESCI`V0d9,2+NKB$Qq**p8-,!8h4"3+LKBMmj,+%dF,$da)D, 8NE$m3&e'D@"KlB9QQeD8P$)F9S0V@NS&%#YRaqj38bU`@(hJ4MfP#Sl9&bB8P6* %0Z-R#(N*+*[KGGjGJm[a*aV#3JUDeG!*CD8-RDhib4,@aC8QKPCIZ9&HU50TlBf @`0,!dqBM%`eGeeM+`0U)EkSX&AL0,cQY66fjf0,BN`ZXcMfjf2,JNiXX66kj`1, S8a*A'Y4*JZ0*R53XQFZ*kP`HImU(TJ0%8@KZ!-U&P#DJA'"a"#U0UjBN'B*b-I8 T+"GG(B-Ua0E+@"b%5Z*D$9BBK8V#h#a8'P1TF'NDbJ9Z9rf1mH[GQ4NrGJh-P1, A6091ULT-pUhHf[$TcbHe"9a01#bQ@11"8CV9k&UU5BQ,+DBB'D@@4095+TEiB(I -Dmpd2I#KT@`HNMAl-0fq1ID861Q&3rp&3M[-,6GC5L#[#TU!G&+,@JG8+e&pTeb 0kLYa4DVKYDSNc91Y4K*IVN)5(@HIK0@bEX(95Gdf['$c2kQkaiC4hHC3&eZ"d1P (QPZ'BNaUUTr%6ZGAA8J8Kdibd&)A0$@,8K'DI2H@KbD(K#YGdBbr*GIQ6('P3fT %`(9'NDk@NLp5Uqd2P,I[T)5L5[YU&5mq8+&q5B@pB4ml`pXGlXN2cQF2p[lpifj FjSBFHaB*H($%M%McfBfqEF$!dPZp+BMl0332c[AkYf&"!3mk$4iFN@jC99V4[id Q1$`3r@$I`hKJDB,R$3pQ(XD$#m+JhTH00mCiX"rA-CM9me[V6dkjl(a6h%4Y2Mh fiQfVUj0MELAl*j034da'hEMKpah$M&Jrk$CiB'IH6Zjf1P'FVKla[DBI*rh8L), $!p'Ec3Nm#*R"fAiI085)mD$YhrML@0$ZCiB1XAl3pE*q)"0ajdEYeE9Z23`DlQL l%ADEIF*)4)`(QIr3NhaNB*!!ai1XdC[2B"Kf8pUrE83TaS0Z1hq`0STpl5ACkVk jG&ATbRjVb"$M33pmXAHTd4IMp5D&Ep"FPRE[pcMXdCe1f"mJMlA9X@YIHNF)lr" S5iSTPDfrXEBfYVC23"iE+i2p!HTkdZ6%b3c[c'2$d248U6lV0**NK92iKhZF*42 0hJ2CNAISljJAKP(8GNImX(FeNrQETc1IHGq$Zr6IjR('Pr0GZp%eqi*DhH(b@+i ,Y,d!HGaBN!$EmlMa@+Mrb@0l)V[cf,beibcIIShTefZIQThlqfZ+mXrm,$FT2qd 4Ka9"BImHQrAbTQ5,5hcBVprDPpe'Cr-ikhrlPA2KE"ihYJGjk)DPmF+'HFKb+dp !(QHFUHa8A5qDcf-5LAER8D**qFqekq4RmpMUc*l'kA"P9*!!!E8,,H,d)bVMChN -EkajNFQF'6@kCiZfii0rR*r%,l+'@r2B1K[@AhT(9Qp0ml1YDEG23"jm+fQ5(pG e29BCGlbaVI$j2aLh9,EqaPf-Hc`2E`$MARIY1YfI[reE@pYiYKkH$qEHUZTGc(d kMeh-I6U2AFapCakh-[HT2+DBZlZ6c4r!h"[eq!&c(brXRFap+SpGc,f4a[HCqe3 H1jLlj$&0hN2Q[RRQrr[Hqm'iC@YarBfl'(FV$cj2!11@VA#([X@Ghq0@q,VrR6& *(YZ4i6E'0*h(,UDc-ipEQFj8(VFKH512lb2j9"il3%rbX0X!Ta"L*BXi*Z0M4@+ L3b52*p8hRmjMAAhcf6bkUkI'-26,9UZ9NCIKVrAGJRLb5C&1h*R(19rQLT,(1Dc 9cHePE(6dQIkQ2J&ehF-C)LkpJj2[cQ-+1AId@G3Ifmkdf5eIElCRH3*MqM2emES hI4*9UD9#9EqF#[ADA6hed3Z3!-HU-%NF)%B!T*@(B$ee$8lVj&Bep!,8`kTpAS! mR0ShQFGZYHqXY"8kBcY0(TIXC9P!TML0IrpE9K5AhEMAqC2LbRZr12B,4AII8ca j)0Md9m4rX,MbMRZ+bqjHdF[M#HULmAVFh'HUXTcGHD&IN9JX%%hN`EfDJFlkh02 h9QAa![5V99Qm!(R`KA!@r%pGE4l5(X(rpFH*8GXr3aP-Y9Tl86AEqE%rFiTk"-[ k6d`qV"Trq`[D92Lj(T[m,)Ia!Z4ar1Ci8`RlilV#5[d9-iZ6Aj8,&EmF&lUh2h* Fk0jqp3I-LPNZY!Fr31"("Cfc%cJhep8rS9cc+DIk[lVD2(CFNRYc(P-MAX'&rGp Q[#Drh8c(Vc6MYHIc,-eiRGFj`dkRkZSMQ2+@@E%pR`GN9U`")0qI&@XKY5pJ9L` q1DAq5+Er"(2h9$"6,`"bqK@3!1VQEfT4MJG%dr'iE-UCr$`%@S`ID&21RXqcY#P RYaC66m4,X(&RqkFEGlCrrUf01e2Mrm(5IKAcrlXBR(pMMm"Yc+Z4a`qBehK"lQ4 H8hPi*rBMl'CHp86m!RX@`M`fRqNcNT!!RD3K+CKia`r!#'`HASQp$r(P3GRX-SL prBI,JrBjIRQ3!)rYDefL&&iHj(Zl4-NhGhQ3!&i1XVHUGRR3AK6'j8%pAkP!A"l NHF1$kZ9"(VD[I(R3AJ$#T6RqY-ZNZVm#SEJm5,qp@Sq0C'f84DBfl-rlmXdFU)` 2$Jfi!i2PU6*reip@TJEkUc5!&`B$2$'II`B&r,@ik,2lpLXBV262-5IjMdP!3C` q'Sc`mc*0I`CSq[qiN!"2NN[lH&8+EpSPjXIRBm6ChCQ[GZ(P+ar+I'Cbhdlppc" YFrRp$qmiG0H[N6qja(`)e0DlIXhHMb`PrVV#hXG[,McikUYkHALq,M%[ih6Y%[- #6[[0,c(h)M"h2p#9MT2-R8qCZlRh06Ih!@$ZIUP,c2Idr9iY`bAQQpT2S#Ue9+M UPe1K[VUcTcjk!I)SAf*HcU0fFAC"&E1US4HJ(PEYm`,N%9eL2T((EVA2AKrpDqc 1FjHBQrX+Rm%[PjLER8pfR0f&4crlN3rY+1aD)c#45m`(fX4I9(Mde`F,1rq3!2H 5kk2(kh&cRj8[-5rR8E[%[*!!4rN5mh[UB98@,d#r@TA&#j!!"erq%[0lkQVc5#m a[bH2[9Z95mahIRX0#hI2"([!M[XjV54GB#H2[%H(Q8YF34(XZN3(-%VFPL0ajLh m@8VFf8ILC["HRmf[rBrcZ-2B9*2CBI*,iZDYBcdSFC*I%YIjH[ldG')f0E3pHE% 5$Z2D[S8rLdcFqm5Iff`p[THrYf)$[REl(VehPBQll-I`bB&f0Zilr$RHa$h`(j@ `jNhRh-r%[9K8Rp[9L@-@9YqlpZIaGG[qJ#E-0('cAS12+pG*%ic@HRa0@hMQf6U p-+rIrDr!Te0MjY[bpkliIAcc69clar2krF%Rm5f`ll(j4qZaj9Pmp!Kj!kGD[bX qJ'q*MEXZIqrhRm#R*pjd2*2Al`,j4NhFi2Y9Qh264(LJ2FChj$G5m`HhdN`jMZ2 Q$20(iXk*MX4e+Zrlm"ii%FHeU5HdhJIp(Vi(fEUbGe,liehIKBpq*irqr,e6IaM I85EZB$%BlBqA#52X3HRbhNIcHYr`2Ra(fhiL(qf2Ue869BVEK@rkhZI[a,IDaVd RlipI&[HJcY4TD9k2cilL1pA%,G%FYpD[IaHq4pXq!fre[DY+q"jMkrIq[(lEK#Z 2YAN3Tr@BSriqcIB0Il4qmp6(bLe'ATQrpbcKKh+ANFrPpIX+@"[BFC-hIappI%) VR9R!ij'r*-H$@Tf%hNML&T+2f9%E5e+Rq'Ved00-h#c`h['!j,h"2q22'qKlZ&M Fpl0rQ6q2XlLLQ-Yh&6JDi8SF0qHljr0)iJkGaj8iEZjEqA1iaD%iEZ6$[EjX[rS "0B$f'31ffTIA#IZZ-A%2daYKAlEI)'b#1mMh%2%"lE2hLR1meF4Gr"hmfG4+MZ, FaEml(jI8#HlLm,8VMhXeY$(ceEB2iVLjhmZIGpSqL11'K'ZZ$q+iaHV,)fdIa(' A#"pG2H+i@CSS'FcUQPhfERSGAL2I0q%aF`kBZ!I!5F`b%cHfPHIlXVM-`emLEKm $LpPTalRb!I0HafX*f0IQ*rc*[0+mpqdEm-'95*Nq#2%TZq&RLC-h,9k#Jf&ICPm 2Cc0IDppl$Rrk6Gb$pa"hJ)QErf[iZNaqRrY*I,*la2E(Km8K`[H@IiUi@6D2+hT jC*jpQVK"%lIX3RaI-ZqCRm!RIXXRi&&Dlb[K[NEm&&V(rjAQ[G0rLVLj*Zik9+- 1Ja1CrI5CHB20!plFBH+ZRb"1HH%#l8BjhH5a%3jT,#pF!4i(UdcF'Lk,0*BA,Vb H2c0-A2HYa#N[("5qK[f8qF)RL&0H12LEH6qG#+Fd`JG`!N(f)bDZ&ajQhQMLP[q YHLM-ia1rL%pjj)S,q2-f%rF1H*La2(+41%IB"jN[UGIK4q#Pe,M0p%efp(ELP&m 1[5h(QbbiD!`2-fZSJF1E`q&1a[+`,HJ6$Qqq#$BDSibEDAVDiFd314M,chi#2ZE `jSpe-)*ZXl,YT[haGALH%AHM&("3lBm9F$8MVJ6Z8Pr&Qp@UNmi&(M,H`j[Xkm! 8BbHb4P4AaCX(UYjVEEr5pjV(%HmPlN36pe"`6[%QmblKU14Pqq1T1Gjm&[jUV*b dFRq10r[!jBcbPHrGi)[L6AD0F%MkcZ)0q+GimfdiTjQdH9$A%'mb(iAVQ#N6GjJ N-F@E-i8ID#R`*1)9EjCp2h(J$h@&6bKqAr41iMCDRRGChNmR8!-$,l$8&EiDiNh QTq&f"Ll!YrDT(YjNh`CRYAU)I)FUra"[XL(F`acNfH#ApX%Kk"c'mZb6`'1(0`2 L"mUc4i6h)GjN2[&ca)8mflbGGa9[-Rm(ac+@CfpMCihL6ICep,!akar-ThK2m5E cXCmK3"FdR2M&('qqm1IiP*F[H6M(QqXI)djjqC!!G!,YMl2JMPEh!)rK9iS6"iS R+9prZM"$mHCip!"MGl-F"bik["N&+ifG!&k5mj[X0m0pMG@-Rb%X8Ecj4@TUV(k hj)Gb[2R'Ea#R@Z2X(mKar4Sd'f2he*c#HDZ1hhchViP6hE$MMKlHC#m8Ep-CPh@ kY&RjcDPS!mEUL82Lf5(HC0kTZX*AiII`M4"[-R[4iBa9i9I3FkkIhN5ZjKEEhr5 CpY2pe'HUEcj,p9#mq3bDS,(Dm,2",BFhCe&6BkAJ#i96bQqqme[%UECpR("8qq" bG!i$jq*$ER0idd00MA"E[ZFZ)5kEa3ARJp%'[JaqI2SEd%N1-A%RJD('kLJVIV@ (6i%[,03aSd[KFbk2&@K#"Nj"(Kq%VlSm([X3!G3C($dmcq0)m5Hd,2NZKr1j2+j @(k"Ab0q2JKmZMmmVM`YY([!(cH05i3H&*Sli[KE6LMRYJ1rji[2[E(N,%kAQSr! 'Br5Ui)0S&8Em(Cia`*m0*Zl0p)Vj6K1h(LiH[-2%(5@HK`BSIpq2TQ+@QVK[I"- qF%rqhL!-drbfLXpGE2,B!-D(q9dip`cDJER2a&fV2Y6mVRQF123PqIX*m0lP0dX m$je@rRi5$FrPGk4Uq5,,lk9QVRk(SFXDiCMmr6JDKXY[fqm3F+Q*qj4fT@Pqarq 9L%HBaa@ITLp$[1cj',eZT21!"r$T%&GkPk-"Q!FY(d),e,JciDK'1%rI`%-@Q$` qT(VVlUlM$[6`XRHTF1j+fhr`%-hM22%jd30Yhm$E3pfVpp[K@)CBQapp'1*pcar T[CHEZ0H$PeUrhUCd!Z'!&LI!J6#rRJ25GH!4j#'FdZ9p2PUGHCIP%qLlBIekhrS Va)N'CGm6$0Ekp6b0PQEHBr(QBhNHjm,*$GKPik5IA2dZTkEQ"dhF'm82YAlAIiB ii9-f6R3p9lr,a"[J3I*G,(kPq3h$[BddCq,J&4Uh'JhHr)L*Ze,kLYC[")jZT2d 5Pp2AHpmS2[T'%hIelMb2rGAhD06%J4pD[eHSAkmfF@q@IK(@VrIGMa*RpF[r"`# 3!`d0$%eKBe4ME#"08d`ZZ@qbp!Gi(9)!N!J(H"p8NBi!N"%@!!"J03#3"2q3"%e 08(*$9dP&!3#[Pi&PXedMiJ!!!4i!!946!*!$D3!!+-AGHF4I!*!'Z[!4!!LbdAJ qT3$Ldi`fC,5RjQK+Ai"mIT)55NR(rQ!RhrRB-b[h[pkGBp2c!SVId'RY!kKhaCa q&5hRD[I2dCBfR+[G08GE9QZZGR51GREPZCSq4k[%Fl9EXc9lIc+GAH0VibK8hm) N!!!'!-@f0NM#-h+X6V)*6l+5lC&0fi6YSjXF2l)PM0`QfkHYc0+LX[8)YG)k`JR PH)T2qV,$GlEa(cZ2GkCNHjeNqlhNq%H1pq5fN@d$#HmNqeN46MEC4fiIkcV**S0 YNZ146@kI6rD%$2B4,VNp5(+Eh-)MQ`%GAU"e`!EP%ciaH`N!Z8e'R+#!Gq6f5Qk e!4Yi)51(1E*"MU`hSpG[,bNrFj!!AHHE!mXV6ERI8HlZG6R2l2ekl6VHC92*2V) (f4R[lHc6@lbd3AT0mY*&Zdar15pGG$R2M#cN&Jk!"4"`k`1X,hdlDchT'hmr+bd H@FJ[C'&EE`(J#rim4hjA%-H4-@D&-GjUiehdX2%f2Q(-'fIJXpmVH,MkAdeF$lI k5G+)Nf)eLEH(3GEcGD4mFH2TZmQXp-cqr9h(arE65CY1k2I,QficCYYYr*@2Cdj F@BjEIK#rP'(8V$BRHIF9G[IZZ8pR`YeM,3,[6E0TjLH[GfA8Q12mdEKc0)8i,kF Kq9kf&RjC6'hkP2eJBqMA`b3GAA`f!3q4Ne(*1E*LeEhQ*(PA(0rfJahq3[KmrTA bVdUAQmripkdYTeRB,%9qQSET8ripeR9DpHL&p$35mJh!rpJV(r@M5E'CHmjIqk5 3!#*Tmf5M#k`Y,KYYCQhYmD,G1Z6b'f#[eqkIQ*bDPGq!9q[T,[LSPB#CVCe"!Bd "8ZF%@c69M$qb%8DhM6P$pXL-16Rh[F"L8H45R+IJV-Yl)f,1ah8r6T9aMq1*8f* IEf"9h`EE,*&,F*l-Z*M9ZCa&!,CTQpbY*a%Ai&Ah**!!D3IX1LmIN!$9K4,Q)#m 0eSN#BQ6a@eRQic`T,i-(m'rrG&#GXPr"m%Y9afqa-#qrZVSLkPaJ35B0KK@2IG8 @,Ihh9C5"@4!"p1YUNp8NR'mX23Al684&@MlUUTMXQJ2pT#bpbf'b%"BV,a1AiVF FhiTUG6,[J2MkbBYQJKf01NRZaPUeK1i@5T!!5PVl#HLQ+c'[F,DjDm8)MI&h'fp 'FC1""`eL6ZT6MFJj!Mqq-`E9KU8B-2a&pURBIJfR6k)LjNkF[@Al'(Y9E!rLV&6 kj1aMCX3lNaa*E)Y`k5GE(5lpCG[@*a$H%Li$CAZGDSMYVEJ-PZe$Z!b4lI1i$*A Y1lJ-8m06dq'b!H8MC!2e4XTf0LkMC0Y+f"FEk+hKApPZaQ@XE1r!KATLS`EMC2X EA-E,pMeF*PKEM,dd86Cmk%&Xp-&Nf9k!ba6C,XCPUQaAiD)l@pPZ`NA302B9A+E ,4JeQb%B0CXVf%#kcV%fhq@cCU'Q9E'$!(0PUFCNVffCFjXRf#m)+E'r%KGl"pZH i,*!!lDpa@5ME!lK3@b#&a"I,4Yj,C#2@8YR1aD9D0XMe-YPq"4HB%VBhi`,E`RB V,V!YE*mPN!#+l4p`1FhDHK"l9XK'IjiZ'rQ!SGJfi%,0X8(C9mTf)bkVC2YpA&E ,pJ&Fk&0XAa"QB[XZ,QGD@dpLiJYPSqI2NShkJRABeZ%#jQ!Mlh0Nqh9FeXMfTlM 3&pLSm9VC`$EL!mAJmRVC`!AULBhk`M+aE5*Y%0[,F%&J`rBlZ&`J'rd%QmAf19a H,"Ye[G$DHK2I,j+0ZS*4f1JIFX3'IPmLfh@iJ#(Bk+%YXYf"#aL,lHp`)5DfliY h3#AJ!0YP!l-ZPBdH%jTAdF#&%pXVFEP-0R*pL@cJ)L)MYUrK)X*0"B6'5-[D+SP *SSj9%RF8ipFfHZ0+fDl'CBpXi*r)1jAX'q&qPH`EX"VE`lJ38hepb'%DC31[i6A B`"6i"6Cki+@b[4`Am"BEQ!Ir`[B4A(j*YUrM3LqV6e1UDf@$RiMHdCHB#(jLSjr *#a[eHS9Xm#Vk&0ZlFD'2X)(PemX'"Vc+f[S4!eiY'rcN0E+"0cI)4Yq#RpM)!Fk #$Eli@YNqKFZ[b[CYA1#9kZY2l!3$XG(he!FEH!Vr`NDI[eifFRZ$E(q#bfr)GKF Z[bRE2q*bLl80)&l5[pMJ9&Tc86Di`@r*"YE3GpLSk@r,pLjF`%aXRm(PGf@$jrf HY3dNT`9rX0(VIb!ER1%2C31rrNJfHZQ2CAXl,Qq4lC1i`1q``DIK[1SE4"lj0YR JL[380RJ1mE'"[r"6E1$&1f@MeY33'lK&[f$l)Lld2MEi)Va$IB2CLhmQ'lhb(YR J52!qE1!+Z@!$ipiV'lhk2YR)mrfbI4bAff5$)m+Re$H%(2f$XX'(EjF0$!2$XF% a2L`EZ!NHBJ-[rN)fk[j4f6k"#e`$'lc`6QXE5NhN,f8$qp%ZX-&AU3mfH0GIb3B I)"GXi!hBJSeFk90Xq)"Tf,k&bkGP3m%$+p3hM"`8A-8'liA6BB1rh5dE(1-HfDJ VR!)E@)#qJBdk`Mfa`@RSAf`SP&qbYZ(N6qJ!f1$`AjB0E[N9fH!mIbXE12G9fF# 4Hf@M0q"Sf2!KAfb2i(+IYBfJ,J-I`BDQm!hCi,er,aZBqNhCi#6d)cD`PAl"4Xr I,aXe"4q`2BS,'+LqNG4a`(0Xk"6r*"Xp")r!"Jl"NE'"pImX'rJ&Pm&'Ei"ef1L EIl'f8G5!`(0Xk"V`1'a`jRq9$IlfEl*42hJV0R$R"l*48hT%ID1TIra30MJkpF4 'Ij!!Zk[J8qV(!+LMibZeBV9D+TEH@eUcCP6`E$kYP'KG5&hN[X'lb6Za)2kT[k) fV6l[E%P(6TF2)JZ""E!KV)!T4"F5"&'&S%+8)3m39)JTK"4`SV%JRK"1`!5##E' %8%)N)C!!%%F)0D34XJK*K"!!CS!Bi!9S3I3JH!!2T!Y5"eQ%U%$U)(1!)'35S!* J!A[!&8)(N3-K)'i30SJD"!eL"MJ$BT!!-8JBj![5"HK"3L&D%"2!'B#$B%%H)%q )+"!E4"2%')J()J4L#5)*BJeL$-!0Z%,Z%%-!)F325#aL"b)(iJB%!M%$%32a!P% (i3+a!D%#8JdaJ""!"#!!N!!c5"NJ$L'$L%(`)(!3-3JBa!X##1K$8#"e!$NN$2) &kB+B3,)J%*!!+XJ8*!T#!)'#*%'B)%S3*)JMj!K5",Q",%#+)%13!!(%D%4SL)F )ePUX4S#'R#,S)'T$@K&i%694I""(%"XJA!LmN!"ea"Q%Gm6dB+S&i3-K([%Hi4S bLP#0')fBKb!0m8C83&"(h)(d)f*!*K'a)(S)la!Ma&X)-m)Z4!a"''%ABS[3#5Y !-%C33h"&Z%@`KG"$1a!X%&d3MK!3%483A"(&%%XJVBLV#(k)2j!!*84Y4&$%6`J IBLFL+Q3GX414%k+'b!V44F"$e%5N3-4%[%5d4%K!*%'F4*4%M%5!3ha%[%+-KE! Le#!`LV$BpURaNr'P89#Xb0MQfN5a9*aXc#9qXQbfY"T,a9URhBia'EGj$VG0i9) M'`f-(d9a`2X9D@0f[K'&+Bel'YNLlfTiE!qME%P$2`RSXU8c2amQXidBYUe"h'c kV6T01rbZdqj@'NFKMEYmCVB9bH`-r'Jf#4FDF$CZqjEE)HlE'JQ'+2hBp8R5iTd kq"l'iXI8eSDB*GSHaAl@GF1fUHPRLl-,85GN!bJ[9GI0%62F0CGQ5D1e3&0pdpi fcAGD!I2Be8J$QfS$iXqI6qR8J'R36Gh15"[pG"Z3!-bqH4LZ60&)kVl(pX$H`'r 4E@pMSH9(0*LdIB1ITV,YLk-m(TDVmN$ldl#e%iCpM5BVTUp5fkfY,**0$6DDNPr 9DU4C[@qmTQY+KliU5eYqRNpe$aLUJ!J4R1-RQX3#k(KN(BZlZeAF'%CY8pjUkER f9-Be2XTkH@jG'ejTF&q40Xe-UE*K`i%FeS`I0&HAPiZ(FUlEeRH)p)DPa&i0krS JHM*NcLP5QkKXQ8%jpAee&-rj%EY9Qq[#9UGRA--1V8qkjSf09MhH4Hpd5S[@AMc D6VBIc"fIb`pPVPaX[f#ZUfipD$BG)dET'+cTVX"Fh@i(AqlR&K4CGi++Bd03MEe KYVhC(Q9aG!9&46QVdGS4*R*3cXDKTT0QFE0iFELm+dlUU4N,JM"08CCpLkQCpM% MYUpB#l--L,6AE!#LMLrllACZ2Eh6L1V&mD8Xm91c2TcV,#b%5G('M0JLem600Q+ U0,9Cc8*IB40CAd@+9i54QCJU9YU!SCeA)SU@Hp6-p1U`PGYU'bP*aDijTT!!VL) Qe5hqAHDUIDb4V"6iT(+RfLBVE*QXdUf!b@46Xk(-([4j!hd%SQr)'MQ%02Ej5f1 !pY(iV#dDRaX$G)4L,YVLdjC'5b8DHf5JX3[rM6hBEa5FcbY1qUf&$XCe8idh2br JH&5`2[%cm+,)ZIeQ@P!FUpI"QY5Xp19j-bRDT&[$"ledIe(K*LIhffF',G&Jc+! PZSiCY%42-B1@D#9Qd"*pa!aDSRZB38[d#c0SLBjK"Lh4+XbJ*6UD$&TU[8`',E8 Q*S1@@Qq838ZY$mUJTGEkC0"5DhJbD+Ne,aQde*UA$&TUr8S',E@Q*S1@@K-8hFT McM*SkG&("LdpDN`bD1P48j*"5ipp))1@([8K'E6df!FbD1P4ij&"5irDM!aDHUb p$&Tke!ePd0+M6LL$PKle3"Qdp+M2bU#P4pe9"LdpkUNbD1P4-j9"5irDT`aDHY3 fCG$5Bhr)S+9(29!',6eUI$*Sk9&hP%&,MrdKJjC4iS+Sj9(fT!aD4YNR-QJCCIi bD"QP[LD$PP(UC$*S'58fb+"PP(U@$&T'U@A*S'@8ZT8-@ND*$6*S'D81,B1@8@V 1-QJCT8iXJjC4ePi',D284QA3-XSDbk"PP*Ua$&T'U6I,S'@-H#H$PM(LL!aDkU& A'E5-XBibD+Q(AQA3-NEp6JBYBqae'E68!l!bD"QMlLZ$PM(Ul6*S'D0H,S1@-@V C-QJCSbBYJjCk-&B',@28GfA3-NC09JBYim4P'E5-%q0Nd$*16*&"5cd`+i1@FID !$&V'QE--@XDT0FUJCCbDY`aDkN&D'E5-8l1@3FXiC`9Nd$*1r9m',H28m'A3-Ni GAJBYikbV$&V'fD-bD"QRrLb$PR&Um6*S'@H0CG!b`4V,S'9L-'LTKh0Pd$*"h*4 "b`3a6JBY%m34d8-6l'FCY%b`af63-X'kbk"PJV@3!%(,"'2*S'@#M&N',428q'A 3-X'H%$DG)'E,S'@#ma)bD*RJ2)--@LBiLb#$PJPLX`aD*ULrbk"PJTUr$&Sk#Mj UC1FCM+C-rNCA"K[S&c!@h+H2`#l`%Vc4QcBSPMU0AJr1`!(KIZ#0dEIKIr3Xh!r 1"qq#6aJG()j(Am06`#bVhG2Im$L`cHMMi#rm!mi'*S+4i$2B$3m!9m%#Z*fG9a# XeMJ06`'M`AEi"E`1R)D$Q$N'Sm26SeD,Klq!CABZ!Ai$TX%E`"E`0cmr!$ECf38 cY`"Z`fhJF(!hZ"Rm#ei'(i1('@dIA!+l`#b`#SbbFb[#UGSqIpP&K2Z+BMMM1"- ieCiHPPY%6X$C'fF&cNUFIA$faGN2ChqF!h!1a$NBja#F6#F1`cNFj`LF)h'1`MN DjaLFBh'bkfFFc[%i*q#FL(-5cXNiTq#FL[0%R00`6XFj!qG-R,0`cXCCKA-1cVN ijh9AJ+Kc!Fk&1"IKA)ac#FkP1+Ya,X0j-Xj6mM8RDL14!`!eSm!qSf5i!,lNJK+ p(S02S@Mr6Ij1ArYiUUjXL'qN[KG09)ZEaLiKPV#)*(!h'XU2&ifNFmLNSkU5@GR 4XS[&e&'j29-kAAM[$FL[1ChQciJqJSG&9%ZAcJK)KjVHMm,0L&P(2leDbJ'`AqS i82Qd5#3#pIe22b5`F+Tel#,eX4''cm&3C@q3!(A,hKRCjK2AAMECfC0bMfQ+&bT %TCq)3iipA"bSF8mA"qVFbm@"A[GfF8#[#KF(LPlTiN$MqlJiN!#L[Li1p,qILi0 %d0r&JHi-F(&![i%Z$M,%)"F(4M,Ba8(''1,L)(--Fh'3!%''ZcK)*50F(156N5i 1-XSS&`HTCE5,Ja`caX9"XKRViL$GR1$L)1Z-Fh'3!(l'ZcM)2a0F(#5LL5i1-Y) N&`H*DE+,J`3eaF9"MTVUiL"CRHML)'Y0Fh'3!,kQZcM)Bc0F(+5cQ5k1PYHHL)- F1G[&3G+VFR'3!26QZ$K)IR0G('6"jFr&53AdTF26A"aNhK8Z$Y,Vk5i1FR#0Li- 8Zm2&3DVGkH)Ja9lQiL$M[X6&38kph-9"1YlPiL#PAq(L)%[[GR(d$UJRiL$PAqR L)+([FA'3!,Ih[KSR'8qjf`@I6X8ik(YX2%h*arii`&PleZl&5-AU[NlUB[Y@!43 #A$LEZ2$BrSrpDkQd8qe$kdIAjYjVcq9RB3A191d'5he2,q9eS(hYblQCb6!MN@E GN4f"0+12GZ64M$ZLc`FMM(E08RNYNKNY0#1&k*PSPHL3!(DX%0d263qp$LdZ@*G Neb5Cp8M(2JB1A3!$H@i3d(!3$-,eaKKlbhkBrrcF!b0GQ9bDerACGR!(I'Cc46S h@ElJp2PF$e10dXBZK#Afrl9`hm+@Y3(VkQ5,4J`R-+qQD2@DljiiHq(XME-#CbA 12MMliZb(Xcr1!6J(iKb#FbM1B6L(iab"Fb6186K(iab$Fbc1%h#1`cNHj`5F%h& 1`MNCja5F8h'HL(-DcZNiCq#FLA-@cYNiUh$1`6NAjcbFmh%Z`,N3jb+FLh%Z`EN 8CcA1C6K2aRN+cP2c0b'Bp5rZQ5q+D9cc&J6RbcGNT&4C2cj5(&Nr0Mf'kjU*dV3 ff,K52QH-m[%iZh)*V!01YeYDLA"5p'&ba,jkAB*9K1cY5hUXa+Uhh3FF9X@YE'# ZQkM@HZ[ZFQlqSM[CNCIc0C[[dQjl5THefjFARhCTb8mmNe[TdUkE&aT"XH5hLrP @L04L[R`)XkH`aE9BSD#JQD@#+6F@8q5cU-%@`9`'DJRN@ZiLE+V80@[2HlVkH$9 9$UIQE-A$l%e-13DE'&1HQCf-D@b`qaG6ENdV$V1Z6@@bD`r6eFMZE``F@pTF9LD Q+qf[YQc*36aENV!E),0HKC,DhCBC*rC$jMbDHp(ZM%bjCEC(TYc@aCdN#'[qI)K 8kZF2Ye"ceB,YQ@R)cZc40)LJ[Fl#TYB-qV'[djHjJM*T1&2D9`2NVjcAHH@$+e5 EXF8kCq(&HMC9d$TRLjKac5+6pFad5Z#BEI(!fh4ji*GXkdc"Fr$9l*X#Rib[J*M ebE)*kjRT`#E(eX+dYQG,Pe[h*L"YF@iVC`C1!mGLZeP3$I`dVMBjj8ZG49IVQ39 BkaR`,ZZES9k"BljFPS$PPJJh)@,JR`(&`$R!aF!r#if"G`BG!fF,N!"jhdc6jJ0 ))q4G$r4#&LcEh*-!dq6Z3fEJPN(0`0N#CkY[HkN-I!Cqc3JD4!K!Y1"rS-`@5[1 q(BfC"Y5m+jMDkPISJJbb"XiCF!fFFrJDZ&Z)cIX@DTK41R*ESTUjCa!Jbcm$lbB 1'J6)mG$!2FY&!qm-(mdlCdP52N*UXhDcEl%TF[bdc6p&kTVmKDF'IPQZ'RKRq'U Vmi'#*APVi0M#AB-36Ibe%+"BlJb2c6YhYQPf!AUcVqDdVBlYlC!!jED"GjEI"Yi "a`hm-c`hlpaHbJ)-bqlk%)K0L(BS0[iP-$BK$X#a#G!1b-Dr!-R@[EhEEBcQ*V( HBCXFJ1CXK$aD*5-d`E2aE!GSieq!k)alUAJY-'eF1i$D"#P"G5j%@2i#A&[hFJZ h3EEecS&faVAB)1h!EIcESG[i&m(E4#M!Yh8[&VB)i9h`(8*h&fah3(B)eb@S,X0 d%D*,m0`*cCf`h!E*)4bAS$L%i3)%Gm0[&r4f`@i*FXY`@i6D!Xb@)$D%ea"D1f' e"+P&1'f(dLj*+K5NZZ5S$M%UP+*+3P4CKLU+8#8*UP1!kT5IfX5R8(SU#8qKl&3 3RESPTbl"U8YZ+SP0CDQT+$39C+D5b"4+6+(!e#N[PF5PSV48%TC`$Glp%H"KmU% I,5QYA!T#qeb00X*3bNh6eRaZ"[R$h-JrrmU1A)MQ4hIN!U6Ii*(cE(f54kj+A48 J4%F&#0"@!6c,&FMdlYT1Lim2bG1(TZH#Y!"B13Ep'-E)p(T,,B`U8-kKA!Z$$5k -*j!!1#Lfe,2#JVUd,hNdbdKPL9Vl%QdE*ebLEH1%5l4YR(#*YSd6,Y'fFF)PfMC 1Z%6EaJQAD0Xii4*Y'bGFSQhMK%ZdECa`LED0%bl4YR(#*GSf6VK%fmB*PfME11& bE"XRA)jYii6,X@fFF$QfM4-ZalCa`ZAB0Nki(0['#CGMfcMKFQ`E*eb1EH1%bl& YR(!jYSd6,XHfFF,Pf$C1Z"cEaJQABpXiiA*X'bGFMQhMK-ZaECa`1ED0%bl(YR( #jGJf6VJFfmB*Pf2E11&bE"XRA)jYiaaFMUhL(&b1VH)FA)kYiKaFMUhL(&b1VH+ `M+pl1ED+`m+qlZAB+Jj,rEUABkXi,2lVASkYiV!FX(XjYSV$!X(ZjGJU$NX'ZjG MUcJX)ZaHMUhLX+b`HcQfLX25kqlPf#S15kqlPf2VG9LZc1ABKq)S&DYT'e-jUGb Ah,UR(MKmrP#!eFU2Ej8d$bR@RcbfmER2$I)mP#)4q@p2Cd"09Q+69ba[Vmh2["h '0I1CPp4`pLq('AD&e5FldL,(TY3lL06MVfVhQQXI,TUV(MTl&CrC1+D`dlaeX4l a+89heUDRcN+[IEBm[RQ,'YZcr4Hpj5rG"elG8lMPLB2l8U-hlpIMSe`(AeY0h5@ IIQfbHU'dM,E*f`ZVp5T`2GLbVKd'MIP'S#G`1A-q(V(Nf4hFDSkN"fcHX*d'FT& m8"f41"*mihIeJ'@Xbr!iame*[IX85[mTM+ica%MM!FZH&4kdFM!'%&dp(-cCJ3G kNf`4$p3M5Dr'AFf4'JrR'4iSC5c2$hbQZ$-FBYErlALJq)(S"aNm8&ER'5%Si)' HA'KjES3,k(0%2$I#AI1Q"I8b[%&2[e6AISk)Pq(jJraVp6kmGHVRp4VPfU#(#*b RjkeZ&(#IVkF8AL#r#h@r52lAk(kamYLN[#j4R-h+Di[Z@a9RQq,ZeleHIY[eA0C ,Hdc#eY$&mQ5%ja-)Nf#+563pIYUjqZ8H+ZjLqCa`djrkLjT6Z-3Lqc6fh$I+VUJ ip[%fi"AYYTkAI#b2Z[+NRLGGr(*[Y@rpkUU6HVEdm6`fP[3XkQ0eA9ZEHLl$Cr* B2cic26UhD))drE2arP%hTrjBciC@Aq)YZ5hcH(hj[1XUZFB9hIFcTZ(R)Bq2E[m blpi[I(iHRGY4RXkMXb"2jp%TT2iiMij%MZ44[f6c-,+fGq(Z[GhKJCKh&4k'r+T 02c(HifGFZ2Zc*hQl#`r$rYeZ21qkAKj0laTqTKlX)04jG1R-U3Il&`[Vjk%f2$X #mYKkY,,PZV,haZ34)Y'422BBpZ'kklqIpq-&DqrhTYr8@aENEF0HiSLhfGZm*r, +HrP)j`Mmr`0alM66hJ2[i(21r6cfQX@AF0VII4c*J6UCA3kRcbp9M[%BBUakKFP XL`-pbIYr2`Ub*deHB3f(mYLl'"elTC[D*0h0crCQR5%"HI"9S8PqAPF'"B4a&q9 Ap`IM2U#TrC4a&r0`"M$ZFpCY1[B'ZVVUeQ2eF(``pj)#qK2QhTh(BHEHRFGKj[j i(SHBHcN2cG`IZ4'R`ZcB(GLGk60h5*m`ph-r2Q$Zkf$AI0h[h'3H6c(h3MeqaYb ,KAf'ZCIc1-cF#fNmbpc,HH5Bqr,6rXhFPkpkNVRA,jJM1"e")[VC"Uh-rGiFTjd IM([4@Mkl[ZAl+H-qN!!(Rb1!FDZR)*ad6R(`VS2FerFeaR6q@Uk-,5,H8ibT1ir $61Ia2!iaRA)H$5B1SYY[-S9l9j[6jVi*YdhH,YL([Zeff+lV-`,9D-TK93@)ehM l$h2rbllqYAiHLPNi![)ic#`+GAf@@C6ck!*KPBGqNN3B`mqM2M9VeVc!,%LL2K9 i+MY`&LJ!5H3Xj@%T(1CX([GHd4eU,Eq@-khBq!hEMZ5ljlDrP-FjFpZ2j9'C8kV 5e'+rA$YEqkj6[1Xf[eMjPXp@2UQG13(bU)R5e)`'I2$GJ6a8)qTKhP$PeCUA%k! H@UYb!Z4KY+S`Mb0DeBkX'CNA'B&DlIr+Gfi8!aLblBj$M1"f,NVhmlL-A95Xaj0 p*KV"c[D4IN8M+(*l2`mQd5-Ff$rHpeSMF!,dUpB)R!"jD#6AF"EjEeee(Z`c10i I[F[2$kl*0kJdZD8'-P3rrhVPH9HM9X%K9D8mmZTe%j+MJMX"mY$UY@V&[8Ib#06 V2&F8lD-cMjbk9Xa$-@P(3"k+ZMS#mVJm29S2YENlqaE(E"j*EUqd'&G!2C3@i`E )3m&CQ%FCce*j+)hJD"j*eAQ(5Iq$VmPk0"L+-@&rC&6R!rf"aZ3)b%0T6%Il0DF aZ3$bf*HDrr9CjH!*R+d"+m3)([,fAImE8lKRaTcfb,8plf%I[HGJaFK'fEPiqfl )jfQLlcqG[$h&#"`"H5K'i!M)3b'j+b#2KL%"GGeKfZhAmdM0I5LN1TT($UQHbi1 [bRmC2eBHQ%L8A&*jE(QSPmIZB3"j9!iHbY5+H$eceE$Z`EYAI((f`Pb&'[-q2M2 $rmBmqX,+0492&bSq2T2e9%-R3"jDTA-#j'&8ZM#2[%UAbZ--ENNbUPK(29$&L[A `mp!UP"1JVRT5jAJHh2Y2,IVY0+i[2mq(4PKNZ2[mB3()i!,))kP#PI,)Ebd)1M' T3[eI(ZM56S#kqSMR!XM$)*iL-8F3Mp+f)Yj@6,b8kT'I&Qr,3c%U4d!HLJ-l![* 3(0J9N!"(`j!!J,Sb3hNFbC0FqQJp-PckD"ij,Zd#b'02VSTe-#qe*N!$G8HIlAd j$pNfd*'(hMDJ4Th#22,E"S)mp&`$MAmFlc@MG!,NS4QPhl$&rQMC%K$89Fmq1J( bi02Ul0'k-X&eGYak9[-`ReFZ9iF!E)$6ma(PVA+MKlrY03Lr[!S9I#kQ[3E(2XI 5AS1'pY&G!Z@kTV@'MLq[mVEf"rX4MRm1N!$p#!8!HABr3QP(T4YJ2d*j2%,Q)j` !(H31B1k1#QEU"%"1Y`*52IQ9Pd-k3$3GKmYfb2"c%'JalU$YN!"(2mI5GXJM@Na E)Li#,DBcKXapG(cZV5f6jC9AN90IBh#Pc6irBA$GH4aQF0ej('C`MqGaL-'9mhL +H4Abq"Rc+KEN'HC9cZ-`mbUNm5cckXlM+HE9PSLMB*GAk3YfHE9rEJ"'S20`5Zc b+UrbLVajq)5f@&1jmFLQ`L3bG$r-3qm%F`,NFHEfC(i8jmrV#V0`R'L8HVIBXIj )l4BleUrZ!%e(laBlMKp-E,kSd6kQk6aC9rH%TX-R1mUHUk[1Sq[003Icm&rIadY f%[PVbRKr4AA6(hEfIVE1,rhD1RPGQb2[pAdZRhI[1$[`32&dp3SL"plVqea[Vke ,[ZQT0+RV22h5EhVUQ+ecQ(c2[a6Ip"3&!90[VY#rmq8E-P+UV"mI+BkX(jXH`hA 04'PkC,K+!cKK--!4mlRL8-#0m`he,&BQhmEK(aC!PG&&JkI2ja1BTRU$L6VAiV9 FI1[-#IPp2Gr1TEi0d(2jcM2(jIH03YKpZPqPqp@k0qTq[MNj[eq3!,rZ8-R[i[G Lh5p8[KI*IV(bhD6m,e'qQjAr&YfhQTAjIC[LeL[ZGR0LIVpdD%1qI%3J+TRL48C %*b*C%V%#Cb91ZU-[cRiiqq0Np')JcN%i"q-F`Jj9jc#F`h'1`$P5[6SDjaLFBh' HJ(-F6QBN*Z#FL(-5cXNiTq#FLK2*H4V1k6KRi'6fM$hbXh&@iCb$Nkfjmh$1ahN 56[C[,F6*200LR%Y`,XA*8kU@$3R!(lSP0P@T6"p`LPddYD8l[q@G-VDj0P(N1JE pfN1UXfTLFKb"2GfMZXGdMqZHd,f(lMeelk9lEpdVG+r8[BrZIAA[ThYrh3IS2P$ hNh3IV2X3h4IS2P6hBES2ehf%lL0e(kAlD0h(k$j@pa0d(kIlH0dRk$j4pdQk6pC pLZj6G6p4pi@k,p*pXHj,G&qUHlAZbh3r@IG6G$ped+l4Nr(Q[QZk$km$qL6)00f Rkcj$pjQkcp*ppL#Cf!QYF&GYSV*PKMJU!DTdRk2lA0hRk3jfqFJaD@YhT@iRrVK P2KH2iZLkk`Gh+`C%*M'@1XBddqc`p'r2bbPl+ErFL2+3!!FSPbQr+`lja6q(bc6 il6cN0`,aHLQrf"rkIZ2Ked2j@EqTm)XU2q[R842Vddl`ZSJ"phfE$Z+(pMAAqPe )lFeA!L-HAje`T[@EqaKX[U)BmHl'TCIe@r3J#bGqlm0P[I9E1!kEVc"'#Y3!&eQ rrGq#c9FB)`@1+9GC[fZTqrP+Bk6![T!!r'kR,ZJVPT(#cVlIpNGKmaA*51%MV)( [Yf)cE15,hm[lIVGq"MCd52bZaq8'klIb&q`*hbm'6G+l`ISYqc8Fd#XT&lVM+1Y h!hYFaG(pI3DEfIIc1*U-IUQq`6p#(P(e"d[hk$[Di8BflDiX*4kNQF2XEk!%[CT C[XFJl6F0I4cj@c1,iN0qmIYC!a82R%Ml,Id1I"FdXiA$H($+(e(c@FefLRKT2qm #k+E4hGA*0%-fe&LrY8APm)8q$YNm6N0p2H6A`-RVG0k*h`rU+YM"Yq1[JlUQr,` 2r'Q3!%FkA[b*39h6IUZSehj2IC!!pNZ`RrfqV(hl*f$6V`H+Q!rG5CM6IM8lYm" "fIPHY`Hpl10Ic3A8L0pZr@lj!EBfl,"qEq4qjRGB[aASEqpikrI[&2MHUEc4QIf qVrRG)l#TrY9qk-89eZpK[Q8"R-52[3RpV0pqiZZlVGrTH%q@Yp,@ErkRiF$ED-! Ep1G6EEbEL'GJ*RQFfmrM[E1`JH(UUd%G[9pC[lZ*-DV11JrZ8ZmIIJmfrDB'T8G Hh-2GQUZ*K3Shq"U48pcLIFfYI(mHH%iHe-c(dGUcL'A[PjrUQmLFpD[q*@bh@Ep Chm9PLFhM!p3SXC2h3m48hqreAi$YJkSVI5hpG-Fqf+J9I[5Kp0-[FiI&KkcIc0r LmM'EGicmi-2@EcAQ!Vc6EEbk6m(K)kV(`m3'hqpGl&(U4[hBDq$cRTV2Ei,YSpE ["HLrU2VQkpb%FSIU3Cp-Y(jIqbGXGiS(-)FJpGY'r4Cm9Ypde[GQkrFJmeDm32- $a3Z&9pANVrIiZ2cHfXHc8Cal!2r9Gbq`UZ)+klIm'MKm`[VGMrH&#Cl9RXYDhfA p[R0c(mpH0J@(6eUr-i&$"XrZiVc%Tp5AkReM8VrDF@,+TeA[,rIkVlE)HBM2U'r JJB*$Y`(,)cqeI[[q[iGR06mRCX%0bBrhF2Ki9PXPVlTEHEbPRmHMa-KlV0qV-IF KH&Cl+6R9je32pNG)Ael(H*mA(UKi"XrH3jb'[kM[YH!4"XqfI`N1Ae6Hc*[iH&C c$IR"PkcI5Q+fMfFe)IX$ENKqm!I"XhTL&Ae"hc-A)RMf0YEb+kSh2%EkD6jl(Qc %MhdhdNp,b(HrD[fJYB*R06%ASm!Te2HDrq[K@HdPMm-"cUZq'mPl"-pZ*Ql"cDR I!hdmflm,Y[XXhkT#23bHhF%qTJI9pd,'&MblRMhp$I(40rAVY`iF,N+mKFr"F3A 2pK!l[kNmi(I5ClIG#KYm818p$h`qD[Pkj-2%P@pC[j-`ra-larUpJYV$rHS$HXA ([mKGem0'29@ma4rXjl'42IHJp9Z+#4Q6adZj@%@ikY@XZq4a-cQHiVqD"p#MICV B,C2LN!#kRq"*YcEp`hZ%[22'F2(lUA)9GkPm@hL`'KGIjkKB64bL0qN$m2%0eQm c"c[J-LU&&F!Hle6VGarRMq"@bZ9dj#hj99af%ccJ4r"#BNYq$c!(-&Cp0l'RrI` U9j,cq'm*m%VS0mQ[dN20)Z3lbU8@q"'e1"FrmfTid-[J%2hKid(X%FihU6LkVZK 2iVH2'XIhaEr"+['lK4cX"cDr9Ar[j4Il*$R%)iV(6*E%Hj5mA-A4r3'Ip2hLlb& f2+Tqj5lahR`qE$qLerm$!!d39'0XBA"`E'9cBh*TF(3ZZAJG8J#3#!Gi(e6lZ3# 3%$DA!!"q#J#3"2q3"%e08(*$9dP&!3#[f2mAXedMdJ#3"3%`Z3#3"KeP!!!)k!# 3"Rrk$[JZMpPjM6ZlhP[jpekR*rFkpl00Ya2+DB0SdF[Ec10(ffbIfFSmZEGbIG[ VamqV-kqC[CHIP`dk*le[1E&MLjRNPZ201MYcN!$A1qJi@A`A,p0V%&r1-32'!MM aecIS(H4C$T+rN8f@ipH!E,)m@AKf!(`"k)"R2X$CNNUeHCjAiRQKilc388GjSD0 V2'pfTm5m-K31L@P2GDSed4a2Tj1TG+`KRESJdC)0BTdUaaq))q8I9YrMl2bBXdR q%I9G*2qSqUk9rc6e[8hqTHVlZ2bRUqqVmTqKC9*2QIU1%U0FIDH*-90pCiXa5he 2&@1fqUi3BilkEK"MV[VH+mBmpAe"M2RUfbA'!ZX,(b('3[8p9Sa&kRZ#')HS,b2 'SHTlS4L,eIGk-3j6hr[&1&ap0i[a)1XVBAiHV,kMaAL)qYD)3HhiYZTmiAZ"'$( e[8N-CJ%IFd0qI&mAiaMVLc!2$eAI-M%HTVj'-4kZ[JiaMPAI9@)FTlkhLr%)pAe 5M%HUlcBaMVHq+$1c4(f2&Q1TqTMl#[9G,-B*kRZ0'23"hdeL,&IIjm8i8Adr%1- Nkj['R+a3hmPL2%TpF6'S&pqcaAL-qTM[PHVlU"M-,$jQSY,k5X%&-!SIY9%A[LB a6P&IPaLRUZm9BS!cq2j-M029pcNaUY6h3c(1X,lTc(1eqUKKPIUH+-CUp6e,$'B Fha[&@+Zq[aEM62A4-q%HR"RJd6Ve-4YRUDp"M&VeJAPekJ0Iek[[A@,8UqmcBT! !%ppha(LmpC@"@4[8arb!$rLDa@!Zm$%6B#bqPiYaM[USMcci2Lh'4[ApKaMJ*(! 0ES)*q-!&CJ%IrAU5qVD*FDlk`0%RUqm2a$K2I4m4ibRUqjSBi!!8!!k`@AhJ9)[ kU+p9I4H)N9$IFm3iAhfr*mB@pB(6i#dq1%&5IEH,3AiS"VK2Vr#"(r"&I25ZAAh -0lL+lh9LT03(*X%Pm6(Ic#a8"Ck69Kri#+I!ab`TXCcp$$'B3Ab[%Z0#pIfj'(! VI0m8Bl[ecD&21p3(9S,$q*LITkR[H@)mAAer+-BPk[X,-DJAhcI%Z06kjS*$PkN 2h(bQqTJVHSl[FM(!C(cJ-E1'lfr%H+lk[L8'YFZC"apl[[VS%rRad5Ii$Ml`J$m qq1+,e2F*-H"hq,i[aTA@0arHp@,eJI[`'Rc-k0AUSbrAU1r0BVa%I@!`q)N2M,R 1qKE!&9qU2M$XHZYc1"a`#Mi0MiBr`j[KNr"Ym!5qV$cCm(%`%Mi)ri%2-hId&!l (A-0c`@P`!ci,*f#1i29J$4J$YS!Tm#VQLVQ&5rRF$1i!Ki,h`*R!4qBFM)5MJBr `*hJ6I!QH"$q#&m'(i%(`(c!!lJ2RJH[!FF"bm!&-!![!9h#!q@IZ`6G`$6`$aq! `F"GQ(pi#Ai%(`A2J+f!Vr!5H"&D!dI!Km"QZ!NH"Qi!CF"%i#*J%ji"VJ#2`$2J &q!HIJ%I!Vm!9m!4m"d[!%,!$M!IE`A5`(&i2R`GIiI*`H$J[h"m1$hH(Xk-GJ-I `%63#Z!Mm(Gi1AiHR`h[JjI"aH$JB"9E$[H%8F'di0[`4MJTfJpP`'I!D2&4m[[1 !Ikm9k*!!f635#Il9UJLY889(H@fJ%i%l[Nj%(hfGL$ll1K(pmA8L--,ALCKGAbG L,RfGL&P3RFKJJZT%"J0mr!029#IbIPGaN!$c$X9$cJHe2aaiV1T%hMmT6R*Z9Ec NS&1S6K5L,kS6KDK"GD)3mk`k83Mm8jdS"%DS6K3#-e3R#M'2UK1&`"$9L8+[eTR &paDG(A`l&5[`I8Ma""rp8jdSp#A&&Ra`1G@*3QJ@UK1&kCrU4'(kU$T4Q,bU%iA "$p@*`Z#lkN4K-&0eSM"BU6T4Q,P8R5K-Ae8R#X0G95F+[dGa#KrF@(@L-(U3!1T %BIUR1P(i4iTK3!HcTcT4#Ee3RDL%hUK19!*QU%j8!YkV6P3#rUT19!*'UNj8`Xb T6P5#,U!k8FNlPH2J3cG8RDJ%rUNk83QkRZT%*I"'eBP+`!R9L5*JR1T%%A""GD) )FkJk8B3C8*dS3JfU%dAJ3BUR%IL,kN34H)IU4"%iKHT%%AL3!1T%%6L6kN34H)M U4*%hL+%k833X9*dS`PbU6K6jX"LU%d8q*BEU4*'[L+%k8H4lBUK1&!A695H+JR' U%d@CHG@*SXb!kN44kP'G+!V(8TdS#Lp4R5J+pe'G+!VR8jdSqM)a9#FD2[51'Rd q#2k"D6lhT&Fqri5E`"qB4l!2A!2c`%0k!ID!D@!Fr3-Ii!E`&A$!jkr-)cJ#(S! 9m"pQ'Hl!I$)MB$kc$Jk"5f!%1!5ZJ3hJ*AK"Vq%02MpRTZ"%m!4`'ii!aX'"i!, J2M2%V)(T2RpQ$TPljTdjKdm`ir!SjY(A3X&5RcrUc"QFK6q"bA!Rm"KZ"GmSk!R J,V1Xr-5#YYV-J-rhh!SR,*8VGaSip#4'Fq62A)%R`[1MSYmELQRaCFN6[G,&b8m +1S4N+ZH4p9*Z#ZbaC#Ccpd6mhNZ%r1fRXe!U2[-clPQDG'CG[1A-4,`eNFj8U", C9dYr6&#Jq[6i2,Uh#cU@jI+I*IrCmTmMrlRbRbRrkI)[PAqCr#2jfM4aQ)#5%Lb *pN),QPVDiTfGEBP-5cVCQDh)E'e6,IDZ)qPV68j6dDVDY4YEYL9EZ9A6h0K3EAZ B+pqIfC(TXihfjhR1Z[L&mHUfH#D6b&4FR&6e0AFfe66%eP@G!rU5e8HVhS%T-@h S(chRbK%d#(!VbVbDiE#X))C$rS[[48Ir-,Z`,erC!BhpQD3df""Mk+XpVS(6MmF Klr#kj[-%S+V!YdD$EaDG'`5CG#,fP++`Zf+FH6a+1UXUbX#"BF9S2YMFJd`fUMY NXV8'bB0Zq3eqb&#$UpI82AUPd3rkjr8HB1hZ8p3R&$kHp)a0,p,hC*ZYp-PBC@F he&4dTK2R*rA+`fkX8XYRRQ!,p[5GjalcU9flV[eLAd)h!cee8"elMm,`$T&X8!p #+JNkh!jJX%Z1NA3&%CabH"##Y8EM&DQZiJA`dq48065)#KZ5f`Em8B-h[Xq&d#J Ucr[(Y0#IUf8ckK,T,BPBr@M[4dm`&i2+hrq`rA[%NEcBd#0NHQZ5k8`feTMBdTl Sb(U9GXKVNjYM0HfGUA3fKMj5ep"FF*m4EfY,T6TLCbED1VfkjPMe#GA((fm60FF DiTQ@H*[aENKFl$@XAP0)ACNETTiq0'k9QRYMM$UcV6F)65VEdLB+XL4-ap-l+PV 8AppBeHe,HhQpKqTU1V+*p2RaPJ61ZRM@P&cA@"[Ed0@46EBRT,5+9E@e*X6d3q- Um[QNLE%emH0@*-pEfIS)'bMCkTSeP35STY4AK!dc'I2646H$#9+R6K"Hq9GPfVf 0eI9VJM%bFEQT`SfiE)BK+B$f(UqcXqAe1KaHTF3ZTE&Y8VK-8dqJ"*K!-SVI$L' 4+bZ@NG3SeY+fhF(D640[)ka2`h21RXNGL#[8SP0Q3hS(E9rP39h5bIC80Y@2)VQ %8`hTca9V6(@P@a*Hiij-0Y%H#mD00(BbKL6'LXk@VG*@3D5B`6ledGlDC-Hf4&S $T"Pq3(9A*TYUMjf9f(&4+YfDmDTD@K+CM1"#GU[8'jFL!1aX0YQa*52ihCD)e8Q RM2H-VQ4EDfcepQ`kR[&@*6ChEGQ55-GX6Qp08i-8dC&S+r4$)`5VBp@TpNkT*Xh %Ll-eX6E4BAbVNKR)8[YQ2eJEKFYr'-4#@&##GF[V)4fQ,`U+04YLpCf#KXQ,*38 Gpk[%eeePIKa`#H"C@kZe`+Lp@akVMAGXkBT,-i1a10'8&T2D%ZPi0TRUm%l+G@0 &V+Ue08Q8i#`05A9N6$2AYU8fDdLZ4lZ$3-['E0IQ!%U&Fq!h8&V`N8K'6@!K*R6 !J*J&b19jr&)II+'k`UFJ6X1MGeQ@kd-rSL9dh`M3P`p-(ZkLR-6P&aX`R)Fl$I0 bp3cHIG'ECqF1eEdRRq4"IjVXTiXr6pmG[2llGh!9lZ"a2mer9F%9F+,F,B8QjAR 5rkUjhKaTfMcjFqXD4NA2c"dcrkQ0i(kXrpC'%-#&Eh2j@HiiQT,mPcD#$1Ej%)U ,jZl8pTq$MC2H60`LQ$L&@`BE!`jkIcf"mqc3eD%CBAdh+"Jf*d#92I2[bVK,)@- 2&XiIiZX"'%J8F,&J+JqBZR!U$rLmD#S2q(h)9"i`-CE,-iK@NJHXAcC9MhN0B%M [+16KaB"*A86bm+V!BkEUi4@'Z90ji!+E*[3GFiGCE[i2jHQj98m#9kZH)&bNF([ $h%K`VTlqQhU1PH1%Zae[M[pkAh#F-'rP1!$1HHGPX['diq&PmC!!2"i62&Rekck k(CVThfC`caahc+0@$S5R$%U$Yi9bieBB2&jE@eqr[UTZGFAUMIVkBpmaVimBRL@ 'fRZ[CIchU`Np5NCPhdAVh[#HHpFpXAhAX([$HfjPp`ChAp,ZM5eF[GiEfRe(HQq mATRH'qRIR1iEJCjVf`24`EhT[QKlUEXhU[Z1GfmX$fm!2jflhhq`S800-V(Re2@ &lER&hTY!Ae,Beed0hpIH`[hd[D'MSjLr[EihNX[Xr@'$cHqqkYiEfheVIkp-0ij `0NF4jQb#-Dbc18B"cfBSSTj0-!*pZIMLd1@5$%aH,Ra`cR4H4Z'`N!"L#$3d46m `fY!L1YS%)a#CMapYi5"BfYJ*a,4CaQ#c1mIq-4J"d&cmj%!23fNZI!qHjQ1,Ne* %9TZJ#+rfECTaI08N4B$9$'-)UdP')9C6&$&@-ib!E$j"F5Mc@3DQ-Kmr1(Vqi)` #EAH1)BMaFr4$VFB@X9BcM)"Y)F(q4Jl#V3C2i+fQ'32FRL4Mic!#ZIN%"mCl'(6 cmAY3Ya!m1M*&h08-4H#9j11S5iBLj")qKVGN'!9EiSY)5rJ)c2V4a5(d8`a-S"m m1'&Q1NDK0CGJ#%K-JRj3*E#)U)52`'N32G+f35!PFJ*&b6%'SIN-aED2J+FI26k d`l$T"qr"c#"bH#k+D%Pi0e4U&6'$AVA*c#$[lAXAUMp(lUfSrZMY+amYf0H5X%m RM5,j@+dqXadU9X1RUQ85aNSeS$j8*l&64GVHplmfeCpRc`Y8r9RbVe,eK`qm9$8 `*!IDSSNQqU*TKKZMm91GBD`1Y)8X%cdKah"$#*lU4LrfkE0m`bVKlPHrpLP-GbC U6RCXJ&`8&68!D&3Y)rl1@NP89-`)hdr2adFNVr#-Yb1["pb9DIq8j-R!IS9MDNl bQ8C9MT&*kDBEJf2Lmr6a9[MmEbV0rZR`+F`)IjfD#cr0-)FY6)5Mii4P'iMmLJT ZPl2`f1Vk9DZ2M4flUUUT5Xb'QZSQAAh%PA+i,aNfGmaB3D6F3IF'1RK3Z39*)YR LE!-'(`r%,((3[BN2(YLV#BeGREc&ADNlVEM88#+2"jBIe#@bkG4&LI5f6+`a'qp SMDGEpDh`(CAQKHG+,pRK-X1(2"l-X2T"C9dURH!kMV##LK89*lR@''3H$mS%%5+ (MD`QF1F*YJKb"T`$VjrQqZJ-1'k3!*Gf4TTAL#cipMk0)J%4qE0+9VRmTmQr92l 6j6pErR2P(lcYDplUp2G#FlUGZXDDeI2-'KXGFRejpIE10Q'Aplj(@C1`D5X5fh9 642IDLI6YJ"55IFVQp9$6j4@kQT`lj8Ml4FbYkC!!5k6a0VNEYbBGYbZah(eq`dG Yr8f*G(Zb)jlp4IPQM*de6m$G5l9C3)j(`RreP,ibI218[Y43,VYGQ3cq*SifJlb Rhlp4@N(DF3pS26q&N@j9U23UfCRc`2[qVS*hhT`a6rFj"!CUhp0pmhiKDFQEQ5k B`A5r(%HJ(Q8@-#`X'K%HA,a"mN!j&NrP33FjE#V2RBY"`,l%A$T9$`Y%9!`Ye+" Vj*Sm,"55@jKLT"i@$YbhD%5K2b`N-EPSK14K)BPpLdB8mV#3!-5q450f(`I`3M, "LK(j4pqFUfGJm6HhbR((V4MKPRZJ5PFD&b$)B3(,k-T5CMXE2bJVYcIiUeqlf3j ,$HF%DiX,5hDZIpU0ZhEGT1Y81pS10aU(q-+KK68jA@[(&E0kQ3YYJC[lV[(64qm h0rM[ZmBr[AmhCrI,Z`bbYl`$B&XB2IhlbA5[iAIJQ[[iLM2h2M6!&[4"'i)0VYQ 9RKhT+l[&B,[AV,cf[dVfR1Q3!$eI"aGRGjFF"i`BE)@FqipplGJ4F)V0B)rrabP 1RUa2NTbLV`@FUKKlQVkFFES@FSEDe4Ur5[1YeVKce&kMF@Ye2rBcc49CZ85ZpDc 6$YHU[dlc0UZpA[2ADemD0-rMG30(Gm$$&308ii%%`JYHB@rDqP6(f2#(kZSD(!$ hL'%lCM'6d@[*mk`UI2pjL[aCRYN08%Ger4@6YdGPd@SDZcp(G9XQi`DSBpd&kI- Vj(pIAhQ5SDkjHT8EB$if0'kSGJ28dE4kBe2&jM%KURYCm+&MkYLDEEp[q*N28mF &Bp0ialbD1XDaNqA'*`k,T2m@2d$J6FR1b4YGGr5e0GA5j3DBqh3QhH)'U)06)I, f+-VHd9G6apj&hRp@aq3V$!pb6c#GZVVD-bEbp#lc2YMjKYT*K,Qc$QF!3kNrBpd "j1cC5RlJ1#UBcMKfGQp8[lq1iiph"G3aeT!!RpDa(i$rXii**,qV$T(*IM[lPTR H2km"-ah[4Xrbr-9qG-V+8Bk!1Q3cqIrV+jIcr$T'NHLRGA6ZCkF6I3hUF!)`Ge0 (*V(PYrMKRQ$FGc`S+NY+6I+UM+`il`DSJe-K3h*IAa[!K[b+YJ1Re$h"h"d9c03 *J*aZ"D5kieKNb'rQeAIF(jU1Y(DSmrGS1L0eZ%e8jlZeQ1(TZ&H,QDcMS"Bc@FG ",HC!(AGT-40eZ"HdQ+&qr%+,'@RX29V-4"d(YCLK-RkZa8c@FEF@-eL)Ld#,'FY KPk3Ebl'aZRk5$j%M8#f'CX6jSHN-!p'pQNi4m9d"QSlX1hE5LE(m2Q*pCpCr-6J TC$r#h-hJ*ZXib1!QkcM)i!l8F4H$QkLM0I(VqfY"(AFcZ+&qj"MF3FBd9-I2'G0 %(H0J,R@B"GiQCX30J*bQMVDa,EhcbNpamU@1e1B,4ZZShhc"J6UF-+mC1Q+1HH* N3hep8b'SC1f'Xhh8+TREZ#166E6VdNc*",arqTUDfY8mVD*f91eTDTHUEI,`5Vc D[VmXAf$iF(P24k[E%C-0R@+0@`8TcGjm%Qj+NT6P@Y*mY4HVlFI09RY'[V63,#Q Y[V%UPNPeT9ZSaM4+HZihE*lDFc@Z41f)&ei61SDK#&UEVkYmTR!(dc'(()lUFAH p#2r,c!qmD9jmX-ZeXec"0,R20[-"rm0blG1FFmZePcRRPQX[YhM3NQV[M'FV[B[ MF-HQE5XVPXH@aTV5A4hE+Q9r)R%(+CaQH##QV0IXP(Yad!ehh(!ii+*BSFXPX($ @24ZDhahTRMf,G&NmYlbUi-Sj2R0b8@J`ESV&#YP%RJ8(cA+#4mRrD"c'+qFBq6q d%2!`q6qb%-"QM-G*$H94(EZ0mRq#CL##eH4r9D$1LLQ`N!$"&#K&cCHV&rI2NfY BMAU3!2arYSaPeI"5PY1-l5pPZ@FCbjR'VP%fj#pMHCEQfk"fSpT0DTqYGUhfb9r DFQaC5mNKZjY'a&9BiA6Ii4%C28@T[([9DQI%'GLC)Z+8f*R#P,ChCiTIlNSK@HC -l%UKFBXNCqPEEVeaFRjZ[[RQlVmri(E@Zk&$Ph"ec4chc%3iHI$$SF,6R$0cRjp 9Pbe1LXBeq@+emr6dV$LqrjPC9mPa`Vf1DFi$EjSYIlc6Iq"j#lhf6,BAa82b1'$ TC4,AUja0[d%ZZ4,Ad40A,[Qmib3Zf40hj%mNTpCAmY9m2KQ(L0CAL*[c5DPGkb[ %(5Ye4,hfV&(bmLp3c'1X,T-iH'JK6ZV`BZhC6&qqE`&9NSmqjH-@m6VLc2CX@kS REMk'pVA3Md2rAZCJ5AYRTMIZQ@q8*lTUfl0EH[XkRrNi[$-Y@"fGm8camDiE)I, i4f5CLBYF!NpqX)ele"+TBkE09mC'$!qaF5pp[q5mdFCGFV)%('(M&KiQE5ZeF6Z qbH"Th5L@#fep(k5CHRYVrMPLP0PmjrkEq(K$NMJ`CEE0pqhI&jpj9e,3CV[80mh Q1rSf#H#*5I**R(HUMG[%@elQf8Q*qhLZMNZH+MjHS*6cZ*95aqGY[U9JlX-eh`H B2aYh(&F&H+"5cJ,UU,"eA(N9XfMMVT'k)c@DlcS*H)6Qqj%B%Fhh1['C9bmPETN BQfhF,B)PRM+,dkPlTBhlm$[%*h0RjJPMPSfl5QE,@kTe[#5BTqM*p,9#qrI(`6a &ERUcq%k`FDF`FaqbqEDm4RcdJ6M"Mp"LQqmjB0*b'hI%L@,FB2-YRLFqr()1%9c 41BLZ[&9m*pQi*X([X-l0L4q6J"8f,LZc%Z"PrS'C4FJk2PlQi`jCac!SAKELATM (bhcFr+mCA,4iQBpEm)BFcKe6"C!!fEKQHAP`CUIYpjm3S)aNKr6*alR6kL6J-6E Zh6Yc1&I+,3$"$FkThmMKh&NINB$(DTrq,SGcele-I2SF`rarc-hPYGm'J,42lm[ KdcFr*$k`9%l,K6QFfm+-R+,er@Z!Fj(E0q"6(J#AXh9%Mf3"J00XA&)`fmHj)cl 0E'Nq1,rYGq5fliZ2'5%1[&1Fqc'[*HT0Ji6JLSpc(Hq9!1@T#q!*&ZHLiEm8Rpi %1"+mXcJAVCSP2Pe+i0"Ajh$Z0TNKHI[4aTdGi&ada5[%YeEMRTl$ZG4ILHp-V4X m8pj`$V0ABq0Db@Ga,R)M-`qHb0RfZ3$RST[SNpih1Z%C1CcEr'6ak8f2)jP&aER 5eiS26*!!FqR["$JAZ3*XA@rMPJPr#($1[MjTcK)`hXHjI0`4i)(2#r0aLm!M(qI bFBRR8D6LA#%Imf0a,[)fpMLSYh'I%SeJpQ8k(f85B'Pr+(4PJ(14,e2lifeFUFb FMh0a`4jjBp1FMMF&1"Ij$'5N8HY'@&5Fq`$m6&q9A-LX+mjG33ac66lK"ciqPF$ Ci(ebR[r[1CbVTDCQa6Q`4rRF8kiA(qm#J`GAjqTBGihic'2%RRHjB*MLA'3Rr'q 6MEZ5Pd39earl&I%p8HF2IUEcrA6QjNNfMR[dLR140j`R!HFUIU0Y+Fj04f)#+i" CX&cjh&["0R+#(eINF1jeKiK2Vl-ImXSFRrX(DY-,jd[")CfR,m)p9*YC"%p@R)[ #MeAlH5&BVR`Zp&+!cmDp5$L(cqFq4JekhDhp@3(14EliCI'T9VF8(UPirdTHAp8 EM9HLVbK1r#eF4E@dGqk3!2T1EkM0C,h)Gp%R9'GTKlI(fc0pr'bTm-XJ,SpE#qM VA0%ci#&jRH0'iE,KkDCZlme`GG@@[MT(dTpSiel&DklkINIRJJ$r["YH*6l9LEj `5kk1Dm%ceIkr,Mc"Vq2Gp%EeS`5m51Zi"6i0cXVCqCjF(@BZ95ZpA@VekpJ1Ib) RSd31VH1crb)qeE1ZI,RTYp`kb[@DFc@imkIYmEkEBGrlXBb&d@-ZhIAp&dQ!hQr icSI"@PYI'aT%eXCp&fhJ1KZhlZhLdaX)2a#p)$6AaPd2[fF@j2a3q+5Ycr1H"9j HC10qa*aSI62I+Mjd&H*%lr(VfbDFf"-Fi2aBm0f[Vra,%U$A0AiLZ12AYqUM%U! lCZ`#Ul5q6m#0i'[%`@Ze[VI$J5ka[!6EVbq0RJ41b[PRi3eKLmIP5q#%PbSHS)p Bh#Slp@DiPmE"%@eFq50I,$kd,qCbX4K(fhaIqlci`%RLi1d@MmXZKj-m@q2JHeV (mHJScl&aArQZ'#qaFG2J&XqeFGG3hcTEaddm03Z2Nh1Vm'hYApReD($29ab#YfM rVN*,Z&cM`'Z0q`bFl`A+cp"VE2r+Sh!mG",bJ6[D[hI"#F%3mX(IY(qaciS2RL, R@mbRl9rC#["-H+,*"jr4rVdFRXIXb2Q5D$pqrfk"Ak+*`AYZcr9T&4`2[JB231I `q`IRK,Z"PrKdrPj0Mq!MFNjRjV4rbm$'Dc81h0Fk,Q6qd0`Sripbr6X62!"Rb!H ZDIpq#)H%5hVr$`!0$P4ME%aTBR*KFQPPFbkjp!Gi(9)!N!J(H"p8e&X!N""J03! ![im!N!6rN!4069"b3eG*43%!Vlj[NV0G)q%!N!8#NG)!N!C"&3!!+E3!N!Cb!`B !kl%Mh+hCFT3[a`K2X[$&FphR%Hi&q8(+AILjA4KK#ipXjUDF0SR+P0$V0V[pC-F 26cfC*kHq,ILRr'MANH0ZX[$Pb#f5(9mB'5am)3YIb#E(&l)F[b6l*2ZmKEA`5r) ,Aii2&ViBZAdGff54X-Ma@cKCH'3Kqlc&ML`R@FimXSmX*m8+Im$VC9e[&rXGpaC Z!C!!KGa#EL'E$"BbAXKb+bHVI9lI`$krY`RY1JGfFJIjFXmQd@q3!*GfFQHCI5b cYcG[XfrJGZ'AGEl,mCl`kmcLejPjHCf3!jH,N!"I1E(hX[ML`,lh5[0cPTfI4jB RbqA!2!!X[0DN3@F622[d@YJq6lLKr"CHNTf4EE%&J%2m!HI)hUT4e($1,A'ZX0S 9pbahaEeA12IfZl$jIU&Bi+QrTUJ@lJcLZ"l&T8SFh4"@dkkY*H9,,p5#X`aClGc j2qAF6qIk(cbjj)NRRhMbZdqialrha,mqpVdrR2qZ+liC8eCejdB8a"NUrr0,%PG P(i(-Ucb@"B24l-Q#2bP2RAl)Hf9KIq(-iXdp,f3f8h$cmaf$(miAp+%k1RrbhIb EcVe[AVmbFGbCCj5M9P#06ZDSh+efb`Z2&rGehrR2MH5"`S[&&8XZGjH6K[ZFqpZ bql&HCK,,Ge5f$,EMF(GplQ5X$Rp8fkU)59R#hCSP0RKPjD[JRP5iGPLl`Sfr$)e SA5r'MAUl"H9qrE*i(2IMjChAEDmf0SG",B`VPH(AXY6kP3R3mbNKNdQ29HCEJcc (8RDHpq[P-51AcpDE"'ee3*!!+0XPm0B9V3Zj@!#ZKH1Z+biYMLaj4`q%9$ZKh@L BLK`5XPrqfDkArrV1ZLj*JqbaV9p$"aHMT8&!RGkb6ZhRXafA[qIL2mSrlFZIM0J !QM-,b2I[(815SKPc-KTl3(ITGeC4FK`A&aiYAP6ma`A)hGUZhMeDRib$H-pkQfC 8PqY*e5dDVUkhaSG,`e'cA@q%m@(6bpGGKH%jiDD`pBVGiRTVjP9hCQJ5fXfVeG2 SL+[j8HZ)MjBJU3D0BfN3@c@AZEMHQNS1fbi+EJbq(l6*plbj0!k1q'bD6G+S@ES fh(06&0H1f$C8Uf'5P#T"1Rh%X('fhULp&NhGZQZrAb6BcDdR3C+%cFQA8iTa@`9 K9NTQdqA$PejkV$LdDAYY0'dX%e#Z+PT8kUh*`Uil@4Lh*3ZcPT'04fe+eGJb2*3 d+DZ,`mCK`fAKhQ0jA4(%8f&DQJM6p*A%cXGEG6PSYc2,ZR8cae!Z0-bMA'JDSPc "6Y*H-$-T$Zd%j8)6&q@Lp144VXh@Uq630N+j8Vi&Pd,6!XU&YK(+KBB4bS@')FS 9l#,J+"Lh99#)FP('FLMADYTH'i*b898%+&H`kdj@J()&-e#ZD&1UaK$P3X-)j8, $!XT&k"'K(2LR4Q(,Tc&[EHBmblCZcV-YY(14B3$`N9f)jRlmEGeD`6KU56cMS"I dE,aQd,-SGRA&c!H0Q'GEkZXmif*MjeN@1c[2XY$D4BE&GLQb,T96SE[c%pIDhZ9 Y1iSTD2$m!XPhH*&KR,0mMaICQ5B[Cp4HRB8fcl-XpRQHCDR4mk%K`N"6r+l9iRT bT-GF1&iDDkIeCRh[5kfNLbC,Cp-fdjHLhDVbBC[QS$Sf85U(j+58aQ+-1FJ+JX` C5T5H8@ZB)I*(84El3!QbD+GL$'e+)ClbEf!C'HIl`m#bY@%*M!YpH@#DEb`$bea RQ6I-GfYjDkpGbp[j[9QBm%*h@E30fX[3e[5AJ8fq3!2,A)8@$0X6iaG[B,5hHPX (#Dh'(HR-pFCj`lMFSZiiEkIEii*4+GAj"MQ`c(I)J@9aFK2BjNBhHF05ZX+19KP 0'e`cQ%`hMU*KD"Z"B@KB`-,30JH&S@@%K+&K#)3&ZkJ`#mD5k)*CHjjc)0KUkS& 'C+SK-$5*%$!d$!'`D&G+LB'rd+B9r8,V![LefEDR-B5qJPehJ3A!9c!$piSfE4Q 18#mdM%![0-aMAQJD3Pl"VLe2HF$Vk2dkqVlZRUqchq[SpGVl[,M(+r9hlEeG9er AeG-9qVQ1AUkpMq[SiBVpfklHVEY[kqlCf[ZeZ&FVp@R&(Ufp2q[ScH+jM4N[c!d RCkHQ`VL8Sd0N1hpljG942e!dEkiD8QaE@J+C`YLM%&*SkiG8Q-8A3iS',D8dqIJ 9j5PU%YX5&E54VCN+M-08j9[2pPbCC%iUM3DYUGN!e'MIHMJK`i&UJ'"M(#L)b(V bX4f3!#QPS4SM9q90S3XiTf+25UJ8G@MI'R9S(83GQV9((G9B9l)p"ahCpXcckIE X1[-Ge'&(`J-(TB`(jP(+!l[ZR"IKEGPXLhjMibZE2`XDdD6jEKeLJYPl()![43I Ym'VL,qaNl2(H(Rm"LpX6e)UDB3&%cGhMrVY,)-,BYL59N!$E,i,mm2"arjePN!$ (qIBX,8pR*dqZS)Afa@f&d,Jd-3rY@aG(3Z[LZN0SA'UAfZh$%JiG&&BQ#VE&$B5 #Jpl5b@pA&%c$[B5SiPTh,&V0SjiL-[Fh,8+cMQf"d%0K(D0JZkFHZJ'[i+5c(X, PMD*GCjd89cK#iq)d)$4Z@cd+c3[E4`AEpYkii+5h'[+V6!96k`UR4iAI1YllcH& VU&4'@6#qHYFVkq)rMmG6YQihUmrT#a"Pp*Ah6bRhTlpfPJhDR1,A33IJFQ6S0IP %b,-&HC(feT@mHS%33M%K**%TC!Bj#PQ'()QX3&BL"b-()GQIlbZTG2JG`erQPTa &GSkR-4RIU%qH`*3)9q`*Rp1,fP,"D0162jp,T*hS`qFD+&'mq"&LURS00`)!!!S *4B6L8Rk![Z5dcdY%-&jSU*AMdCeiVNHq8J"4CYPj&I)'+3MVD@i9(B(!8"FKKmZ YB@T"[5VbMPk0rhpHH&l24%MTDdBhlDV1e'[U29G23'*6SNp4e9+P4B+QKXB"f`I heYX[4l9f5k@dGHJ$3hQGGHC5NkbB4*V-HY9U$H#Jd$a4U5k*MhjhXIBd[F,EdmR D3cf%N!!8q5R,bA%L()T)C*3bMBmSJ-j[`(q!j&--),QdjE,J#!bIUI)m[BIhZ@! C"UMJ@Eh@[aD1EHBcaB@X+SGT(0d8aM0*+9[K@IlZmG)PK6AhheYBXh[$MV(5q1C TGe&T3Ur'94GFl3VE(R(ZA9mBZ'#VQbVY'2YKY-HV*qRI60[ePk!XmGl280h$QZN 8T(5T&aFYjh`HbpTQ1m&RcV,KQqU6@NECHNkqq#8-MZPB0RkEajMAFTVq'TBllpc Rp[b$ZUT%iG,I'5JmXJe5Ym46kTS5a8rqYY[cp@pdJr`BFPTZqGL(d(PC"PN6+h, ,kap&4l2[IPH$1FicZH@&(mIJe+j2@VA"ZHA1Kp%YkeLHG#q2bYabachSPRFYhmR MNGcbNcq2ENA(mYHh%ZI3h(,kl4LXl&Mqa[8mhTYEVVm2hDTZc9c+`qd2%mAce8D ZlPLq'&+lT1AcX8pJ`$$$r9jk-BqcFmX(9k)lV@[jQmkGGdCZ1I1!i-4BhUTmA0j -%b-Cp,mhL!rXbf"!dE,KGhP-E+B0%6EP,$r6`ih)dKf3!%MGI(B,ZY1lPSV1-(& 4EYPIY)EVZTC8Jf6Y9B2ScZKDiZ0kUm)2SU2H%Zkc5%8IP(J!5685jkm*4j4m+r* Zj2h)Yb'T0ZVU'N@Lj(N@a@EN#e5D5Ri#qA%N$5Y94VAHSU+K2*5m"dP,HK155U6 e@B*mRD#0XP15$T+XcV@+S2*Z4jk22-X`KpS'TAiEq4S"Nj+[4&k'[%leU54e5Xf m#!P@-HZD,kK5FTlJ4mN&5#U2AZTL!Bq59b'IMpb1I#'5QVd!ZGj3l8*KKY3@8iT ,N!"Jcb0)+[pFUlJV$@1EN@p%hS%%5F##0b("`R13!(FKAiC8Q1Gf$Kp"IPLSVH5 Kb%H4'j!!i#JB65@$8pZ3!$FL6dDqeP$k@L601cM`%U4#XF5[)&q02!aj1&+KBH) fj"&)Z"k23KjY2FB$b1&)ZSB4b(FKMaAD+$N5#9ib[!'EDT!!Bj(MN!#eDS'89(4 8#H(1413Nj-1'9QUNl!f*'"ia++*Md--LaJPk'%J(!0B249BKDGi(@Xm`#!Pb(D* 13mNKb-R)+FLTb$VNLFL(e0FS13-j(9Q2T#04I9MLFdM9fENMTTRU**4m2r*"0@T +[Jp*ac0ElCQ5(d+q!UNkYF5I)KPpfJ5qX%qd6B`8$6&Kq,Nc*jGpcN,a2BEm-NL Li!d8FI8+V0DePjhc*`18K%0j$A`pFD%P6+LY(XbmDp$L[%XfKH*Bc2I8,-JR4p` 9NRhRXc[`3hTPR+4*da0-#da*$eie2(E0b+V5UQZ'YJraE0Nb[&fGT8APXmC3EdB mdBNpb-Z4Nj!!,d"HJE`+H69b-r*Lj"EN9Z6cNGZ3!0Z41j!!Pb$R)HFM&b"24Lj %,N+HJPb-E%BZ35j&YL"245j$,NHZ3+j%VN+Z4Uj"RSCFLc`GZ3jj"[*-j&R)jb( A)mp'EN#HJpb)2"Gj([*mj#EN"FJ,NDa,RB#FM*b#R)UX3jk)R)DFMUa(cN$14-j 'cN'HK'a!0L+6b"4b!R)LmP,N+#3c'#UT@N-@PjBiK*DRPKYqj1H88`bS$1k5Tqc 6H0KY[cLMVrdaD,cJKlY0AGlMZ)UI,@VYSK&dDN,1K5IjKrdAC#QRGSBm@$BNhmp mrXc[,q*peZmcF5KljT1I4(i+q@QN'Crr'C,a1@0d-eShSh6'k)cF[iKN,-eBRK% hShP'hU`)X%l!%)8a0@X)CQ4[aZ4I3SDMFXENG&Q-rmfSR$8!a[q-lY9-e9d(B"A JXmJr4[j[j*mJ@A9JpB1e)eBR@*0J4B2e#(SN9LKB8@"0j"Y)eKPBSf#GJG8+4R& QGB+e$9Bf@$YKPB39KQmL@89KMB+9$&Ba@20JAB19$PBe'-Zc1-AU#5X0M1KCZ@! &K9889JaB)rK6T&NPB%$-ZJ(V"'D9J"@%cb&C!f!Z`dS%R65V!+b3!,"b`GS#+aq X[*KG9eB3@&Ai2**9MA$&`JcLcCU&SEjRKH%,5,-rbd,@Ab2r"[Qh5,AkPIJkmUq 3!(q(r(XN5eprLI`HmV[)lb$r!IQ2b(p#rM2bqmKr3Ij!q#1Yl,GYp9E&cGUY3l` 1qA9A&&NVqd2N(b&C3Q,pK&Rf9j'XDl#f`QS*+d'Xk0#0X@,#bXaAN!#XU,#U`bS +UcUX[l#H`mS2kc@Xbl!Q`d5Ee4l@GPLIq4U5G3kckX'U#QXjV'1`eX2D%+XBV'# `#[0e*+XBV1Z`#X5+#qXbV25`QX(+%#XZV2Z`qX0UNPPpB5A)E"5c!X1k$1Y#V!f aJX5D%UXcV"qaTX4+%UY+V$LaVX3D%UY(V1q`IQ0@SPL(BSf(e4h@SPKVBVf%&4r @HJTV9DcpX%E&HJdV0DbMQ&889P"B1f%0KE8J'm*RLf'+X*PY@FK*%8RfG"4Tcm) @4&hV'c$)c)q$U@B)rr6q4+SmZLhUccmhG"hrLM"ZePY"qU2`14`#*SaTJcq6F6Y faVMiK+hYS-)kq6G8KeRN+2"B&q``m*SMaE!2Y'%-K3jq9SBfc1Ajm--,G6ImK'B Mef$%r-4@mC91q[!f%$Sa6df20*PB31GPAId#-NYE5`'SKS&KZ`AZXp&XJHkbl2+ bp03bBZ6eU8hmrq3I#lZEPMLXCM5CQm*D+DF0f+lf[jVaA5,M(Gk8kjUM1"5EkrE ,-Pl0p@RTBZbfZNA#JI(YkV4,Xl&L3k-493HVTQfD$PTGjEc@M9hGh'hMAGhmi@C Y3DP#pC3,@fNBclE6RX'Q"H@mZCjb5C6@GqrTUK9pjkD&0#`,NfJfVLi%YMbUcR5 9+b#4pC3V@r@j"H@1HU1VA"`&5Y1fF#UFDqG@$FQHPNAC'#5GJ"XCUfkc9$60"!X &dB4'`PBTEpMF95dFlDUD2f3UYcJP,bMRcEAMA$ZASDh@H"8eldB'Z++k2+c1GKc iT89G,3NkL9i3QVH6Jf6D01U@M5fGY#eXeF+jXFNE1PT9KT,bK@1GYemF#mHkB6) f-TVYD6F#U4fhN!!f'5+3!)hY&P9B[Cl6PL"1,&mY-e1Qf"BQBAaMafaETl4DSU3 q0j&DK5L&SY$e!U(!aG*2fUT!*TY"Yh1&EZ0V8G9G8`F9UB+QU+eX8$4'YEbG`aq k5aSNCiF+ad0(dFd0NjNdDTHR&*aRV*Q1PFAf0'j9Jb5X0TAiJ,UkK-HZIrI3N!! #pNT&,BPD+S53!(ik!8aXLG2m-K(ASVSU*[&4*3V(a8#AeerCkl!9QqAQ+)e!Fc( CK!2"5,b2"qX-rQQA2Kk+hQAjpkJa*5#hR"Uf6@`T$3r+P03X"c2@G,8ZU*`E9%- TQkNQe`8[iA9f[66[0#h+qX9!5Hh#CTCXCC*i[h"f5i[5Z8Lp5A91TSbP8XTP!fJ 9IA!LjaG1l"SHflKa-3E&8abUhA"9M4E#K9ZPZE,cX0S%,%S*''d3&'U#-TFa*-S 6Slhk3*ZV%GpqlZKSTT9U-#E,dpT`eh@KGME!Blb&&Q)l"-3Z2ZdX[46`DCP"2QE 9%#Q!b([bMA,H3YTaNeY02k-c(*B3[[a!A"1J+c!aU3bVANG6c,!%+FPC1T'&)c# LEDYAVkeIYkjf55mUE4M@L+5-G*TmLAHGdV"DjpIM4*6RHPZQ2Yq4D%pj2U,UL3a jIB`2)$l+f2aJ-@FlCJkME&!RleNX5"HU5SANZh#"Tkhm[-UPPj8q9E8SjfEPS3# MX!fJ$3,fm`+(I1jiLca(I)i62Z+!,h#qjjR5mmcSrR8,dH%8)FpjNGFmb++K*!m Tb#2+mF)K+1&p*mAl9))E6laS",0896&jZ#KV9dXh(l5HH4"FGY"qc%%AphqVNB` 09'F1pV[$!Y8*UXLdGPP[M+'5G%R$"J,,Ujf*$EcPrVa&c8A8h'(pJLR0SHkZcir "-Y0HRlX`9MNrPT8fhfiSirEdrLKMFCdQF,dkFXBUfq*)GUT[9d@dI,DYTJQrbKE F&#pU[U%ejmCK0JHiF$&6VP,R*NqqRPK[QA1K6`0r[-9Q+IPX!rF&2MNUMH)rm,% 8c[kpcmH-`UaPZG[6bX1SM+$C$R+XR3f"mrQAZ3N@m1!S)&X$EF+lTGQ-@TAUp+" )&R*H$9YI0q00iA[C'q`pbjQ6llCr16YXXEfPLU!ir(+6ZSj[aFLZlGQk`H0aq11 rk#[Pp'Gak)qG8cFIfea82Hq&$@j*l8@hFY2ea82cAbbJGmkPQI,*FhIH)Ii5pD9 +EZr0!fl*3(I!JZe2ebfVXUP@bmjKQfJ9rGZ,GVNUl"i%-pRmMmmqF#r#[K9T#m% (9eVd14P"MqhRXd3`9GJ3CK(r4[h(p4EUZG+1T2@[5C!!I$RLVY&q3+49hJpcT'8 ,IL)J#rh!5,6'a`-,dqR(idRdr-#qY-l($3[8YK0qJVU!*@U(p`2MePA(rF"DCIc !bVADa`1Eeh8,IMS+@DlTH1K%AA4rpTTV544UpFa[3qS0,CRSfJ&)12CqiBc3+XF R,&H@d!*`U`FhHj3Ke@Qad-iNhUC@8mP+C"pNAf4rC"9b!()JFK"b-())FLMb814 Kb-14`j!!4b#24"k&j$6CBj!!eFMKb"()Bj(()8FL4b&()mFJDj!!Bj(MN!#eb11 4ij%6N!!6NC13!#FJ*b1R)+FLkj!!*b+R)DFMkj%cN!!cNE13!,14Fj!!*b%EN!# 0b#ENA13#j#R)aFKQj",N8Q3,mP6N-Z3+j#VNDZ3Dj'R)YFM6NHZ3!'FJcd5HKGb Bh39Fr[)8KLr$F&jYYpKI`0HDm&NM10`6blH0E4XUM`b1l",4BG[hj'8YB9cfJdQ 3!$eKlb8DN!#D'beZ@L!p#PEjV+YI5%0JDIRXFD4(qM-M5`LCc9`EXQNcCS(XfT! !Y%*DE9C5)5D@'iXm-QBq#+R03"Z!C9@!$c*J3mE-ELYNch`3r4)l(i5qHZ&5%r% DiKm)T5'3!1D$r0SFN`5K0@65I*!!0V0'3%V*&k65k,"RE3!G"0Z3!%@MJp3EdQK d%("$()f1@3)%dZJJA)C)'Kd%ba"+Si2J'd*TG+aA#M'L)j*X5+[43Aa-[1JJ2TE EJ4cP@rD'("%C8f[S@)D!i"XG*-i3Lk1$S"abFA53!(kcfS!1JQM@&p""5#e69NG Ne,)8QP408VrSU"R)c0'44r+2$Vm3Rk1M[L&!4`Ia%L6Sk##IKJ`G(@64N!#KSi0 N@UCZ5C'+3ik3!d9Qb-l4X@i"k6Nk#+1*%4hc#!M3d8(B$"%k1SLFU8Gd%$4$L)k 1NEkd,8R9"+6Vk#""Kl3D(56SN!"@Si1d'r*U!f8b$8N*Jpc"N!$5J4(N'4ee#%% f1R)UJj58BS0B'ae%h$*V5SNm'm*XG""Z3mL0$Mc!$cV)dDNGG1ad3qk0$T*V19J P*B*UL,l4JA2J+MTU(Ia""rQf,*HQ4-BTPb#P9Gpbqe&DZC4VMp,#*VR[+#dXN!# ,MY+U+lRK++dFbG9'DC&pbje'D@'EA'D89LlP&U1dL0rPqU+d#,rP$U+dL,[PmU' d#,VPeU'db,EeG81*TDTGDJ3GT2[J"MS)f'8K05eLG9NY6)YX(5*pfJf`R*bJSkq 3!0Y[bY32b)drCF*6#1l4J91b,PZQfS@S(Khe"NDK)im3j+2$,cd,1SM`)G0("j% pK2VSk&INb2Fb%C,,5R@CL-8Kf%F(SEc-dXT%k!kj2MT)lfA39bDF*NCd%2*#ZUq qM,!Cc%3([JZc@8Ci*d1+M1SC8Rjde)q--$1+%i*qG03S23Jk+!-Jl%F(S6Qfk1L VK$df)ib4GDL-b16"+h33f82QVlkXF)9D3%G23Kq($Rb(p"dGf!TC1cV`Lpi((EJ $+6`kDKA5H(68!,d!1R)"L6`kqL5`"4hNlC!!bD2M!!")jG&a9)"l@CA589XZ6i, 53FK2cY&"`%mXkLYAr`IT2$Vk(XMRd9&RN!$3Sk1IS4p"4cm!+6dkm03pqNcT`#D `$KeB!&Np1ZS+2%G(lL#[4iF[HMedN!$9Ja[S)*Z(d"iGKa0!E)m1c!!rdA%J!Md 41R8mJ%YbMilM!S5F[N,B$mNp1V!3%RadB$mNqHM!IRT-G24Gj!%G1DEA4NH1kER 3JGf3!1LM!cFKddF(hP'2k-!AHKCde"iBL)jm3E+2$VrJ2cS1&)"d(afp'Z6lk$L X3"B!+i3hp(VUUp5m!&*qG26Ue!XkqM0)qY(4Zd,@Milq%%a$4cr'm3MS`%Y`!af p"rL-MYj!eX-UK8-FlB!1(1,B"R4J$AP$4fh6Mk1MaML'!"djiTJ'G2MPS!Cd(,a !AD0M9N&2Kik$#cL+!4ep!$L'MMi!RqVVScQ)2TV)M[,CDeCjV!$d,ZjRJpM6X39 F8e8m%H%AAb%Ch'1Kj$cN3Z3Lj#R)aFKQj",N8Q3,FKPb"A)PFK9b0A)0mM6N@Z6 Tb(A)-j!!'j!!'j&*C!V*)@qFdTG"CT(Pb!TN*E)2XLqb(l)+13!j%$N)14Jj"$N 8H5Mb-16Kb'())j!!4b+23Kk02!CCM4b1()%m&RNFFL4b&()dFJbb"MN@13jCLc` H14ij!6N413Pj!R)bFJTb+V)1H5*b'R)kXKij!cN613Xj'cN(H4+b!HNI"f1*16I !)[1CddZk6TDNmcHAU$&P05HLQ204c1NSiFNSj[56`YNRTD[DQ"+D-eVqhc9YjK5 Bm!5BdX9V6&I0q5j-TjNqQK0+c1NNjJ`6TXY-PCPB-$Nf*ji`)@BUbl55LD`j!58 mrF5FF"+HEf)Mq1ab4h,Yqqa`ICl0l*3A$X)0f86E2P[%3EL&CIM0$c8IHVEj,!r eG(ALbF`KQ%'!@i@V'-dFJKN%X`Kl`Kb#'35YC@%1`3c#A2CSjK"Q"X%mSM5(+-` JQ$p3+F`JQ&%!ccD)@B5pK[bSl6Y`KCahYSj3HEGpPSLcG@acmf%qDm`K(K9Zk6P (UIErlE-2!2b6M*Y@JHTYCpc8#f+bJ@jPqCipTmVp$Jk8RMfRbNB!%Ircd6jlqG" AYHE1L,E6Y+M@f-ZC[(-bl#bI2Bj%bK*,+"JFK@0Rq5ab[D!3PpJp,RlF48TMFpN jX#amlJMH%@P+H%pbefHS)0@hkl`'1d&-GMQ#""[&fIK@RE9Dr9N#pTSd#PJTd%! p0*%@I*VFi1qXApm-URhGaME!JMU%'[T"m%VK`ARj'B6@0N`)m)#ViCheq9U(h#9 @lr+E'@eUi'$`32@,96NHq(G%,8q$9Lf)Djfl#ZZcmrRU(5q&'[@9fFN'je3ZE&8 EXl@`EaKQ"(M30qmA19*Z2Cf"VHd,m+!bai2klJ'Bp@j`lH#9rGD3!#(!JhlpiiK p0+'')MlHHe'@1jf'((QI(lDcbVdICYd9hJq%3jAH$`4aIE`I516kHMrXCr6cIL# NkqrpX#Y3jIe!DMI!qi(iEU$h!bRH)Gi2a(Q$[4pfViCi2a$`$I9q)1Nle2Z"a1p `l`HL[f(H$f5!4hJr%!BHkIe!+RL8p`2ai0(H$q5%ahJr%"K@Hcq3!"`1phiJ3Kc Kr8#@H+ch!k(LFGi2T)XM[4q)'8Gj2j!!0ilfIL"i(12p3!*Cire!&$R@qi&-FTc hijjrmUpq)+Bmh[Z"Z(+mp`1jj36["`,-LGi2**Q6["p)0%r`IL$FR1cp3-JjaIY KHALUp`1aCjhh!qRRLGi2*+(6["q)4+Gl2a#0eRXrN!#4c["q)#bGkIe!DMV,qi( iG,Eh`h"bM[F$LHT*hJp%U`h(rAJAm5NVb&JEI6`3YMCj2h$bcI9q)(qGjre!$M[ Iqi%iGS(h!lRXbGi2",3,[4m)DQmmi5G33&Vl'Zm(8YYhH$m3h`lbIL$(IGF*(!M m3+$lZpi2*,[[pR&$a2XHl`Hbh[Gk2j!!qElIqi%Jq!2H$`6#(r4q1$hR3liZ1%[ RB4m2Tpjmf2[KR*e(I0bFZ[14daFH+R01DINp(`mRmMcUrA$#bZpl2jc(mckIEml HHI#d(aq![Gh!2CqpbimlM8jQXh$f`k[kd1d$fqIi!PVh`r@"jeDfrA!e@13Da`) HH1Ieel[-6Kp1AHrb"A,Z3&HARfqV4r%2r'SlipHLK3GUIY#rlp`qF19rm8GBY2$ qPhK3dAH12k+mIaaI3)!(0VM2YRH!PJhJXmqG+UFj2'if2[$A'U2Zkqc3f9Z-'[V eGK$YVHEc$AE!l'eQGiHplc6lqqhp*S[Mc4EAAHER,4EA@qepYrPjQrPp`0j[0lY ll-$DHh[RGf'jIR"[hFi8YGGmDlG85PZ(2M!N@G@E6Lm+EJa+%qmH,ee5@(2r[B8 eZcIX'#Z0Ejjf&j8Qp'TFGF(9h)DV$Y-FrS@"#lDkUG)11mlebDpjCkN5*0@JS3Y D1RfX'0QeIE"GY90@Zq0SZRcidNZ2KP(+kFrLd"qhFEVjf1DLkRN[E(",DLqkPCZ Z,akDrf)"[A-Z@d$q+[611qc!h96*lEej`#dCk*i,Jqe26m5SdRj!FfARm2KX+kd hMrUh&YfI!&qqHREaGhQm&XS2h8TceimSf[b!%Ml29qb(EXERqBVpj2LlBMr`GrP mB,%IHLHIjb[f3pIQmhc&IR,mAE%Iq,Ym2V$B$raG2XpAl!Iq,TrR+rC$YqVcI-9 qi1rbHEjL2r"hq6aIX4riZhbHVpJ2r&dqceIX*mIIaHhp(Ajbr&faRaar9q`Rapm 9qmRaGm9qF[aGXCmFIeIX*mII&I[*mAI&IR,mAE'I((pAl#I(haAlbI&haAjbr&f aRaar9q`Rapm9qmRaGm9qF[aGXCmFIeIX*mII&I[*mAI&IR,mAE%Iq,YmAUlB$ra G2XpAl#I(haAlbI&haAjbr&faRaar9q`(rLkIPb[f!hqAcr-9qmRaGm9qF[aGXCm FIeIX"riZRfmVpJ0rPmrc&IZ"[m[RqBVpj2LlBMmjrUlB6ikr+rD6iqq+rH6iZp) rm!0rPmp6&IZ"[m[RqBVp`0rPmhc&IZ$[mRQqBMr`GrNmAl'I((pAl)GjS-m(&[Z "[m[RqBVpF%aM&hqApbNr(+$BaGm9qZ&)a5lqVY!2I'"Gr&fK(rM!H[QlP"ri`(V jZj3Iq-#kq,Y#2db3!,[iZd)rm)&emAH&IZ$jkZ,[#[h!mpA&haAkiE$(,[kZd!p mB,hmAFS2I'"Gr&fK(rM!Z[Ll3Mr`JIAbGbNrm)(emRFT2r#"pI*h+6r`JIAbGbN rm)(emRFT2jbphXAI&IU"jkZ,[k[i@FciZqacje2DE,iKeL,Cidi1YI0f6VDicp, E19NS3*1,`&,CpR4jPl(4`J330ST2YJfbIHFB`09"iCBj"["-[cd'F!XE(L6rNr& j8hmbUZFm([JA`pRQ,N5cbef3!+ISf9!IZ%MQ18R#"a80,*!![-X2I16#Vmc2Iq[ hARB#MD99m(2HabFk@m$9`Mi,pIqNaNk3!'rJ%iCAf&YKCJ9[B95&,48Q9+iCK1N 8&P-B5Q%$Ji(d%#3-Sl#(`J`+kbH-RV"e`X3*bbB-QV"M`R`*Ub@-PE"4`M3*Lb3 -NE!r`Z`)Db1-M,!Y`U3)5b)-L,!E`P`)+b'-Jl!*`K3)#b!-Il$h`F`(kak-HV$ P-6k$j3i'1pMTB*kMTQ'-J`d1TMGBh'"SJheY2T)VbNb4d@r!hN[PXJpk-K,f0CM 9B%f$`3af-KM2E!ZIUP521&SY$Pcmhm64&Y"[DlYkpd3k1fPV-cD@!V$'lDAE*6F !E%2AQ!4E3(fk++mC8k)G)+@ddI3!pTQ+X2,JKi@L+1`eQ'E$r3cI@Y+GYA"a61I Lb,#K5NAE2ErkRSGXD,FEr3(LD#k2DP0RckHf!+Uh0-@Z%Kq1de`CeBD2$5#1eF2 D',)!j(ACa2Ma#*q+`ldrjqaT9df50Dl`RG[FLUeTed(jTc*GBp"S4&'VY$PXG'm IFZki-p-j%iIfkqh'!F[qVUrR(KirMR(Dh,)#a2&i3[j[()qII25612B%FL#1MA0 YGr$KIAQp[Z2jkIP[EbK)2rJCGZjfhZI'`lhZRB"fqDCD9U1IrY`!p[F9$MjbIH( fRp6'QijMca9%qr,"1TmEaq2PmC1lM0BRr3,Lq-9p4rVclM*5FHa'STrFGp46(e6 XRXq0BlZE2SR6+Jd05G0P3'e-#cLpCRMXc6i'(r2Ik'61LDUcTq2SqHJrYLAa'eh $Mq2B2YfB21fRCH4d9P8FDL[-$K!(hhL+j0QmFT5'G0aekklY@p*aUmafq(Lkiil MX!Cdh%[I[pAZViSrG8a9EciX(jelGeDIlYalihLLFqq0iiR1I9mF2qlFHq,SkGc jT(0hIQRPpAd!1[I1I2bdFim6qe6RhK2(%jelCaM2G1ipF9J%1[H08rpAppD2MVY ZhF`a(dphh0eam&N#1Zl9pGD99j6QePee[11Zq&((T1,BJ`a2GNbpF6c4kHb,imH G6NmF6b*jCac2)(P2((Y"6m@KkRjICckq86q&9X&%BPH&U$Lf60j`-SkPNcHm'8G &q3hqM[*bH9Lm)aD!ldH)ej4AiVii,[VhAP(&F9'3!1LDjFeY5#d,bI8UqTa`Gjq !["lX'EaHHQp2IL#1(Z6F@fGHIH`i9@Brq[TN4a[Z`TMqfI4aIHY4TNVG8kM5jdq K[VUr1hfd!X64e%J5"m3S!1Q13f%pH8fFR*1l8d-V3$lFDCm9)!iclGXGai&ThrP TXq%Hi!j8iRMT3DaI@RJDrG"I@&2BrhMEV5rFYfIc!rX+GrfF`%3a-P@eX,qkF&r VbiApAm@Ia('"ULM1arikNbR,T[EVpFU)a3@LAA&`G@4#aeNHV(YhbQ)&U&GhbQ) &L)02`jPLV[TPAYdi9(NNrVFqPN3Yh8J9IdkjA1N$`#F&b9C2kj%iTrr%jN26f-G IRdhTcp6BlXrYBD`!F5bk)GipL(`fVh5PpSUGaGeIU4FUI(i[p0reiIG#ref[qbI 1[H0QpEQpd%(m!)(AeYY[EZ$XckYpBR,0*ch9Vr,UaV(h(YMpFI5XH#A1lrqfilA l1p$Tf*9f[!jqPU8GVkhY8peT6ekIh"AEhlPlZf)(2`[)VPJRJ$bc+pD0e,D!A6( GZ6H(mG6aS@Lfrd6REURS6+d!b'PA3+VpAbr$X[eMTQ0aBFVCr9N)CM&f)+DFJjp PL5RR`#bQ)a!E`5cQF4r#Z,2RXfmal[5XrbF'qPAXrcr4`GNhH!5Hl,`kirKTja8 Rj+R1UbF1k`3r`S(1Ub-3Z`$2JSjMikNk)iL0L68&ZrcB!6S#0`kV"1q$KCZ*dhN ,lm$%kAEZ9MBQcMeerj`+JSPc41&6lFqrbX4jGqfYSJi6TlhaLY4r[lLH+q2Y*4I A'ek9dYAeiFAe&S!Crhpp0TSZJGVNV&MU9(rTV%V11M$af0,jqBH&BrDfEa%!AX# &m`q8VrR&qIR(ZJ`D9VC[#FdGI81)#imGf2R8Af2QXLYEfliAd#``#`PaiBUmArM LAr9e`i@2-b6c*bmD&cjaB0YYCmr2rd&IYrN#9r(hq'!dCARcBqHjH0mT,'9bTjk phYK+N!"2HG`GNj8LchDC6deH+1#9aE`Z&$,Q#X4jU1Z(cBa9ardi26pXP9cCpC1 4@qpl85pZ0Ne12ql(#dljB32PKGi2@bTAHcpXXQ5kIV,(!%(jBGXPHk)Z!MpXa*4 l2fc09(JrE0C8HMpXhr6aIYM3kH[pX-A6crYKdkHrpm-f8*Ah`mE3!1q(VD+"hJp E4iGi2f`Q$ICqf&iDi[f`i668qf%,kP$[K`fT`ldIYUL'H6pX@KhKrE#0GD6h`fE @8Gi2feY(HcpXH"hMrE!&9ZhpX$%hh2YC`R1%pl18jl(H$fZZahNrTr)FkIdXicR +qeR1Fl6hXi,R'1pR*FmDlfF9cl(HcfUHilbI06aV[Cr6H"l[rDcP1Gll1ChR"1p R(Fq*hXmC2#Gj2fIb2-(l1B[RC1m(3SNThJp%QP1p(hDekl`IGX02p(lBp*RQr8! $0YhlJC1hh[Z"#@k'p`1A`%c[Ca22@Gi21qUc[4riMZGi2c"8RH6p`+A5i2eFc,2 4qpR#XmRlJ4eLV[IcI*lc["pB3qCl2h!F,2"qS$JifIZ"`f'Kph-TceIiZG0P2+r VqXNHQjXU2jIc[0(2ThEbI)hh!ch2)1rR#Ti2,IL*mKMkZBVRqh`md&JmH0U29bM fYhd0Hk%IfSkqif0MQRTjArQQm4dG0KTRC581UpPp(*[#'R5$kfYKV&l5fEKPG!6 h6XpCFKPNP0AEUqV"$j'pkZ+5jXHm8rBZXhIDhTAfcYJlDqm+HjIEHj!![I[BZkq pQqhGhpjVl&ePl`(f(YM,9qUX6@%VM1ZGR0@EMc2XIEUpcl6h@ICHB1r"pKjLlk( f2Y6HKpRlF(X2XrF4pMl5hN[XIC5pMlEh8RXIBqpUH`qhp`Kl(f[[iq`pdYkMl$h DhQ2XA@2[XIBHCqpDHap[llAf(Qr[#IDHD1p*pMl"hT2YICUpTpMl4(Y2YAHG[9[ X[GMHTpTlQEfRfAZM[FqcpbTl6lIh#RZ[YVHTiaQp@Nqr[4c&i8E120Pq@AE`bIU dG$&eccc'B-p-Hmqbpfalcl(h5ICZX(HM[C[XIBUpjrEL,MphBPU864ZL@NM!LQa UbfaFc5LRA%K8J`6c6[AF9T`&*#PHZ,2M)0BS`i9Ej@08cdIP-Z`h4kP'6bB'&eE 91p2cdfF&A&JkP%eCi#jQ+LFZ6ULh`B9eTRFa9lhGZP"[&h29fm8lpAEaK&dQHEY iS0kAfRZ#Hqkjj`SAMQc3Hiqd+hr`BGfFl5NQh*dCXeE#rCBa5paLLkU[0`D5@fd fqiD-F5[KlM,'QY[0lShf[X2LZG2dEl*ihQcah@Aa[-ALHkZplmiB[K,ZdqEhlHE hRScY+q%qdf2)fIma3&JbYQfS2$)iXNZVB@dIQfSk,2@3!2I+`[l#Q8A0GXeR2lX pmElm*TRk"8DGm[Bhp@brDHH"4lq4[6Gm1,[@`X,%U$eKliE&5mD5dRIHRUKX2ih F@VcmPP,Kl`jP!'qAZMha*dcBh*lBMG2YYbIQFGT5IRZL6D&cY`2G*E1lFqFc0`K qlHNeI3!kGl[8lBN(krij,F2YL9[rD4Y6THiT91RcTe$RPEV64bY!(-(YLGeaY0r BPjq+Z90$+d!qh'QI&5!1lrE%AA%FQ2DjppBYhVp`Hf*b@A%AHR9lB[+FMab%&@c UXkY(rkKB1[3m,Y@9#!1qK[f(LZrjdS2&FciU[VcJhVSi(r[V,,JpX6Z1pYX6mh% %YbIq+KrZP-8+8+rZP-8+%!HIKV2%rq69M82IR[LV1*iMfYbH#)0S+Z-2c8!08k8 V%cLDaIlf`@I[8VQ#"r961B'lY3dB)!q@q`E+FMcB(24[`i)m(U4KFRE@j`XUbfI EkMAVlAS&QaT!'$a3rD,c+Kji0a(Bda!K`)0NMJFEdcLk+BaRNY*%'V4U39cV(0e 3AjiB,3f[Gr9@2c0d-(LJjSYpmrP"IIG+M(ShZ(E`bRjV`i3!$rVPH-$T+q[6rQd MT3!2+Yp5QPd'S6pp1ELkVPp*I9@iZMKI5Af4Z%U*NZD+F'T!Ab+HF,Vf@emIRR# h)rAPiG`kVQq1i(XI8PmLRR"2)bY0abj`(`ZIYlk12&&BaD1Ik9JGl'qkdhK8QHl j2)"MG-3pd(4[iM()G!rb1-4dIm*MX1RqPXH3!&bA91kij4cGd6`10Gd-(QTAhG8 YXlT!arlV-00GaH-)drdfMb00Gaq2Sdch#4l%KHl2H4aM1PMeC6XXTAL'Qqi%(L0 -Yj!!al'QBqR[10-"8500pa)HSdah1`pU"afj(f1k2qC4BlUrjM%fek99Bi,fDF9 3DlSj2)ihh@V"M1L)Hi,TAXE$hGeAZMYi6$,G"hL3!%0dRq-afA6I-6`"1X#4UDB Mli*-CHYiR'Jkm!Bp1RE,Tj[Z5Kj#)&af"`rU&0dlHF`d(68hbh68h1aFPa'ZN9Y de+elq)65ND-'da'h6+icG4l5@f4qQBG-N!!cGr+3!,2B-f*ENSP-jLNH#dch94l #PT*4V92,`#-iXXKda#dl*9R&,42mV$#pfA5rcQ1*k9iR5"IGlbkd%pQri('UkEl *!l`bm,[FG'$3#Y04EbY04rbV6%HG8HrS`,BeTVZ*"pL,lJ%HDdfRZ"i5(cBGq9j RZRrQF8DZUa$qRQNkX1NXde%rXMjE)4YCDUfBib'p8F@[@Uq"MMS6MS'+2qBK+c) 9cr'3!*hd#Q'EE$Y9UNq3!*ki8VK',D1M9U9RUP4XXQ0IUAc,jN1PmLecZ-S(H&a XZNraf')kkNbQ!'i,3cq#MKj!TMapK&r5GrC4E8YVf8IjN[kickdm,MAGc6`Z-pf p2+J&G)raf'QkEr'3!(&MAr9DFQepAr85[fBkm!kF4%GYNeYdj*TidEfB"fdfZPY j[-KdlqB"jU$l$)rI-0eImF#Rq[UTpk2[3!HZJ)hS`19V6!IZr+ETU*RI-Kh[Ddh h4Kld%HMHbq2PTU0(T2E4ICF(rChkqUYAZmjdp!hAQ`lFIkAT`-GAQBlk[m&dj2V 9TU21EM6G26cS)p"pR!Gp($VU'aa3Aj9kB(bLSfm!rp&4hf!b1Z+qaA6JbZY04he 5AqL)RliB(A(ICVVIjd([KJk1&1S#hIrK3@qP[J(#XcY04ep(RiZ1@RqckF$ZZd` (CVh&G06Y@de((ZmfhIrLm6E62FT$-mFP"[k5"rP""jF(@+5qJHV2hf%kF)iq&ah p(ML*M[k(AJ`G23!aSL-IpjX1$+#23%HZhf8kjJ6d0HMS,F!LG'$HHdch!ajJKIS 'U5E`LBlHq2fQ!iISIp(4)p'6SJ2I2fJk-1j$TU2'(M)GpJqElV-m2Qbk[qIa5+i l4$d023JkHQRk2R4J2(@%MRk$ZNB(pRc8G16lBkBM6M!((A92hiU1ZJIce6GB-iK 2QJkmS3G""kj6)qMS9Il!G'$P(jU1@U8h4%F-i$NkHQ*bUliKDK+C$k"M4J$fSU0 hC@D#MMk0AKiGGD0S"PdG@2Cjde&,i!DkVr#J,e2I82AFIfBkCKpI-Kfp0cP(4qq (6h6%4bq*$RcmQZQSPDqEM[FhFYfKkJR)*cS`!0a'4jrh&kDM$rK,dp&lJ#IS`-& [QikkC8D"MKMSGp4hQ(SGHK"dc'@qCcTQ"#kAMG+"pr5Hk1L[rXCdj)pC%cV`3RK k$P2HrmjdhqF"YUM[F28@e$ik-1`I6%G[riqQSjrm*p24#p&VS`1,L38GYId[TL0 (B+EkKUR@Q8@J8l9L4Rl$Q(dSYNLY8lfkBr1rBI53!)l0riE40cJfraX'RMSfraY 'I6SfraY'R%jRrQI6qDM+C$C2631+&IhK,M-+,Up4GjABj#icmLjYXEA"3!N25TI i*-*'e'k'VA6pF&3,G`CaA)rL8L@15QXAEl3*M!X"f,c`3#jefRH*ceimf"H!,3X 2-NF[mE'aI3%HC2[,AH+Mm+"FXfHE!Jp[,c[PNIfhf#PE4U-q!"aA&K"Q*3XCbk9 Yih)31aNET"Z(E*YhimHrpQGZ('UXrfb6j[&F(baDYjpq$Vl!FQNaZEpXcfFRBi0 dipJldpPIVfiF9SQC6Lr,CEmq5bbApS"EKL`#E*R@NZZG,#9XN!$PX0%FkCT*HJ6 &NjYKM1Qh$l[mj+`4PTZdl)3PcAb1@+('B#I-DqCE"F02AiX[C3`pI&I#J&9TmB9 fNf!P5PPmS9fC@*XUfc&BPha)E%r#B11)R@j%ERHIf'L%cFB41pVJh'ki@(b%fFB 4LpLVFVXAD890@'k5B[YCP0[9LJP-''mbBVUDQ0XY&E14X0pNa'!NrP*L$")QR+6 BGkEPGLm8!k@`BUC8JIebZc[&VLF-QE8`*+8YMTh#&f(,G"Rf*(rpa-JPc*NTiG5 `h1jha2!Q,*S2`+E@YjhEA52@+@(8c)+JcV,FVN8-3m+ZQ4*EPm5h8'a9`V5C%V1 Ge0REj80B0e0L0ZZIfpdVYNKKi$`1r($1X,U%m8rB1&2+fHcFETTd`XbC%KZBa2% "iCH`G0E"+18mNp[G)EC!BHa-LD9*mR5EiK2fcT5Bfb42I63&&5E2-M'C2C,EZ3b G`ZSj%VBNjlcFlLlej-,`19VXBQr*lEkJ@K+f6aF@aQGfcVI%8LA-Rp0JJdZZb2d 0%QZ8X)!Z!4FcC[FG-@9T4P"R2H1Kb4mcIl$R#6YSZ4VTkQDD#&m0041T8i&AhG9 -XiPeB,G0GIDmCYT3lJ+lY0Jk"q!2h!hX8Q+2NrViR&LqK)Nd,3Bj`FXD-BV*9Q# C'$HPcPiXKMpK+"fMANA`m[H%$F*@@Ulf5R"V!lNhc+9TXF%*APD)(8YB602#-r( hX0K$KG%dV6j#m2,&fQN4GY-bX6J+ARj%M'(#G$SE*M5$Pep@c-*k@UDkN!$mE4B ERc#JCT3c`FZl&DZ`SIi4l(Ippq9f0`RlT00FJCh"biZ%pF+5@LD'6SR[3[NbM+R 8XG4C[HTHf&2,a+3S12G&-B!+NqSQf1!-APiV,"4@eG(#3F(,@p@A#-0U4Sb*%XG (08-8YY8,U&h"5qHIa5)Tc+XC-Ij*RMiLGM[$`JTMSX%$f0@%NA@$qLI"bpH+Q8` ka5h8LF(,2aA$U$#eEY8'K1$Pp@)f%pE@FZ9&ifAbAM('#B2V9YMA$&jqANaTXS4 q'Bb-"LmhU0r5c+j1#r`cH*N9kk'`[-i5$PeYH'NBLpAh29Mk2,`-l+kPAr6`-V! EV9`D[!cX(1')e-G`-9N+Sq`BXEJ*AYiY(m)Z@b-FP$TcThE#0$Y&6)H#PpH)U9& BCmHTS4$FqU"B%i@"YNEXJ)*r3i9RXQ&5,PBh`EmV0$U3!2P%8M-M`GG2b*pXJ#5 &`4,I3$'2#Q2Y4R$Di19YBX@6#A*5V(L5[kaL%#EEXDS*`FX[LAP1XpSkCm0U1@# ri5[-NF*`@dq1$9j18ad,fff0mQl`%[CCf9FV%jC,R9dT9N2Cm+N4DkAJh#h+K6$ L,U!r-AMT%M8+1qiiXF-+AVj%1Q(+(DYq61*iRM"*aLiRdeHBr[*LpEA#S$Y1[E, NDC0bBGKdU8[*diG9Zm+XkkCAm(+mX&9BGRH3!%Z$PkX8Jc$Z,K+,T1$P!''PX1r @bVIJjF1UE@(L[3l-0RMj1qT0KCAhGM$9i18Nc3md3kpcN!$k0RMj8E&,#P[[5Xd m6(pT@,h9YaRmGCih[!cX4QYH8QYi'GV"+QV`dVGclL'[PEFddkNMma[R3[UIj'A 0GS+rd1j4HUrd[XTSNM)[!9Z&5ALU'!YPEK6i5pc1[-2C6pcd2%&IqaVkIXmZ`1m DeH&%X`[b9k0jJG60Qp86#QYaR9KMTIi@LR95')b6USYdERH*jJ(#CMa@IH2CZGf Ra1!Vc-De`Q-GAqSG`K)CY)m9(Z[i8X[9``RMF9Uc%)R[$p3Ib#c`(-d&*,kEa1) TXmCD-AhUq$,,a!STV-LVK(-k[X`KeBHX9kE&FURMbha32D6-KLm9'kZ1,r-ZeE4 X"Qp8rkrk*"FR$11l+V&h`5`kS)-6JGdSkXDjhqV-YdZX8Ki06J4f-f"bGDifA!R XaSUK92FCMBqT*p3ciq45jPr5Cc6qQ[S*Q5IH"HZRi&rM['TGcck6+jR(#2ie2U` jPM!mhd*r+he*iceLrC3jjPLa$QZmErVrBTq9RC[4QRpU['pm3Efbc$I(#T0d2p( i'jUGb6l(kqP,T5pTr)VUAQEjGFU0lNZDcPFr)8c4Bp9E5a`Z@E$-@fqPhj1qT2% acBaN6fL@HQA*peH%Fm)QAD[CM+llaXq+i98fHEl0R%Rk[+B9QQF)bh5C')Xe(M5 p9cfr-%jI*Pc8H0$i9FdXKAekP4SFhBmf2UXjUc"4e`SrG$rDq'IUY@6YDCbD-UQ Rm@*%&SEU'Xd4T*lZ9@mRE0Ah++qkIfUF9ac#A(d[V-$52c9GU0j,@+a[9MbkIfS D9#mUM0Dc0(r8GG#d@MJKl0Eh-C13!2kTmAle'F*d28[pZHlM'rpF05'Xel18HmR I%2@e`S$p6XdGG4rIp2r%q#YXf'I,VkkcaV[8S`XcpYQD$4qAfFfp6jJPE-rMe(r U1TKlUrS2BAkqAlfeMQrZ%m*Jc3,Y(&6G5"er4KJYM0!eUUhacH5P2La4eAc+f!A i1NjpB#9p&EJ8q(Z)1@MbE9PmL5'aEQZfC1GRUDh8&ERG&0@+-#I29Qid6LIqAYJ K,-TI*@i6ajh#9'&8rL(pLBRM*-ffK&ejYM"HiVK5Z4+QjGFb`c"a2+CjMfCGGTB bEc"aA#-fD'&JVY-m9q,S*rc6E-a1%9C[%mF1c@Bd-l0c*Uc'*Sl[#R1&TAQPQ+V G1&iirah0BS5aq6,0j2Sff9,eDiE[@mVlrFhJj8hLfqLhR(`H-c$4l&lBRXGT0VB LYhZh'*H&qAQUqXpAjhDM0$r@,0$1hH#V-j!!fleIZG#-d-i9c!NN[N&,a4BXl0$ hDCBJmEPEbCSTfMPE1C!!q,kT(PHc4MYA8TFQ[MHS$p!-dXjDqJU6[qZ&*F)QICp U@Z*ES9j)-dXllp&F@H*V9RqT@DDGUmL(LHmE`Lc011dFS1j-rXV9afMfDHG"kYA %pchP9$041`pU,LAaI9BBTPQTRGqR(c$aMG(XAKLU[diIPXclQe5'Vm*@ADYq92V bpkV@KEQk9MJPGLrAE%pBV+H)-9hETDp8$bq-eRm"dl+*l`,emF*Z28[cE)RM#kT ,BETHUES9ZdHeqb'XebZ9,l&l@20McB$Y$$,2-['p3Mf"X''2%dZkj'1"X%1BXDG U0LCaA+%iK#@l6V-ZXEY"61UD-GYC4[fEq,kP[NIBXfGV6d2m[9XB+NcDUp3l5Yc pe4[,61CXiC5*MlVA$0[11jRhP$QE%jM,-06AV2j*c@[G18&S4aaQ,KABc44$YTN I"(CTpIPTQam%GUHSAp9p3(D*-&@cI#GhJ%mbemq1Lr9I-hilUm&)Q4pN2kRB0IY hXXCq`Y#m,mpq6,fG-)'ISMQ(RKpNefV@,kcJ,kHANMiMZe'l4-)3rNVm5TePIef pXE#&efPHV2[,l%H&RF)FAL0XeReKjPp85m)L2N2l+j+R`c5(%%EaaCVV5jjZ&cB *ZrKL,J#3!$P%pKCKJ6#0Rk1DeR1)l!I9Z`MVH,2LNcL1%SZi-*!!hd"HC!k4q4[ e@X*'IT(Q5AT1N!#GdCaBQ-QAU)BNVdhUii@PI*c`AI,k(Fe#K,&mP[DT*+mAULF 8p[,IdTl!ah+l'a5(-*RIa,k(c!1bbp@M#k[jMF*#23r)a[)R$1HE0D[6mi$X*c3 M&*ciFj(S5YbMk@m-mrN'p5*k(T!!r65iD&M3PfL1)(PGUPd3kCdhUVF@[(QCGL1 Nefl@43)5hcTdKLRp@[R9rAhQbqUa",XZe6a4prIC!AS*`k"HUrQ)kGHpHHIr"`! 0#e4ME&0SC@aXFbkj"fqbp!Gi(9)!N!J(H"p8BZ8!N""q#J#3#2q3"%e08(*$9dP &!3#[[Qr$XedM`J#3"3,$8J#3"MQY!!!PT!#3"SRN"J#e[5kfX&X)TqeMC(INpS$ K#EX)Xp['9ZE#RM$##0YX)C[C@ZDeV-GdS9EHFQ6K+CjkdP1QE`crY-c0PT0&0VY 0f'*mB3XPbaNRbaQjjGM#Pb-,[pM#EcP@E$Re&XRaK42@NCf4jIP#Gf36GTY``Sf `j6cVqI+-,-HA-pQLLe'J`b[&AmI1LZdijF8X,l+5dF,**JZCF(,,NGqa"EmFrVV 1ljYd$VCRN!!EVC%YRTCR)lS(,[`S(h4XiACZEC,A3El3E@bIEXdZcckf)Er-)&r B[Mcc&kp"Hp#eiAilZ,r6@dj,b"Gq3HemH(T`Zm5$HTd$Z(Z&H`,P35pIH*l3%`U -"4"`C9k$[#E*MeT42U$`q-)D3%ifj![C2Pf!'3(SG13$H%AAV5LPhU58X9LP2Y' [8NIf+29pAi#pbdJCF)e1[eZbYeUHjlLHQIIF(ABaL(b0P0-4pd*`(YdKem8G5Ve 6l)'[jS5q'p90iIeLP@U'6ifY8f36FT*%LdE6'Kpm1[l0Fp[*)HAZK)$ZS"C5[VI p!SeA6%cG3VM,ha@XB+L*d*2cGa-'$kBPqXSKLb-Qq)P,e$MPlK0lTj9f4fIJjmI $N!"kdIXTaTJa+rA"CX0*4Gc2P@pf@*j3hC,EHZG!XG*M@bAEbqFc,pHkGMV$-QS TJjY6BE@p1BSD0`%9cE8!`5!!$[&iZ2Y#0H[01EGQ&GfC#T68B[AGaXR8[ZMHb$a 8(c,qc$MeTX9U'FT`Se*rR8ZN`,#dfl3iCHbCdh6XhT,[6GFpHmMCrHrjF![4MFl f4,(2ZY-2V2"bi4[%5b"YP49HcYk`f`PkV&UTBRZ[*c#'lS&U`hmr`G'G'QM[-6m U[1f!2CZ0BmDCe0FDf*0fHNS&I1%m(T6l[r0'%jXK*b-lfK%jh*Hp%Y(eNqA3rp+ hm`T1Y9ka68"Jlf,3ZRfRSPcUq1A1I$kVe1cM!,[[k0BrrI%%K'B+hiqMYLFjU,M XJ2m#Q"E-p+)T`+!M4V4-%pTJdB@U02PH9VYGG&Kh$X0I@@c32jQkR(-*0fVl+I` ,BRX2rN@ar9D)!Y(jIIbla2CIm9GQ'$+I(V%Ya5A5DU6jA0G&YM1NRYJZaQ@Zf+l &"BD$lF1il##fIir,MQ,l1LlcaIDr``k-@SdD,a5EU%A"fm@f%THRL@dG,MZ*lA@ il#bfIi(,BV(pQ[3,YYY`FE+6f!5RJRGT@jkpX84XZq1bQpLHM8Z[f%l(KITMHb8 Za-(fdlMX)EChil+Rf(i6Plh%pTpaf9YXrafAIE5YJcfXD02"ZLLdGV#RIdaXTq$ bG,%"jmm3'hR[*cEbALifF&G``pP%L`cB1pMq(*F$Y+f6IAZJf-KjKGLHJmY"BMX 9Pi2&"YiG)VDVF6P8E2p+m!IEEq"bZ0LqJ%ZIf2i8PfGT@i%i3NpKSar)&aXqcaA EbEJSUKIBh`j2aABj,NH+l5fi(#@f$q'L-&pi%THMa8B0MK(E(EJF+cB8aq1dV8K XHTlBk)2RLihm`4PXp0p2L1d9Z!M2FEDVF&&F,K*[6K$EVq"bSYJqMFYUXAd0PaH )lEm*9J1rB-!DXB%"e"mEI8[Zf+JlrBL0qfPL3hm'Pl#"Ibm8fcY`!C1aJApRLJh mHj(BrJ5A&fYE&c(qRiS06$a,E26j6iU0@Jb)l5*FAL+f0q"bYYM)qk9Lqh9FeSV Yph"jQGM!SCGV@cHja$PL!a2TGfc8Qel$4[j`'@bEF+(Qf0k+bhPL%ii8e-4'MCA fGV2[,a$Ehq)#EX[T)4p3"DH(H%FpXG(cbZek@%Hi$,BVF,P%E'r(j9+a#Gm04-, U)Gj3(fcI`NAH!R"QNE-Tmj[&[#m6'eJ-TQ%$&eiM0QT0[YM!''APXkJJA5NfmUE IXIdZ,[pFE2m&&f*LqaiZm$ijXmR(0SX0A[&kXB'9p#mfm!*1JBhD[9&Xp25Ea(B c,Z!rYUrJmQDaI4qADl4Y$VNC[!mE[A@Gf-#YRa%E[3H'Bb-@[BcY"Paq9Qcr%CH I%pZhFIPjECY,6[X,BS1$JEhBi!P1C4-E1%LIBU2IU#'fAm6PR@,lYlKJarC9A(j *E$r!j9pUfccbbAH*$Ei%hm%'[X1jX)&"F'TXp-Pla3B[Z9jX[i2,qm6f$9cHVff )$X'$BJ2l2b!fqZD$BL0AFX%'9[kbf-!&Z!BfqJ&qMHdMZ0"(f$k$#pL)lBpaq9@ ar5pFi!9bGL6I*LBf10P0BS12I94XB$piMSekIdaXe!!X`NB[J3rBm)%2BJ2lEa% ER10@ECY2c[eaX9&lqK%Eh"AZM!h1TMV5I2)6p!TXB2&[L`fmq+6Bk!di)$E`!rk &lEZir$YY@d#Y"2d"'rbFhX4'[HNAE1$aCm8'PrJ2BJ2[2LFfHKZZJBdF`'&XD#I N,QFKHGAYBJ0h2bmf114r%KYmKKl""Pl$)l#"#em8'h9"Rm''E[%(fZBN%6Jq0V$ `bf+$[i,2f-"em!dE(!NY!KXi$LI&"REmSGLSiaq*$G`&0q3mMAS3@JdfHK4ZK3d H#qr!4RlJ'cEkmTYL!erJ40LS)hPKJcG36cNl%32S(@aS"f!&0[MUR@+$)p(,f-" PH$3fX!DG!4[pm'GLqjqiS,I)fCNi"rI%KYla&f+$PrbPf1"[m#CXm)6r)6D`L9b `8GqrdVE&l!Rd""[Kd,Id+he+Im)&i-[8&+i-Ei4M`kh"&(#DIS5$d`2J'I`GlJT h"p2!'hJKr"e1#"H%qm1j`6fi-hd#EiDc`C2Kah"MF!9q$"DM,p#RB#1pK+i!AS- GB!CB!8E!%H&lp"@m%$i)c`4AiB2`3(!$(NSIJUrJ&*J%&i3$`RAJI(!p1"lFMPk &Ip#Mm$Mi'rJ!Ai1R`F[JD(!cX*Rq"ErKC1!cZ!`HJm2SQ2"PX!Yp#-d5R3,0$-d 5V4)X3FX##q!Nk+RS*QLTm"*`"!k0RJVhKi2#@q%mD*S!0hJ)9dDrK'HL9rVA11J %i+&r4`'r!62K,R!+0!Gi![`!2)82S!ZL"i+KD)&J0*`$l4!Y#Ed"$S[1"HE#Nq! rD(2`2VJ5HJ3BLaD$"J'r3pY%d`3ciDAJ-VSJHL$k%2SI'LEk+ISIf)eqLQi+j`+ ld8hK*r!c1#Ym!ii+ai(E`P(KTR"5Z$(F&mi!&i@$`MhKR2"+1#Ci$kH%5m)K`@F i)e`4$Jd(J!["JH!qk$TSH2!&Z"Hk(ESIHKqk(4`ER3jG%(i"2d464%G!)i(ISEf JZD!TSVHJXk"6S82#&q&"F"#d2$3m1$2F!Jk,[SPQKeD(jZQj*M`&VUBDjq6aqMm BjI9rm-2Vrr5ferrT6krr8eZ[ri2YA[q(0hMp(elJpApUkl%)R&Ephq'Zk[m12eA rGlhUAhM4PkVr1mkKqVrV4pAr(EDUrZm`fq[re&(erj!!'+RkIdJm8Idr**kTrKm 5Ke6r$pPRU[q(l%A9rd0b)YArhGX%eIp$pV,Urb%jKHVr)I&)pIq3!2LLqRr)@UV q(j*rUIiI%Yp8r`r*De6rcl'@U[rR@![9rh2%8GArFm35eIpca!c9rh2NDDVrjmM K92r2N8HSrZpHkkMqRb0h8rhI[Ae3r6p(,&Ap2mGDU[kI)rG6r6p(6URkIilBTrT rlNA"HH!&M&$p2mmq92drcrUUrTmRVURqRbI@U[kI*aG8r6p2MUVkIjjF3rAr2$& 'pImmHCVUrhR@6,%a6pkQqRqHI&,erccjTZVr(F3eeImlf,HUrhH`AUVrGa$c9Ir [)&DVrYp"R&$p[i2F6I9rpmj#pIm1mNr9rcZ)IkVrGj!!TkMqhd'ZS2Tr"hQCk[m Ga!R9rc[)2eArlb4HUrlI5Da8rEq6f+6kIbHa32Ar6[D9k[qGV+2UrjhNikVrGe) $82frNca1pIp1mQc9rcYC5pAr1iN6U[ph%Vp9rqmN0eEp[j1BVIUrSa+UraH)ikV r&eJReIrGQ`l9r`ZXNqVr"GC#pIm#m8$er`*jXZVr"H+Ck[m&iTRUr`AbGpAr#q5 &U[mAb&e9rbq3!-HVrZrHIDMqAk!'S[TrJ4U[k[p&FKM9ri[N"UVr&iQjU[mALB1 UraH*1kVr&pRcU[mAf61UrlYh)UVr&jQRk[p&FQ[9ri[8*&6rGqp(92m[N[ZUrPm NleAp[dK1U[TrN69@rEp)28Merb*l92Ar)V8eeIp,j'qUrjH)hkVrPeKMeIp,a&R 9rd[%(GAr5kbPk[mPpS2UrbAQSrTrLEU0k[mPkLkUrjI)keAr0cq1-12*Phm6KpH +d6[*F0qfPpjDrM#If0KmB5KjQJ0GF2IVr2LYpMUViZ`4l0pfr['YGR"RJ+ICkfT @m%EkVBN!)V6XLRm4riAi,m&r%IlGq-r&I`lq5r(I(Impm0m6rlhLPpa#lhK#QF- rMrpmr(N@!1dVi&r%IblqXr$[`ApHT-IB-mFHQ2d3-40K+b8SL%l8`RkqD'-A5!D [M25dq*J`cpJ0J2-%a*X""ll5k'@40ZCZXRCCQBVPqlDIhZ1)IP!qCr6Qc8fGYe1 ,HRbUK5A`MRaXYN3fSkA-dMLlARhPRS55p(E'Ic(q[ILMIhVYflmG3FG#,d@I3X0 !Zd"(J(ZL9k#&SC1K2D+"SNe#cY"4d#E4[Y$&d,(3YG!Hd"A3Sp#Hd*R3lY!8d([ 3PY&Bd95T)IhThkE3NqJLD%hS41JpD%(d'4S)qJ@k*rSVqMCk0pS5'JGD$2S6ZLk k$MSI'L$k%$SRqL5F!+d8E3[0dEpr3*0$Gr4D[YG#d6h48p&eiCAS5'KNi!DD0$S ffJVk0rSU'UlUK8j233Y%Gd*[3UF"@2cE%R4JN!!!c3UY%&d(23Gp#8d124YY%qd 0I4U+JdD',SSfL,B1V0$Qk)Ed0[SMHMUk+9SS@L'k&VSI@L(D(PSSl`V3r0$EdHr 3pH&0D2ISHfK%L)4`@E3QY#3d2p@VIh4bk)pS`SJ"3m-@Y'IkZMDdQqeGR31GZ+l Zc3c)``)VjCJa-f@X''R5-T0T"1ER0dF3A94H@UmA,d`K%VrM,iiJS[[0K4&%k@b R5$ma&05NbS&iGe0YF)*0*ldc[KcqGkC26IV,CK`PYZ3j`C605*J#U%hX[9#"pLA (N!$rSUX6hDU9-J0d[ZVJ-$`dV2HJcY54p[IrSUL!,R$@IXE!P$#,BKTK#kN1@5d 2qGT)eDRE)qfCbMZACNqKVbeM8mTr'5plAi@*)(8cRlXZ6['fmhpL@V#P$kQrchM #q(VUA'0+Q&hcGN5kF6DjijUbADQBUp2b*VCb'P2X3'CcJ8+@PIH-ImJ%`,pRNK- c"H8X4B4ar`k!ejKraNE+b$M'!NDjAke2hI&[j5-(k3@C[APL`366l-dkYC&[6pm d3Sm)AYGV$8aSM-h5!-)YG+#!pAC-f[Fr*X5)G!2J2#SFbGQQL6ARdhZVk1JmQA4 UNjrP&)Y4EU#641L%kZ8FH+(UTPe)"1H4b99bH+[UjPki#%l8[bmY0m"P5!9lr-h 'i!13!,6m[!d0N5([AVG8UZ)`9#NalKE@dMjpN!"@qSph'XE+X5CH!8@pQPU9j@b KH4@()CSAXa`j'FhMVJNcYm$0b[+j--6!$FR#!6DkME[b'Q6JQc'XQH-lK[rFR"e ilPff0q+EE,6H`S*qFiR4FI4"Sf0ShCBqXlqRV'ie#l`Ge6jrV6)fBl,NdMpUQlp *$CYiAjAJ4flqji8GjXC6Dapk4KdmH($b(hlTJHhUc*Nc&rj[`l1[L[f$4ikm&11 KIl1QV9Leh1f(rbfIrR4#3Tlqf"&e"ap'I%d#I,J[Gf012rG[C(GX[T(YlmjpijP X%bZDVkDpTrA%9RYlC1DrXY@rNpe4j1lBDQ+2rc9lffr#[m9@fcNhlC8cASGfV8C bDI[9mRS`MiIVpeKq)r@ILYI-Hb61`hhcB-q1jT'pHS`IF!Fj0h!pYf,K-I",2-Z l@q@fLQQGlBGae,%AZrVdpYZq1qS9iENaA1,Rb(UpYqB%k5,Y*pZq@-5cE-4biZ! 1'0FlJe@NZlcN4VDJYiBTNbqcLME5$!UpI9ZfTI%dH6QYUkbJ(0j2br52eJ+RDSG Z4fiZp*UC+)U8D$rD*#&0h4GTZDImFU2SUiYZYHj8(,YNDRlQkKZe39,S)#jbKF` YVaI,$#-[hTIljFTNXY)"kjfL&6KZ$IQ+Y9+U99[&LR'eChqM!$lAhNAQUY8M*[I E#TS$@S3rlU[J@HeGiNM)FUAS!JRMZX!pm(D@U*mNKlKaMV8@Vh5@V5iYb84ZfQC LlSfmR@2I5m[UL&G[ElAZHJ(IM`IVV8V&G@XSj[SkFD0r@HDffd*2-Dkfr+*9#Dd RfAX8lNIk9E8YdpIGhFaKpBB,jM4R2jfQlq+mJ65'Dj!!T#i3lPAjV4I-[M*Ue-T J6E*hcQZb3*Di%mkDl)6)$j3j1TX0V9PRPIfpYBTNiP'$"R&4HaA[KY,A@*@-Nr# 8*9)E%U$32R&Y%MR[1e@*b#Y1U!*ANDX#RXCaX%Fc4TJjQ&kcHk-8U*+,$cF3GmP hq3RkaQ4$c'AI#!`J,8QmU%RL%05RMb923S"k429B6V9LHJ#1TSiH-BRSbZTJVeS `-U`jeaSL*J81U5*-VZ&c4UZLG-3`!!+aeLpk6Mh3$C%iP(1Z42'**MkZ(ZGHLP5 T8ZETZU[Z8Z8e-,ZM0S+h5D#M0ZUHVf$[84Xe+cMEVIPZa8ll`HLJ6mjh,Z)r,lY KPed,3VY,k-4#*fcei414`bVE'lE&"[kTFrqS(lK9m`IYZqpb[C+[1S[STBX!i"[ ,D+)"a0aS&Z`JF'V$[ZTf8*G9U+Lc(MAU9%VQKYf"CrQUbaiF(4kf292($$3Gk!r C''NkXq`9Yd%RFR)H+@k`+kUhhqbV!a"P![1&C$#1GaeRed,EdBl2pbER$6+&T++ BK&G%Gpe4,Q)rQTA3SA,Z5Ih9RIVl2,'PH5E0JFRRTfKpJ*QeDX1M&R+*fq*!64B PQl9H5&1$&A'T$c)l5b@(AN+)+,@dXZIXNY[Ckph5hCUl8mhM+ZkJa)PDJK,8R8i ZHb#h&a'j*,48CmeSR3`,"dPY$9"#6**5"*`(D04aqN6N'Z'cKR,iE!-I%hEb6kS 'fbc(MT[mBmP-HdiAmR-5pVC6QCCV!``ih$TF`ie6Y!@1EED8J`8bcFJ)@Z&$&eJ YbLDeZXT%f6f8KG6%LiI)T9BF@%0A+`j8XlX9Ka(,2A%F[i9623i2SQG0a`NDF9K (BNiV(dB0lc!GjmT'(,HbeMeeC,68Xel*1c'`HX@c@h&B"q+jV6LX2A&m('F)'(3 abm)VG8`-V$6aKPBF9U9i8kXqV%,ajZ[jP"[+[9jY2'RG,N#))i5d29'[-M%[qYX -mmZ&`dE2!NrmVqPrF4hTLikZl-CYa4'Ra$H$TaA`!(4+2)$2qBhiePmJDJE8C"* Gq0&2*Z(Sa)Gi-XN6ddFUGRqQ*T28iVIcIU`qPAU-a(dJljRT,(IeM4h3Iir&X3r qichBl09K$!NQNZAQD#&8bcp2[LTr&RkGM6qc)'9[ClE&#'EK2aIr1C1E*XYrS3L 4ISG#[qZMhr(4l`X*Cq9"!H)`Nc(CB`N"f1mTkIFVY"81qI[pQDL(hd2%eia$(DN RYD2'e0(2-$B1MK5K&rmLrR[J[bIqHq'r0rlli,mVrN[`lmCr0eDY0$NFj2mV&[& cUL(&iJ&qF(FFqdQj@,T#pL"-CUU0+aFf!(ZZfZp5,UE8KYVp-IEFY)rN292[IkL (IC!!pf2cc-ClFL4HHaCE,CrQUHGK)QLdNDE0ijlbT'@)X4qEI2qNj8U%G0+bie6 Q33f0"#AE$0J0k,lP#3D2fca(0MdV2h&+hpA'%r%P$YZf2Dm9Kkh@*Tpd54bf8hY a+ilEiR2Nk9`5Kqh9MQc&36%j-RTb-Icd5la39Cl6LJ2+p53(a%RR(IE*R+6HR1- ATea2FfVp(1bNmjJbjeHYAKA0BQTikK59KU1Q@bY#0(GZ1&AeMNFcCGl(B%V6qCG #(Z[@,ZASb2P`qYS$1K-VFkj0fXUmdlPEQ@XkCbYcV3bbDRLQBkdDlUhHUSbmUYB [QqM9G"lZ,"fG9Hf9C0CA`h0,kC,K1Je(TS)0HJeeDf9L@1DDcJr,A'XcdDTiN8j )Uda$b3!bpDcLBqTEJFHkSlC"hFrA1mZrLSe0jlL"8fG&aY6(!@2UNH*LUr)+BDP [$496ja388mm8%e22#L6@(90BUAXhfkQ#KeRK-MJFp"eU*JA$V%%5,+`lMY8X3F+ k(d$BF'TeC`8'8mm8"922'JKQd*!!BU#AUc2mLlfUf"Il9A![GG+#TckqVZ9FUeK AFiaE-hC8M)[Y$YpLDiTYpBSU$-9q08b,(E2KLYiVaE,BUi*MU91+"kPRV68Uf&8 Z6SCE9Ep'Bj5RP'V4%ka+RBEUNQ"8kJ-qC3lelUVJ8Zb9BP,X9F1MFKZR@*41qFd !+A1YSP,QA)'QKQFm1V,Qk!YF,8)9U9VHF9GQhSTCQC-$VX`P4DqK(P$dbCaV1*C jTf#@ZDD)PVPQScGVRY9"R$Ah9Qp98+jD[`cUQXl$RD@J9qf9"2NDRPY+Pf"J`a% J(23DkYB+*'DZ+5jQVM9`V1*&LT!!(JqFer'1IdNc5FHe$ZTL)MpI!)eid228h*4 ABbaVbL,66"Y#JbEDF*3m8kG'QM%j5&2-Z*kQPcP*DV&$FkKXTDh5h!EK@"-Fp*3 X-kp'UV8je(@NVJG)`EVZA81)HS!-*1VZ+GlA[5Z3!0pb6U'c&F%2+flkCJ0kaq" rf$pQ!!hrL!68rG,@VRYAZR[)HE4J[[hVM[FJ3)e(MJ3B+hH&hV5Flfl6K15dI1% j3iiMlC!!XTfkGdTikYj9!PrhVh$iP[0)+DYbN`lYENSqhV8QqRLr3Fh#ZpB901p BNiUmAe8XUVM9C*Q+EeQBUAJebeXAM6,2LQ`8HmE#NIHSm5h[9f9FUGYJ-4)ZjPe D*-ml$iU"9GGQqDSk9m9YT+8bVD[LT@TAkY)SE%hamRjEAL28aUjRhZ8akid(0-I X,YTk'RQ6IGIb5Th,DG9I(Y5cLJPc,D2BXCa0UZR@-mP)F5fGc,ZF8d1(UbG@arK DEJdk(+IAiJIe$,2ZDik3!-mL0!E+Crl*H2R-X69X2Qh5C[*TJ%EZUAZ5HZVAbMa Zk'E@XA-MipJeb6EfD@@DYANch5a#)qI-2dNmFfaPAdH"CJ(U34SeU)G)bP$hE99 LQ"hSdK'$ElhUZ`8dANp0K!$akL''b)3[3rf&cGha@d@S8ipkK!Eem2QR,b6'iVE b6NR+i,S',C,L%fmSea-C$1q%81-dp4"MR-DASU@PEFfM9C!!&JZU4c()ML%cicT mkq9&64imGX1-Defhh3BiJc1ZH3e[r4aVBXEe1UX#)[F2GAbLQ'GKKD(!U9R"'qN rYV(M3cBC#F(3)eQ3!&JpKqFA5aa'88h19jBiM*mD'4)4*bGa'",aR&BFjJf2cRp 1iM$QDh5ZFa+(0Hj(jc8RF4LHF3hRLiQYGbSI9ZlhFD!,Nm-ia)[K'D2cXj-i,-m h1SmlLF0+ND0cYT-iV2%r1GGCiV"qrmLmjNSGpmEekZYabJ"LRXp0MTH(L4BeXPQ AKiRAhV*EMKfh2)`FZfCVeiVUaUcH[*lL+km2jL6(`5FbLaY&#4ld$I0jjETLBKX `3"G8GQ2IAm'$mkcN0LbSiN%R'(BSNb0dIlSqf4R58J-)M`I#&m2,H"$[NfLR)8+ #"kaq*(K3RQ#r*X"qTJ0HDA+,dEj`*mdq2%Zdc0$"ii(SLl1dIX##U30"FTZ%N!$ JJ6cl"`rkFUjRFf#AF-6P+p-VNYD3!#("JpRJLceYeaH!A+c(2$ae@1k#VAKYJ$a @jE,VVmHT,UAE1U[bfHk%J$a1bh3P!p6eT%,rG)EEmMKj`lD"p'"C&Afr3aRr[&r 0f452-#JG#@hTPViH'Alqik%Y,*`+9i&`HELPkXG1ZZ$[m)RbH2TY53&jh&f3!2q 6apf,R[cI21j+C$U2YE[VD[c4IETIEcKER[MU1S2f"8q$afpk+&bAH!QHj*BfPX) H[Iei'ra[0-C2E$F1[@ePP-Fjrp1[V1AJmVLl2DUl('qTk`8BqfJ%j#',0[qSVUa 3iI-B4k,T2#DH1Y1ZlH2bZ%L9Ch"D0f4f31eGDcM0qXcYA1XV0JmHfF$kiYH+0R( J(aIkhMA@F&mHEJAFL92G&,Te@%(B"XL$ipE8rY&CMEmblQ5FDIAB(iblXGqmRSF BpeJHCJ$M2R(pTYFQ2PAhaQiGii1jMeEe)HBqQFIpc(dbMrZCqpBmlQ2Zl6cDc*f Mc$dm-'pl!J"c(kl(SmapV,$EQ(XlMrZCqh!DMc$hGKi6c&hbQ#6[%A0I1rbrI@p q-'kf#fqGKaMhD"iF)i"abh$e&F[0aT6dkZRk0Q1521j#KJFBdf3Hpc1GVARFah6 DH6b!j-0j2),Nl6`Q3%rbF%2ef`M4hLBm855fG)MNFIiJYb)F2E,iq'3HAEPVHeL AFVP-cq[`0hVZ46`C+%mREXeMrDYF8I*BM`(djCR``ahp8RXS)D#Z-j`KjY)6R(` kMcCb6[4Ch"mEVlEC[DFRA%CJ#mE-#GA(JGTM8*9'9DMQ+DY3Gia&kU-*N!"(ImA h&5"'!'3d$m&kkKV-k141063"kZ(82K-J$krfMHFaVIDG%e3VkK(X6%JHQmIK[GN i$IZLR4h'f-Qk1Q)mr26a4rBCKpp(-*(&@qI@i2pDiq(2G4PMcb'Hj[%+GY&B2DE k6&@@GI8VrBV%iS"S5alX'KG`*EZC[RFUL`R3VdjP-3(bi%4`&RbRVLi2DBrJ4Rq Fi0CHR9%EjR,j")$4IXbhD912B'lba-Z(rVjlVfK6dI%p0RiFKc%"mPLj`aY+irp %A@'PGX@EaI(6j%+e8qC#6r9(Q3XpeDpf`&Xaai9Qm!-%2X1T[rB#CkUZpS4bc9& 1p@4GA4i6@d"1jG&qiK@m)rRYMGIiQ@BkYY)EVjPM,,haZU"qPCffkfS4[2+@Yf) ca`"j+cB-))qm&4Y&DL[JV9KPT(RV&*-RQ,Y4`8a0!15d&C!!DZUd"q8B)*U1i6) TCr`B"&U-$63TCqBB5j0bTV@BS84-JSNlGafGZ(2AXEFQlV5Ir`GY54A[rqpRF2E '()%(Q0G`(SmbVl'#E'0Hl6c-LIN)dmaV+"&EB-j#P-IDUhe'%QYp)39EiYJ!M-$ PB8V-IC!!`cBp,&V%[A6XMS8RP4Vjl+8JI[Ph8ql)6&m6$J@f4d&f#l(MhUABF#J `YCTUqIe5+AUrC-Qp9qP-R(Z[8NL@HpmSI,(RrqS,ljHXZIFUjYal0Q%**rAe$63 M&$EfEjQF(aA1i[EmI[rMcZlHl!EZA+lhhH@qP(I*CD(BpfKNN!"VblQ"klN9ENA K@#K1'Y!RY,!4-$m(`lCL'8-FjNU3!'kj,q)G18c[Xb5C1A*hmH5qJrM2iehHA#b 4q#k1f(F9ZiXRFBTbprRZe5K+arH`$f4derQMAM'XLLZK42&C&"[4LV-CV9cZJQ6 QbqdU)4AB65VP+LKq[Ec,E+`PM9bkjc%ATZ@Z+eU"JbQYr@k*BjYG!56BcR*Ir00 (eEPcjbEriF,hjj[feYq1HlmfH"+Hd-dA5r-,6V9HX8fLd6+r[,4H,bjTaR-Sj@C $pa`(L(m(,L**RIji%N+KMX"4@`k$lm!d%`EA&V4RqVSfY*[YACd$RELZlXd-Y#H V0!$6Irlaj2"DMhQ&&X#*DY%6j49j#,Lk@BKZSTRmCGeipdD`#hrbRSArl-5&[JP *4,8Q`3rKIa)0cLTR$Ij1,I!1Tq"r$6PYTm&YkQA%TIa2EdDi&RqhK)diY&U5UJp FhdM%JMRXal+bmrC1rZFf9(khFFkD"IhQ%U2Mk)0'ap#k,AeQIdpCh@S@H$ZUIIj DC@`q!ChQFfhc0kPKFdYI!j1#P0Pc9#bhTpBqp!aTRc2,2Ic5!pZEp[KIXlIp*[b E0Ch-Z@Q[R2%kY'XeNN[EVjEAJhNmA,r(mKZTre5mCYiMF4lZQ`GlGL`2-fhAdj2 #r8$G+I9mM0I@$PRIHb'dKIFI1Xbl`E6"`[jleM8h"mc4AYRee29[Y1[TJ$pL`Mr UeqqHSLjLJZekfX$TeUkR9CbfcAFp04'BZ`fd"p3iFrHkX4h!h'fTA8pRqRklPQ( AdaXA2399D95&DTkb#[Af`j(kD!,NdGMeY*&(DkI0ULVQ9%-6S"j1l6-"mSKh2Gf 5al6DjrDE2(iXh[8dpjE80YKPep2Fh$['eI1T93I1Cap2QDI1)U6XHMV[br$r4'V 9h[fTZIGd4(Qir5E(kM(9CieG6aYjY(BpVHE4f2AdKr9`+SX*d+p1C6%"mZ"NZjl qX+iZMh6AdarQXCeSXqZT-6H*-ji6p,@hKj1'$DT*R%X`ZP[R1SR[lHcAh,+pC[, D*-iD6P[`NcLIC1i@dL41@EXKBZlK&dph*!!`GdYV%ZGNhfrA-NcLr*2II"CXpHm R$TC9U0f24ZUM#C!!aq161'ZUQ&-06B"k1,A2"-M$UhhMH8bVI9XRF4lkrGqFa(R SiXZ61-IU-G9RMdrLV1Aaq#61@Kj1C6%"qY@T,#C!(Tc(*R(@kZVbq(q61'YjE#I D61*NRpKmZ&eXJFXYZaf`RbLb'ACdChLfHT1G`&pZefc2+5Df!B2Ip9QZE%dXH(# HPGb'"98mk-3Njh#0IU#bCV41VYRABeXPfm-fqIBD(JKI$#rM3EbXZjf'#!NHj#l MJ9LY0BU3!1""AZ0"HC2V0B&9+ePHDA)GrVjF)@YQeLLRPQ3'$XRZq,1eRR3fa[- 0"-PYNP+#"pdD$rTbVQGhBf#M8-6P+p-VNYD3!#("JcRFrRjbTT&jHQ4-pI8&TeU [f!2&")$a$$E(-H2HT!NIK"S@8hV6C%'&b1"2q+NS6JlAVPDF2+kP9Ta1A(H2iZ3 B0MjA0Z,`MR,(1%kD6pL))k`f@"M&b9r)Tj*h$kk(6FH*Nj-iXh$YDm@CLqX4V6J mGIla9T`GF6dqlKrDVY@hmh%Y[0*R5Cb&Z,iTMT2e44*R%DjAAip6EVci[C+9(fH )RYKeTaYrTLM!kE[`"ch3#cJ3BXJT@hHJ$F$RiHUf`N'Yf'@b*Lr!rb3DI)A@i(p bdq%8r+m4"`H%Tq&rHM2#YIKI0aP"NPXL43iqJ2pCSD-L+,0ph,aL(jUj&e%%H`0 P4@8`0ZTP&adE$J9-f$G*rGdjJ*rTmLc*M(Z6C0KTaADFAXLajE9MMLA($Cq'rhR km943#eq4"FS0Aj)&UKkq(J[86RNpGD'JaN@BQX6C+(kAb[e9i[r6FYmNHEaDm[T R%ZFbbHYbZEp'iPdKm9iVpMI+r8VaHehiZLe3(`jIXePlEb3YML2i&KV'6B")Z8j 'Bek#RU%C#"b"Aj!!G2(d()4i2S6%i8hTV#K1iHAj%"*R9eb2RSi6*bGaH+*j6#[ 1EVJH'm8TASKcC5-1Q`f9jea8kjM%f4hAbIN3%QF2A%IRF#4apX4eG2j(%QF[A%I RIb4apXCeFLk&a0N(emQj&"*R'DlE-`Kc+Db$l'`i4@IlFJ%$V*bc8%4M5`iaQEA em*ZZUq6q8h,I,2IA4fqqSUPK'm1h9i%D&Ep,j(kTj1[IJ$hkpS[TC1@hAk0[[Zb "0c&bSYGX%B*@jU94-DT#*DJLPH"GM*qK0LGK!a@SQQm&+Nf&UI4)PHf&+A&4GaX BEA3%MYYf$J$Uk-TZh&BFF8TjcpfaY4"ZFh8'LXJVR*(6J@iEpcm6R6MUEhUpi(* aiMF3%r6&lRqCG8qF"kI&@J`RTfDhA9mhFR&belD4CdIl@Uq-ee`V(3PYc@dM`rX q(YV#`UP`h+r"Y'hNlBp#Mk9IEcKER[MU1S2f"8p$9pVd8"KS#IK'D@1iHhFiIV` 0rMFDibHf'iIHYM,+`dlD0R*L!UcN-ENST'i*HFi-6ZZ@N!!1U,eV$DIYV5dKPA' 2$41f2aLh!E5cYE(!h'fJRDh[CqlKJARE%`#BZrfcXl8YX'[e60mE),Y@RrYbM%G fV4l1Jf-%-1lfBUjG549lZCS6ql6D%hZRQJ$lSMU%-5Af-qh+I@[VkqL8FVP-cq[ `0hVZ4EaqhBPEmeMr+PH820CE[QpQX2LEV(P@+flFd5qeKa)#kMV$'@)Z2F(*Tr0 S)qG%RmApXI(D8XRhR*j0eLjV"Q2QK1VM31daU%UM+P6cP&@S1mBLpG%%b+1ri[X +%#-!-TU(B$ee$@CdFUFDQJ$eF'UI#C!!KeIla[1B9[[1#DS9p8KHjl&j(0kEMG1 `,pVCBBbGV+[h'!qhVhjNRh(iI356RE!De!Ei[pCiq0e2'Q22)ClQm3Tfd9JpT[T -9CCep5[pLXVLJ'K,(QIdjNf9hR-eMkPk1*A&"1KATl+B!(P`)MJ,[P0APiHd4h# M2dj`Dp-Vk2Z!Uh,j")#04pJZYddpJVR*%bmIq[[Z[D*04FIhf2Ka(-B%b'2P$Qm SMIm6GB@9'LFEdMXZp&4rP,R38reU"bM1MJ[0i!F)I)C6Iqd&cP4Gl3RPQU1FkXQ kZMcJ9$2p-EN[cLl*EfqmaXmddl'9hRM0('2TMGId4[*$L4J&Em9QMJ(b9Q`B3"j j+cD+e&E!@l')ZDqb[H&T8E5B2-(FM3TQDJ)JTkf!9&1R25M(!0&d$*G*1H2()0" LE+"*162(@*U8-kh&$#9L%@JaGmI3L6Yh(AYViNllqAr3PP6ar[pq"QG[c"&iJ(N 0jr%SmaSVb$EQeFl$R*L2--fmKK+a"HBX4(QX[GTR*,(@&e+`*Bi0`!KF(UE%h!F h)c5[Ti1l2FM0Z(d$Q5l,Zdf("hh$GXhfR'*L'c$i2HRPfU(ai$`VZ3d,URM3L8R 1i4Vp3'A0D*eFXkr(YNUfjbHT!B6(!q',XSYk(3p%cVM3mK`l33d4%Mc)D6aB'hM ZAEBhiTZ&`+U9,+m%34a8f,3Q9mLDQ6A+U5@CSB2(!lFr[Y-2cXBiYS%JZ8e#52# J5q0"Amlel'i-k"11Z(aPHNA5'M)NH-#10Va&F&Zha!&3(@8h[SpX2[$%N!1q&a2 @`#%lml'kKYpL`q2#-ipY2[M*LBRRhTVSKJX,XFj)$4H11eCimN0+$5p2G-1&AT! !b2*U3K%Z(!JHqDQ*L9qm*G%0&ik5$CXUZ0"2A!M8b)&%0ec3Xjd'-iR6jYf&fiV $c1eR$HB8(ERcU`#S'#dD2,9R1X,N`3q$SLPX3%`,MCX`"9UZNp&i*Ua()SlRC&I JJLR6pdQ[EJm`i'41c@kl2XaYFA,A,,HcSlf86bT&!8Sp(q1eYGIdpei)EH(pK`l cEM$0FYYrclVQ0[Xjf[dfqhkSPfbcchA!(c(K(rAVGdq&1i)B5l2F,)%CE1I-i,6 1B(0!l9eV1'e[c@"6aMdf%YrqB0`'d%4mBi'jfd!6mFHCZeFGl3$QE[p-a*pJlT, (*(Q2*pR2p,d"-XPqH$Il4bECEpRahJKJh1faTee*&902cBPTTIE%9%m6B"UR3aK 6B[TP9qjE-r@M8mVP-Mf[`prSZ4IaqR8REXeMrDYF8I*J)jAH$"CHNrA'DX@01rU PpP"#3&eR1%2-T5FiqA3HEH5Fk,1i2cCH'pPpcqRKaLlM'$-R9"p[A2389+94&DT jbLV8f`p(kU-*N!"(I`@lc%3VcBcQi6H4'GI*R@TS!Y6$UAdQ3"jHl4[2BeVY1bH S9P4f61HaH4a2ZiUTEE![fYQ4QR[(Z(SqYHV!qHcM+I28@B6F#GMd,IKr)V9Ulrl 8h(XkSMcFTMpMpCMU-e9CeY@[p#X5L`1L,AQi6ApB3@HQljh+BJ,dUe0C6)!m1,U Kcj0eGAP)H`3hqZ-%YcDpi)F2Z#UA[kDDE6hXA05Q(X(Fj)QA$reppel4TU)cY3@ 4ic!Q3"iVGhK$DIbIU#ZXe$MC2m0aSDIkBcX-CZZTi#2p5Ve69IeJLTed3`QF4Eq U)VJ)pJlkEEMS&h,2jfA`@hI4la68fZ8KqHAr-[CEM$b+qh4q&EpPriJhj2K*IK@ riJ)@j3)2NaTb*aFbBFfE&`klDlpEb*pe0'ci%lJXd(llEB&0pe!1Mq2b&ZehpDr $TRZ1jilLXP,l(IU[X1Nqdjh[aH8`lAFQ9F5#j(%',V1ehp`"&LMb+l%RRkRphNK TS#4qEircZq(hB1[5ILX4Vd2mV[S$ePMllr5iIM[2Jke(kV55c42jhISjf'CT[j[ q&!cP1Zhh9ZE-,ZH84HSA[NAl[HJ$F*JMpI[&1,p6PX'QqcMRq*CEqqaM6m#Q8hG cAf2Xb1rQRi9Y"qfhp'q3!%Y"qrh@6m&"p`$2X`E2eAj(Xhlca3m&3r2i$1B&"25 9XpHANFGAY0q(I`-1#b8H[D9eqK$c@b4qF"kYdk*2`2Bdk9IUpbRYeh-2E$*cJ,2 RlFK[*qhhDjq(`ml5Ppr!j9pV[fr[C'pTIZ$KFZdArJ9XZfLrTi-Lj1CS[bA!6J& 2G`j(23VLppI%P&fehkH"IbXqU[efr6!FPNMHp%&[0I#*VmPmi22Z4-q@UN'Sa#G qPl'IRPd0+Zj&[`+9pRQ)"qiQITd0[2cQ5YKfNlVbpPlamZ#PV)(krAEFCpGqNBd GqAAXMI(bmdmaGZ6Ap8+-CaZq$KZB$(k$[iUA#jjKifNp`"h&bpX1XH'eIJPHA[X JE(Z,Ai+AYcm'fclDl`ASCiqAGj)U,T0ip,(@leA%URh&$hr&birq)@`rT[eqN!# 1mI)pl$9P[[XK*iqAPj,[JIrdaqr(q9ebN!#"0$m`32[XQ(mKCLMZ`Km8jllc!'a J,1k[Mr(bji"j-SXKkUHVBlcm!,(j!-'*&A%HAb"HkMlPq`-,29i'a$2Ld*ldTGE Tmm3QHTrfK,Gi2!!,$KBrm&hamRd&f*3T([)c-9jqmlIJF+Mf1i"m5r(bR6r!API mKJmUAYl%@)GV[b-DH2RY2MMdDEm"i+,(b`eIJF1c0#hCIh1-Pk`E(kb9rK"q%q0 P-[llrF$,`MV"bm4[$h,(J`3[%lpZjZ2a-[(,N3YUIccMcf'MYY6eR6&HIT6ir9c *Mjl62M[cPeMSb1pJmMI&blF5MhRq$Na4Gm@Ycpi2fj(Dlm$IMI&bkBr$TLpR#ZG M[0am"$E91I,RBVam$fZS,eXkb#Xd[cri-GL1dAiAIc,'bhp#r&B&ZB2m5H[hbmc Y1+R696&HlXLk4P1I`VR)fq2PRH4NcpIaMQcJj5CL$2`8Z2j%R&mr-8RIcqe*60) qZi5iSLqAPM&AaENhN!#,Vp*qa`$[29kqreIJ)2MJqSDF&#p[)aF(@r#$afSHej% hU1ab,2V$iq@ja0SA5,cVicTYHK3fm*ak-%P2kl54f!!fdTk#hai[IjGmQPkJID4 I29iH6Rk$jJ"XdVZ+P`2-5AJSCmAZ'#ph!GB'@lAI#EmGiq9Yj!(S!(*qjCGM[2` i1I-,G9qqj!XaAMll'$cS"HU(cZ(aXVb$Hl!I2#mF%la-r*D42`NZ1Va-r!lmZ3C H*RiKHCAfaaH*"@G+AHN9aFXjj*S[%VrILI[X,H4),pCqcbIr8,cF5&f%RJ+kiCN HYq#AJ[1Z([5ciZ@lIK)f(F0`)$QCiZ9eId@#SEL1@UYiZ4[a3,@hJiK2QYrPj,Z UlEf'qTEkl8-G8fIE(%*Xe[TpR4LRcc4AN!"V+PiH4Qi3c8J*ld1H1al@IRp-(U` [F9m1RZ6amLqSSDKfHp#[aIQpMEQUMVB-rHhll,)AB920E`9c8TbljCpJdhNajk" Q(LrIJC'3!)(SG`H6abKHRNNY4YqD(%4rcH-Mj,5UkkhlB)bARr`-(-!&mL!RVG- eR2@MD[M"j#9DTehB`fJTP!8F9,am*R09RA%pp"H2PpF4*e5MhFMk+PjH6%e(*GP $b"-8,cr*2P#0H4-iYmI,2iF@&Hc5rIF"F$Z2PdZ)SjGU[cp&[6aHRNi0$K`'8Y! EIP,`8M9"iYd!hD*3&V`Xq`@h8UGiTZ"PiVILq3CHP[ebbcq+pVLX'Ja2kCerMCV PhPZYqiLAq)8,J!%jPFrk!AJ`Z,**q#JBTMTV*Br,b!0[3Yld888hJNHq5r`5[RX 3GCePiPI'pA!*HqLpiPHT+c``kUGLMPa@RchY3aiFp@ATAFr#*VM"kD4HeU(MICG k!rR5YZL$,p&qGj+V`&A*$akPq9e",JX'JZ[`J#LriKqcaPF)2`DASra+lk$fK"B Njh@IL[0l0c840%$bJbGSIZF5RekRr9C5$p$m[NU0"ij2)`J2mrAlG@)k[*KbbBl k2VrE@"[G9hm&m5(+Vh3cFpXXZ)+IpXHHl#IiSj`LG8E0lfpr(cEi#qR69jVIpmJ 2d,'P(0qQ6Z6a5E9Tr0$NB[dMmIXB03EIpf@rB"AeBSp2LGrP2ir,-`62+[(3!50 qNlH)jB*M)-P5m"l9!r)IBChJBT,haqq,F$HrP"`9VLha,[Ql'(IIc"c4FZ@m'hc Emk%[N!$E`ChK%q"@a$2b(G6XVT9q+ZYYqIh%[q[%$jkT21C,e0Tq4[Zp"c932T3 I*2H'DmYC6IiAmD(mGQV%D0VNNHMF2b#RdIPUl`Ar9$k8(bDhK"H$SqM4@Zm,b)Q PrTaqiT(bP3q6irf#lSqR!`18AqB2rLdmk$Xj*HSq%4lN2N1Yp'f#"r#m#!rbEci 0'ca&cY(ND4%2c[F39piKHAmiiX(jGrm*E2!qiX(,PEGG6db%%mNjR,UbmVEIT"D &$L2RIG6[)Yk@Vr*YJqJ2R)mJ2mrE[[DVa*LSVRXc2q9YId2m3+Z"CU*M4Rf3!%m 6im%PLEF2G"cPEIQ$%fa8j3I`[8Jrb+mPeX#,k9IHC'MpEU5fLfi$Ai&$42T"rSH Tf9%(i"V1T$cqC[*M0&MkL9iIU2T6HRRi(Z+)pdYi8MqafIXPI1Mjl$2[9m(,5&q m+#![6RM9[f&r[e2LPIf#&m%MFpm9eLNi36d-(9lLr5&iDAkjpMZ&IF"E$1U"MKE KFA#!I3-INALc`3Yp(VFbedpVh$d&[-ARm5PUBh"jqKiHTRPmQAP6CmPM6r*1c@- c-3,G4Pc13(iqMcG3hq@Y#M30(UajR%9Zm9QGamfSQFrM3m4dY(Ga13Zil[2B3)l i1HPAF%(cq$VI@pbQmrJd--RRm4[%3M4-F9N,(GcRmD[X5l#1pNFVdMaH4Xa#-`G A`19j9EbU,rFHqGe'cRTVeCUDI*!!+i0IKPShfZ&(U0h`eJDq"6ml@IYpMMSPZV6 iIB[aIeElh8b0kIGd(Z[!(m)flIG#iMGm@IaH!9ccqEfD124&RFFhf#ZDha(8*q# N%ZpFaYAm[N,0JPc%EcfiKFr[92B5HT(iRBFB2Vp6U@ep@IYYi"X,cHm1kLMS1IM aGN(cfiPpr&AYGcj`dHFhRlb%(K5r#i$l2Vm$L8eIdhk[C,pTIPrkHpMS,r'lN!$ [3+,mjRf&Edlq52a%Tr6jR8"1b*a3mEX)Z12cqb9LiYHehdEb3Xh[F'SKD2ALGc( e)DhI#QV-D(Vi56kDhlar)#G%ja5A6`*[FTT[GIrSlm$MQlVaZjP(a%Zk2dYYJMF Di#jkRrG$[`5Mm%2R8Vr0a)C)N`P[!FjUIMecU('L5B+l[#H*i[9m,h8)p#,mH%I KrAMrG+IiSAPSIKmNld'INI`q#Th,eqr9j+0`56NVU"0S[&F6#q#`q-&,e1p[L!9 r*[@l*IEE`(F!`Y2*laE`C*rIPkLTd-[3+0i*D,bcb+(4iI&$(eHrlp2R,lAI6H3 EkRF-X9,Hpj(ICi$M2Vr[%`Yi!b*q1j!!2fJI,+(1$AI$$ac82(k#IIaAiNIrUpr (U-@!$m(r!`!!*)d!!!%!N!0AHJ!!9RS!!!*kEf`l$3N*CR-ZF'&b583J25!UC'P b1`d*#8jKE@9$Eh!50#i`)&0PE'BY4AKdFQ&MG'pbFJ)!N!0"8&"-2j!%!!""8&" -2j!%)!$rN!3!N"+Xp[d9!*!'@I3*#3d*#5TfEf`J25"QFbjf8Q9Q6R9Y1`d*#5T NDA)J25"QFbj`BA**4$X0#3P1B@eP3fp`H5KQFbjZB@eP,'jKE@8T1`d*#3d*#5T hBA0'EfaNCA*"E'PKFb!p)'Pc4QpXC'9b1`d*#3d*#A*PG(9bEL"bCA0eE(3l$3P p$3N0#5Th!!!#L%&%3e)$!!-S$9d,iCE!0Qd2b6Z[IH9Ehp5Ue9CEkEAkC*9FPqJ 9+UeD(CpNDpA*@5)i3-Q)R'5k55HY1-"hcYF,r!1f#E,M5[UMC@C+a!jlH+aC@B3 V[%icXLX@fR,DNr0`SMITBMNC8cDC6Z*'D,'pk"KZJpfp@@YN0fce%Me#6X-#1je 1j30JAcZ3!!lQ+MM%ppFL13@,l3`kNiq#Xra)29V1aZ2p8$e-6X$$l9JkMKI#GRp !ljGYH)IYT+em*paYXfN1h`AcrADp66EM8cD0CR)dR2%&qSc-`1RqK$iT8r%HQd[ cZ"kHY4l823UZ0RLjRL2VFBIRp%(CJ[IC4YV%pd*IreFIPcliY(@PE[`Sl'hl8'r q(IEcAE4D$X)KIUZ@bRMmhLE5"2iFIVC40*TrJM&HU6r)*&aMlDNGr`LGr#[p@MV J5&qYUk3cVV@a0)lA34GE5X[i1hM(rpDrj$emhrr6A[)FrQmId,[m$hcUYIUPI), If"+DaGp#2rZB2Z-'k1NVp3[TL1IC#r3+A`5[qX9kSEb-Jra'[88'i`hf%Ah)em- )[dU[PQ&iV8fKSA`Gh'3$D6KI!rhpCLf6!ILDAk+AbZYiZEe*Er%9F,kp5-rcZI# 5Ak#Ab4Y4q[3RrF'2`GYqT6iN[q#[rV!q)VmK'T-`3"4Cj"V@eLC8PNBMkcLAbb9 6p2B`aCDaP&9&U@-[5hXk6QI5UA49HN(DD[*0fCDk4QmZA"bhC9*QKDeY8Bq9e54 !3"2#XdXQSE`ZSEJ`S5P3&#J)Y)Ab`R#S$SIkd&B5D'e1lV3f*HZ5PSJk56D-!bP *#TP!2[bb3,EL8QK,"6+"jSS2"5`IY[4X3MD3!)N6iRa#69)'!*!$,d&%3e)$!!" @$8X$RHJ'ApX&YA!,!-!YrkSA!!$3@iYDH!'Kj[m$@)8HabqAC[SF!*!'*lp"4%0 5!`!rmJp9$AC'!4!aiqGMIjYcMV()-TE9'U0IM"@MlZFhK%X0M$Q(cV&kM"'6f&` D[K#b%A#b!`R2br85Na)aK#$0iD9FNLE'pSA*#4a,Z66Aaq24A%Sje-FeP%XTKkD %BiLe3#RJ!((Ipr[[lr[QCJkplE[hrI`('k5R+%%3*%%52*%"I!+Dpk1@k$81XCK 2KMmBkh)ImdEZFT0$AjL%ESQ#Q[A"f+5lUd1X8%03`%TJXZ0G8#P3K%U%iPa9heD KjeeZFCT8f%RNL[a%6Xl(Kq@H#NEkblD+H`kJd#!9&R6m19E#N!"@#`8L1LLBQkT *bA,EbTI8INfUkU#1afYrX(Z[U%d8m(MZKZ%5'MEBDhm3C0iJK)p5BU8akQ"S@![ 63Pml6kiTHVpAihr2j32Lf+fkG@ZlZ2qbbrfRcfYiFSC,bG5Y8d[GbakZ`C*!PqQ bISC,9cUh[kq,Qp3XJ@&0&dqqhqhq(hIamEjq6RGIeV6GIBqpj1,qPhCcdd[G20R ajrS$`9R3X$UYkqliY"IALYEQ6KjA1h*[iHHed5N0*R[[V!iNhcQ&U81EjPqfE9T dZ9HB2YR2ihfK63fRECZq21eb,hd!JqT8iV&%8@1[1[8Q"(UmB&C#-Z4L!dNfeDU T$R9UF**EDh0$am8D%VjcI3Bl(HC)AEh(&bT[R-U`MaT@JphSYKeETNk06r)iPN6 GqD*Sf))1(1bLli`H9iDUf$lE2P[YrafP#h@UQh(Y)eAQU!L"dYE4-rA'5f-6,@j F-Qe%FM+L3VJ20NjCD2[LY!M#e4HMHX0pp*'1e"CVaQ'`l%aNBCU5(l-J1fM"hCp L`8$3JXIql3+aM&$4Hci))BmbK)3b8IXe[G)kX8DXmGE#9&M+5leI#B-maQ2H"K3 Xh1,p5L*fe2eSD8VFMHJJ,'U-N9kHY$IM&A@14GXKc1b`Hlka#dE#'"h5B*,%,2( +4)Bb"DC5Ha+[)UFl$+3fh58MPq2TKVX`,*Ffh(9Z5fmH6'*kV36NJGU[XHe(eBR )*"IjkhBV*CH*BS&Sc6Z#@4$*j$*aR`5JE-J6C6Ipj21m0$XJhJ(&3pi1JdT0KrX Q%UFk2KPJ`VB,"cZ,'"TZmZ(lPR9cGr$a4m0KCXk*TNYKFSpYHhhhRQ0,4l28MU& 5Yd'*'I5aqTrc4RhL6FjhV[TCfdHr%IGq0&dXBm`2Mikc4%,+@0*N,QQb[)%-qeJ +-%*D`qVDc`fVFC523&LG+9bj#Y#X0$9Ui43UG*CT1*UeZ$-F$A'rYYPZ6BHdUY$ *Y4Tq)8-aGJ&aY'VER[)M13EffUT"Na`H$cDX3T@*GS,X08Z"CB0,'qRUekSEZVA *YMhDbLkheN3,(9Yc&$4Q-14,NpdlLXR5TB0q3RQIrN+'IDR`b5[G0QfPm0'CPb* #")P`%e"+4ZV'kRakDTVYa6dZ0+%Prkm&#-&!I"N-DG'NMcebMIHiTM)8,Si3q[- $J5YPmE@i8MYGLDH6Jc$mLKi'SNEij!B')[YiVD9UbRj-DG01[I'i'*K'!T*0Y$1 `(BE&`Z(N'&8F"N6`Z(-S%G,''V#KcX`0"D*)KeKq*2GM*E+K9rK`Q(+8`"Df2d, Ej0`Af*!!0%-d""9Lh'Vi%L%'#LqX9cXFhmY4*SpAS4&M)`E+)JL)i2AD"&H4I)( XkdYI1mk(IPL!6"35#,a@i(MZe8,H"d,$!8*94Z-S*BVF#+$U[H0)p#,f2X1rJ$J 5[Le6M#a%jGIcYS$XYr,iXcbdKC(G3Q$fUGmKST5B)N(k2K)L(V39,*!!!15+8"J +5V)4'G%bL'$'UYdM6b%m8d5NaGX18lL%KTpj[R"peE$L++dDlUXDpMRmUH(c!4, V(899``%5BijNeA#!4"5Ek8#QP,C5hSp-d"F@e2PQ3jiX'qD,qILjGK$!Liqdl4A h)l"e`f'%dRF5Ri@14)kbKYZ6L9))T%24-2H,C441`DF(`TLd-03V[S2N*jXYf4T BBMN+BHf'I'!b,*l%0$(mH0L56,$k(DU3!0%X,G3*FKi3'3YeLhfXH`X4!ZReSrj d*&f+T!hCc,b%e"8,AcdFFXZ($0qUr8TU),,5NA%NbL0eeYPpif-VZ+Af+erhKBa ,h(,6B%rV$#2G(GkR$akADkj4Q'm00Aid1*MPE@CS`#dU)B%MfRKL9"rjGpSdTkG cXpSrh,rlMcbZ3rM#[Icq1h-I8)cYQeAAX)Z'ep,`RqlrHXB$1-bMIrd04*+P40V 9dqmDI19Qe$XqG&b0fa&98hY#%r*H3eMH!pBbA*JI[-RpFS8b1T3Rm[kM!mQ%Y5& 2VR!f2iY`XlcRi"PZN[FVaKk`$i"Gl8q%j6)NSrj,XhdJBqqNL3M-`E#mAjV)3ar TX,bhkVLF3)"Q&8-0mq8$GM@5ar@bA&L[jXQ(3&"f,lXrZr(NX(ji[V`A8mRi16V `ZHT#je%f'4HhTG#pThGPRPacLF[,-F@Ke"3e6fSZePkQT*Q)jMk&N!#XP$c*9`M Cd*!!NY(FBc"5`c`)0GZbPa)STi*0K@%EQaHR`18J"F$U,1qYj3MD%YV'R(d4&`* 2fha'CjJYeSN)I&NDf2,@l5jAeR+@H"9KLbGad1mj6#'p21qJ5clY"[$8i&X!3R0 ,fekj"JKd!S9(@(+I*hpLKb#T0"ZfJ$8A@EI)qi2-FF0mq33Y*mEFMk('RY#0'lB !kHb'e835a#CUrkSC*p5Vr@S`UrBd8kSQ*MV!R-X#[jbIa-Frq)kM35QQJ1l3fGX FE'MQRilk2V6I&$iL03Xrc,ZJ@LN`j25icj!!bJ0NAS6NcUSZiRiS'4Ui"85MIXk G-2A'r(-JVXF`e(Kp50pIaZ11q*`5CGjfZVBkYU,V0#P2&!lf&6Rp!2AbB,,f0!A S@`m%+3FHk9KM`V(bq$K,[19Y8R*mQTRf&l&-h)"AXcJ23h%44bUHTLc,$!N3mk" dH+9&FD"l+eZLJZdL%TK1PX#%m4QR")BP+pP1[d08aX!XN!#IcdLUM'3m-9pX##, C(#VijlEGCm@5N!"02#V'S#l24!EH54Rpr$2f2+",#EE3Md)P3UlImhS-pb&6MR6 hT(@f5lHIS!j#*pT%m9"#YpRSp@#k'`"YP%hHb5l9I4$0QTK!Pj'3!)4e&50"baH c$IHaaF@%Q!k6pbNb,80KjjCZTXUr4U!m9rM-HIU%`m8%a')N&46J&&Y5)!QUD!K r`R!bj[@`j8m4HI`$&F@j#9e@dZY*63k`XL&FhA#3!),AR"2qFB$`q6m4N!#C3B$ -C@3`P0`D!%)!d(RqL8)"%!+`DYKfr[QdV["5(SNX-6VXK#kq)m8!FQMk)-lNPeE 394+kTlmPG@)5NcmeVI!aPF%%RjBQRj9"M)H%$fRc#p0C%)$c,BQfLL-m0j6l[0Y @2HE0mmVN$##+kRMZYPTVED+f"HVPIr&1j+l*A@1`-j%'dir8*9YIc"0r8Gj)+1% mVkSBVKLTbh)JJdD"L"EaGdi@,RGBAY5A[dX(k-blG8jLmffAEGC)AH[bK'iVhk! [hi@I-P+(b[FDE18l0a6`52QqNESM2Q6hJS!5YF'QM4fZJ!UQ(LkMB6M$',[e'r6 DT-'QM6#Q,'a@5$X'pBf!G!cU*TYVIiGX3pY4+!hjDhm(YjeEdQHdpRFrq&Yh&TC j62U5%V[TQL9!''Lm#kTIc'(XdQZ0KXAP0EiXTj@TD3R@$&Z"2&Tlj-dDEM%C(5D i5m#4JlF,kKUIj*b5#--@8ZSTF8MVB&Q!FKTe)V'49$Va"T*mZ&)B`Z,AKY$KbLk %BEE'S'lD$PH3!-*jZ%bViVU4&p(%D6I$D(!%kZBK8MVAjIVd!aP1AUT9EFHmEpU d8AkGLQd9@jB3f$L@9SH(3'G+TQN38kmVp1QRD0%l)h9KE'fXPCC%ER,,PKCR+j3 i*hjZN[VVYXN3K*i+Al-J'B9"q4TR`rPEBaLZMj!!NPmjNI'm!9F*D5ZK*$r8Z!c Cl,F1IfiBcE%IcN@f6@iFma`NKG8qr85'diUK%@QSJSEXrQpL-5ArCkGke%'Gb8) L0E'3!"Jp2%mJ$M-E('YH(Mr4YJ#,#Z11F4L9jlbS"cKj0)ff%Nh"`SQ-)%+F#1h HFeJ@&"pe+LHFJ-&"-(3Np@)2`NF($KE`E@5@`Bq4b#!,fJl)K2DeCEl3!GNCTd- rA!Qe,FpY1h`%2hX(3j[3J+[c-29#A!I*r(!%Qh6N-,Nq[8r$)h8[9!0ajM#4!8Z #d60L-h4V%fKZ-qdH*X4K'hqp8jJ'`KJNi0Ym68JElS5iN!$2frhNR)1IDA$QmU@ ,e*!!20#i@*jUI1`X'8`AFpqd%J`U',``Y`4ESXS@Cc-fe8"Eh6`'iHFc#'0*fHH X'f4UAR-FJr0pa8Kd6bqmH'ZYkMrj"`5YLN$-N!$Q`P%QFe,('K!fr9Mmkli!S*D hI,h1YqLkkG$K)i1K`h$kDVh'",@i8fhDmFZEK+ba3e)hYic4J3P#P#1CSa#`X6N #@PT-,(X$aCXI6d2TH0S4AVcaHZh`50hQkHN3LNqKDcU&BA!NR$IkN!"KS#)XmIA DNiD3!&P@M-,'%1UU,a2!CRNL!iX+KR&3Xh"3XdT#EH)RdQ&jQS*U,#-3P625SH( i)f90@9km,&eMY'R(NB[XNM'Kfak9%'HE`p')F!pY%'XqJTE%YT'5#H6l"0HX(#! aG46Al-6R!XU5'flbkpSSblJir+j1GY8)3jUl)h9l)aFb)+!%LE5P6*!!JQ1$XG8 BcB)"*KTTKhKAk&cMbcUe$80qChXNbE2XSc$**,P&BMMMp2MDZH98$-0qER(5F"B +ULpNVT%QK!PhMqj#"LAEKbYIe*YV*$2,Rf2,#!"I[ZR1UH'%MTrm[Q[BMF+(Ued rAf+2NBNk-ClHQRYb%!DpN9I95p6JFFZ`@dQ@VYX-MdKma[ETcqS0!amY%@ZfVB! 4-0mdrj8#8BBE&4PiYYS02TMPmP3-LYc%TNUm3SkPq0JmI'B)(bCZ8PS0cl!P*M$ (l&%-qc'F4+%84T0RZ$r5adf@G&imeQG*pqMAkAN@)pBFlH2qcF2fj$SL'ShN$iU Q1eH&ckfa2Y-Bh%6rfcBGpcHSprd($2&YVl6aZ+r2p2Y6pGBqbdEFB8F%aM"R()$ 2AAF64rId+rQQ''rfjCGUEGfBZKR,G3El4eLZI[TQIRb!ecZL1BTck-fEI$hhj'3 j-eqibGrLL4F+qRY@IBHh1LcS6VjbNhYB+15+ZQViq)9205[+,Skm5eZY-QI$eDi d1ARah-AIGrhXchB)+ccb`@*bpKc19NCKBPq6d*9p0)cKHDIY5GpTZeA4lUlQkUm DBI`RYK)$JZNm0[+NHK`CT"(X2FVHfdqF1irf5E%ppra0&'kGrkrREk13!1diG`N 44Ik*dr'ULX*lrh4,T8,&UDZh8,"N2[Gbi5N8$$BE-9KZRA[14SAX3T5S`+8r)-i M`pKLKcrb$(m9,X$@b$0)mD*1IipH5FEk)Mqr8)+-S+!4Ka-LL[HL!@"EKJmI0Y& [5G[lT%eEVhjk&1EjBeX5h`Ul)rVaHVXRSKqXYmI`kS2j86rH"mGD##HB0Zi!1MK +#@e"LJXERGHDd0&4$V'Mr*I5e5kKX9L3!1e-BJPANM3!Gd3ZcaD3!)&lKYh@HMZ ACmhM6Zh[rd10SR-H3qCNPVmSZK@K))BHRLES%5AdL%hb,,"I&&$4jU'V4Ai@`Bc f#&kP0[pC[3#JV!3$jXd!B(f@k)*XHjbF&VR(Qk'1JfhY6`i")FY&KLq43h'XhUf 2rG#(%)bp'DqNhImMR4,,e5N4iI0Y(3*%ZMM!'3GDU-I*r@@N%FV*E+!Y%!D1SA! YiR&#Q+N-eV9-rI3&U0EFbKJmZ4q$SARN5D"V"S%63qM*kFrj@$'pr6%5am#3!"& $aU#KT#-V4e(mMUbhP5D-F6$'Q`a&-"5K)8T++*3%%A%[%2M6N8BFaMJ3)fQkidc Q2KJ'%cPjKe2-%l82i5$m`pP)LU,K$b9Re%qCZ[!8#@beZFJ@%F2VkVKp''lT%iP k"$5MGXmmr98%CFqffC1aqRHA+GTBV%HI'djP'aa$5cS,!NC-I2c"$&,((C`F5N8 MM1iJ#!&X(h2(K)#"d+BaM2!j,4D1pkklYhrUhNml5%N8@d)N&MjqN!$F4ID&5(# T#5BT0a`mcUh5iMJY2KYBA*c1`N+2q!i@@X@&M04TU*1jca+j$eMJ-SH4+jE)[F- !M!,!p`"B23"l4#)H)q+I6[52p,L#L"XCm4JM(K')`qM8P1KE!P'SJ'qVIa(q3G` 64,ajT2%"ZV4VeBMV8q(D%[Pp),HI!GVN)-f2-k)a!,U,$T318MV3#SRiNL$LS(e IGaAa#R)#V!qc`%3F"XCQ'&@XNAbdI@rCeP-@qm!&dE@#13*R#Sl!05X3EUeSq0" ZI$"MN!!C!mIphN`F[4%+F#-6E(F&ZJ4AGlP%-qk-B$K-Rc@c0H034U*`r[eI8%` qH6#$`XYJ28)"$&`*$-iVM2f)&0Bi))5[j+2S8S3&0!@Bbc#8q@#''XPpN!$#e)0 mh&qlp1"a!U,f(c6M$K-F%Jii2G)LFQB2XdRQpBdVXF!``1VT!eK1NmErjYrL%-R &AGc)A"CR"Y$aT,$Yr@GGUcVkHcXHl1I-p0qRdd9QU%Rh-JTZ9Jp2ZNR*RMMra-Z N[0EQKXG(1kj`YAGS)YqL&2VmpQM-kLkTd#[q@+Dlj2D1jGcR[fpTYppA#TAL$Gf S#V(M-[Im5@"4`T&5[Q2lE$-#E&((TXC5'S!,RU[`6PG(GGqUACBf&(453EpU&ip "K0aFh8fL9+PBlF+`6qSHN3Sp%Y[6eIF5ffDaHJ$$&k4Z45VFNYLDUfm5fcUaqJb 'mk6ZFe,KGY@89k3T#c"F)R9IP!VCM1@'a(+(QC!!"&0p&SbVj1`GSDDjjh8Nekr $058kV,I#FELRPlS`''[S,Cb"KMiD&*UaEE`MK)XqcJi%(5L,D')8K(0DQG)-pCR I%04RT4iG1j`80SY')Clb)JTP34aI,T!!K8%BM0lcETYjP[IlJb%%Q'SDEHBjU*! !mHqDN!"jfRXfmdbB'M#apmE+ii@Gp'(Hllhah['JiH6Cd-BlbPjdPG%J%X6-L3c @I4(6`-(!dS2"p`'@MKe"039Zl5`X[ZL(%($,&N%FUdjk[mh#P$RiD2CqQc%P'C- a&EUV!RBk!lD&!6ZEJ2ACc!XZ654XjRRTU#$@E'UKJ[FL#qa3#"-+qkCUB4#-#kS BIp5%dF3BC`Q$!$P*Nd2GjX,N[XAQKCF+ZQcQcmUAi,@m[!A(Y!6(Y$5b'+%2MZj %SKI%mbeBBUk$S28@%pd-l9`DA#J-3Ya"SCdVQE4!BJBEXD3k%k(bkBdZ'%YQNqX !1F`-3!cJbl"a$"bfb4r$K,)%2p-hf-b9j5eil4-@H,m2BLYC85XJ#aaJSZrLmR5 T(Kb@-)b!B"4J93@5Q""`6qf+VZ2QP8$L([0RH'de,m9,-5rI8'!aQCIJ)f5HMYH RjKDm$TTRSi1E'r'K0mpL(62a'M(2B4h69*YjTF28H(*5MbS6bC1&h,4"Epkh$8, )*e-EfXb9kb'XRi"c`!Qpql2(),*[-*42aq"m$#ikdFB'NdN$0k*M550G&SFb#eI Ed&EH`P"PQ)4AZLc3BbrE5*i+lLrUlcUqmEUL"V%FDFT5ZijBK%-e!*N01"cm,$! X0YIKCq&JU(bRpbjHqlcAT9"ChE2Cl2L0`L&54RdAl05TdQB'MTB0JXa4bQiNk[P Z`[4#KM'$3fa!"rYBik0LR"LkEQkCCMk+c6Y+VM4NmV'6dGFBaP#A69i$aU4$l0+ EMkTC,)-4!&8Lj1ip-ZpDTD8%bJ*cN!#$c%%%L(BXB"5b$*!!q-h)5X&N3[&V[$d NDdJ-&qF,dbDbP'faN!"X1G8+HrS,GZXCB`mr&32E'M$0IPb[c!*,6"+I66fpe+@ X&&#8"&K5b'-S+#UZS[Uih3U6Cj5-Mb4FQV8NB!SX")+P[Ur!iKX&FLJDZ*-NJj` &KU0G5,b-U#,6aD1Q%R)D1"G'&B%i-piXJFT[TF9`1NMDNk0ReFh1P55`eJZ11%H `aDqLZY&Lmi&E-F1@3Gh$6e)6AIY2[R&lM$SGHBdIiN!2T$)m,F)90F5m854Q)0P b(0JB(9K#RdCie+YJHC`kiIUE2j!!N8UNf-ATD(8q#[V5jQk$)H'Y"$N,5)P1H5* PEUN+lMmf8[H,*B)CJE+T41i,#TKUT0!e"50(kM)253I13KqEbJD3!06+f04IPl& 0XkB-416NCRE#%4JQKZT-r#cVkS#"#N(R,TF8d)i5-SJG$"QD,Jc$0(88`D2N)+T @aGr[+TKilYc,fPKA`GP98bm!S9)NR[E"2%8U+Z6&*C,4dU6Gr'qQLY08mVke)5e $#CQ-`$1!c"GN"ej6mXZ'qk`KqDEli8'Ul"#5E9)K,48+T3)IY+6!-Ph!346*&-V bf'%fP8IPPjR4**k18"JrqID&$!6`*C-+NY*T$6EjPPeP6*Q8c$9eVCKl"FGj,i5 CZQSVVM@!+af5c%flYRme`65lp5db"FP*ZP`J'`VC$aR2+Q@mERCaLh4aK9em3(j CJa!X,[C-eG925B@`9$JM&5b"UeZZXUYEF29kG[91q@8!Ib(iqNAHl9cIqH1[rim &)h8("ZMkQi`-KHY6drhL-Ph32-T-CCc2&G"YlYbe2(a$B)RH0YP%@IE"K'4QaV* Y+-VfGPqrIC+51&PM9`'Q4TZ*E$6,RQQbbFJR5G[2GQTEf5Y653U$'fbb6eX2CJ1 3!-dQZi"U0VP$fiIAK&BA3$Yf!$kl"J6Rf$YTBZI3`9j82(#*+j!!*CG4eSJi`iZ C`Pf(Mp1Np#V0U8[Y(#0!!@$%&j+(cM!hM*`fU-JlUi*R-J)B5El1(Yd!JD@m8[' MLC@U1U(D+"b!+$YHXd5-I2ajIrd+2SkTGY,%QrI#I(kekR0R*-aI&(I#F*k%N4a &9VeKjl-VH*Jre)-LUf##*!9,CX"i5L'fIa5BGQ[j3k`i)bFFk5epp"*9JQbRJAH T+J008H8fNM`UQ5+,dk4BlF686R+-LT8%9dBCTdT59BN*a,Sl!SUEMK#`jHrKjdJ )4bkHa'Y#2#&Xl%&XLhJDVfla-MTFiN*m1-9jH0d5&`J)-D2&`hfP-2"(fCDl8S' ICr9LKUr8RSNX0HT-iY9TE`D486LN!h(&q3VX3B3Z6Mr!b@!Ej#H"9ET1`#!r`V* HGb"4)9-bQFd&jjrUBX'JE"V&G*e-Q5XL8NNZ12"dSH+*YYZ(+c-8C4R$%Fp4N!# m1H(ZU6@%4&N6NK-!5b0H&`c*-(XhrVL'&35[DmH%jMA3X&CcbDbG#d*Va1[5iD! CKQQLl[!dAbr#0dQ3!(p"YV#'&Dl-V'P9cm#XKXD9@iaRHmQF,B![qi4XCh%(VP3 8EJpTTqJB!-4*C)immB4@Y`&1qpSa[%jVkhfi$$Zq*,Ij13C+l4'`,8+Q3M8FV4( (N!!")b%GHj38#FU!k&U)$)S$#Kb1$aR)ILXG%V9)jPBLJ*)0XEhi2lI!H,e0YBR DiBjI03*Gka`ap5pNd%hmK@@qX,J#BLLbh82A#)`H,),!"'F*XEJ"cLqfT3,*U0D `@$MiJ3a-9@drFl"Eb-*JU"BbEK3C4qNjfrX'!hNpMQ!XB,3[KcTbE&rJf'UH9*2 8P)9,!S-(&J!B)@RMFR[!P#iH*4@L+Pb(N!$q50e[@aRk0GZMj'3#B`#3!*-E!k) c*3qNVUcD`kpSG+89bM"6*&G6dM*cfUJqr,RhI2J'Z4M@rKkZ"(rSkCh+U(+FcI+ 1qcjdcJjbcMa%$RF`9V$Q3c2*Vb1TQ8Z"369dl-XZrE%[m,0LJfYMYX'fXG9JUmj "H1N+IMLDT8r`8lmY9$l$e#EZX-GJPDhfYr'R%GVHMm4kEfG)GU#`-[)BjrFFX%8 RG9436*0&%,)3L$!0851@KU0$1R5X!8h,LXXA"@CFe@U,MNS,4V&J)j))bb%JiKN imY'#"4LiFIN2)hADph`ADF'P#ck!P9FYC%RY)CBCh$39$"aqDBT'harSF#mP`(b &-D2Ke5jKc+dd$CK,*I)r)PCKdd50!$)H2##!FJDSdCN18G-A[3+8(+2%X%Qc9Sc YZ*d+B@h!SCC2DqS8@-U4)$RbS%cMN!"+)-$KXV+M-+R5X6&Mm$d(`P``3%&B*b4 mKT!!N!$#V&fpD*`QY$%KmiG$f[VfV'q$(&#[UTV)50fK'YrG2%r%*[j&LbUC`X' 8cjh+`*60T'JI@iiNrdF$'D5XmQ@TTJFErdA$iQ-Vk%#1)6XFqa+&,mM4M5&QK+Q A%D$,&cf,Mhe"TS)Q6S"@##20$A5e1"9rMb*3'+qAb%@[(Lk#%8-KEiFEB$-pm!$ 'A,Kdr3J"Y%-MkABq",!5!![9D!29q1N3I$Gj,%p,46K1)jZ8'`11iD`jY$*MBBf [%)c9QRBHSkQ%#GK$&)CH+N#9arDAb%@`(P1@![RQ5YN16GK-V`D"VN-V@D0998N H6IblpMK0kmL%fCK9pFLTFLH%JY@-CS(%Qk6JeTS+[C)VbSpRBikBriD4A#E`F)U S[CiF'[*H,5aN,Z-!6h!#dB`(h'5C'8GJ(`-lBb,h#c)(1U8VL9pUq%"'X'XY1mL 66PBC(qBm90Hh5`fP4(Bq((Zdq+Pfk+K#*BS,m92'R$fd31SqE`DF+`U%!DT-LF' eE("ZC$kjlSLI1@G&jM1hRqA1*A!5LpKeM(d[@,r,@0Z&!BQ%L)k$V)-D"Y(1(R4 J1!RA"J6aP'E*r+Tp!BBBlKFH+'*1+8NcbE(f'JH)j%Uq#`e@(6QPS%$KFP59P"F *lL4b$VNDNT-+'BFB'K[46)i+3r,q9Zj,3RL*UNphjQreGh,D!-Ij2*8pB!3L)j& 2EB,6PA)h`HY9"lPel+Tb8jSVZ#Q"6C9!ZTFf`@NP9c6DPT3,%0XScYmK9b!NPbH fj`L8qceQbUfXQYV*MQjZP6Y5TH$ZJki1iH,Q#MDG4Q#Nbc-(-B3pK5BLjH4$KPl KD-`,fC+)F'"Q,hdbB$Tp#01S4ArrQS'B&0b0T%@251aAT'R2#CFeRi%lmPkqNic NJXU(V6R0R+,)l63ARcNS[)e'ZjL#-*,,f0X`3cB2!pA34,mIP"NX%(6L3VBK!5M PPN0,i3J6F("1`T8QU54lHTAC$Tj#GMP1e345&9LZm3)%!aZq4*8!M`HSm0dTMXI )E0%M@0[&a)S'Z!R'hB@FUKG4*LL%+f%Fj[Tc)CJ$a*-(Tm6E!,d!S#Z8C6AFe`[ hNRcQ%RI0EN`4h3+95#*k!@5QiHGa,0iABX&@XB+4U`'C&JUl%KRRHVJp'C(`Q@K k(16%50hqDXdiN33j9#Ak,Ki9Jkj62!9Jmd3'Ueba,0KP1RA9dEP0rNqNR*mGr)0 K04T)"R+IHS0,0!i*lV9*5P+J20p4ZJ8AkmT)H"aC`)9(R-$pSjeIFFfiUaE"fA4 )J`F$)I4!4TTkaN*'3d2ML@'pJe8PJ!0-9X#P'C@,9J[*dVr@898DYS6F38'f+RN #XX,4&5#NT3S3+A-)!l12h-+TfJ-fl*h*l`ceYUjc&b[eQ8EhBjGG[[km0EjqCj` HL0+!#N#h*JGZV,aaGCqLCPS&"PXV'+b*6S(K,+Y3iG2R*Epjr4[6RjMa[eZHMlB E*cmC+PDmhjMZp!pmVUaTAcH+!69qm[0+226KQ`prFVd5MmHi&%[(@B@5-lePc1' c1Cd&4e#UG$!3MNpNU&NR2rpQb98Z2JQ6qmlYEC*UR2c9k,+Uelq2PJ5lU,0!'Dj j9Rq1UhpAr`l9YTSk"r&3'ULQb(JNU%A[3&L@QVmX5Zch96AE3*)$DjXfd%!e`C5 `6jG9iA)QVd5RSi,H&@lUj9R*AJ6ik[b'39f-*TK*9@8d+pKNU&3ZjKPX)J`3BUA 2aC4kPm2kpq@VpP520YkBe+H0JcT,Ql!-XYfAh%m$8-jRZQrUbHeX#!ea""e48YQ )B04+"K0P#X,[8'"a8I8`&ZhqSjkj'q#&cj``((r8)+BjQKA"a)Z@%d!T`N9IN!$ aJ-H$8Bl#5E5!+Y$4Bk"'m3%EFL,iU!l(QKk9HjNe*1lj9fm*VJc"V()#eirBH,f iblCNE8MFEqVI)G+M&S#SR`rT8D89#"ATjj%mDap-@'*P@5iYq`V,P!%D1"ICaiE m0LJRZpCDKi[FIhrdJ9Q,aCfME3T9NZ(LSh$#4q8e0'fS'VH@UdAZCBpQ0a+,RNM X+b%#C`Q3!,0S)&[keN@k88Pq9%hf&)1Y!T@8,dD+bDR5&LHP,RQS!)NiA4DZ"bj *`(i,9CjVX&"c5j2``af0hkYI3iqb@"&m'&Vr6hmB4-cCZSD1C(HTb+iDVlTU(0I [")[H+B"d&5,NY$@kHm6P0R%rBpj4aEa$h*AFcGZDEN[jPIr[E9NX6[XrfjLKi)h TC"[6fA4MKYki-6eXBkaA1#TkAh@)MGdDIXAbDe[65aekqkHrP2V2MApVr&YL8Vk f$%GfR8fiP`(m)GKkqK2p+l),Qbql%[f6c*hfG,D5a%IbG(CLGbFEZTaGGr'5[ki i$bjh24F&4%QK$!*p*i04a[mCS8cN)KXbjI1cZjh6&@k1NaJV9Z#kILSJG,*lEVC a,VUV&9kcLbh&idCD$b"4HP)`S*0a3Lk!)D1!URJqQMfT9cbM(ErG)qidR-*MTC! !m+jC)BSp[4-h)VeCIPYPbN3ZK(l*+-3U58H%"f&XfN80pa@Hcrrk'b5dlXH,eBj hIq1*ZIm`p*hre&+hffjF@aVT&d@R(pPk&"ArL`SX$mhhp9r+(-5@$4E4BlRiF,K %DNa1N!$`dY-pm2NA5)5IQ"IX8ZrJ3f"Ufb1rBc992'*UicXD%kMY*(hm8Ip6I"V BCmP2qM3CK+)D9#9T"f[D*R&aQ0STN!!DbCXXX2`k$a8G2)Pq((mf*6H6qVljh2V $AQkDiBVdalJ0CLPHTr1EA$[%6VmMXR0arU&Tl+%DpfH[1KBe#89+TXK)D)q4NC! !YUE(*KHX[kXi09EPDV5)FhYBf#`NP6[a'!Lrm,RU506[Fk&jKfY53PV@9k,K5RX 6GP-9ZfPll&89cYmA'#RlU2S%,S,M2a*Fe4M9ijLD0QQ6me(T$Jri#mim[cbcrFc cm1+UM"0$aQQKM%,KQ4dL5`VQMZVleYhQ(UTbM+lp,![p&3Zfq@'Q')qdmD+VR"r GA@eC2kYYeLpMI14GHMJ!&YmBeIHi2(Mi#+m-$*d9KQB&KU#QNI#q6%S`QP-2#VV rJ4m@#`mZN!!BLjXQ'9Kd)cpV#6,h9$F$MAAG4ee[)"*8BEq+Q$+52dL,NpfScS2 PZpMb(rbdbf1"6iHPdHmT)8@UTlHZpbUA[lJQ2AVXrZbAlNC0E2J)QI5&6&4c,kU k(K!H##"Abh2N#M%LkX8#SEUl`Klq"A6B)hp*kX&J9J`"9RI*)%mE"GA&('1CX"G )rVdRCU8UUV-+VAh#eU0bPT'bprm%SP2P#50c54MiI#9Pf[eTUZ`LLEFETb2a+4% $&D@4h5Y23%'-GYR%LZTjAEh9#j%JUG8V0pJfCPF[-LbZIUpY6r8R9B)rJYj8A@" T!`(PJf',c%(915"6*i3RBI$+&J3+CY$aerlhVZ0i"*!!6Gb,kSeiT@2HMdCHp8k -[!S!!!*#!*!$#J#3!h)!N!4#H!T+RFj1ZJ!d6VS!*%*R5(N!!2rr5'm!"%KA5(J !!5)krpC1Y4!!)'d!E%k3!+Rd)MVrbQF%6V83!%je@Bm[2&T&8Np#CkQJ*&GCMbm m4%&838*RUD!J9b"3)RJ*##45B!ibf'B+-KTJ!N)C8FRrr,[*CZkTSkQM@Bm[2%4 548a#CkQJ)&HJ*5"3iN!N$@!'-KM9Y4!!8FMrq+QM6R8JAc)B0"L`@&I*rrT+3QI q6[!Jr#"I-KJd',#B9mRrqNT#Crj1m#$k)&mb'$3BX%*Z#T!!3@d'd%""m!!#-"" RrNl`!!!J,`!%,d%!"#)[!!J[A`!%51Fm!#3!*J&)3X6$+!!U!8K&b-A84%K#N!2 !`G##60m!2#)I6R8J,`!%,d%!"#)[!!J[A`!%51Fa!%kk!*a-h`#-)Kp1G5![!!3 [33!%)Lm!##pI!!4)jc%!6VS!I#!"60m!M#)I6R8J,`!%,d%!"#)[!!J[A`!%51F a!%kk!#a-h`#-)Kp1G5![!!3[33!%)Lm!##pI!!4)jc%!6VS!$#!"60m!M#)I6R9 +J'SF5S&U$%5!4)&1ZJ!J4)&1G85!6VS!&N5!4)&1G8U"DJT%J8kk!!C%J%je,M` !!2rrXS"M"L)!F!"1GE#(BJb!`8K!-J"#3%K!6R@bKf)D,J"#3%K!J-&)3%K(2J" )4il"-!G)4c)(6R8N!#B"iSMLLE+(B[L!`F#(-J2#`#i$5%I1`%K(dSGP#*+#BJ4 %J8je8d"Jj%je!*!$A!#3!i!!!!aB!*!$B!#3!b!!!$mm!!1Tm%&%3e)$!!"B$9- $R1S'YiZ&ElRP&ZjU#kJ&,-#Y&VE`,r!YGe&Vp9i!!4lq2r+65hNQLaM%"%SP-R' )#kJ$EAISXa!"!*!$#PM!!!`!N!--!*!&I!!"!*!&D3"M!(d!R`3#6dX!N!Fp!'! !miKF9'KPFQ8JDA-JEQpd)'9ZEh9RD#"bEfpY)'pZ)0*H-0-JG'mJBfpZG'PZG@8 J9@j6G(9QCQPZCbiJ)%&Z)'&NC'PdD@pZB@`JAM%JBRPdCA-JBA*P)'jPC@4PC#i !N!05!!%!N!9Y!'B!J3#L"!*25`#3"33!5!"R!31)-P0[FR*j,#"LGA3JB5"NDA0 V)(*PE'&dC@3JCA*bEh)J+&i`+5"SBA-JEf0MGA*bC@3Z!*!$6!!#!*!&-3"R!%8 !V33%8A9TG!#3"3S!8!!F!4#)'P9Z8h4eCQCTEQFJGf&c)(0eBf0PFh0QG@`K!*! &#!!1!#J!,U!#!!%!N!0q!!%!N!96!(-!C`#["!*25`#3"33!53"&!5k)A8&Z)'P dC@dJGf&c)'0[EA"bCA0cC@3JGfPdD#"K)'ePG'K[C#"dD'&d)(4SDA-JGQ9bFfP [EL"[CL"dD'8JFf9XCLePH(4bB@0dEh)JC'pPFb"ZEh3JD'&ZC'aP,J#3"&S!!3# 3"9d!F!"a!+`%!Np,!*!(5J"9!41)1P0[FR*j,L!J5@jcG'&XE'&dD@pZ)'0KEL" [EQaj)'*P)("PFQC[FQePC#"[EL")4P-JGQpXG@ePFbi!N!0Z!!%!N!9S!(S!I!# f"!*25`#3"dJ!AJ%PL%j6EfeP)'PdC@ec)(GPFQ8JFfYTF("PC#"LC@0KGA0P)(4 SCANJBA*P)'j[G#"cGA"`Eh*dC@3JBRNJG'KTFb"cC@aQ,@9iG(*KBh4[FLi!N!0 D!!%!N!9G!(!!F3#X"!*25`#3"dS!93%6L$T8D'8JCQPXC5$5AM$6)'eKH5"LC5" NB@eKCf9N,L!J8'aPBA0P)(9cC5"TG#"hDA4S)'0KGA4TEfiZ!*!$+!!"!*!&c!# 1!1!!dJ3)3fpZG'PZG@8!N!8%!!3!``&L`!)$k!#3!``!+!!S!,B"(!3"998!N!- -!#!!#!#L!4`!JP99!*!$$!"L!*)!m!'B!)9993#3!``!+!!S!(8"2!#(998!N!- -!%B!TJ#k!GB!KP99!*!$$!!J!!J!SJ%F!)"993#3!``!+!!S!+i"6J#e998!N!- 2!!)%)'pQ)!FJDA4PEA-Z!*!$-33!J!#3!`-d,M!Q0#i`,#!!U5!a16N`,6Nf,#" "E'&NC'PZ)&0jFh4PEA-X)%PZBbi!N!-D"!#!!*!$!c3Z-!p6G(9QCNPd)&0&35! d,M!!N!--#e9Z8h4eCQBJBA-k!*!$#!FJCQpXC'9b!!!%-d&%3e)$!!Ch$9803b) 5%HCHEK"N,4P%D[*%*!X3@DZQ*LHh2BZ-i(ERb%Qh-e2bQAph[qrELM`EhmbhY8# 5eFlXbH4*f,ilNa'5j9ENLDc)laq42j1IbEcCeRB454B6XMFYb5)S31)(rdjCKT& 84$LS#cYiiLGf)5c5J1e3aD%@GK*H(mq1D3bR6lpC+R)6)mRY[@4[%r6@hmf'R%[ )+8FIZEr5&V,ejRAjaL3*5bPTf0kN&a@6NPGC,a$mi-RK`KFHI%V$*QM4BN6+hFf qTX2b,*5j55k)jb(*(2h&i)XDJqim&Fee*9$cG*JIMZ6*i#SGjViNe#Xq)@+3!*h [`af,NK")heX@$ED[(5XhPA-`LA1fRcbNbSE0RBqrZ,m'l)YVm[NQUD!A@)"Ck2@ aqNDT+'b%UlJKdF4%D4j'8D8QKLJRXm5(8JQR40@4X8N6+L,JmB-'82KL!,85ECR 3J#8d%@TbLdfC`eLTT"qR$+aeU)[Di0J#T6DMFe4B`aLflrdNJ-)Z!m3jBTLiESA mcl%RFHbLl9fAJNh,JDRU`pD$+ZFdM(GdeX@!G"Z$#pDfYBXaSNc2)HBbh"2bA1l EQ20L2d(0f,[Q&#I)A'ZQ2(KBb@@qIDUNT-rSkShVZbh3b(2j4EE#Hi"%aD`5%YX K48JPi!JpjfESS#*')G-lpU&Zma9#N6ZP%AF+hP-PhjBJ16hDlDNc*qDmR%1jlK@ TB-cEfPh+FK[jplG1#3aZ,GrmP`rLNbG@J3Mpl)N"@`NmD#E1Ye,'NV,SJ&0-'N" 4lGDH(L15jV)kGQArf*KLjXEBBNT+ilSFVqIQ2L6S6,2!-qdr5A,SM5rZ8%e+qrr FIEa)TAK+(ePf3"KU9mH96KeiJM&J8-CCH2(UplHlTpQ8&pIV!mfS&!eYS22Y"H5 9K,,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(bC5reTB0Nq+`1N!#ULm1*Sfp KL@KA(V8&MK(J'6fDpK)ZJ-$X$'lTUd'pQXb1L-Hl60lqhlJ2YkIbbBfVNkBAI5l bXT26-1CCQI@i%dADZX@J'V("P$45$f-VG@mlh@!+D@pipZKGMr,CUC9ZcXXMqF' dI'XXGU%XA8IkajQ+#fPh$2Aj@FVRjqVrINKT#[0r9hl1a'Bar[EhjGLF9@FZ6fP Z&[UQ90aX9RVbi))fT0[hNY60m9Pip++5qIc2PqqBK`c8pE9GaLXRlhFHm(""&mY 9YB2CTqfiUkZ$G385RX(1bd[ERX3qk'4JZaVPpDGj!R%'T["3[!PH+Gc$PhJ`"hH qIVA3@F0Eeq31!!!",d&%3e)$!!&Z$98,Sa,3(`,[MX0G"i1VS')4Q(4+"CeP@S' Clmb(SM82Ip(I(*K(D4A2I'$q&[0K9K8c&"2&r$@V5EkTU*K9439&phSP6c(*!"1 aC5A+J0LHE33'eM"R5Q-Af($455FbMP!J*%5L5"VfFJe#ABTbVcRA4B@a96dp+RH hD`rFF&F@))QYk$RCaCMM3iY@r'%I9"NNRi3H&+6Nb+Ekq,R[CKIQhmVFF$J`VdQ 5m'YemhE`p&D5E6j5(VmrPl$l$k3rXTPHl)!0@&jc$0ZABIP&mp&"JI!#DaENdTM ml81I`#icTcGeq@6Upd1K&[m+1ImYiqD1UMI2ikh!"rA+h@GFD3IbmLC@e9$jp9! k6JUl9a2!KP1+'B$U)Bc230$[U!%J"*%91SCK"!!!#4G"4%05!`!1K3jG#k55),i bhjhrq-jHjTcIRm3X@FlH1F3CSh%X80,b[R0QLXqEJ*aX40@UcFUD#%5Rl(e8Jll rGqBa*dc)b``NKG+`*T5N3Y"1UPMIThV[djD9N!!b0-6@8G9SS`-*3XV@EJZ,ppf G(@H&VG9l$HjZ05)#-d3M(d0&9JkT3rK[IJhrMG+c8Cl(B+4U`aFMihF0N!#jkkJ (bAf)aK,IG)P[ca,IG-NC,*)9Q2S@4ApLIjK&+S'Id[Z4`Ve!C&F!hk33*VJjb0N B50)-%!X)p`RCp6"I8pTh4UI[+E8`dFID4ZkGr@lA$AQDlbldTY[ZH@,hr!+XiD9 #H+cpQa8c%jVX(JTT(9@GRD&+8bJflXSeSl4`5cY$Y5BUZhI&Y(p9rDdY9MhmA'a 'S26RfD0D,'"MJPS)PR+'Y$*IGS48-42MQe(`[2"&@fPYS(Z$2,ZVS#hMPle6m-b hq8GG`NZPN!#-)R+V%99PNPlh36fhm*9bM*6G5(DLl6*[`RRN%1kYe0apJX"08h9 pBpI"UeK@ZP%fDY[@f0f"j$FB'16,"hmb'lqqr(ZIF,[qqr(8P4F2LPmU8Y6lJ@, C*HD'0C[m5%SlDaYhr0f9c5@RlpTrl%Ba0h%pIrF&([T)hhCPQkhZV!V"p*ICGPY r00)ATYFTIIZZ+Zh!F'lqJ+RpekRmf5JSrZ#`Jfc9YhilkVTHh9L([6AGJPqp[j5 #5'i#SGl@1!l!f0$([Z4B9)JpbTMr8K%pV8&b'lM9+a*8%hV&U'bb498Z@DQS*MR Z&3U9S9IX$jNN*bhPP@UI8TA)Arc+eR608jlGh#RG(Y%mCIVZHjY0eR5&1qC1dXc 90emD5,Ej@(eFD1XV&rqi5CRVdF[i&43@eN[fU#"2lpYa(VlC*ZUUNZp0XGNQB,2 *LUI#aR9CrBK0&Sp+b8*6C1J9E63Tqf"5i25flDL4ELQ!0#R1JdB29[1P&-F&`EQ V34i-5ZXME9iP2CJ#Sq!JM5UKU,HpAUd@9Ujj,Ce3erhrA2Y0)fVEk2m'%q('2UU C%2HLD&+GqD$mXUXk4$HdCk9'VaEk0mH(e6-fT4pmjRa9e3I09fm)JH',*UjGkCY BVDUp[eRI+)5dJF4`UL@ija2YP0UeSHUUm2!Y1A!N#i,p%r+mraE)KC!!h)mYI"M -*-j`h-92m%VhR)6A)GbRK)!S@)q!m3bE39ZF$L3#NlajP54K$2XaQX4Q&+bEm4` j1AMiN!!D$8bLH48j)NdQ4ZlPFU1$$j(RK3$Nj8cC#bja3Z9@VceajE1aV$3CP1@ 85*e1e)0Q)jGcLA5!ibD49*QcdSUIb6+I1lrc$,UNCTa,i@!(l&NX8Z!UXl)Fc@N 10p%$TmlaarF12*%VqVQP+IbmGAC[Z(*i4%i0ElMdXHT++-Ze+['9N53H0#4Y9,3 %Ib#8d),3L422HK!GJGBFY,LYf`X9ljIeI"9HZ54kVCUF308$Ta+%AGi0FXiSpX5 "dhYD$!,RQ3U0(P3fjfdBeq`NrZ'e,erl6RVGI#'mVR"`phbT-2,3[')Sd$cb3&! %V`adK&KR!aa2Y%%,Z,h0rNH#iVJi,$5IJe1*KV4GN8AeTLJdhii*%jh+4+0lL-6 G`Gb!1(p'+l"R#Xqlj[FAI)G0QQ+9i'Uh+QCdXfkhYb)Q$Qa("&X5L'&#mPXXm@0 )Ucd%5eJUcINKX48pJ6d%PbS*K&[ci9Z%V*(I3hJPL`MrdJSI3`D53``T(FqmS[E kqkCA(rKLZIm!-KZ&[1GiTPFGl*ZpSH[blmr0kANl3fU1pr3DII1R0R@Yr)*!qJH 3!1C*GFpaYEH[Hmh&ZN*A@%M6!%pD0diEiCSl$VHQjr`k#`[26@IZ9DI$daI6KAA 2pN(q9D3Y+FMIp2MMdq%6Qblq,Td1hibPQPH&k,ZJH0C&,1fSJfdU0CD1i33[B40 4!YdjT'r8eK+UMqe@Db3GV(dcl%e2@"m1dpJq%Rh(6&#9H,q%2[!CM`9RLm[r%li 9iPZYi6IUKXJLDiC`*LQ1j@0C1-R3A,AUd"L@,!$X'#)f9Q`GU4qjDTIlE$mqA(M 5%LlfVkUm(4R$6f-Y*2qH0D6p36il*,[YSYC3Ef@,rIqX9*l!Ebf0'B$Bc0CR("A bR`1@-IY,[Y#8e9pF9R&@mL*83(aXZ8)Z"La%VB`"J[[p584Bj!eI5+Z3!-m'FQl e8ke"Xl)9E+f!P-EiV3U5Rr1e(UmFZASXGdNpP#jSPS%Mep04%N&XLQ8J!kB+Phf ShJLZT1Hk&EZ'!AIMZcc23,,Q+,p414k9S,B6,'a82bfhAaYETNrA%56ja02ZG*T 5j4lME!"-qUA2Y$MMJiY4T!6X@Z)k)D`B8d'!AjJ-cVeXTE3(16-(E(Pb4Q#Tj'@ 9#%5hl5$Glld`DH2L9KVmeH*EFa9hpIDl1`$QYF(BlY&bTX2dqBA$reLmd2TDRl( Y0,(GBIAPhAX"rrC*9qj6Dcd$H#M1@jc&$Y'NGA48bXlAXh*S@kH!Zkfbli`-Z2M "q(b&pHX4I'G4%de6YE9A(RA@qh)a&f[!UpMFMmNq0q"eB[piVX)kEUcG1DPY3V0 $`62A6#EC@@pc!%i&h!kia8UMBYEe3)A945F$!Zi8m+KTci21HV%pT#rHl4bkG*d El!9mF@EmL(@Qr)X@N!!HQJGM-lYP`%2C`r@*QVC6V('0%["TN!#F,[k0%(eX#hU 3!0aHNqRj@JSe6JF*I04KqTHADUE2Tc,B-J[*j9f1hMkq&-B!U*!!KfX`AB-8B"A h@IS[4f&li'IQ$1CAe9if%aiqGN!&Q%S4&CiQhDIf@FS1cNUjaA2YaBpQiQbY3i' CP4mCLmX+L8rILUK3`8dZHmjaV0YkRM[jP2ccRlVip*4Me-qAPMjP-@A,$9P,I85 &#Ulqe@iaGfcqU-aPXh*qlF1-@ZZSlH5C1mA0TJqUQTkf2j&8)5`qd`4i3-FVSVN )cQ3YT[jL52V`9&+&J$mj!EMGASjQX`p@2&,*6%A`c5D4[Tl00DT3H*AkL5leI'' P)l9im[YlhCrhTp2DG*J[E4#Y4L*[6e`je+K#q,'4%64@!PYK&Z!k%mV9AKd1kGd &SBA5Q+kqLIFl@5H@2&IJeq44!*!$'!!d!!!"(!&S!!%"!!%!N!8$k!#3!j3!N!- )!#!J!3!#!*!&('&eFh3!N!-"4P*&4J#3"B"*3diM!*!&J!#3!`G"8&"-!*!&!3! !!3#3!`+!!!!%3!!!#5!!!"13!!!!*mJ!!%%%!!#"!J!"!!%!!JI!J!32i%!)''! J%"[m%#3DP!K-'[3NRc)%-N`ek2NN05Jb%$Ii*!J`i!J%(q!3!J$!)!%$m%!!J!# !!%#"!!!JJJ!!%q3!!!R)!!!%N!!!!!)J!!!"3!#3!i!!!!%!N!-$J!!!"m!!!!r J!!!Im!!!2rJ!!(rm!!$rrJ!"rrm!!rrrJ!Irrm!2rrrJ(rrrm$rrrrKrrrrmrj! $rRrrN!-rrrrq(rrrr!rrrrJ(rrr`!rrri!(rrm!!rrq!!(rr!!!rrJ!!(r`!!!r i!!!(m!!!!q!!!!(!!*!$J!#3"#!IU5!a16N`,6Nf)%&XB@4ND@iJ8hPcG'9YFb` J5@jM,J!!&8J!N!-"GJ"1F8U$CKT"l3!J-,`!#$&m2c`!!M&m!!%!"$&mUI!!"Lm $,c`!!"5Q3IVrd0$m!+)[#%+RB3!#*Ylm!""R%NU$C`4`!8je6Ud!)Q%!!pDTp%j a5S0Q!URdF!"1G@"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!!4*)H[q16VS%i&K2X(Vr@QB!!1b K'Li)##S!"J!%C`BJH!+QS"XX+J!%+LS!#"JU!!5Ae*A8)$Vr9U%HCJ!!c#a))$V r5L)'`VJ$'PK"B3$r8L!krd,!Z!-D3IVr2L#!5S9Q"+%LB!3J4D!RCJ!!Q#T),cV r!Lmkr[S[1[lb,cVr!Lmkr[T)H[m5,a!J1[m!8B""q[lf))!J$P#!3IVqk##!5(S !HQ%!#L6Hr!!J5N"R!URr)%kJ(b"(S"Yb!")%j`RM'H34!!%!)!)"!1!J6D"T!J! !(i!")%fJDYA8ep4"q[kB5T!!C`K`!D'BF!1KQ#"0*8J!#(!!60pJq%je60pJq'! !rZ!J6U!IeG6Ae#"(S"X`1!)J-F!+B*()B1"19J!!51F!1#KZ!!a(q[jD4IVq@L! 8X**Y"#!5+)"+J'm5)&-LEJ!)SLiJ&0'6NC*`!'!%-$crf8cI(!"1ANje6PEreNM R%aJX,J!35IVpmN)(S4SY52rQ5Li!#fF')(J#TU!E,c`!!+$m6VS#RLe!rqTB6fF !!Ai[,[rU6VS"q%S!@%pR"R!"B!!"FNKZrrK)E[rd5'lrlNkk!j)J,[rdS4iY52r `6qm!$'F!!8JJ,[riS4iY52rmC`!"1LmZrrJ[#%kk!qC+VJ!88%pQ!!#8@Bm[2%0 24%9`!$m!U"mQAb!,ChiJ%h)Bd)%[!%kk!Y`-3!!$@%pQDL!0FLM3J5e!rpSJ%h3 Bd))Y32rH,`"1ZJ,`5-!Y32rL)%ZJ+5!Zrpj3J#P!!#KCMbm,6VS3d#!IFL#3!)% T3!!X,blrr#mZrr3[,[r`,`B[,J!-5'lriLmZrpT)H[kX6VS)9Lm,UD02l`!N+@l rkJ!-+@lrm!!3+@lrp!!8+@lrr!!B,c`!!+'B6VS"L#e!rpB[2!!!U*p1ZJ&k)Ll reV#"9X0%!dL$5--T3`!F+8B!)#PZ!!`!*%Kkr*!!2cbJr#mm!!#Jr%kk!54BMam !6VS3@#mm!!#KQ%kk!6T+J%r[!!aR"%kk%&B`1!&Di%!-3!!'CJK"qJ!D)FJ$2(i ")'lrjU!E%!G-lKM)rm*1ANje6PB!!%MR!4K#"bmm!!#Jr%kk!2)S3#!-@%pR5#m -6VS!8%S!@%pR2#C-,bX!$$mmS2`[2!!!S2a1ZJ#L@)mI!%kk$pBJD`!3S"mJD`! BS"m`1!&Di%!-3!!'CJC`!#(!!caq!4!(61iBJ2rd6Pj1G8j@!!")ja!)+'i!#(B !$+a"6%&%!!*Q&!bX4%008!!'CJT`!l"X!!TQ!RB"%!0-lK!)rrK1ANje6PB!!&Q 22cbSER!"(`"1ZJp-@Bmr2+TZF!%I!%kk$ciJ(l#ICJB`2!)!B!3`2!3!6Pj1G8j @!!![!c!m#!$!EJ!+FJ!b!%U"8X0%!fF%F!&J!R!!*Llrr%jH6R919J!!51FI!$i Z!!T)abm(6VVraKS!F!!3"3a!!!&B6fB3!NF(rdkkrhb`4fi%F!"J+PQ22cbSRh! "(`"1ZJl#+"pCMcm((`91ZJkf,"qiKPI$4!0R"(!!B!)J"NcZ!2Mrl%jH6R919J! !51F4#$iZ!!iJEJ!)+&"f!(!!-"3-J!!!384Q,R!!-#`!!Jb!!!"$8QBJ$%IrrfF B)#`!"%*!5%$J5#)m!*!$rm+!5-HqJ@B#GJ%3!dcZ%)Mrp%jH6R919J!!F2m[!%K Z!!K1Z[qB5J"36fFD)'i!##!S!!4#3%K!i%JL2!#3!rr#J$!"B!*`rdjH6R919J! !F2m[!%KZ!!K1Z[pL5J"36fF3)'i!##!m!2q3!m#S!!4J!R$r6Pj1G8j@!!")j`! B*Qi!%#KZ!!`JEJ!)-,`$!A!!+)!'P!!!!53'P!!!!NJ'P!#3!b!'P!#3!i!'P!# 3!i!'P!!!"*!!"T3!!!%N"T3!!!53!!D8!*!$I!D8!!#!!#D!"T-!N!-N"T-!N!- J"T-!N!0)"T-!N!-qF!"-lKJ!rrK1ANje6PErp%MR%aJQEJ!),8[rp!DZ!*!$*2r d+'lrp!DZ!*!$)2rd,@lrp2ri"Ui!N!0)rr3YE[rdrr`'VJ#3!clrp#!Zrr53!+i !#,#Z!!aM"R"PB!!!X%*(3NCJ4R!!-!F-3!!%9F0%!fF%F!"J$(!!-!GCJ()%6VS 0)R)!-JFAJ"J!F!!`"b"ZrrM3J$''#!"`!$!(%$-)!()"iDRF36!(8NG`!$!($%! !*'@`3NGm!@"'F!!`"`a!!!&9`d3$C`4`!'!-F!!`"e1!FJ*1ZJc-FJ!b"aQ!'!" `!$!()'lrr0#!-BB)!(!!-!F30!J!FJ(KUGa"-!G54h!!-!F-3!!ICE"`!%cZ'-M ri%jH6R919[rm51F2'#CZ!!`SEJ!83NCJ$R!!-!E3J%*d#!!`"P*'F!!`"R)!-Li !%Y+"XS"ZiN*'H!*J!!#D3N9#4h!!-!BJEJ!)jB!YF!J!rraJE(!"`+lrr0j!F!! `"A)!-JCd!"3c'!"63NM#Y)"[+(!!-!I3J()!-M3)!%U"CJa`!$!(d)!jK!J!9%4 `!$!(d)!q0!J!B"K`!$!'FJ!b,J!5dS(5J(!!-!I3J$Q"#!!`"9*&)#lrr1+),8$ rr(!!-!9b!$)'G!!8-aJ!Y%"LJM!'8NDmEJ!5C3$rBNcZ'2$rj%jH6R919J!!51F 2'$iZ!!iQEJ!3+'i!#$JZ!"Bk"qC0F!!`"h`(c%"q!(!!-!830!J!l#Kb!")!F!( !!A)!%J$HJ5!(d)"b!$)c#!!Z!9*'F!!`"R))XS"Q"N*'-!954A!!-!63J,#(BX" `!$!%d)!L"j+!%!&-lKM`rqK1ANje6PB!!%MR$`Ji,J!52Li!$LKZ!!Jm"qC1F!! `"hS(bN"`!$!'IJ!H0!J!F!!`"A)!-J65J1D*CbT6J@F@8i&Q)R!!-!C8J()!%M3 )!%K"3N'1JA!!-!C5J()!%M3)!1'*MS&`!$!&i+p`)*!!"(,ri+R#Kc!"61i3m2r X6Pj1G8j@rqT)j`mB*Qi!##KZ!"!'VJ!!!53!&!DZ!!!#5!!8,@i!&2rd"Ui!N!- J!"3YEJ!8rrJ'VJ#3!i!!&#eZ!"6rr"!6jJKb!")!F!I!!A)!%J"536e"rqS3%q) )FJ!5!(!$`!&b!")!1!&84(!"kDJp32rbF!!3%h*!`J"`!"!"28$rm(!"kDK6J$e !rqj`!"!6FJ(#!'F+F!!`,[rZ8i"J!R$r28$rl(S)5Qlrm'G@,bi!&#mZrr4`!$! Zrr)[!#!,8S![!%kkrcKb!$)!ji(D35mZ!"3[,[riF!!`,[rb,`![,[rd6VS)I#m Zrra`!$!Zrr)[!#mZrr3[,[ri6VVp)Nr[!$"#4f!!!2C+E[r`Cc*`!$!Zrr)[!#m Zrra`!$!&,`![#dkkrGjm!"`!F!!`"L"Zrr4b!")`#!$D38r[!""J'R!!-!3[!(! !-!8[!#m,6VVq,M`!fN42l`!-['lrl'B3-!G54h)!-J"#0"J!B!!!MVaZrqjQG%T Zrr"R-R!!-#lrmLm!,blrr(!!-!8[!#m,6VVpF(`!(!"`!$!')'lrp()!%M!)!0T "6qm!%'!DF!!`"#m!F!!`"5m!,`Y1Z[h!2!$D4%r[!!a@4Q!8F!!`"e1!FJ!b"aQ d#!!B!$!(8NF`"P0'5N"Qj'!5%!E3,[rV-JG54h3!0!%CJ#J![Qi!$Q8!r`C`!$! &AS$QL%cZ'2$rdNjH6R919[q'51F2'#eZ!#6rj!DZ!*!$*!!N,@i!*2rd"Ui!N!- J!#3YEJ!NrqJ'VJ#3!dJ!*#eZ!#6rq#CZ!"c@r!%Ne[`#50Em!#$@r!#!e[`!J#e ,rpM@r!53!#e,rpc@r!%N,8[ri0Em"*!!,8[rm0Em!(`Y5rr)er`!!)!!)!Z3!+i !(,#Z!#"M"R"PB!!&8RS!3NFJ,[r)d,`!!)!!,8$rc#KZrmJYI!!!J!$rr%KZrr` [,[r))'i!#%k3!%UZrra36fB'F'GJ!!8B)!a5J,#ZrmaMC#e-rlSYE[r-rliJ$&+ !N!#ZrliY32qf)#lrZT!!V[r),8$rXL!Zrlk3!+lrZLe!rkjR$#"-)Qlrb#!Zrkk L,LKZrklCl[r)5'lrXLmZrmJJEJ!)6T!!)#lrXV#ZrlC36f3'F'GJ!!5U(9crah! !%#lradM!d)"63$e!rqa`!$!Zrqc3J$e!rqiJEJ!3)"$3VJ!-,8$re#mZ!"`[,[r F5(J"*#m-6VVmG()!-J"+JGR",bi!(#mZrpK)H!%N,blrh%kk"E`[,[rJ5(J"*#m Zrp`[,[rB6VVkCLmZ!"`[,[rFF!!`,[rX,`![$%kkr#jb!$)!5S(C`5mZ!"`[,[r BF!!`,[rX,`![,[rF6VS&FLmZrr"`!$!Zrq`[!#mZrp`[,[rB6VVk'(S!3NFYEJ! -rp"2l`"JB!!$X%*'B!!!Q(!!-!G+J'Cd)!a5J,#ZrmaMC#e-rkBYE[r-rkSJ$&+ !N!#ZrkSY32qL)#lrTT!!V[r),8$rRL!ZrkU3!+lrTLe!rjTR$#"-)Qlrb#!ZrjU L,LKZrjVCl[r)5'lrRLmZrmJJEJ!)6T!!)#lrRV#Zrk*36f3'F'GJ!!0HHJ!D((i )F!(!KGa!F!!`"L"Zrq$3J$``#!$LM6!(8dG`!$!'$%!#5'8!rf!%4J*)F!!`"Ja !!3"N%#!Zrp"5V[r3)%!3KQ!!!ZS%4J%!F!!`"L"ZrqM3J$J`#!"`!$!')'lrj() !%M!)!$e"rm*`!$!Zrm*+J'-!!+*JH#!-8S#`V[r-Bf3Y62qQ,@lrc2qU)!a5J*! !V[qU,8$rSL!ZrkD3!+lrb#e!rjiJ,[qUN!#ZrkBY32qDC``J6#*ZrmJJ,[qDSLi SE[qDfHlrb%KZrji[,[r))'i!#%k3!#!Zrjk`V[qL8%pN"R"RB!!#G(!!%"c[U)U !8%G`!$!($%!!''-!rhj`)*!!,[r$F[rJUF+&f%&`!$!Zrm,JVCjZrm*#4Q!!!*K `!$!(5S"QG#!-8S#`V[r-Bf3Y62q5,@lrc2q@)!a5J*!!V[q@,8$rML!Zrj+3!+l rb#e!riSJ,[q@N!#Zrj)Y32q'C``J6#*ZrmJJ,[q'SLiSE[q'fHlrb%KZriS[,[r ))'i!#%k3!#!ZriU`V[q18%pN"R"RB!!"b(S!'Kaq#(!"`)AF3(!!-!BJE[r`d)! m-!J!iSd`"e0(['lrlQ8!rf5FE[rZF!!`"L"ZrrM3J$e`#!$ra(!!-!BJE[rdFJ! 5-!J!28(r`R!!-#lr`NU!B`!!T'"i)!a5J,#ZrmaMC#e-rkBYE[r-rkSJ$&+!N!# ZrkSY32qL)#lrTT!!V[r),8$rRL!ZrkU3!+lrTLe!rjTR$#"-)Qlrb#!ZrjUL,LK ZrjVCl[r)5'lrRLmZrmJJEJ!)6T!!)#lrRV#Zrk*36f3'F'GJ!!$qF!!3(1qSLS" 34h!!-!F-3!!BB`$rIR!JN!!Zrm0brq#T`SA6E[r%F!!`,[r#i+fHE[r#F!!`,[r %5S!QE[r3Pm#hlJ!-C6BJE[r38Ulrd"#E)'lrd&+Zrp!3Qb!Zrp"5V[r3)%!3Qf! +)'lrd&+Zrp!3Qc!%8d4+3'EZB&C@4#!Z!"M3VJ!8FJ!b,[r%*#lrd*5Z!!b5JLC !Pm&J$L"Zrp"5V[r3%*X`"&0%5N4R$#!Z!"M3VJ!8X)YLiLCZ!!aJ#L"Zrp"5V[r 3%*X`"&0%5N"QlL!Zrp#`V[r8C3$m5#!Zrp#`V[r8C`4`Cf!3)#lrd*!!VJ!-)'i !%##!F!"-lKM`rfj1ANje6PB!!%MR$aJQEJ!81#i!#LKZ!""J!!%`2!3q,J!18ND mEJ!1C"*`!$!'FJ!b""!d#!#`0"J!CHC64lK(C"*`!$!(FJ!b""!d#!#`0"J!BZL q4Q0)F!!`"RS!'M3)!(!!-!Gb!$)''E3)!"J!F!!`"aQ&#!"`!$!'d)!k-`J!F!! `"p#!FJ!b"Y+"0l-)!"J!F!!`"p#!0i8)!'##Z%GQ"P*%B!!!SR!!-!4k!"Sd#!" `!$!(FJ!b""Qd#!!B!(!!-!FCK3J!F!!`"0#!1M-)!(!!-!I3J()!-J65J6Hc#!! B!(!!-!I3J$H&#!"`!$!(FJ!b"*!!JA)!-Li!$R3!0!G5JT+#XS"M(Lm,,`a`!$! (,`"`!$!%,`"1Z[lQ1!G54%r[!""J)#m,,`a`!$!Z!!i[!(!!-!G5J#m!6VVqa$e (!!j2l`!3F!!`,J!1FJ!b"*!!JA)"XS"Y!2l!61iBm2rS6Pj1G8j@rra)j`mB+'i !&!DZ!!!"*!!8*Qi!&%*'B#"`!$!')'i!#()!-JBCX!J!'!"`!$!'d)!hKJJ!-!C 54VaZ!!jPfLm,,`a`!$!Z!!i[!(!!,`"1Z[j)3NC2l`!3B!3`"P*'['i!$Q31F!! `"R)!%M3)!%U"CqK`!#e!rraJGR!!-!C+J'-NF!!`"R)!%M3)!(!!-!C6J(3!&$3 )!**#5-%J,[rmikJY32rmF!!`"RJ!'$3)!#SZrraq!'!1)!IML()"`S@#J#i"iSd `"&0%5N"QkR!!-!E3J()!-M-)!#"Z!"$PJ5'('!!`"P*')#lrr&+ZrrbmEJ!1CB4 -lKM`rq41ANje)PmJAk!P,S"U!N+A6Y%LAa)I-"p+!@F%TdCJ!U0',SK1d5*I%Km `(b"I5J&R"+C(B!+L4dl4)Pp`!D'B6Y%L,`!%)#m!#%(k!!SbI!!#6[#5rQ!'6%% )!8je6VS!*#!"6R8L,`!%)#m!#%(k!!SbI!!#6[#5rQ!)6%%)!F0!6R9+J'X85S& V"Nkk!%C1G85"6VS!2N5"6R9%J%U"D`T1ZJ!`4)"%J8je4)&1ZJ!N4)"1G5)[!!3 J,`!)3IS!#M*m!!*1m*,qB!K-33!"`d"1G6m"5%&+3@BF)J"#38K"C`U#edK"5%! `!8K!J0mb!%*!5%"1G8K"2S)[!c3!*J&b!8*!5%"Q$%K!-!*b!'!@dN&P%Y4#dB# `JfAdN!#$dN%)`3!!C1iQ(c3I6R8!!!%!N!0AHJ!!9RS!!!*k!3,f[$J`!*!$(!* U!"&%394"!*!$NPT&8Nm!N!1H4&*&6!#3!kT$6d4&!!-!YP0*@N8!N!2Q4%P86!! (!2*"6&*8!!B"8P088L-!!!'QGQ9bF`!"!E*69&)J!!%"bP"cCA3!!!(L8%P$9!! "!Hj%6%p(!!!#"NCPBA3!!!)53Nj%6!!!!Kj'8N9'!!!#+NP$6L-!!!)fBA9cG!! !!N)!!2rr+!#3#Irr#!!#M!#3"[rr+!!#[`#3"3,rrcJ!!X-"![DF!!(rra`!+SB "![D!!!$rrbJ!,-`"![A-!!2rr`!!35i"![A3rj!%!!!Y,!#3"!3"rrmJ!#dk!*! &KIrr*!!YZJ%#pR3!Krrr!!!Z%!#3"BErrb3!,Q!"![C-!)$rr`!!,Z)!N!@errm J!#p!!*!&J[rr!!![XJ#3"!2SrrmJ!$!3!*!%"!(rrb!!-$`!N!@#rrmJ!$"-!*! &KIrr*!!`A!%#pP`!Krrr)!!`E!#3"BErrb3!-(`"![CB!)$rrb!!-)`!N!@"rrm J!$#F!*!&J2rr!!!`V!#3"3(rrb!!-,m!N!8#rrmJ!$$d!*!%!J#3!b!!-4)!N!3 #!3!()!!a)J#3"B$rr`!!-5i!N!9rrrm!!$9P!*!%!qMrr`!!0TJ!N!3$k2rr)!! rX`#3"[rr)!!rc`#3"B$rr`!!2pX!N!@!rrm!!$rl!*!&J2rr)!"!"J#3"[rr!!" "#J#3"!C`FQpYF(3)a#"cG@CQDAM(93: \ No newline at end of file
diff --git a/mac/tclMacResource.c b/mac/tclMacResource.c
deleted file mode 100644
index 0c1a372..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.6 1999/04/28 17:06:07 stanton 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 = fsRdWrPerm;
- 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 == fsRdWrPerm)) {
- /*
- * No resource fork existed for this file. Since we are
- * opening it for writing we will create the resource fork
- * now.
- */
-
- HCreateResFile(fileSpec.vRefNum, fileSpec.parID,
- 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 f9376db..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.3 1999/04/16 00:47:21 stanton 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 © Sun Microsystems"
-};
-
-resource 'vers' (2) {
- TCL_MAJOR_VERSION, MINOR_VERSION,
- RELEASE_LEVEL, 0x00, verUS,
- TCL_PATCH_LEVEL,
- "Simple Tcl Shell " TCL_PATCH_LEVEL " © 1996"
-};
-
-
-/*
- * 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 d387cb5..0000000
--- a/mac/tclMacSock.c
+++ /dev/null
@@ -1,2637 +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.4 1999/04/16 00:47:21 stanton 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. */
- 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;
- }
- statePtr->dataSegment[0].length = amount;
- statePtr->dataSegment[0].ptr = buf;
- 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->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;
- }
- }
- }
- 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 1a8f3ca..0000000
--- a/mac/tclMacTclCode.r
+++ /dev/null
@@ -1,36 +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";
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 7790e5f..0000000
--- a/mac/tclMacThrd.c
+++ /dev/null
@@ -1,795 +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
-}
-
-#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;
-}