summaryrefslogtreecommitdiffstats
path: root/mac
diff options
context:
space:
mode:
authorKevin B Kenny <kennykb@acm.org>2001-05-31 23:45:44 (GMT)
committerKevin B Kenny <kennykb@acm.org>2001-05-31 23:45:44 (GMT)
commitf16a9d29ec4b0f401338397dee7f5d24f9acffb5 (patch)
treefdd7e6cc3e4c627755440c7f60e6ebe4311248fc /mac
parent97464e6cba8eb0008cf2727c15718671992b913f (diff)
downloadtcl-f16a9d29ec4b0f401338397dee7f5d24f9acffb5.zip
tcl-f16a9d29ec4b0f401338397dee7f5d24f9acffb5.tar.gz
tcl-f16a9d29ec4b0f401338397dee7f5d24f9acffb5.tar.bz2
Development branch for TIPs 22 and 33 kennykb_tip_22_33_botched
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.pch47
-rw-r--r--mac/README176
-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.c832
-rw-r--r--mac/tclMacInit.c694
-rw-r--r--mac/tclMacInt.h60
-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.c2937
-rw-r--r--mac/tclMacOSA.exp1
-rw-r--r--mac/tclMacOSA.r76
-rw-r--r--mac/tclMacPanic.c235
-rw-r--r--mac/tclMacPort.h283
-rw-r--r--mac/tclMacProjects.sea.hqx1
-rw-r--r--mac/tclMacResource.c2209
-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.c242
-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, 21237 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 bf130ab..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.3 1998/11/10 16:30:35 rjohnson Exp $
- */
-
-/*
- * To use the compilied header you need to set the "Prefix file" in
- * the "C/C++ Language" preference panel to point to the created
- * compilied header. The name of the header depends on the
- * architecture we are compiling for (see the code below). For
- * example, for a 68k app the prefix file should be: MW_TclHeader68K.
- */
-
-#if __POWERPC__
-#pragma precompile_target "MW_TclAppleScriptHeaderPPC"
-#include "MW_TclHeaderPPC"
-#elif __CFM68K__
-#pragma precompile_target "MW_TclAppleScriptHeaderCFM68K"
-#include "MW_TclHeaderCFM68K"
-#else
-#pragma precompile_target "MW_TclAppleScriptHeader68K"
-#include "MW_TclHeader68K"
-#endif
-
-
-#define TCL_REGISTER_LIBRARY 1
-/*
- * Place any includes below that will are needed by the majority of the
- * and is OK to be in any file in the system. The pragma's are used
- * to control what functions are exported in the Tcl shared library.
- */
-
-#pragma export on
-#pragma export off
-
diff --git a/mac/MW_TclHeader.pch b/mac/MW_TclHeader.pch
deleted file mode 100644
index 4982c3b..0000000
--- a/mac/MW_TclHeader.pch
+++ /dev/null
@@ -1,47 +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.6 1999/04/16 00:47:19 stanton Exp $
- */
-
-/*
- * To use the compilied header you need to set the "Prefix file" in
- * the "C/C++ Language" preference panel to point to the created
- * compilied header. The name of the header depends on the
- * architecture we are compiling for (see the code below). For
- * example, for a 68k app the prefix file should be: MW_TclHeader68K.
- */
-#if __POWERPC__
-#pragma precompile_target "MW_TclHeaderPPC"
-#elif __CFM68K__
-#pragma precompile_target "MW_TclHeaderCFM68K"
-#else
-#pragma precompile_target "MW_TclHeader68K"
-#endif
-
-#include "tclMacCommonPch.h"
-
-/*
- * Place any includes below that will are needed by the majority of the
- * and is OK to be in any file in the system. The pragma's are used
- * to control what functions are exported in the Tcl shared library.
- */
-
-#pragma export on
-#include "tcl.h"
-#include "tclMac.h"
-#include "tclInt.h"
-
-#pragma export reset
-
diff --git a/mac/README b/mac/README
deleted file mode 100644
index 8f05bbc..0000000
--- a/mac/README
+++ /dev/null
@@ -1,176 +0,0 @@
-Tcl 8.1b2 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.6 1999/04/16 00:47:19 stanton Exp $
-
-1. Introduction
----------------
-
-This is the README file for the Macintosh version of the Tcl
-scripting language. The file consists of information specific
-to the Macintosh version of Tcl. For more general information
-please read the README file in the main Tcl directory.
-
-2. What's new?
---------------
-
-Internationalization! This is the first Tcl release that features
-can handle international characters.
-
-On the Macintosh, the System Encoding is taken from the script of the
-Finder Font as set in the Views control panel, or in the Finder
-Preferences in OS8.0.
-
-See the main Tcl README for other features new to Tcl 8.
-
-3. Mac specific features
-------------------------
-
-There are several features or enhancements in Tcl that are unique to
-the Macintosh version of Tcl. Here is a list of those features and
-pointers to where you can find more information about the feature.
-
-* The "resource" command allows you manipulate Macintosh resources.
- A complete man page is available for this command.
-
-* The Mac version of the "source" command has an option to source from
- a Macintosh resource. Check the man page from the source command
- for details.
-
-* The only command NOT available on the Mac is the exec command.
- However, we include a Mac only package called Tclapplescript that
- provides access to Mac's AppleScript system. This command is still
- under design & construction. Documentatin can be found in the "HTML
- Docs:tcl8.1" folder in a file called "AppleScript.html".
-
-* The env variable on the Macintosh works rather differently than on
- Windows or UNIX platforms. Check out the tclvars man page for
- details.
-
-* The command "file volumes" returns the available volumes on your
- Macintosh. Check out the file command for details.
-
-* The command "file attributes" has the Mac specific options of
- -creator and -type which allow you to query and set the Macintosh
- creator and type codes for Mac files. See file man page for details.
-
-* We have added a template for creating a Background-only Tcl application.
- So you can use Tcl as a faceless server process. For more details, see
- the file background.doc.
-
-If you are writing cross platform code but would still like to use
-some of these Mac specific commands, please remember to use the
-tcl_platform variable to special case your code.
-
-
-4. The Distribution
--------------------
-
-Macintosh Tcl is distributed in three different forms. This
-should make it easier to only download what you need. The
-packages are as follows:
-
-mactk8.1b2.sea.hqx
-
- This distribution is a "binary" only release. It contains an
- installer program that will install a 68k, PowerPC, or Fat
- version of the "Tcl Shell" and "Wish" applications. In addition,
- it installs the Tcl & Tk libraries in the Extensions folder inside
- your System Folder.
-
-mactcltk-full-8.1b2.sea.hqx
-
- This release contains the full release of Tcl and Tk for the
- Macintosh plus the More Files packages which Macintosh Tcl and Tk
- rely on.
-
-mactcl-source-8.1b2.sea.hqx
-
- This release contains the complete source for Tcl 8.1. In
- addition, Metrowerks CodeWarrior libraries and project files
- are included. However, you must already have the More Files
- package to compile this code.
-
-5. Documentation
-----------------
-
-The "html" subdirectory contains reference documentation in
-in the HTML format. You may also find these pages at:
-
- http://www.scriptics.com/man/tcl8.1/contents.html
-
-Other documentation and sample Tcl scripts can be found at
-the Tcl archive site:
-
- ftp://ftp.neosoft.com/tcl/
-
-and the Tcl resource center:
-
- http://www.scriptics.com/resource/
-
-The internet news group comp.lang.tcl is also a valuable
-source of information about Tcl. A mailing list is also
-available (see below).
-
-6. Compiling Tcl
-----------------
-
-In order to compile Macintosh Tcl you must have the
-following items:
-
- CodeWarrior Pro 2 or 3
- Mac Tcl 8.1 (source)
- More Files 1.4.3
-
-There are two sets of project files included with the package. The ones
-we use for the release are for CodeWarrior Pro 3, and are not compatible
-with CodeWarrior Gold release 11 and earlier. We have included the files
-for earlier versions of CodeWarrior in the folder tcl8.1:mac:CW11 Projects,
-but they are unsupported, and a little out of date.
-
-As of Tcl8.0p2, the code will also build under CW Pro 2. The only
-change that needs to be made is that float.mac.c should be replaced by
-float.c in the MacTcl MSL project file.
-
-However, there seems to be a bug in the CFM68K Linker in CW Pro 2,
-which renders the CFM68K Version under CW Pro 2 very unstable. I am
-working with MetroWerks to resolve this issue. The PPC version is
-fine, as is the Traditional 68K Shell. But if you need to use the
-CFM68K, then you must stay with CW Pro 1 for now.
-
-The project files included with the Mac Tcl source should work
-fine. The only thing you may need to update are the access paths.
-Unfortunantly, it's somewhat common for the project files to become
-slightly corrupted. The most common problem is that the "Prefix file"
-found in the "C/C++ Preference" panel is incorrect. This should be
-set to MW_TclHeaderPPC, MW_TclHeader68K or MW_TclHeaderCFM68K.
-
-To build the fat version of TclShell, open the project file "TclShells.¼",
-select the "TclShell" target, and build. All of the associated binaries will
-be built automoatically. There are also targets for building static 68K
-and Power PC builds, for building a CFM 68K build, and for building a
-shared library Power PC only build.
-
-Special notes:
-
-* There is a small bug in More Files 1.4.3. Also you should not use
- MoreFiles 1.4.4 - 1.4.6. Look in the file named morefiles.doc for
- more details.
-
-* You may not have the libmoto library which will cause a compile
- error. You don't REALLY need it - it can be removed. Look at the
- file libmoto.doc for more details.
-
-* Check out the file bugs.doc for information about known bugs.
-
-If you have comments or Bug reports send them to:
-Jim Ingham
-jingham@cygnus.com
-
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 7a8efc4..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.3 1998/09/14 18:40:04 stanton Exp $
- */
-
-#include "tclMacInt.h"
-#include "tclInt.h"
-#include <Memory.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/*
- * Flags that are used by ConfigureMemory to define how the allocator
- * should work. They can be or'd together.
- */
-#define MEMORY_ALL_SYS 1 /* All memory should come from the system
-heap. */
-
-/*
- * 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 716237e..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.4 1999/04/16 00:47:20 stanton 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,
- StringPtr srcName, short dstVRefNum,
- long dstDirID,StringPtr dstName));
-static int DoCopyDirectory _ANSI_ARGS_((CONST char *src,
- CONST char *dst, Tcl_DString *errorPtr));
-static int DoCopyFile _ANSI_ARGS_((CONST char *src,
- CONST char *dst));
-static int DoCreateDirectory _ANSI_ARGS_((CONST char *path));
-static int DoDeleteFile _ANSI_ARGS_((CONST char *path));
-static int DoRemoveDirectory _ANSI_ARGS_((CONST char *path,
- int recursive, Tcl_DString *errorPtr));
-static int DoRenameFile _ANSI_ARGS_((CONST char *src,
- CONST char *dst));
-OSErr FSpGetFLockCompat _ANSI_ARGS_((const FSSpec *specPtr,
- Boolean *lockedPtr));
-static OSErr GenerateUniqueName _ANSI_ARGS_((short vRefNum,
- long dirID1, long dirID2, Str31 uniqueName));
-static OSErr GetFileSpecs _ANSI_ARGS_((CONST char *path,
- FSSpec *pathSpecPtr, FSSpec *dirSpecPtr,
- Boolean *pathExistsPtr,
- Boolean *pathIsDirectoryPtr));
-static OSErr MoveRename _ANSI_ARGS_((const FSSpec *srcSpecPtr,
- const FSSpec *dstSpecPtr, StringPtr copyName));
-static int Pstrequal _ANSI_ARGS_((ConstStr255Param stringA,
- ConstStr255Param stringB));
-
-/*
- *---------------------------------------------------------------------------
- *
- * TclpRenameFile, DoRenameFile --
- *
- * Changes the name of an existing file or directory, from src to dst.
- * If src and dst refer to the same file or directory, does nothing
- * and returns success. Otherwise if dst already exists, it will be
- * deleted and replaced by src subject to the following conditions:
- * If src is a directory, dst may be an empty directory.
- * If src is a file, dst may be a file.
- * 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 */
- StringPtr srcName, /* name of source */
- short dstVRefNum, /* volume ref number of dst */
- long dstDirID, /* directory id of dst */
- StringPtr dstName) /* name of dst directory */
-{
- return true;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TclpRemoveDirectory, DoRemoveDirectory --
- *
- * Removes directory (and its contents, if the recursive flag is set).
- *
- * Results:
- * If the directory was successfully removed, returns TCL_OK.
- * Otherwise the return value is TCL_ERROR, errno is set to indicate
- * the error, and the pathname of the file that caused the error
- * is stored in errorPtr. Some possible values for errno are:
- *
- * EACCES: path directory can't be read and/or written.
- * EEXIST: path is a non-empty directory.
- * EINVAL: path is a root directory.
- * ENOENT: path doesn't exist or is "".
- * ENOTDIR: path is not a directory.
- *
- * Side effects:
- * Directory removed. If an error occurs, the error will be returned
- * immediately, and remaining files will not be deleted.
- *
- *---------------------------------------------------------------------------
- */
-
-int
-TclpRemoveDirectory(
- CONST char *path, /* Pathname of directory to be removed
- * (UTF-8). */
- int recursive, /* If non-zero, removes directories that
- * are nonempty. Otherwise, will only remove
- * empty directories. */
- Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free
- * DString filled with UTF-8 name of file
- * causing error. */
-{
- int result;
- Tcl_DString pathString;
-
- Tcl_UtfToExternalDString(NULL, path, -1, &pathString);
- result = DoRemoveDirectory(Tcl_DStringValue(&pathString), recursive,
- errorPtr);
- Tcl_DStringFree(&pathString);
-
- return result;
-}
-
-static int
-DoRemoveDirectory(
- CONST char *path, /* Pathname of directory to be removed
- * (native). */
- int recursive, /* If non-zero, removes directories that
- * are nonempty. Otherwise, will only remove
- * empty directories. */
- Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free
- * DString filled with UTF-8 name of file
- * causing error. */
-{
- OSErr err;
- FSSpec fileSpec;
- long dirID;
- int locked;
- Boolean isDirectory;
- CInfoPBRec pb;
- Str255 fileName;
-
-
- locked = 0;
- err = FSpLocationFromPath(strlen(path), path, &fileSpec);
- if (err != noErr) {
- goto done;
- }
-
- /*
- * Since FSpDeleteCompat will delete a file, make sure this isn't
- * a file first.
- */
-
- isDirectory = 1;
- FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
- if (isDirectory == 0) {
- errno = ENOTDIR;
- return TCL_ERROR;
- }
-
- err = FSpDeleteCompat(&fileSpec);
- if (err == fLckdErr) {
- locked = 1;
- FSpRstFLockCompat(&fileSpec);
- err = FSpDeleteCompat(&fileSpec);
- }
- if (err == noErr) {
- return TCL_OK;
- }
- if (err != fBsyErr) {
- goto done;
- }
-
- if (recursive == 0) {
- /*
- * fBsyErr means one of three things: file busy, directory not empty,
- * or working directory control block open. Determine if directory
- * is empty. If directory is not empty, return EEXIST.
- */
-
- pb.hFileInfo.ioVRefNum = fileSpec.vRefNum;
- pb.hFileInfo.ioDirID = dirID;
- pb.hFileInfo.ioNamePtr = (StringPtr) fileName;
- pb.hFileInfo.ioFDirIndex = 1;
- if (PBGetCatInfoSync(&pb) == noErr) {
- err = dupFNErr; /* EEXIST */
- goto done;
- }
- }
-
- /*
- * DeleteDirectory removes a directory and all its contents, including
- * any locked files. There is no interface to get the name of the
- * file that caused the error, if an error occurs deleting this tree,
- * unless we rewrite DeleteDirectory ourselves.
- */
-
- err = DeleteDirectory(fileSpec.vRefNum, dirID, NULL);
-
- done:
- if (err != noErr) {
- if (errorPtr != NULL) {
- Tcl_UtfToExternalDString(NULL, path, -1, errorPtr);
- }
- if (locked) {
- FSpSetFLockCompat(&fileSpec);
- }
- errno = TclMacOSErrorToPosixError(err);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * GenerateUniqueName --
- *
- * Generate a filename that is not in either of the two specified
- * directories (on the same volume).
- *
- * Results:
- * Standard macintosh error. On success, uniqueName is filled with
- * the name of the temporary file.
- *
- * 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 94582bd..0000000
--- a/mac/tclMacFile.c
+++ /dev/null
@@ -1,832 +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.6 1999/04/16 00:47:20 stanton Exp $
- */
-
-/*
- * Note: This code eventually needs to support async I/O. In doing this
- * we will need to keep track of all current async I/O. If exit to shell
- * is called - we shouldn't exit until all asyc I/O completes.
- */
-
-#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)
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_FindExecutable --
- *
- * This procedure computes the absolute path name of the current
- * application, given its argv[0] value. However, this
- * implementation doesn't need the argv[0] value. NULL
- * may be passed in its place.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The variable tclExecutableName gets filled in with the file
- * name for the application, if we figured it out. If we couldn't
- * figure it out, Tcl_FindExecutable is set to NULL.
- *
- *----------------------------------------------------------------------
- */
-
-void
-Tcl_FindExecutable(
- CONST char *argv0) /* The value of the application's argv[0]. */
-{
- ProcessSerialNumber psn;
- ProcessInfoRec info;
- Str63 appName;
- FSSpec fileSpec;
- int pathLength;
- Handle pathName = NULL;
- OSErr err;
- Tcl_DString ds;
-
- TclInitSubsystems(argv0);
-
- GetCurrentProcess(&psn);
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = appName;
- info.processAppSpec = &fileSpec;
- GetProcessInformation(&psn, &info);
-
- if (tclExecutableName != NULL) {
- ckfree(tclExecutableName);
- tclExecutableName = NULL;
- }
-
- err = FSpPathFromLocation(&fileSpec, &pathLength, &pathName);
- HLock(pathName);
- Tcl_ExternalToUtfDString(NULL, *pathName, pathLength, &ds);
- HUnlock(pathName);
- DisposeHandle(pathName);
-
- tclExecutableName = (char *) ckalloc((unsigned)
- (Tcl_DStringLength(&ds) + 1));
- strcpy(tclExecutableName, Tcl_DStringValue(&ds));
- Tcl_DStringFree(&ds);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclpMatchFiles --
- *
- * This routine is used by the globbing code to search a
- * directory for all files which match a given pattern.
- *
- * Results:
- * If the tail argument is NULL, then the matching files are
- * added to the the interp's result. Otherwise, TclDoGlob is called
- * recursively for each matching subdirectory. The return value
- * is a standard Tcl result indicating whether an error occurred
- * in globbing.
- *
- * Side effects:
- * None.
- *
- *---------------------------------------------------------------------- */
-
-int
-TclpMatchFiles(
- Tcl_Interp *interp, /* Interpreter to receive results. */
- char *separators, /* Directory separators to pass to TclDoGlob. */
- Tcl_DString *dirPtr, /* Contains path to directory to search. */
- char *pattern, /* Pattern to match against. */
- char *tail) /* Pointer to end of pattern. Tail must
- * point to a location in pattern and must
- * not be static.*/
-{
- char *dirName, *patternEnd = tail;
- char savedChar;
- int result = TCL_OK;
- int baseLength = Tcl_DStringLength(dirPtr);
- CInfoPBRec pb;
- OSErr err;
- FSSpec dirSpec;
- Boolean isDirectory;
- long dirID;
- short itemIndex;
- Str255 fileName;
- Tcl_DString fileString;
-
- /*
- * Make sure that the directory part of the name really is a
- * directory.
- */
-
- dirName = dirPtr->string;
- 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);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * 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;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * 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;
- }
-}
diff --git a/mac/tclMacInit.c b/mac/tclMacInit.c
deleted file mode 100644
index 6bf6169..0000000
--- a/mac/tclMacInit.c
+++ /dev/null
@@ -1,694 +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.3 1999/04/16 00:47:20 stanton 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;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * 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 f721e0f..0000000
--- a/mac/tclMacInt.h
+++ /dev/null
@@ -1,60 +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.4 1999/04/16 00:47:20 stanton 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.
- */
-typedef pascal void (*ExitToShellProcPtr)(void);
-
-/*
- * Prototypes of Mac only internal functions.
- */
-
-EXTERN char * TclMacGetFontEncoding _ANSI_ARGS_((int fontId));
-EXTERN int TclMacHaveThreads(void);
-
-#include "tclIntPlatDecls.h"
-
-#pragma export reset
-
-#endif /* _TCLMACINT */
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 b09cb59..0000000
--- a/mac/tclMacOSA.c
+++ /dev/null
@@ -1,2937 +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.3 1999/04/16 00:47:20 stanton 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;
-
- /*
- * 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 7be4938..0000000
--- a/mac/tclMacPort.h
+++ /dev/null
@@ -1,283 +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.8 1999/04/16 00:47:21 stanton Exp $
- */
-
-
-#ifndef _MACPORT
-#define _MACPORT
-
-#ifndef _TCLINT
-# include "tclInt.h"
-#endif
-
-/*
- *---------------------------------------------------------------------------
- * The following sets of #includes and #ifdefs are required to get Tcl to
- * compile on the macintosh.
- *---------------------------------------------------------------------------
- */
-
-#include "tclErrno.h"
-#include <float.h>
-
-#ifdef THINK_C
- /*
- * The Symantic C code has not been tested
- * and probably will not work.
- */
-# include <pascal.h>
-# include <posix.h>
-# include <string.h>
-# include <fcntl.h>
-# include <pwd.h>
-# include <sys/param.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <unistd.h>
-#elif defined(__MWERKS__)
-# include <time.h>
-# include <unistd.h>
-
-/*
- * The following definitions are usually found if fcntl.h.
- * However, MetroWerks has screwed that file up a couple of times
- * and all we need are the defines.
- */
-
-# define O_RDWR 0x0 /* open the file in read/write mode */
-# define O_RDONLY 0x1 /* open the file in read only mode */
-# define O_WRONLY 0x2 /* open the file in write only mode */
-# define O_APPEND 0x0100 /* open the file in append mode */
-# define O_CREAT 0x0200 /* create the file if it doesn't exist */
-# define O_EXCL 0x0400 /* if the file exists don't create it again */
-# define O_TRUNC 0x0800 /* truncate the file after opening it */
-
-/*
- * MetroWerks stat.h file is rather weak. The defines
- * after the include are needed to fill in the missing
- * defines.
- */
-
-# include <stat.h>
-# ifndef S_IFIFO
-# define S_IFIFO 0x0100
-# endif
-# ifndef S_IFBLK
-# define S_IFBLK 0x0600
-# endif
-# ifndef S_ISLNK
-# define S_ISLNK(m) (((m)&(S_IFMT)) == (S_IFLNK))
-# endif
-# ifndef S_ISSOCK
-# define S_ISSOCK(m) (((m)&(S_IFMT)) == (S_IFSOCK))
-# endif
-# ifndef S_IRWXU
-# define S_IRWXU 00007 /* read, write, execute: owner */
-# define S_IRUSR 00004 /* read permission: owner */
-# define S_IWUSR 00002 /* write permission: owner */
-# define S_IXUSR 00001 /* execute permission: owner */
-# define S_IRWXG 00007 /* read, write, execute: group */
-# define S_IRGRP 00004 /* read permission: group */
-# define S_IWGRP 00002 /* write permission: group */
-# define S_IXGRP 00001 /* execute permission: group */
-# define S_IRWXO 00007 /* read, write, execute: other */
-# define S_IROTH 00004 /* read permission: other */
-# define S_IWOTH 00002 /* write permission: other */
-# define S_IXOTH 00001 /* execute permission: other */
-# endif
-
-# define isatty(arg) 1
-
-/*
- * Defines used by access function. This function is provided
- * by Mac Tcl as the function TclpAccess.
- */
-
-# define F_OK 0 /* test for existence of file */
-# define X_OK 0x01 /* test for execute or search permission */
-# define W_OK 0x02 /* test for write permission */
-# define R_OK 0x04 /* test for read permission */
-
-#endif /* __MWERKS__ */
-
-/*
- * Many signals are not supported on the Mac and are thus not defined in
- * <signal.h>. They are defined here so that Tcl will compile with less
- * modification.
- */
-
-#ifndef SIGQUIT
-#define SIGQUIT 300
-#endif
-
-#ifndef SIGPIPE
-#define SIGPIPE 13
-#endif
-
-#ifndef SIGHUP
-#define SIGHUP 100
-#endif
-
-/*
- * waitpid doesn't work on a Mac - the following makes
- * Tcl compile without errors. These would normally
- * be defined in sys/wait.h on UNIX systems.
- */
-
-#define WAIT_STATUS_TYPE int
-#define WNOHANG 1
-#define WIFSTOPPED(stat) (1)
-#define WIFSIGNALED(stat) (1)
-#define WIFEXITED(stat) (1)
-#define WIFSTOPSIG(stat) (1)
-#define WIFTERMSIG(stat) (1)
-#define WIFEXITSTATUS(stat) (1)
-#define WEXITSTATUS(stat) (1)
-#define WTERMSIG(status) (1)
-#define WSTOPSIG(status) (1)
-
-/*
- * Make sure that MAXPATHLEN is defined.
- */
-
-#ifndef MAXPATHLEN
-# ifdef PATH_MAX
-# define MAXPATHLEN PATH_MAX
-# else
-# define MAXPATHLEN 2048
-# endif
-#endif
-
-/*
- * Define "NBBY" (number of bits per byte) if it's not already defined.
- */
-
-#ifndef NBBY
-# define NBBY 8
-#endif
-
-/*
- * These functions always return dummy values on Mac.
- */
-#ifndef geteuid
-# define geteuid() 1
-#endif
-#ifndef getpid
-# define getpid() -1
-#endif
-
-/*
- * Variables provided by the C library.
- */
-
-extern char **environ;
-
-/*
- *---------------------------------------------------------------------------
- * The following macros and declarations represent the interface between
- * generic and mac-specific parts of Tcl. Some of the macros may override
- * functions declared in tclInt.h.
- *---------------------------------------------------------------------------
- */
-
-/*
- * The default platform eol translation on Mac is TCL_TRANSLATE_CR:
- */
-
-#define TCL_PLATFORM_TRANSLATION TCL_TRANSLATE_CR
-
-/*
- * Declare dynamic loading extension macro.
- */
-
-#define TCL_SHLIB_EXT ".shlb"
-
-/*
- * The following define is bogus and needs to be fixed. It claims that
- * struct tm has the timezone string in it, which is not true. However,
- * the code that works around this fact does not compile on the Mac, since
- * it relies on the fact that time.h has a "timezone" variable, which the
- * Metrowerks time.h does not have...
- *
- * The Mac timezone stuff never worked (clock format 0 -format %Z returns "Z")
- * so this just keeps the status quo. The real answer is to not use the
- * MSL strftime, and provide the needed compat functions...
- *
- */
-
-#define HAVE_TM_ZONE
-
-/*
- * The following macros have trivial definitions, allowing generic code to
- * address platform-specific issues.
- */
-
-#define TclpAsyncMark(async)
-#define TclpGetPid(pid) ((unsigned long) (pid))
-#define TclpGetUserHome(n, b) (NULL)
-#define TclSetSystemEnv(a,b)
-#define tzset()
-
-/*
- * The following defines replace the Macintosh version of the POSIX
- * functions "stat" and "access". The various compilier vendors
- * don't implement this function well nor consistantly.
- */
-#define lstat(path, bufPtr) TclStat(path, bufPtr)
-
-#define fopen(path, mode) TclMacFOpenHack(path, mode)
-#define readlink(fileName, buffer, size) TclMacReadlink(fileName, buffer, size)
-#ifdef TCL_TEST
-#define chmod(path, mode) TclMacChmod(path, mode)
-#endif
-
-/*
- * Prototypes needed for compatability
- */
-
-EXTERN int strncasecmp _ANSI_ARGS_((CONST char *s1,
- CONST char *s2, size_t n));
-
-/*
- * These definitions force putenv & company to use the version
- * supplied with Tcl.
- */
-#ifndef putenv
-# define unsetenv TclUnsetEnv
-# define putenv Tcl_PutEnv
-# define setenv TclSetEnv
-void TclSetEnv(CONST char *name, CONST char *value);
-int Tcl_PutEnv(CONST char *string);
-void TclUnsetEnv(CONST char *name);
-#endif
-
-/*
- * Platform specific mutex definition used by memory allocators.
- * These are all no-ops on the Macintosh, since the threads are
- * all cooperative.
- */
-
-#ifdef TCL_THREADS
-typedef int TclpMutex;
-#define TclpMutexInit(a)
-#define TclpMutexLock(a)
-#define TclpMutexUnlock(a)
-#else
-typedef int TclpMutex;
-#define TclpMutexInit(a)
-#define TclpMutexLock(a)
-#define TclpMutexUnlock(a)
-#endif /* TCL_THREADS */
-
-#endif /* _MACPORT */
diff --git a/mac/tclMacProjects.sea.hqx b/mac/tclMacProjects.sea.hqx
deleted file mode 100644
index a5d6f86..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!rB)!!"Cp#K08dP8)3!&!!$f#(*-BA8 #r`#3!aErr`!0$d*239p8Bfa6D'9XE(-ZZ3DE&S)!N!J'QaL%jTX!N"3f-`#3"2q 3"%e08(*$9dP&!3#[[Qr$XaYN+`#3"3)AYJ#3"M@Y!!$d0!#3"NDM"[L16aBq)C[ G`RrKj2NYr2"N1Ej`Zi8YI'AAB''%,DaERUpmCHBAPG2Mp%[j3QiKr2#pc-1c@pm irZ2Rp`Zh46q6F-)*@mKbI1%,rq8*AcMKYa`rYpGj5IEj5EDpPq6f%rk%EC2`,Ri ,@`LrCF$*3TB4ArJY!ll`KGp#XF*lE*AfG[h#[H@iYh!MP#aN)Fr*3KBb@BiXC,! -9Nl`dSPIj[(h'QK[0M+l[2eqlm+cH0,bZNcc0XYLqqf0p5jkRHGfNGeq'hQpNml 2[%E@`)(CC`0qLi2m(-3A-h2HHIDG[GG*&[2,JB1'!Q-""0akIJMS5krXc"C1q(G N%difJ4UA!,!&(r!+I2PqA`h$ZZ-iqcK1lJ3R[qqM6RkrPaeRpNCL2TM,jrJEIL[ #QVrFLk)JM0bK+&cT9j01V#IPkmKk`Gb"[G&a#SXFClle"eFlKk6"&c[lT[m[59p X6er026hklAUMdbZ%lGfYpl#d@2T(rjqF@jml-(rTG$A$fR6PR-R*c@%rR-cT`c9 Jr[*GFl2Mr25NIK,5YV8AGPDYiepIZIPV!k'kZ`6d-EA`#I642GeMR!2h,iG0VaV ZVP(D1F%j+2GBIPhRIlQ)aVNLpe,ZZAe1F1C4KKXFjdr+h5NkM8SCZA+BNFG&[d- (ACal),FTrmD@$XV@TS"cZ@Ti(kSQj%cXBT9(l*)Z")K@aCA!H4(l0HcAXAq&r62 XAf$r'[X0V($'i!AXRf2r"[Y0l0pL[iAp0[Blf,r$rMrXhf2r!IZ2f(r#IKIl2Ha A5Aij9[)fd#Tc-PEUDdl#(S)p&(XBGKKl-2D"f!GK(i`p(2Yc@'&NjR6XNGL(BRm HHa4@DQq+f"(X8R)p%hX@pXRBTf"r!IXN,&ci(1aQl#EX4Z`cXDGK,m*HM$dGH`R f8ZbTf#GLDHYcXEq)I4Tf#jCH2!2l@1c6XFr!RS*p(2Eaf#GJr`hllpMr`2iRpJI BImAqPf"&qrhlf(qa8#SYEm69TAh0IYJZE!UEaQD`JYcQB+a`8A-SYTHhrjRr&f+ PISEk'@TRqV!2ali5Hccf%GKMX-GL6m"+cjYcX#Z`Vm!q'lX++dKK"V&VXBr%VX1 HK&f224Rl+1`'l+Z`MmBq"L[e0p6G8(I6JhdepMABjf)&)mdYf&qL6Lr&ASPp'IB Ul%Z`9f#[aViF+h8)2Sfp(#Ye#mJa)*H!A!,b#-JM8"krM2d9l+pLAiGp2IB0f$G L,m0HLi@aAiGp-jBHkF2ZBl%9(Lqp%h`rGKTf1PCk+U$2JKp-86T`eQ#P*`*k,K" k5Ld$qM'J(i-MX!GJ$m3HK*f"lFFk9M861m[L0M!Zr@cKq$cX4l"rK2dSpQ2B$f( r%2Yal#H`Rm6q2[E$f%pK2ihp$"DpjR2Bcf2r'2XRf#pJ[iLp#IXPl*HaAm(q!DN ,Xc"ABPq)I4&@DQbSQk(I$,8ce-l3$iEk'fTSU+'KKSBq-I5I!4-0r@'SQD'HKRS DHX-FJjf$(F61aFl$cXG+Ej[MX!ZaLl"$UGi8j1Jh3mmEHYl38iDq0r5l8Em,aJG JI`!RJ)YBVJ0f)lN)0`MJ"!&F)##R!-`2b#Zi(2YmV13AA)'&38Rq!EN(m)F!rK$ !'`*i3`"[#1!0`V@%YiN9rK$!(`,U&e#rJ2S&e#qi"rZEf0r#ASpp+rEAXF+0J[Z aEmHq"IXfl$Z`lm5q#rXlf(GMhi0p,rChXHr$[Krl!H`(XEq(&58TZ*ZD#jm`i*X "p``iCH!F"UjK`$)$Mc$`%30R-(!5!emam"8$Mc&`#32Q'@T[i#+'qKZiMB(E',L 0JG-B1)f"daKiLS'R'(L+!4m0A-A!93aFaF"4$"c&`'N-Z'R!68-2'E$6J*e'Z#P F)B!V"(#%3,a3H%3!M`MJ#J'm))!A"(#)!0i3J2d"R#)!C`*`*J$l!l!QJ)X%F,% !,KE!)3)i4!#(#1!3!4`LJ%-%F)d!$KI!*3*i4!#A#q"b!9`Zj,&qKHrF9[A1ND$ 4U[ZMeEU$(4bCm1YeTa`QB46@2AFJU%4HY-BT,lHZXr`iI8F$"leQc4hfil!G9BR F@UfA[@UaeHT["NQK+[pk2lBHLF`jmDbTV-4jGP"TN!$ZmPVBm3ApcF529RK9Rc5 $NIl"C@1&SD&53Gl9AM+4rYp3'QihNk$KTf&(Rc25ljBkVdL*PXNR#@RUVNM,)bH HQ#VkfQVBD!Ae`+qjIEjAmk1d[Q%E4)81XL+[ARi"JH&Mbe[9#6ecH'&q)CkSEdj @1Z$XS1SP3GJNAr('T9Uph(TaVShmY`[JFKdmhPf`F*8VK6S`&4Y854B[@(MfL3k 4KGlP(ANb9bQk3*kaA5"9@615HX*qNKbbME2+1q'dB0l#fSQP6TLfQEJ(1p%fm)J YKC!!&KYfL"VXEl6#+((a"fGjpASB0LRQf5hKaSTjTEPcddKaV[ALUPG2[H[mY3l rMiiEcPKTF-Q5,6QXlGRU6R,H-R%5X$AX,1V!e5$GPhr$0NK8&r%(jD(P@pfZ-ZV 8bZ#0XVI"*`f!,0P11(9c*i4aS-`a!`1T0ppCZAMR,5#C4"5K38,8Am#lH[Vk9Ta ap$aP@E'N6(3%&0SRYNh#i1(T5S44fB4LZ!T$&I$d(3Yl0'1)QCAdUYdETN#9l2Y `!`QAI*FrV0JXf4"h,MB%!dK,p&lB*0NRU-m4+RRd"+M(U`l,U9D@(S#M5D"$6&k dCE@`9bJB'4D$L`f4*38@U8*-,Z*cRPD&kBKM)`4L8eb0JPCL'L)+b18F[q)5M@* X2CkbrD@i5[P)fefPN!!#Vi(CMI6#fq5KN9l6mc(fM[3D9R"kf)c$ZPq)NhBP&ZG l#ZmI0p"cXGp-8Mr2VrD#*MlhrNM[0T!!b"+eN9j"PpCJj@J2T+ViCS%6K5rU)pD C`k-%%q28XJ9alS6*%V'Qq%k)2TUVeTVL92+$Z![-T4KBV&hbIZKY9LqIUQh!08A 6J66SQU)Pp,!ri&2`C[-U2l)"X!S0@0'1Nl$KRZf[Z55-DV&6V)*3@k"&@bH!TSh 4Z*qi)hk5"-haf&N5N!$XDR$#HNID3EhQpUa1)Lpf&[Z9p[Li(lRQcF#3!+`9+FF P6HZ@HD[0*T(e3k5ifDmlrF2ZB!ZDFGCDAU&3X0PMr@EU1bD)[6Mf'a@P%&84Pl# em,r1ES@F8V-5NTR,R@UlV2!P@8@YJ-YPSicR!Hk!eaa[Hq0qeJ5('-)Yf@b+8US IR*S9pM#h@+X&LK*55@%&$QfCMUf(&4X5eTTX5d%qaBrC!Y&$-m`Cf$%rr+)XAlT arbXHEk(X'a6mIDAN-r8MdV1G$BVq-4[J!jM0mS"mUA38V"aM66M&C#HTiR%Vqdd R&TfqrRAQ#5qmDTfN%XfJK6-Bc'``cm(-"8&ZES2j$MlQ-CM,B-k$Q4!h(m*-5$M Mk5riFM@6H[3Yp5lf5R9aVbf&YB'QLj,[XIe$lY,LH9,5aEQY2kKeejli8kKq+ei %$rSKqQL(aHSEXBaN%$q%AB4GL*f,RBHGMjf06@(ha`jJ$m"fBrZ`[GKK1mC'Zp' #Y+GV5ddY1b*$Qp+1Y#qYl%Ce[!M)&IDRr8GTPQ#(XA6")$D&RBpGJ&f)(9*RL*f 0(F"fBaNX!DR''c&--&re'+$S%MU%kY-&9*pZT"2S$+ari3-NPkP!BQHq6i*L)#i KI+jd)9#I204ID%AqLN"M8BdQiCqK"8,Zd,GPj!#9V[&QSE%G3FK4NfbClN&K*Y6 Lb63hc8Bl-0('*"[6,N`B-P8))$$Y`Z3-dc4-(c+9b+3J%i0-16(9a236diK-R$' C5%X`2F-N&*-c60%`*F1d$"-d6"BbPFM8)T-d6%)"%Na"-BN'!$'4`b318ie-@c( "b&3EP@3DNLNUTR@BhQ(U%E"KkT'T+kDV(*0LiSVT0bDPQ!*L-SJT)B#*b5bQGJ! cTUqBk+%YhH39deC-#,QT(UCmQ-*LQSY*,DDl!%%QYU!))!66Fdc@-CR(&"I6B8a L-KR)*#"6Jdcj-5A)0")INd9-Nc&0b13G8ha-k%&GQ$TN#T4T65EqQ!4MUSNT*LE (!&DQb*J)Bj+6k6l((*P`BNS-!'65M`NRTU'Bm'3bP1P4*MfC0Q85P%P"TUHB1!A 8Q54P1T!!U9'3!-90MM+&#0JcHFM%+0J+m$1KbN4FrC0ZR*`"h[iGaAIdd*!!*N! ['0XaIAa[2PPRHGDB0[)#C&R%q%cC4e3G(2c[6XKf!F5JBr&!leKe99#6eVPK"&U 4PbK%H`KT5%)Z%Vj-C-r`i+"J+2YepJi[fia2jX"XU%`kIeAr3!mYhfErlfrrYp[ r(IErJIEr3IS2hB`bDTZeBcJYPe#RrGmep@$l)9Z(e`4[p"&AMBcphf[rlfZc(Y" rU,ckCeYrhe4b(BHU[VQ*MP`YTpTAACEp8kqQ$Yib@DCe4d630qIB0h[XrfNhhc` *p5cEF&Dq)''d[V`HT65`6Ae)cp'(p#"p4ql8N!#kd9Dd&"e$Yp!TG)P6PB`6H(9 %kjrJdDNAa)QArRRDIb(DUF`*"N(65ricr4$0lQLJ![VGY3BP$kka5P$9$[d#D`r m!3XDR"bahaBj3JFN5Sq9[R(e4(8*&KRX@KIcjYcMZEIbIljeP31%'[,1rr3$4pA Q6NjqfFJAd3IMp-"pi5+Mk22#6$"i!,kIm6K[`'G5-FP2miQUF1#ZH86p*1B%)j& 0BE&$1iYZ3-Ae@Z,J2HMD5%cVe'Df!KmH"HFimUFLZ`p"9J[,bBBET&E,2GafL1` XL&X6N3e!lAi-6`kJ'pJ!Yc!LI1%H!CqG1JMCGfBI"pMXa6NR,BG(CZK,e4q[K`) Q['#`+m9k0Gp%4IJbl"'U6f6[rQ+'0EdV!+rD-B3!LmZU[Ak!6j!!IpUlqacb94l FaL04+KrGEB&(PXXGMN*eD-pBH8+Vp$(iNS@4dBb,!6mPSIPdb-*PcI30JLBIEHD N+bD%($PMVX$TQNa(ZAP2TRqF)-*8&P00I%a(1@"NLSX*+$kQM0`F+$[%h!!LZjp FCGRca-39(lZlA+1`Ji[T(MlfjM&aa-IH0bDD+#peC2)((e0+6"cKBeS-2ciQPjL #`XGd&2A(al3A%dAii+j-Hq&MSS[*+Aa-PM%&KBmT-+DKm$'aa[362[CEN5mqpP9 "bI&45bDHm,(r$l+-Maer6%[KBemGNfDd*l9N#J`IY@#D$4r6B%b4i@0U5NFLfd5 [&5EE0$h&e"FqTYlXS+RiQ$CMQJXI!Va14,9T1SeT-(cd+&0cq0M0aD3F2QV*9"d qpUNacBC2GJrD#69ml#TNqJ`IZrRS,q!&M!"2m0'(6,(KSlj-Xq&c%fciN!$lQA$ $aa3B8fhiQ2jL%JiIdh1mL3q-B9S1(lZf&+6E962GHG@ZA@mUeVGV&b06J2MBSDJ $Mah#0DEUm0'hp"FqkJ8qi'0+M3NhI-JD6,cK!bH)aFHd)C0mq*LZdr'&$Ndh-Z@ ($raMU!!IHmqB!-6(rMUQ'['aIdjRHMU%%qJUq'3[BDL[#%5$ep3"(eLTSe+G`LC 8&RaJ!G15q1JVa"Cme0&+2Z*M3XmU-Z*M@Jir2LBJQD6$aa3J%hViU#@pL3qFB() 5(rM0""mqGZ["&r#"fH#5Sa*-@1)$ajRQ`dHGQ2E$4jqVj0#P1Y&Iq+J&pF%((M! KL!pLbJ3S2[!-ES+22BDmJimpG-b*iD016*2LSdlJ*$lfGHSN5jHiKFTH+A%ETJh a`4PdKdC+0@-Z#apiT#T,5Vd0Am"(Rc#CLSrrF#9m6&SUG8YTlb+c@[M!!c!%(hL JT$XPV!A$mE%M&!c%abj-TNlP5iYVdE2ii#dkD*-@6f!L&4qB#hr""kiaVBS2()' liD-RQA$&4kfCC-9($[3A2UC&Q5$&"fm!kr#a)j*T8RcXmq-GI&"dDSk2ZS)Rq0L jb$3T2RDP-[f,MjfRB$XqDX`NX(`CeCL*B(c`#DC`mF'TQ#6'"aGLSKJII3PHi30 Ei@[i`$MUKSqHYq0$iU-(`Md92S%22[Gd5,IMe%k#HXB$4pj+2ieB6Z4TqjkY1Fi #,Ma,Z2$$bCGfb1jHYHqjQTFYi-*c`!AKA#XYTr@bIF)85Z[@[+YIF4@LKq@6Q3i 9b(e[hhdER1jHlj'G%mVRiK0B*G('Y%-i-ZZ"'IkF2UFdZ,KRMMYRFA'db0qerD9 41rEM5rNU+a4dP-VVmhNL9LMF0Qjr5b6%aCfY%,l#,L2jRaY#Pi#Hc32ZZiE3X`( TMrEfq&8qEma`[JpKVm-1q*%AZXmC2+GBlLRdM0PTaH*hqaDRh0FNqZ(T,ek+cdH aAX!hTf6i!G#TT)Imp!Y"h%1`UZ"1VXbXfmCh9mViCMkhB!IE9rD6+,c%MeE&V[E b$)lmd,"lBQlqIAIPjUmiFpQJ1p`hi4cRMZMIb*aMcq!)(EQFCHk6XijGkSblbma %ZICkfl(2fURJYShj-qlj(HIDDkrGE-dIr0D&cUC0QlEDDeLX&r[IYQ($MMIZYY@ DeYiUjZjrX1plj*%Z#AQkcap4Gr#K'HXP`)IEFXp4'[Xalqji#$2Z6XCJ9i,M6fk $-"rcl@k[#AXMh!`ZG`+j[5EF!H6fQM"cVaS"Gb5j[5EFkq2fQR!cNpYV`[e'EUq *h4fLHdfifmHa+U1G",VAa1Kq)GeVBM3(lrDDF015lM9T8ieeVdQEGR2SAT-flC[ 3[5CYfS1JHdhD01H[HdhXEJrGDp+QfhYdVdQElL(5[5CY@UHMHdeBeqVfQV4VYPl hQV4V0i1+mHh55h@[5E[f)qKHNhEY!Y#p*Zfk(dRhQV6VEKrGDp+Z@kKdVdQllTT 5@3"Lk[DDG+JZZYHN3cfYHddk*0lUAT-1cHlVAK1lEd2hQR3SEpeVdU(G!lVAT%- h(HPHN`lG8U9l66V9YlVAT&-jkek66Zd2d,dQRGUMSAY01LAlk9k66Zded"Rq6Yh -T(Y01R@lN!$Z0HR8RJ-GfqV8EJ2GDp)P(0'p*PhU"peVBRGJk&k6,LRAZYHN5rf YHdfk*)$VAT-Zl863[5CGfN1MBd"GZRP*pjTdU3DU&(CT$iVZ0HRL6LUheb3PE0+ p*LReJHie55Prh@Z58[rTAT18GQhSAT18GLISAT18m%EhQU4d"j,Z08RT,LIGDf* h@ZKHNj6Zh0+p*QPKJ1ie53X$G+p*@RfVHdh5UV[Z08RV[qie5@XJ82HDT)9rZYF NV4ZRG+p*@[LRHdh5`MrGDj,@h9fkeb3MM0Hp*KPKSZiebDM2GDp*4VA3[5BCl3( 4[5BClFA3[5BCjDel66+kE8RhQQ4dEj6Z0FN)Kh5[5EHiK1iek4BQkPk6EY9EpjT d+hqG!Hr@hK!GJZc@,JcGDp+Y1jYdVdQhDUal6EV9pkUpG1Yq,YeV-N9m3'H*T`M [G+r*&2@m5Ya69%IGDc*&HdCdVmN8lF[3[5DXjA*l6DB)Eh5[b46G1UCl6AV5@AE eNEIZ0HN4&ZYHNalKJJjhp+M@ZYHN4aLM#ND2GRESAT-HjDel6ATdhjAZ0HR4h@@ kek4(pj,TAT1TiQ1kef5UH)AZ0CNUV05p*P1&&lVAC+TUThY0TUURGDr*90dSTAY 0TZT1,0eV-PAhL1PHNeja-peVdU[HdVdQ[F)Yh@[5Upl6[5DpHN[hQ[6UGLVGDp+ V28Dkek4Apk,TAT-qF9VGDp)R$UCl6IV%%h5[5Cp`82HDp+RIU#%qGXp`qaFqEU[ #Miqle,J&$"mhPV&,4ljpa#Hj$3`II!QqJ`pmKh2K!i2Je2MS%hE#i)1AX2X)(cY JZ#--(rH`X8G)[Rf&$Gb+K3rXPaZ[V)qqi9BXI14+,[M!5Ql0`JFZ`$A`d3r`Dhc X'+12m(%I'0L)Mhdrh++&Madcm!,jpK2IjNemF$*fmZ#$Ml(6"KrB$jlMSplFV)@ 2'S"&q1JPm!%I-I""I'!r1iM``6RB95AI0(&ZEYc#4qhT4ha`9lJc2MLEVVZE*Rk #AS%2,1EZ-AaJK0`VCRh8&`k)Mee(m#pmm#hZ*T0[ZM31p!GmF(9k%apB5,rJ)eI fQ1%$dpN$KSmqilibI23'A!-ImH!`2V!+l*+2HcEXh@Aid"Hi[``I[*Slc2#"Lr3 )2[J'2!)I1-KpC[MSCr3CI16'[Lamk$4`I2QX2-,Z1(c`$2!C(a`1I--(cd5,`!I R89hT!'%dGpRK!brBfiD2QS)Eq0M,K9BMhi(5Mq"@q0![i"hii1(J'cii*,Z`m-& Yi%6i`!Pk""pBBaFVLSrHS*lik&H`3Vk$T%141cl`RYeVq1KAhX%(9d0R`!IriAi mI'!hHJXqX!2ZLBmHi+imI2!NGU2*0d0k!(jmD#[XUF-(,f4(&Ml`MleNq1!rk!R ik"Yi%$jU#FEL)fGfa-RAVrcJSIM!H,J'2V3!Y#pmF&5p'l!IAZ3N[hl`aXd`p)- "E-'e2UQeh3FShd`d1+[AiH012YArCZU11pArCZV'-pArCZU@0YArCY+,h)GRIB* (h)PRI9*VlXAMQkAlhe6rQkAlqe6rQk9lle6rQkAld96rQk@lh96rQ`@'FFZEp3Q 'FKZFp8NrFd-FhfabjXiikq2q0pArCS-VGXmK2ZPeESqc2Qj28re[0Kb2'q5X6lJ (YmKCRf!LpmGCRf!"GmMa$9!llT'c2Zi&92e[3$IXUIihS&[D92mEd$edU[m0J#[ F,@Gp`NqiAmlk"&HiBFlkT,HjCBj[$MALTMRVSfp8rjZM+bT8rjZMHpa8rjZM'ra 8rjX$9l5l(2%*Rq'Z3HX621AZ36kZ5q%Z3ZZ6@R!ISI9adk$UIi1k&8le[d(GrkE khk$k4[@r3AJDpa0DRh!'ZcF5Rq!MGa6bcD@(ZDI3qX!BeIrQUTDUrmh9(A+Urmh 9cA+Urmh9$A1Urmf&Ah&rSI8*(q!13ljjB*!!eCEa5Ip`Pk(e5E`pD`!IY`+UrMG 20q'TrMG2G`1UrMG2Y96pEjlk8[8r@T8E"Ue2HTJl"kd2M&(pEljZUP2pEllUTrV II2@LkRrciC!!h%"SIF*9Z)@3!'q"F%Ae[`Ad0RF3@KmBV2VI![@kkRm,G-ZGkRm ,d!LiNp$k`%M9raB)Ye6r@kJlr&6r@dL[FN1KpA&(SHTr#h9cRqTr#h@ESHTr#iA aU[mYK&Yb&jle#EIKEMbq4EVC6r@r4H!1pq*CRr3-Gq9CRrcRpMcViqj$eIm@k5i reIm@#Hp9reX%plEl4I%*cq3Z2HX6[X4pHRa$UU[UId2#IYArKS4KU[m08@YZeE- qlY06r@p)GbZUrMH%&X-0HpBR1J+hl&NIH+Ekhj!!m%ce[m@kB9$e[mA+@r@ra@# @R@A!*rh*hA[@*rPcfk$eNEIUIi[4HVK2d2V)@r@raI"KEQ,N'pB0MUVr$H['3GA rKX@I92mETYEFe'Gph&qSqYq`lZY6r@pBrD6khl$@bk[qYd4h2kVqYd6BSrVI%M# )ZakY6qV)IBr@aff2U[mY3ArKYN$VSdG9reX#AqA@3,kPZ[93pEqP`Kl9rjD#8pa [D(hJJHTr5h8MS1Tr5j@IkRp,d5DiiG$kZ'&5pEq$G6qLkRm(kfj,eIm1&YkVrRF `pE9lD2'*rX@GN!$@*cS,Yd*D(hLTqYmbhD@SqYmbhB#TqYmbBBRUIm[SFfiGY$l *NpX'V8pd,QiFY$l4DlKcd2V!HpArPZZ@5YArPSY2U2lR(IUbZm#Lmm+mUereAMR 2bZH2f`AQKGd,'CqNk'Rjr(&Fd"GcdCM2l!bMl'8dHqVi2m88VVRD5rqFhV-k52U i9*Jl2qri[$DR*-8R`'6[6BfqC`Eaa0ZR*2N"6TlCrX8R`2MPGVajB6$!'r-aMhf qh6aeJH9i,l#ET9jSYe1pb'kJZY#LaN9fBp6&0Zl&p[p,E2`ep[pP0Sr,E9jAf(G HD[1kd[jrQAhR+[[ZDqhrUfhFbqe'UeGdlR&dRkGL9f(X,UCU+pU[SljXI(kGSFR Cl4cbMMek02H1@`fQ$qAHB9lrk*h[C*16GjMPIqM-1mcU6jPj"pcSRAQ(fIcpGY8 lHSHjr4Nlmp&j@IX1Fr`RC1r8ecK+&$2qkCQmQIp2cEc$`(PQjKef"@cGq8jF(rB )E*Pj"eTkjX`lk!eRclc$2S)RlAdR"dLba%+q5Gcc*lrMMp0YI()ii)2lGQ`bVae )S$Fm6@U4mNjHLqak6iZ8Gp$kMYRj6MBjH3HYEqA-1qc[@Y9j*r@H*LM[S!P1DSa km11NGLM[S290DSIb$M[#*V9$H3G0F&)lP(I3qLBe2(Q(A@16QU#mJbBiU6(+1fL #NjUP(J$ZmpB1[32[F#Zcr'ha(mF,j4elJ2!Ylc#(dq**d6Y-%AA2[#0QG*BPHJF H2$PV)qm`KG5DHBRHBEIQ[M[IHF(81da4YAKVp!ic2JrC1fYMEj!!P[hVYlc$RXj *(Lc[-![8j)pa2ZcaE2,4q"efI$CjC[`11cqE2$KqKhfJ6qVJ91-Gr`SZHjMImFC Tm&k#`iEmECr[BX,G*i"ehV4E9Ed(hplP`Rf4rUmGGH(XcchlU&jTrlr+rRqerIq DcVkUm0U4Lkd1GSQ0Zp6qIl(0eqf[ZQ0[9AL0LGYEeGTAjD%3GId%&lAPN[XUCHr Z!R8eff#I[4P)VfCc-bcbhel0&[QcYZLIL0XHAkhTC-j9Irb0ef'L9XeF*Z++HGf CacheqdPqcIV[I+qDGr1GHrVQcTiGcF-[YlR8Ar$Y45#`eA0E96Z-)8VV%6U1G9- eFFY"A*d1h4!dKdYZ+@bd!LeLc`HIYh!"S@Ii[AlcR8LGFLS(DVV&)Qb-Uejp9kS D[F',QN&c2*k1APN,NR$lNk[#j[BF,3&ST+mpX(*e%RREme[4MT1`iClYVlNNM'V ESiqZ9[diGSHmC'*lk%JlU0IHbiRMFZV03q3a3Hc&XGqS[0d+d98kjF"kF9I-+mf GZkZe`Z"'Ci@(`"4l4@EBkU8MFUaddI"E1A"Ycj*hSqVGZVC8M"Zdh'Dr2KfkcPq lUp,V25l,hHU1q%Rb6UPAmH*Jf@ZedYMXY&)*)*2)!MiQX6%mPJ+e$8TaVYljr![ B@!h10R!5V-LBa&KJ6#)5A+a9AL%XL5fLBK+FJ')5Q@"L%KP$BLN`JC95G,@GBMc -&bi2KjABHM-T'1BE*-,#8Z"Sc5)N,-8"K1@J@RI'-*K%*LLB4"C"-!m0#3C+K$h l*)prfDJ#pQAMBYa,JV6J5BbVDblA!YB9!l1YQ3e8M-[k,EjP[3QfP5UU-*50+f* D0M$"Xfa8JQACU"M(NU!%$j,)BQ[%f*8V6Kkh#R(PaP#mbK8p`USNU&kA#+15'2! T(e$UVKLAXP%**Q@MLRL8Dq-%LakdF08Z3TB2,D"52ML'TR+N&VXFk!TF+%)"U@V 4fDl-4bYQjB-XF19$%[5Upi#L6ckiL'2jk!6-mU%*SZ9$BeJV4bBB8Jk[p9D-FSA kjD'Z'YcS,!@p3Up%b&H1(#YGK)(P3)#`%PA[eKJ5mk%*,ZC$Lq"B`)X%)4dHf+J 6JRLlC[,`BAH`P350B1d1BF5LM&cFI5khc93L(e@HMJTA'B5(HPI)Cj*T@@M34-Z "NQF59%ic5`k5&20F6p2,"dPUfB"b@[Qf5R+V`,%Q@)Q8,204j956blUU5&ek)!( V8R34)8S2j%'L&*lJI5NkK[aDF!+GY4F82@Za$LV,6C'(rdCmPJ'8id-58)T,@VX 8(AGh2EK9-0IqTF"E%+$))jX2M*BlTMHei*[E0#)jY9Ki6Mf`f3i*fbP&*i5R&&d Jm+AiQ-2AJTZP,-K0)lhr*2Qid+,Siq)UQS8,,5PS,V!S&EQiJPJ8Ka9PQ6Jf*mc %8GAbPN5MI'3X'f8MXm+4LbMb,4GAB&a*@+8B%4Gc)6@5ji)VBQ!KY&UqJXi9Kc9 E+Upea9'UGL8KjF)@&5mA9pGK4hVhk1GKH&e"$f0E)QiBhKKP#)2VqRXB@e2JFk& e26XAAe5dFj%Pq9TES+(%ap&P,9kM#fTm'&AA(X,BQ[S3K6D+90)Q`V!a%54mS$@ eNB3hbeXE,-L&MVGLGEJJ&jQ-&d4KpH,A4`c#f)C`98HhBRa$JkcM@c'qU3eA%+i BA&Fa'aKAID!N"jC4VY3,66@cKR1Pm++L@8'kBR"GU+TJA5didE'DD&GmB931Vq0 G+EkQd6B3VrT!Sc(,5QdCp#Ua9E@f!R[j5aPVb&GjBP66Uq0IjBNaADq#JTAiPVE A`-,''e@eTBb)e6BCdrKUZ&KpSD,c9G#a%Yr5qLSBfB`[kRe0T+`mXNhcUq0PpBQ QlYG!cFBESbeF8rr+m&N2EbL!&4!YV)BE8dE#q)Bd%JD2DL0KI&-F#D-EkNJBA*G (FV%08TjlS-6+Fk&PrUfpd*4)i[#+L+$K4C%N$'ZS*'&`A5D*BTZP+JXPBGbi8K+ q-#U9*2'Y-YI&NPcXYXDXb5@jd,aH%X8eZU#KQ)6"6FQNMRZP"jUL54hj5JqdC*- +pT@L'm**!reU,j3CHKRrbNh4%NpU#&L1,mNR&3`X46F%P!S+eU2c%NS6"dY2M)N SG53X2e#A84TB@(ZKfDB9*D8-KpAJQTC5!F6+fE(EeC3+,&BIZ&P2UB*MpB8a4D8 -NFhi-8*H!XTQH*eheq"bp)Q'X*!!J'BeG%aC+80R+hkmK(9aTBQKe9GZPPIU5&T lSb@`02#dqFKB3pFePM+`0Z+E+NX&AU0,6QY66bkf02EN!UYc6bkf22MN)NZ66bk `12S8aj8'GH,JD&)R$S[RFV*e,Smrj816!D*XD'i!bS@8*U"FB(%%+SQVPL3HJR) ap5NS&edGJbV%eXTB()5+ieS09KL&LX2F,&358kP`D4V+"@j6rBla+qhaF6pb$Fb 8iPH0$Ze89CMX@lQkkY1I6fd+Z*T`@%baaJ1cD9DMDkR'*5kQQ'"N0V8iUTC5XF3 2F!HmjRME!apDbZBKDE-2dZfE)Nr*P&iip*mPY-2FBSfP"2+US!P)*l@SG8#e%Y9 hbY@S[K*9T"THUdVF209Ua2(P+X648ICa@#hV&PbYDcIK"C[q8G8pYKj@E!jeX48 )RAbNZ@8S`U5QqNRXC(l9K844k$J$,A9"8l-S&D(*GfppD(a)Z0)9cIKEFfh1&&F kT%B%A'F8k@STq5+ef[C!HIY13LLUY+p@mH)$&HSA9pJEpV%c[0h4(4AGl-%qS([ FE3,FN!"Mcb)"$iiB&fNqUpUe$4KBHUXh"A(ILq$"19lh0L`Si%'R`B-MNP8,#r1 lYp%%K`HL(dcELJH@*RMHm'$k9M`iVaj8ZV,aaJJ2pZFk"V0SDQ[p53QAR@q-DUM 0Td9HY'C4H@6!,DArC",UL*'`(9ApVQ1B%HN('B-(GZEYT(DV&8E*SMlIUrP4h%f 0+$Jm%,hC[)-()6-ibqqLKJJ4(V6p'emF#CVGc0!KdJqk2Y)2C#,ZR,#jD+KGU3G 9YlpCVEGVAF*)4)3(UIr3NhaNB*!!ai1ddCY2CaKfBp+pE83T`S1-R6pB(8DqpT* XF8mZR&BiYGXD-N4id!eIR$*Vl`''rHDbY2Zq*f+2EV@k!*bh4akVb`0RlAe(#1p JId1++C@Y[l&kD%"A2[S!mYK3@Y`GS+lV4SChCRKA(ZYlaNB,P3QR'XIcRGcIAH8 F-PcV2*!!lNX[J4cak[8`E,TpIVec0C2jUeG6RlRpKY[dhqE"[C0MhqVPVYNAe1S 1PmG5AD$Y"FMMjS,FNFI0ad,pGalE%YQGakE9,@IHfM00[elriX6NhjkCPhrkmpb Nr+al(&B%KIelE0V,'q09,[&K[hlRZI3f1T[(QIrEVj`,Cr1iZ6h)3cFXM4Bfc%1 @@hN#mMKp6f8RkXUjRbk2F56DRFIf1c9GZijr0SmYcX4ZR!jA4J8T8,[3)NirZM6 i)BrKM98I-*Nc`UUpc26rIr#2TmA4"kcKYMbf603VHpq4e9Z6r'a,dZi5N!!(hh+ Dj'GeABY9aKeYE#YmrJr',C@Y[h%hial0`a[!Z0HFY96hjfrl9JmYrl!HRJrQhUV UhFap-SpGc(dbMeh-I8FHYc(hL6`QQ,ZlNmdI`0`EpIJaFamYl&h-I5+2AFbpNFD 2Q2Y%(YZCZq3a5Gj$jVjTr2rlh[["Z'9VFIf0ZaPh+`mq6`$MPUe`KjlL6Zea+hb CIfG-NXFfC,LG-8hQXB[Tl-MM0UBcNFIY50l)idG)2T((GY#621`f`!Q%@-iLM[( i5*%Bka$*ikQ9PE[c@&0Cq@%HQI)(Gc#Rbq95hdI`erTZ46cCT%JRlXMMl(rKLT, (fDc9cHePE(6d'Ik+,J&ehF-CXPak1bIIRFF%FQl[XfarE0h6CVGq8p)pbf-BdjZ UMcFFrc5U8NZ&URij&HUeYhA84bp!(L[UFH`!-3)JV6`%kkPVX&XRYkUK&k!H9Zh c!Z6Ke,la2(DVI@FQMEScX0lNFI&'PJ@NmQ2i$lKSIRlfcfjdrMLri1VA"lkDGjp lN5IP8[0pALEqa[b#bkl+cljbILH2*kZ,4ZZaXmp8C6QVpAkr)V&B)"V,JhXe!jh eZDI[VFVL"HKAUl*i!I,J#q%Xq*qkfMbN2B,rkim6`kDrKc+BFRQS#m"GjZc2R+! H`HcZ%j-2+`D[IeqE#MrABq1Ij6"HJ$b1AaQY+'"r9PGBUEpLCR(mUh+KiTIM3[I e4ii,hGH[rS"C-FZ&pZ!(#2cBS2AK"-l1Z[SRP'Xqj96r@eHEarC,FRIQ-6(L&4c 9r@h'DrcEcA6m5M0HHcl2dScAZDdpl(5LVMk#+@qC&G[cH8"Qa4S!mU0CX4C5q`* QaD+68qU2T,T2-(G2"62e!L#RA`'TGRi6Lh)m)*U1af96c[MR)G"Lr%#EF[CmRU9 01EZeQ(SLAS+01pXqhELclI0[EGbC'2m2CR@VQ2rIaH$m'hX%EQGHM6aqc,a'#h) AmjV)`cZa(f%hmkSRiKIBXa$QX@P2Rj'%l#305F(B1hi!4Q$cm%VXIBJZ$dURPd( Xl6pF(V6IfjF(qGLqeL9+iH9"[VG,P(acP`ITj5"lUfUA"qe&B9`He2ea"H,b)-m E(P3[$r+`IHA,JrB#%#l0mDGG*TAj'%*aHC!!IRZe(K[*fLL,6'hBRrIPQckR0,L iCiilCh&aY-MIYIfPd6RG94V!#i-"RTM22i-#rPTFp0PpqqF-9[VRQ*2mam5J)%i I$8EiHCQQ2`-drApFb#I*TAfm+S8hl4,cil-ai[5'e&Hlm2*9Yk3q-r,FH[hh-'e cqHb$klEFp@[NMbma(`#epDjIXr'K@F6IN!$Eq2#&Z4X11kf6KqIV%[-b6YFZ-5r JY0rm%R-[!R2h!ehT1-lFqC5jQkX2[l!,!(2h5eeL[UI[pfSC,M(If(`89DQP3P@ rR!VeN!-GpG%,N!"(q4,cFKkeLl-,UTK9$Ed!pE"URaFJMq`PjQ0jl&Ell2A4[mh Z2(H*ZENQpehmFSQj@IpBbpQ3!,[hqBIZAjHllA5"L9aLhYFNrS,F[GpHR&[rKl` AAamp@SqGI9Dqa,bF4qd5md)Hj8[-lkf(99Qm!2eU94B[3"jmq8[-lkfVc51ja2c H22CZ95iahr(Y05cF24-m!REFhfR%b63lHFa91XaFiJU+B0Ga1S"4iMC[Lc1Rm'F aF@GYLj[+Hcdf[rBrbZ)1Be00DTh*,ikEXj6eS-4*IR&Fjp(mk@j&E'TSHqb(PA! BerC6r&PJiYiRrYaQkr'$l,ePbr#efrIS[DY0h1@rL8m1Y,0ahq22m5EZ`IqJK$9 [1ZIq*ZiPS[VFVNiFXl$kh[9I`CHar3&0Q'lLCKb1Mb[A541-eRTm3eYijYJkACV 9li%RiG1T-I-cfAYArMkqZ5DZrFQXITpl'YmmqakEIl3HQpr#4iq3!$G`U[@lmLj mLfcF$GPlRhd8Rjjidr&'9Vrcj"XfFIehU$ER*,(`3(Z-lb*`SZ[-4T)Uae(FV&l q50cCiEDi6Z@p$qq"%e&FQhT#khh`lq&lU+dVHbHe2ple5Acd1hRdCZqGmZ[iMM* a$a#$dIjiZ6$#(T3ZlhdNUrI(EmGhY1dRmY(qZ&Be8D@iAILQlped1Ek90Zip@Ar mKVJ(GDC1Ll0kI+%IhbNQET(QZ,9q[EIKHjcY-r"@hlZkJ1raYRiIb1Uh9EMb"*X (F9U2@HV[8fhIm%IV0dGpV0aLk)$X[HF*2j5l$,f3!0A[Df"YB-G0M[`aq[L%4M) qMFG$Id'1"cGD-Ed4amdR(l0ZD#"1R2aKkU&RQEJCi,hM!I&lrAr+RpI6ph#aU1p RITdr6l5iSTM,Gc8iQX@9+'l@TkEbL1-1RF+9+'lfMr2RF)Y$8Gc3JjfqE$rM1Rc J'hh'J+hfj3h#[ZY-h#2e4YLAlHF,Qq!1mMeFI%$ll,hL('qal1`+rUaYa0YalRl L!biZVK2FaH&V9aEh'QKMk[YX(d4aXjAI1fdI4(%$`MAA"e(F3[APNEB2SVM9fXA JkK(&cG"%5ApDer6XAk(Ai6AbI4XH-qX9%rFJ1)QCEH*'9[0m6aUAZ[Y0i[BcX*J HFja6Vc2[G4a"`$5ERr!RFi"jll[Rii-VN6*p%1*6HYNALC-h,9k#Jf&ITSq'XjN IX1qpJ$qp*ZjKMa"hS)QEqbemA5Dr,hi@Rq`HXIha)A')m,fPca!h`qCaC5H2e&Z [%YG[iTBFKHmVjMhc'AcLYh`#(UAe[JVZDm42SAAmAflH1qeca-dfF6HJ'R8BR%K YSXr--6B2H(1(LA[r-((+#qGT0mTT*Sm0B)Da[(!CH"`X0('VZ#c5@&iirccq6$9 aQBZ*8elB,h`0qbRemP2%+5rXrel@6bI#+Bh`!Ca!N!$pX)QE!Jmc2f,LP[keHLM -ia0I`kFmFYQKr(QVLAX(2-aB(VP!R#2XJp5EkRAi%AJT0@icIC2Z[j3ijCF$jfC iN`BAMH&KjR4Ui2$QF,L6X6aXXhLRpYqA`8CMP(%c4Nml["NJ"f2jfIhJB`j[rP3 ()qJf+pYZfKrIK1FCF6G+!3I9rPJ'9c2L5Z!Zp9@m@DNkk9cJ)B-G[%NI#DBB1j% eT,SUhMaBp9jYqj@qecb1q&AL6M4aM`$R&'p50`P(*5rE(mr-m1B,m&GMjD6PQc+ mf3mZCj5[I1m'Aa4[dUF,Kk6[,0k!IiShhi9cQK'E"h80m5Ee"&c(M*Ui`b5*+Gk F)Ia!5i%R%DpiXq3AL30rU#Ym@r(lJKZ*ff"jhZ9C2je!$3bm`&*Aq'U)0kR2`qd -A-$bNVrXi%hkA$LVe82N1e6jKhL6VX-pc'DH$AjT(ab#cQ%Xcei((MZmk4-r8*i p*,`2m5Eee*H)#hQfZCjh&@p5I`2(-TCREi8R+GkNMk5(M9RrB*lK2F@Ee$Hq3)! ZD$Map3a[[[4Rq*5A,lSl`j[h2d#Fm[)"k36D(fIqR08p`'2iPH,%3H**bYHI,Fa 3[$NH2F$Bh5c(JBX1EiE"5Q-RJ"GPr#EpNh"IBcAMj`K,&'pqMCSDUpmYqV8-Ell e(H*8DjcjbaQZAiGQBqbHQT-jEpAaQqqr4TcUKKfAGI!QIC4iQmkiV0'PcFT[6N% E-&C2("$2$[%QGD2U#Pq&hm-h3Va*E85(-eD&AdE2ZAjk)lQDLfardfID6rGARkQ qq6c93r(QmfL#aQV$c`Hh(0kF58f0PB,2&diT[rRHEa1Rf[Ca`P(YJb[313bFL`q jcH&00c8e`QhjARJ)FHNd,MJ)M$E`CI$M-cq+6R+)L9X(KKUVSbclCJHI!PpBU'0 'Pm(RA"l,d)3-R))mES5[ZMbHF!X"e"NF26c,idMa*l3XqDk!mlNmVP8I#1D3!-G (`!qAadh+ihbE"ra"mlK-q%'KL51qTm'dBNili,Y3I2kG$@pkSY3m!@m`4Um+lN1 V-1,[m)`qrU`hF@qL9mc2QlLeF2(JPdcF8H*jD)$bp`0S+QD@LI[@6q!$pq6[ai9 KQYm@mEQ,6"lV`IJ`[r-Rhd!l-0HBZ1[9KjVIG3m6KliNIcm"hV[mCSMRSG2+hdq LiERmMP3YAfcj[G6-eHm`G&NM(*1r(d2$F2PYr9d#,M0aRp+Z0-h[q,m8m3McZ2* CqM,%bm`mX-C)j`%2i01++aI$rF`0PJqK"@VFefmL$TbREq!Kmd`H$a%rdpeGalh 5`F[-*q#djKGXrm&$0)qEa$1ZYRd$E`peVr6ISbNDFV(jdBI+,kp9hlc#a,d1[06 kT41`am!",8k!!jVI*@#F%BmJ$q'8,Zj+X0Y33mXRd(I$qUA[K#XB0#MlRQ#`ijI AJ0(QCSXh(mhbq!jkUJ'lE*cdNpB[8i5MQ&Y0h"[%$l9qAd)E0[!T'bHkRU[ILk4 A`B2NZdMm5[0lZr3N0'ILi"8DGk%ifHY-h&A59l6r8Y*+dAk*bqRVkGHSQIN0%hI YKLb2'q(Z4KSeFH#(pYqRa91[0A&[NRi4eLpcJ(Lre5rr$`#3!`d,9'0X8fKPE'a c,VN'NUaF"TX@JJ#3#!DE')6JZ!#3%4B!!'mm!*!%rj!%68e3FN0A588"!+qqEm1 c(4"T!*!&!X05!*!'1*N!!-+q!*!'pGB'!-9R#hr#D3XrXLpbqpKQq)8[I1'd-PF QI`NM,$GEb-*X,3FYkh%US9EHFQ3a,Tjk-TAGHPi-rr%c0eZH46Dl6HMbaJJP1j2 F2V+3!)@`aBiXr'),ZqAB,@`K@fq4(&mBi4ICNB8XRJ[Gj$CK46MK&q(,HGEcj5A ,mH9-1aHM3)GAURAFkpa2HE([2,+5hq3@4MCCb)56@mL!%li!l0C"ITG01LmlVi9 lPYGETUAAL'jcS2AT`ZhFfL5[LmHbkc3[FqXeF-Fl[hLXDq3ep"V&,hpaiVR2lq* jjFM&NF@[ZEfhm-[5@lami6kima-!#b$JbN'$['C&V5JId19iV-(##9piC,11EQ" '!$UpI,m["d&0+A@48YCLPIRiL-VXfkl8Mhd"pJBVBm(91be"a9h[K+%AK(Ba$$D ljEMPUk5FZV3@%XqM1XaeA)p5EaGl)P*A*El,e-A*r859QAdq-PC2MNA)#3,0@E0 @rq"6pah205H&N!#('!+UJebBp*hh%4T2Qcja5m,Gr'h#XTDD6M`jIjLfH$#0eeF 18H`fcFqiH)@6VcjMccMCS(N'IRC2RT5,h!qb*UdV-ZqG,6L6%IZck4Z@T#HTVLQ X[hZdA"YdRBSE&SZjlqDkH$**'L@9L8Xb5EDGfA[9,`)bQZS!JN)!(-EMSHT,ULX Z,35q8`l1C+"H,9BrBMf5fGQkPb02UPqfrYSkIY&LY34T@+R82a5-&"J@9CXN*im p`fFGKk`V$Q8ESE[*frCImA",SKUYE@fbMlJlLThNFX,Va-Y!fQ`RZFaIXmf,"af r8R2$#`&dSEXl)r$I@Y"dJcR-pa+[1f$2#ZZ`p96QQfhXL5SpSJ)ZF3i2m[@IHE1 )eC!!%j-GUBJ8lP0HHG(@NqC3rkCZ4jDmHU2QfS$!TX@JG9ZHH19N,kVf&SYjTDi m!V$lX8lVSFF-#-@8r'NFX6h"3Bh,H[L2KQRdQ9T8"4LdaiLQD%+Eq-Q8iaidr"f q&qGZBrfX26[K,b`f-6)6ZMN,#6GLHaRq@E&GL(p1E*p-8-!lhm#r3@crKVm``b6 MD46E4&`mVFB8RkdkchDBj"2ELEM!Cl#GJmY)X9f+bhTLqb`Zki[Y*Pa'LHfrNJV d5SdFEb!fSaBPhL+f@EKX+,B&Z'`NYTIL-PCXEm&PR0Jq*2@#l6TFV1aNE!DR%JZ e,FhD'#qf6A'C),CGF'N5fk'iN!"rE#r%KAH`[4bA5@+l!*I*B[Xi,TZ*lAZiE#k frm"P#ffVB`d,fY3a,`+YGDcTTiMY)&bf%KY`rP5a%II@BL2ZU@)$G`eZ@*[4)K1 X(@`raf9EEFZ`EUH*MCLRLqdCZ'`RYS0af9jXi0d1BRX9,MZ+lHm&Il"p&*HGaIB eA*V&pP0FRUjY@H))0B@0HL"HE2MX+VB$F4&8cl+q,CiDfiYaf80XVm0PKYMHKi[ !I2C6Z-`8'cRB8f`hil+Af&!FppDf(,(TQ@+M$[B4'r'$-pLS[lm@fl'i'*jME@I L)VLF)plX*lB2i,+rf+l&CBlBEX6P@@,lGm&Ui"F-Q#Xf-)$mBk0ZL4dEHDFHXA% r4'cScq!50[$[f@*l+bjJ-ME`lh#aJAr2%GY2F(QZYM83irp'E'$L%@+McTmR0R) a6fa,F6P5E'IM-PpXa(f8f$k-bp&LqbSZcaFE123#E4Y#,R'-f-"%kKdEqDE@X"% rA!EEFPc)1EEAih+Ff!a(5[KL)mG#HiH`lTH)lAHiJ0[Q0*)2L),65,`MRpLSHH& fMF`MA!EEDELF*,EcF6PCE)E[*N6#DL6HN!!IE$r#aI3#F)D5X`Rc'mUi6a8E@!b QB3-AAL)fFNfmf-!BBH9$U5#G)6ELTYkaI4QA[a2E[q,#QpMZa!AHCmi`mV%9BS0 AR#8fX*,ka3CH`#Q`NEYAL)fDIUABVX)&r-If(9aH,EEIi2)DE4Y1EJE[`dCYR5X fF1ZeBU2f`("X[%8YBlX-PcH)l9p`HD2BEX2P6GSfJTcfc@+$Ji'pf1!*9Q8c0R# 3!$V&4Vf43fa[aq9YB[XRA,"MqbiZla$Elh&jTlD0**pmPpMJ5r!GE1!lR!XE'!5 RaNDG[&YXm*+,a2BjA#i@fbfiA+*YL!k*"m8'pVp(E060Hm9'V-5#$Dam[pM!"EJ '0ZS"IShYFPbS)fbIa`9Xa2C$A$iSY[r%"9jJc[VNflb*$8jfKGMJBeH+$H`(cl' 4liq)M4b!4GLS*I!"'cl`3@aJrp9LJh0FSffMb,Nr*MCb6ceLJl[#RE("f84('N9 qJPk"$5cqP0M!Ldq,MGU!!f)$2q"If1l!jCqeE65e%[3(E2"cDK-EqDCHX)((Aa! EA1+,BJ2[[L3fDKZZJBdB`'&XD#I%EXi'j&AAL`hF[8&XF-L[L!dq3ieJ!krK%GM !KDq,MEbJcf"$YrLQYPP*")k2$5cmYYMJVq!c0R!GI--'4d+,`!D1`dQaJ4hI&aY jr)(B`&e``j`0U3HKe@#M4Z&@f1#am!jXa!HqBD-ZEa8Eq!)R`NBHL3XE[)&mQV- 4-B$D`BCf!&CJJkrH,MBi%V@-$9b'4f-$Dp!CX&%22a2EVh""Ec&R,(%1lSN0[H- ABS1Ar&*Xm$Gi%cCi`[m6'pK%,0M)lkqeE4aV!Me"4cM8,I9+R9+IF!(i-MQ&+m- EiGK`Dc!&R+BHiH$8!(J'IiHl`Yh"02!'AJKrKa2#"H(qF'j`$qj-RF#Ei@c`C2J ah"KFJ4q$aHJ,e#RB5#fK+i$AB!HB!9D!%A"%q"je"5q%$m)c`9Ai)$`3h)#(8SI J+cJ&*X%&iB"`(6JIA!q1"lHM9Z%Ie#Jm$[i'2X$Ai'R`-MJDh!aXTRl"EcJCq!` ZJmIJ-$SQI"RX3Kp#Xd5R3$0$Xd5V"%[3XX!#1!Pk+VS*@LUm""b"3k1R`[hKS2" @1!qD*X!0(X+9d5rKQHL9VKX(R3!mG(d8m"X`%qi#Td"cJ#I!$m"6q!#k)(SJ')S @#%E$1G!1dC,3'q#`k&aJ,M`*rS-f"qq$+k&(J,&S-@J3m$Zd6640-"0H#LkM#k) (SJqKrk&KSTqLri(Gk+ISTR!ZX"[G&(i#2i1c`MIJU(!FZ#dF&@i+*i8E`hhK$(" 41#MF%mi*Vi4MJ[G`5VJN("*mKM2#&H(3F!#i%"`)lS1ZJiB(Ai"lSGZKqk(hSG[ "XG(Td!AK&r"$0%9d"$35q"hD#jS,QL*k#cS,1K8k*(`4(J3(3FY$`i-c`bhJX1L ED(CSG@LHMQ[#8q"USR(f(DIrJe&1r`FrR2j2E6[pRrTdqMqjGISrf1ldIhL$drr K"8lr*lF1Lm"TdImYlSVqEr&6p(pEUkl$LlS8rGpb$Y(rE6f+rQqa9I4rLpP1rbH 2S[mRLC'LrbH**k,r*iPRS[mRL81LrbGCCk,r*eQ,S[mRbBP%rlHp#D,r*eR,S[m Rb5P%rdm5Md6r6a*I42p2-THLrbI*[d6r6a,I42p2NYH)rTpL,NAr6c%AS[qRL+1 LrkH)*D,rTiJCS[qRb00%rdq4`iRqRb+2%2hIGZZ)rTmLGa2phrBqL2kI)TD+rTp L,NAr6j(lLIkI)UF8r6p&l"2p2r@#i$c`!ND)rTpQ(BVqRfCq4Ip2%pG%rdm6DdA r6j-,L[kI*NF9r6p0VL(kIjSB)rTrQMa0p2mdFbEBQ#C[%rdr66iTqRqDI&2drcV LQZMrGDaEdIrVQ#r4rqZ)qD,rea'V4Iq[)dk)rPp(lLEk[qfc%2frM[a6p2mkiTr SrhAN+D,rej%VL2jI4eiQqRmGF8,drcVb6p(r-m4VdImca%V4rc2%*Y(r-m3#dIm cV#[4rc2-SqMr'I*adImce!"%rmq3!-H*rTmKcaEp2m0FL[kI)8k)rTmKIS[qRb% h&[dr3m`@rGp5#G(rXm4adIqcc*2SrlDR3r6r,2-NqRq@Z4$p2dXm%2dr5jiXqRq @H#EkIjCi*[TrP[aGp2mXHD(SrePb9p(rXq6aS[rE[Jr4rl283%6rce,M&Idr4`i MqRq1h%$dra`a9r6r((&3p2mFF8IdraaVA[6r('Y'p(rE*b,kIijaL[kI)lF@r6p (68,dIpXr)[TrMYaAp2mFHDrSrcPb8Y(rFmbak2mjkN'LrqGBSk,rjkLYLIjI6ri QqRmpm9[drhVQ@26rHZ+Xk2rea"h4rp@BBjKaAqGIlk&EdHZ661lFm&+[j@2aq-C +Kk'*8afSJJaE93[GqD)P**ARe,cYJ[KVcPmkY"0hafM)AZ!lmH[KKkGe)S!4@ME "2iIr"[L2ahm-rN2`(i(rF2`RiVmTrT2`RbcpR2NHEL3CfLK6q+Ia(i8rY#q,I`l r%IJ2aEm4rj%Y28DI1IV!l!GcM$bf1Ij0q1I`Ri6rC2`h%lp0m"q2ra$m*l4d0Iq S-1hX#X"C#rTU`"%k)f"YT)d4DjelR&c0L5)hbQlh4$r)Rm1'L[EDhVZS46dqe8) 6k#2[QLh42J$(RNh1GVN(j@$#'i[r12bEm%IrG0Uhkae"ad)[4Cp#`d#l3%H!Hk* AS)@KNk%pSS'L68,6d&(3*Y'qd-A3XG#ed"l3SY#Gd*M3lG"jd*649Y&5b4eekAT 5U%Ad%$3Qp#&d(M3JkJ[Y!ad([42G&9dER4Y0#Cd'$3EG#6dA23Gp$qd2A3Kp%ed 50S&'LUD&eZMk(Y$Ld"ZGKZmd8241G&6dA2JNqK(D'(L"&SeqMHD0TSTZ+aUKeIl 3QG#Ad'8!%YG,JZj,jD04S3fLik$IS#HK`D&ISf@LYD&(Sp1MLD'$SJ@LT3-MP$8 k)E@-hSKqMNk+pSNfL)k&cSFfL*D(pNNI!4SIqMTk(6Sq["qY(Md234$HLUk%YLH kY%T`8UJ9Em+)!N1r4RIRK[[@G0[GIEfM[EM1'FU05Q1"PR,8Q*Nb@S`dUCR*-`E Q4mf1)&TD[DA4+-p0)6*qqaSJ4K$&Nl!X3988e+6`3-D(8(@`JNeKiT6hjZ14$Nl k)e%Pk[l#ZH6dfj5%+B"Hd,iADXU@j"MQ2rVX4,G#TY3!RDpFaV"ITqHi2*0(bYr pF`*+pZ'`kUa9%jJ5TP&-)k`Le3l,TC'[$kQmmSKU*Um5Yp881Z-8&UAjEki[U`E rT5jKZqZi$'pMr`I6%XQ8X)ZY4ke[CElDRK+Qer51Q'SF4ZiiYqV@D[EbV26%KUF ma3jN9KFSC&jjMrQ(Q3$i4bEC1e23R)PiSFHr$Z$9j4qcND"r`NfY0$IdE8YRE(1 mF4L+9qelVN2HEdp(mVHYUml"pFTl$UB@c1c0r8XfQ'C6h[1hr'$kTK*kM1"eNGE !$)h4@3V!%!XC++#p(C@frdH&'*'Z!Kc'6CL4AI9SbE36KV!I,m-&PSJ`DPS&`LI AD'+9qI6a5H)*ZLAcUT9$'8kEDQ@H($qMDm@UPGIc6fGQGcc'062cI+m+pRM24UA V)N`r[D**4%Mrk`1C,fA+'#FNZG42'p,UrlY23eNjfN3AN!"AUe&XTY1'l[XR@)j c-,(3F@mlaaKAB%GQC54JCKIB@9RZD3BCf#&C1-"'eh"AD2#mElqKc4aA-Ia(&0` i$1je`bf4c8*V+PdrBYpNp4amd1VCY'VGX$db@&8hf#AHCR3[@UQX1c&CFZ*RZKD Y9H-fqUX#r%JYqVb``p48CZAq*pA%N!2-2rRP"cDUTjjkDZjr(YUq3[YlpqelkBd (rj@F9YmUaUirr+rqj#F0#A'kSdIN(AcSm&8*m1(Hf*8jrGceb+irfb2EdPpiZ8f fJK@9VQRRU6faeDC"QIN[E282XMZ+Z9Zf'YMpIp&Hmq[eVl,9@X`9HhKkmP$,98F X0EpLA!r%m9$q(Sf[)rrpleALlRMRSETjS'BliiLl([d'lN3KL)-`U$PS"MibG-, l9''pQ"Di8I+11$CK9jqQ%6F+QQ%CRXZ5*AlfD$5'I#r1PQNrd)h%BMcc4LclMff 'FC%h9NHi8bY"bjBBmM&[m[P1f8@BLG,3m,S0@E3Q6k9eYK0ANrXKZC'Q(hYe0h( Eiml5N!#GDleL8V3eE5BJ#GdPD@USSQSlkA2+3EhKe6bhBQYqC[2VP8'3!1K%QZ5 3!-a0EC5VI-Cd[%q0UV@CB%d&,2,+6Z`&2Z)eeM"9XpH,&H1Fd(dj!5l@TK[YCFZ hf0a[+c%lS-A`abd92!Zebc[QbAbQU!,cM+d#fq"Y,9ipQ4Mm`YR,@Ec8@l+mFP1 Zj5CPCXa0,@rVf2c5XMV'UfQShJM#Q2hMLG91V4B%2T+jU%(FD&Q5ZrRQa0-BjcK 4fDNPeJ2Fl3Vh2D+kfT!!'ql[RieKcTSjFa5cQdl6r1+mJHJ0@b""AL$FXi[Vjm` Z-f+8c'!0SVI1Fr0!&Vm5MTLT"-m2P*QCcbI@Z,,brXjD3$,M8B3'ib,f!YkeK5p [K4%(cj-@6fd)J%,Ua*D*jlcPL8aiARj!)9ajVJ*imSk&2BV4`mc@m#V9ki9!PZc lF!2MEZ+GHT5q2YN`jVb["`D3!*EJ2Dp)r#I)6c06(M`"k['U`h+bjG-$F$4bG)M *LcDY&[B+#52#SR1a)(a5B*(+`q3L2XHdbJ[('1D"3"`GP81[%HZ##"cb-BH[Z%! $(jZ2K5GI#V-8HpVU+VN8H!h-EXB!H*YjD-D!V[N3HfF-D&B`2r#MS1CQSlJj&T( c,F6lcmb[ZFIeim4Z!pUre!YEDIL%jc$E$FGGXB&riYc5M1+JE[q-Hpqp39L*9'm CYE38!,kXLL+DKcHAf58hMMer2&,p([)b'aQeeKP0VeDaefb,3bG5IHjBFhcF$@h pCN,6JCD%M4'Q0CZpiKEV3!iX)X6&ENd0MGM$$3#LQF9m!KQ-j9elZhjLQqP&l$F jES`K""R&C(L&GjFGj6cf)e%C1T522FLrZ*0r&bHf+-kJ1$#jq!5YYlAcMMrHG"# ,AaE60&Ndd4`G*M3eFAZDkZhXhNV&SjFK4+6DP,,Ml#DfqDZ$bRfDZj20[@["Q,c MP33T+$QTe8H&RI`6UF%kbp(M*[pS-Y1HSiAmV)5pjS66FR@!!BHVKf[BFBUk`0( -KQ[S)01-Y+!92L`)m&K1PUQ9iGTjpk6XT'Dmk%@Zll`$F@MS[!2E(0*jKbR,MHN lEK'RdM[d4!qGIbI4ISI0*)ChiQ&'eRVcljc4IXGZVA9h(TNZpI4AiJi-E''a5qF G0S6BYI-18f,h6GpT``ECc6,l5Ki$!eY1R(hZRA`"f)E6FKIUZLI#1iD0eLEUK42 c[,r1-,rF%&L[,A$rrjhqjqH4SUMVb`pX+'ra+Z`C2+5%"Y"qm3#bk6EL@k3A@*@ M3%dQNB8Ih@35MNamm#H6V*dq%YVGkCp-8Rbr&[HMq3RcdI(ZrA%26QGC96Gk32d pqSjqm1qT`8UYYQ0)BYS`0dI,Bja-VH4HIhKK&hBN@LjlMZD2@m"3H6YGE1%Z(U% r+4F6EjFp#)1CDMh+K3l!RJ[f9FT&[pT3[$r+RL[fMVJ(mrfRI1J(F6mkckbR*M[ HUmeL+mC61D8i9!50eMM9c`aFqVm)r4E9cJJeK"aU#%Uf'V!Ed11FdQlhCUllT2e 589qY2a(I[-2@EFrX[-0mlEjq,TQGrGc11hD,cikqZH!GYPRESr-1r@YlY2SYf[[ 5M"HEX6fMm`lpDihQJ(HLHBI0-LHTUH"&j41ZKhMq#!Flb6bQf2Q8jFYDXjM+RM* &TH`Si4D6i-fGD`p9[2h46,(hRTM5G2c**rF+r*-a@R,H(Vl8J-c%LTf,NlCLlfM Z9Z`DcGQ+AF0"9QA2D+a9fEeD@q()Ud,qiSPH&HIfbT,4@B9D#@CpP6fl8aF-ebN l-K@XeDZY@X1*BE&V0$mXGLh14#[J463K,Cb'%J0Nj&R!amJhK-H5Sj4"bFrP1ik rJ)d9Clq!)fG"aXM(!Q2N%H&L0I-#BC&[%48Mj`J8)mm)%b22%"*,MK'XP,`Vj46 LBCbi'!jEIGZ+5F!`,T!!!!Y,MPdj#j!!X13(%*DGUY8C`Q$N'D&Jj&N%`4JD)Ja ddNU-IljA!IYm[a$h)LG*H16MmTU2YB"e48Hr0(e(`6MIE[(0YdEB9XUS`*!!leI %00ma(UlS[#)Xmle#()ZF)Mb)2)ZP%@*A2MNaEKAmbS@4Re)U53q`+R*UbdZ!8C% 2q"3lP+SVa#AI+m)NhkZ)4rNbMV!SQ[)E!e,X@N#Pf$Q%TV+R2cUbk1J5A%K#!DQ UhRj9aYk#@E'6"DlB*8+[YKS3p)QGLcJ@HdGJ&VY'L"DlaU-hLjk&3Ca&pfTYK5K Ab&m-G4ARpXS5d#[85S"mCFrZe!8B@(B%#&ZpfUSeK-6B0F,&f,8)MJ@mL"$5iB( efYH,6QSQdEM@9Ph-b-p,S"'hHKjF11&9(XXDXFJSdV,3))'@(8fFN9-j6*mF4#( 'A%r#Lje-D,j$CDKX@&C4E+e`,!'fHTSSBkpbU-8je#@N,Md3JAA*ZiJ3T3GLN!! SZ8GiAr)1)ErU(%&Rp38hV,ML'`rSlB,rGRqI!C6p24*3mSY+Zq3G9RHEFfI#A2Q A(1p'J#+2l(LJ+pdK[DNkhe@Q!FQTqX*cfK`lbL&L1bA[L2#8[!X%[Z3IF[LUFdF U#h+6$1fZ5$l1Y5Mk1,p@cF+jPK3djeL8LTaI35`+hBUb61LE&fC#VdTk5k*4l"R +4VkR,a`jMb,IFRi&aK@jY5BMi',1T8VbR(1V'&K`VD5[S(1&EKdP&@YGSCHSAC& ,1E&&aF[jGAFM&-HZaplj-H[P"TSpYj9G2Bfm`Vk,F8A1qE"+R3HPU(c#A)c)Gma (%fQkT8KL8P`-*rE1ae6@i8U"P6#q'&ZC$[[K9IP"+F+iqLSMj1-AbJ2PBrpJ[(c X@"df(a9T*IMSJA,XNAX3HZ4AMG`[k%V8[R-jBYmeL0EhU8BDPhNPh2L&FXbaIa" il&L0[S3#P358(LRRS24%N!#'NQme%qhX3*D1D1he+Zd@81kHkRd#a#Xpd8BQA"T +(6Ch[9p03SPkP&iS8`mAIp3KdI9Z0Hk)T,5ZDe!P+5l`XR,G'd(l6JK&6P0kSS[ 6Z&48YE69F9368Q9"'YV@#SV-M1[NMjjDe15"ScI-Z2BfDP)#6ZZ-DlVKYCqM6Fb iAZ$8316qP-Heb6`#+``P20q*A`rrrU%6IlDCN4!-26),%SYRqr"Lm`kMYcU'+pH ehf()FFH3!!Jr12-13b+HdAQ(BF1G`jq$GeM9[R1SFr!1Dpeh$QX1hQ&iaYMjH&L jhld$AHJEaQ'm'*l4-6`lI)F9)6Z'FBI[X&*Naj!!lI!Ge[R['1SF[X-DrKe$RF[ `SmS29rEhKr&f0G*CpiIa0pr5@iiHYcq-AV1eDk#QcFR"L-k@aVm1rk(i$m1I[9D cq*[0pa0Ai$m#rq(iViIrk'6V#PBH55Ip+eRd,B`dak%Z!SdGBJNH0)qc-A0"fGJ '$"!0%HcB&0MJ`A'1Z3d,#RL3!!%h6mV-LER0"RGEE*CY)c8eJ("iB2KLmK3Hq*X SkQQ)%1!"5b-C2-M2[TmEBl26H@&PC[r4jQ5Ec@E&fr(eHZ#[8-dal$MD015ADmf +)3`d("iBIA'%eJpB6A9HE'k6%!)m-!-$`)2Q3K#k(2@ee,ieZc4la`SeXl1XMSB 4!4i-!epXl$Uh1Z3i25$LbF0D'1c6U`2%-EZ3!&pplTh#1V[9-lZBlcF%a(&)VXm -N!$A!dSMma'ZLH2!04Y'Xf099BkL(Q9pBjHkDQdkr+"qAf+,p[Yeb2#QMbDfC1R i*1mf$VZ1IGH*9J0Z2eiF@peX#SMMVS6mGaahVBMb2h'X#Q3JMU1h0G683cYe[9l fG(AkkkXXfNFrJIkLjIZ64B[(SjQhIU#5e1Me4lVJ[p+D1VV4fR2YdPBFCUHDYIP JS3FEaehP8GJ#Z6Z[5c!`8JQ)`kcSr1HmXRb&Lk-(L3ELk1f3!+CFDmI'X949cq# dl0CXJGUj&R'DaCYVXCD@FfipCRIV%mmRVII!2dk)`YGB`leaf*@&HdpKaqMUBAP K(5!1MPe`qmpR$[l#Z)0"U)@MIc$ZmQEdFKjNh&eaU!'-Hrr9Dmr2LLTXR&dpbJG clmcUJmbp,illQ(YI(2Fapp9ah-[FDh(8Q$Y(Q(Ybph8E$3$-[6dIMc$hVX5ZBHk e11jMlZeK2-cFDh(d-RF64apjpjMldH2r9rIU"q0Q,r(UHC!!FAI'`9%#',FCbcl p0VXpAle`'Rl!Q%`FUj!!iAl'e"I(I8aRG4ch-TeD(2FMHAXF$b0j,BjHd$0af(( m0B5`Hm*hRd#4k+i3%mIaBpbRX21BEF[liQJS[,E"GAfKN!!E[!"rRHFHa$1Mk+R %eA%XHT8VQMJ@BA4pITTmHd8Ij@ib"14eN!!cq&bkPj-2a&&$cYikmqYMfGNbZqF d*QX-G'2-m%4pR1Fr$&@T8i@UR,`+GI0N5he8!H*SU8@4!X3B!1Q-`f!pHD@6V9- RYkUK#T!!$k[fU3"a1,@[*ii"YHqBZ&j6Kl"Y)A'XQ),h#ZYaf-GXlE%Q(fQSIGD "*iiFfQRYI6I"C#-dKbk'rqR@JFre@C22i$f*ieK@89FqqZY-9*B&MG2eLX4LJDJ l$VD85h#CZm'kYbU,#P#[9Q94!H,JH(#@H#1[0Jj6(SNhkf1r`(peZQfb8#JD!#B #-YqQ4Md5#m`6R3mY`amiV8ejap9Bcl%F4J@)BpEQF&-@rl9jKCAU&6f,2DI#KBS Rci@HV)mm&hUbA[@!AM(,K3Ea!`3qc'ZFlm$TckXqS9acK&-pN9FE4qrqN!$pFG4 D["*[-lreH2@F!DDM+r9i$4jPUFGV5H-X1khP952SmMDpBS0(!HN9D`H3!)Gla6U 4@J[S&3XRS9G2cMc"h*8+CUS#)+HZJ&6pTcBS4`(4G"5A56Np4b(3BR5J56Q$4eQ DP$1JaE3&SK*-h&PeC1,1UU0[6GbTYImRZN`9rIrh-6KpBil!rFbV2Bj(Q&GA3YB `VeSFkX4mK!(Qe4D),M"R`B[Mk,0e4K"Q*UP(#VVId3%BJBe$PCMlS-0Xb+r%("d 1"H)Y3BErm%Da*FJ#V!HLRq'"h3*#cGX54'h$Jk''qGkNlK0a"Uq(LG98ke103C( V@FNBjhT@XQDj(NI$&aYrD%$SBCTK61YKbRiI$qa00Yr6cI!JG`%2$+[8bMK#J!I e"[`H4c0YD96*UcGUVSeGX*X@4p9E'Shb6E2[iHG0H'imJZDQ(m2&5&'((M-K*'S h(,'P-,k1IN`9TLGcG(GZZ'p0YphGec[DLqZFSGaSYeQP!*MmmjH63TIH%%0!0XK &Q)m1'fLE5'*Z`,mabD2hJTeiC[jd$A,55AkmH@M$$"q95NERRGXV4)-jE,NbUrH ZA[j(Y08lZcI1h1Y(l*ZXRS-2@MfE9UdEYNF'UqS'Zm6EM1j&+j9eje'PI[`cAB[ @UR&lhI!XlU6X`B0LZ6kcF[q6T(h@E1l*,cq`FGEZri[fQPq[Ib@RI6&Al1(Tb8- Y9afae2b+F6d3ad2jHc5qM[ch[eH*Zq1GKqVQJCVYLN00fpMdJ'6,6h[U"cr%Dh8 6V$ZI5fc*MqhCbl[#Y)I#0YYAcHlrPk)ph0M8eUqhXHQmD)X0IkpHlcK1c8-&fpL dM029M8d,1+fEEfbU)M"h(@LETalQlR4M2B#jke)EQ`l@r6SY`mDQ+fpm$+T5T`T 91AN9k[bp,I94"BLM[,&T1BlUCTS&9FbUKLT!2UcDT`,%i@pXfKh(J0TRYj6FGc, Gf$4e@@B$l'CMdp5#pdbTCc2,GMqI2jDaMcq0*mh'TL1r![p2C*EYf*9CF(p2+`k lT@4A2[VVV,baD6Q1kXDQK6M+'jXqPJqVXUJ!p@T9&K8J$NkmXHPMHE9a4"ZE2KE (1U,0aUE+h#41Idl3M@p**JdV9*-iae[@c&`RihXpkc@eC)GYAT[%@F4T$Ai5ja2 -A81Da*QBBHl*,chHB`"JlTV@*-kqZPqRCCM%qC-rr#,BkKmR$ZC9U%d2YY4(&5# 1abGa&P8aUaUU!2Q`DTm+%)G6qhVL'&$l9NrLh2(@EdrLh((aU8QFAIRSVl2(*h% @ihKm%QFa$UZbU!$eDP8@&5!1cU161)YjYA(mlb61BKcVL$D610N20ThFXKJ0-cc ClAKYNY@`)l[#Xp@EfIAj"Dl[KTkaE0A[[Z0fI6CAYLBfH(#FZ@cYmiI`)+0hKEF 0+R1E$A,0jN(AUEKKC&)$#)F(KLmQ6q'"YcAq!YHJKJJ"(U41iB'aDQX8)F#$Y-D $r#EAFf2(VcKK"3d5X)6P+`UP[*eEXGVc6@EJ%1b1RrXq(YMEmI9ki+mS0XGUAYN HmXZeCX834LS$2+LrJ!H'4kTNB"$M3B2@QqGMI1Hmf0`Q13Gi-%6M3A-K#0eq$(4 GDYqDACUp`l5'$!%H$)1#X(VQQATkc"MlLdTH[9&c4mX'J2%Y1XG4ihT@cFRJEeC I-(f+lY#aQ&$GKpmkF$8kTQmbZ8&$iYU-aSF3&jjfH1%eGbNeq*M4$4FfZ1KPA0M lm&[lh1RTEh3EhA#K#5653%1%#p1!#bGKUXKEM'ki-!0N`DM1%5kd(&jiqI,Tk3p qa1#'#LTX(d*,I`(JTlUd)ZKaI3JS!N0(KSG(Cjfb!b2VCLE!*Dm!2$D9UQk0)*R T(mU[JDL`ZG`Rbhd5ldDdhNcXQl8M5(89JMJ)JaVh'V'Gd6MaN!!*hJCN(YkJr@$ k+Sc,mdHa')IK%Y83H@`-ldEbDT6l8!R'[Q2Z)q5qR[L2P2I(brXZRNh%EYmclq6 N2U+GM,UVQAmcG1riCPK1XQ&6Cej[NRZZr9VZ5Vk@6h0@)R*TYKN`Edk3!!cCc"R lTV`E"@pm1jBKec%@jP`[+$ZaKrR+,8'&!pGY!XaMBq8q,RPZpdYrrZKH06'3!r0 2,Elai+bpqMGKQMmcpG#*'J34R-CX-QCe4AT8XNB`Y1mkKJmUCr9prp(RF5"r0X6 r11Nb@T`S"JN95(I*NN3T5+LYSKbF)1La&&-21-[%lf5jRb,q,jIlFSRM44,AhmS lTdTF,jEl5q5pdq5pdmAq#VQI)Ai[6C5-K(TISPcSFdLQMab$EdR,ZKJ3DDjpVc% DASi(U[HHrJRG"Qb*2jI4@6!F-Nj(mK1YG`LpSI-1I+1qm`jmBG2@1kQd'G+F-pV [S'+ZRli6aC0X[`12Q04k*cdA6aKh)kilcErM"fIH'BTVFqHG%EMZeRQ(+Ykpmml kZ1kEeNpEaCYh4Z'DIDA1JRG'ilU!lRDUELrFq1r8!%cIIdH(8h6@,4F`3-Xj'iK FUmNKjXEi2p66GDEFAbEh&A)rUpAc4Dm$29rHC--6aHmNZCmXmESHX%Gk[la1G0I leGRcT4,da(MGE"k#KVhaC)bXN!!*XNJQk+ZR1i4U''lB3!@bjNU"6*0K-Yf4CDr HGB9$G5XBCE3EMYefcNljR*NIf&$HiP@+BE"jI5RCjZS`*((+k3$U8'dprSHM%M[ pCI,AZ2QH(VrAbEaMDpKr*c[A5e6AIQF6A'I1[q-(CpiCMqZHRAFQi,TAkjhFh$Y RY0pK0memceBKMm%lQq,DeqYNhTP%r+Ve1TPh*K2VlRjR-e`lHpQ#GcE(YDr(bVf c$SM3Bk9I6!C+U5ZlcUdE1FlFY@hNr0DqeV250GIUpb@fbVD4b3pr0,%P5mFRH9H BYSfmrL(SXG6VC8pATlqqbU*pp"23PCE[6aiD$lj42j!!l0kGR$V5"Iq9eY64MGD HDjHfiY#6YShXRICUiZKE&&+fK$cQ$%l,PT!!&ULGDa'RpDdY)B9aG`d1eMmBY`+ dXl@b`0aeS*fYlf2ZbGhAE63!-(IpCfGVA@$AkX'k9d"fV9lih6FHhV@k23k1%X# iDiZj0TJUpR*9*rCTe5If6P8"pN@e#+0+l'ID82MHeYIHU5m8FS-Ai+rch)0i,ES 59mHak&@ZD1*Bj%34GhTEJM@ZLXRe+rSSGj-K)+q$R-(RdVfFI##1'R,feTPI(mY H@bVjlY1ieVQ(3q3l-@CiSMl1maq'UY5T3P91AS@kHE+P2US!FE68SNJ"BJb!G-C KX*km*XlSj&Be9!(bBG8q&5!1TrEea$'JpKd6ef[U8&((X@)+hLZXaf%IXlA(QRb NSGjT(HKHIQLRYIIG"*10-#4a-Ia2Y`kmie2@j$0i6q)iPPA8PBrq1K19C8(MG,f LXPJJkSlMX+'LVE,EcmE4R`qVXUJ!p@T9&K8J$Si(CiNhmQVM-1@4H,-qpJ[mq4A dhB1c#d8$`(BME*GESak*"HD*cSH@i3qFeUDmifUXjeJ1S`,%-@YcZ#Q,rpUm`NU 9N`hT,4GkXMlbA1M*HY8$&'I,K3Ea!`3qc'ZFlm$TckXqS9acK&-pN9FE"jaUX$l kGX2Cf2c@ip9c"TL1VY6M0AL8T4k[JBhNf`*4#RV&"Sm#dL[@$L!2piTe)V8@d#[ Q-IICEMJq,iVQc"2-ADPJTLS!FZS+509rDS0b&""04h'CP00c&!)Y4JHDP$0iP+9 *130D6&XJ'S%@FpFE-R&ReG'h*Zl8f[m6ADD+r[rl'*bq-8IJIZE9(XFMc+XV)@Z B9bd1G@)q`J$cDJY%&jLci-9K9hrV2!4K0Vcf5%(h1cS!)l"aU"*c(qb-d(3b*65 El$QYaZd@b(4CqMBY(M52ZliEHQ9M'c#i2FM0P5e8$4iFKjAiY6BX+1"""T1FNbY dJmVFCS0FXhR3G5TZ'*R8!-,KJH',CLZ[%Klibf$UDBJ3i%&+im(4F4MFkiCE)VX 81hl&#5XcDhBf&dTj1lGLYHHEc0$"iB(Gi1eH2,#hiq[e`&p4E)jKKp+Q)EpFDeB -B53L`)2F"6``V&)P!i-B$qUe[MJIiaVRaHBfL6(!J`D0"mf&)(6l-F"cUAeVGQR f$Y-D-J4i-03SYrp8rH#(H+e1QVcc16eTmS)pHhQhrFiVEh`-IM+amS"NQid`MXV *ah(qhPDrX`S3"bHHa&Q1Scq[0SjS%ZGMFD`MfNcLe(PhiGEL-(2G@B-jHFIFqB8 !DS`D$ClU-a@KmZ#(3P%81L#Q*Df,-mQelcADK1@B&hYLdLY`3C@Tqk"@e`8BF$+ PVZ`k0maYR,PVPY[mdp2`UhY0&kEK+dbch,EC[QTfQrd8l@kEI6I8bfbcch9HY-@ '[eH[Gac(5K$UdL`h6@!'fc&RF&TQX&QJGUj&R0DhCV!*iqiDLDpr-'i&D#+qXX$ FGD#*q$h-hDQ1HJ"cehmQi[FbGa0((hRh*pN2eVd#-XQqI518KbICGfq@SJ3`lYV Bd`C6aG46G@*DU6iae9-&Q-CT%8D9Q(lC82MH6(h[e"F+ZF%,m0GjlN'm&Pf*Uq0 Bp#TA0('`N3UlV#h"qP,&j2S9IC6laMihIMi'1B22TAXjq8!F0H6XV61r2TDGAjf Rlc5H@ceSH+)qUJ$E(9Re83@)`fi-j+ddmm4f4eBe9!(bBG8q&5!1TrEea$'JpYP 0IrDGe('XQ%*V9bkc!IBa@hXb#picTCl0,0[pI2jBaMlq0*lF#0Md)rKr)V0Xakl -J[Yl@R(B6AqkmY&ICk+b,'LFVPFN&JY%hA(B6ApB3@H`lYH4FEDH5Var4+QhUhS 8Rf!R3k!%$U9I34%F!hXGr4Drk*Hm$CFTm&[`SYp"b,@0`m5ArV[8EacLb1h8mB9 q8ri02H6iQIK#[pce6-U5%*-D8Srm"!1@Z1P`f&6lA8hq,+0KNlq#bfMYYr8kf0, Lpiqi[%ll[HVhBE-6FFbc+h'CTIefr%rB-YS[mbjFGY*qKe0&c%SFKq%b62Z0''@ #2,pkeZ66Y0mV+!h8LprjDAbAr4PX$GT[&YkV%lmcri)jP[Sl0-hIf1YJDj3mc@, aH(lAI!kfSGV[5Ya(6QUrec2QB9)h*Rr*bl6IFhi"$X-PIfp2icYS#@`M*$jkZDA 12[)SE$*e0r90[ZhjAI8EX+fRr5Eq)f,*DVp2rMSFeYGqDHCJ9qdhNrNE*AiS'", (jc%[)%&IFcEl+Z,iM[Dlp!rJX)'m4fe*RYl(q-D)(ja(mM6Qil"Y+29+rMkMr4V [Kmh-(1"-[J[aED6p2[4j1)b9ZV`&Phr3IVGYC@e*I1$K91fAr&[B0YCq@i%LT+l 5IZ1"R3BmlGNCqFL+hrmRTQbLrDlp,D9ZreAYYmRli$"HiUB1QZTa4(`0jJ-I"lc -A9k2%b8qm,Z#1GZT(YH#&rfbR-Sb%Zq"Zi&ITSfAYbk&EB,NPGjl`F[YEf%1a1p 6DCfGmb8@YZGAYb2&baXHipZHAm0c+CiYrKCXB$,i$Ii+ASjqNS8Rq3"h"#q[fm1 #Pr`&H(R1Jl"Y,Ri"APlr-'aED,pRSCiGAYj1UMK&hU11*AqR%+Zf&$rm"5q[r%[ BRU,pIJqqi[$b3YDD-0qY%C2$bj2*pm"rkZ-EDA`R6I!KL3qFPMVEmcq)'B+lm!I "Z4mr!"XBLrYC+9kqm5[-[G66Ue+mI!qaH9["LHPT(&mMAX+c#-GJSF2,",'"GbK 2kP,bG!1aLGSR4A5)1$`!#lEAIT2)C`3[,bl"*NaaK`qQH(RV(m&K4qfh,IQ@i1A EISUe,[J0(a5m[)*[lDcpGQ[Mj@h$F*!!jH(R!HFFALlq'KbHVQR*0RHQH$Q+@,+ ,e-GAfRJCM2qqj'l%XE[JCH!hLGaa1m(,`'m)ih&i'ILPb!@P2Tlk0l#4@r*Um0[ KjCA%ledP2QT1kZc`hfDL2ErYbGm%,ep22+Ep(CJLli*EArJBE(YS[fPrQZ,Pa&q #66TRXXqRH,PL(fbLFk6"NaaHAXJF5QG,(AQ&a2I0Ai4Y6qehiKqRH2PAa'p4N!$ Vb*mNIqpRE(Y,RXj-mA*pjY@EqT4Fm1piEUAJ,TaX(rhH(QfmA%iXJCm5"fp,I#h %*1QIQda-NMSlLEJLR8[6b$m&jmiQ&jqYrIB%hMZm[14hi'$``Ej(6)+Aej',Jbh iAC6'F5jjJmJZHk%q(&iZ*0Bq5rY0*rj+RTBr""ZF$VVaZ642biJ0B#2PDI$EiH@ AbDHT"FV(e+[$bjh*Ep!FJ%eU9r"b(UIc'4jUiciPaFZ0JE@*pGT[[cp*mI)kmJ$ iK6NI!'Bi[2`B1I1cG9dHqB88,hFj$!pUJIT$jh"i+GS(jdc`[15Ni'AJ0iAmbH# LaF[!EpT[Y[%bm%Z59dPpI*eBF,MNP9S4["a1V[NFmD1HT-jH4ildA1fh$r8&`FY Pe%@S+D!ERZP`#hjTF0lQJhS@[(cAVm%QBaLQNC-*ATllpb3BJZZSYB+A%iJ(SVe YGbb0lmANZk,Y[B6kP[KY34e6CY[X3'b@r0e%M*-fcHRNQS+A1j%EH$05NKp'R'1 1DEmINJG,*qi,`*-FA[k#'STSYp[pAKVIHBa9G,3TU'pACkHq!*YSIY-CNq$FeF$ QK-b,13BjFhMj9Sb%6)KqYcejM1$PiG4LT0GN1rT,(*H6diUZYq#p+9jqqY0`!"H )JjJN6krKV"p4`lFR,j%mEF`D4NXK,H#Ji1A6'+[SM)ZJ[cLm2*Fi)4VY-ZCAm2* %DMSLbHj!RL"iq@R@J@M-bm'j(9lq(&T8iKjGIam!IMLm(%mF29Rlr46jFRKj+$8 iF"K)3@piRZ#PD)+mpaABXPA"blaIiJEU#%m9[!cmTMrEaXXJMXZ"H80fe12a%hV RUG$*8ZqU0b+m&rJP(rd%kHQFI"5$"i-Vbl9M#hQ8k+cKHlH3!,0HJELTSl`1P(` RmI9GiKI`hHfSkd`4[cbZ*jmK6VpEr-+m`J1pHXS9b'@Pl@N,mQ#[,ZXAIK%fJaZ F$2@b1[hH(G3EL*Hb44mm8[[G6Ui#9b8qH*6%GaUj,"J)VX-$[2KbRbAA28hi-EM Xa9Ir0QT2D%(Q["4eiq+lJ*S)'L$a`4-N[SA%TjGU[eR8!b5qle,MJH06#)D(ZIa pQ*J1,mBG29(LZikjHCR%"cjimG9I`YK@#+lJ*r8aQI8%Ic3R4je4i[[GRm-'Ib% qkNVLZj2m!"hET1-fmP5(6k*0@lpcfrT(i(FYkm$9IGi[XBakXF1R`'mcBVc"!iY RiA[SJ"kr56[%mPGS@M84[%IdJ26lQ5HiQ)RlBq#lJV[T@mK4iGVQ[C2q1FAG9c0 'Y&ac,J$IGRcSDq4fF'Ii"2U(ac252F6DFk5Hi1FHcdM[)[kCr&XrH+E`Q'p4DhZ YpVX314!qP"iMpiCVQc1(r-rM3qQ0V'NdEH))G1lINp2)I,9hJhm+(dU2Ne[#Lm& 4p'M*pa*biMF*6S0(`PFZ*FGlXkk2VB!"`Lr6%rm%MlISpqUTqhKiN!$k0,A5m`3 2i(NH(U3[I4`fH)Sj-mR62"kF(L5Z[&AL[V6&Jp2[q#[Bi(fm"bmAhRB4-4&1C-l 1e1Q&YhfF@K5kM6NA8lrcH&ZkcYk'GfUrba'IifdhrLiaaX[VjSa2H0Y[L4pS0G" -G%b[$Y*CBMcDPhP[#qJi`Y[5%p-X91%(m$e22dL[*0E!LkPAHM)NIbZTlD,cQ$L f*)I`p)2dce+c)`r!0Ca*H2a9j-GSX15E@Tp6MdlUj5h8aTaI`*0QNSXi[i!2c54 2FRiKARVkiY+B[$M35rCKAEj5hJ[mIJ1p1h9jNUI%8HTKk2!Q-pm(,dhIT[d1BKh 3L`%Y3Xrem$LaQhAc'IhH-,cViVL'@(+YaYf$`&YF(*qKaJE1%`FkQX6aEFB0"c& aI"BDLBYM"6'#2"ZA`q$RiMLEqLkp+Y3C[%AL1),FiJXkMXmM6KI(qiMTD1r'j3M JZSYM-6RLPb31F%(LZ)Rp&YIT1,k)ZR4aI*4B5*dDPk1KJlXi2XLk"1XSIl3LLH2 ja#`dFh!&A"jC4eGp[[D)lcTbeQ[UcSR*"kNUq'95kdEVr4be'hTYM-X0j'F(DVm [8DG%PcCq2q,lEp"q9e&MqUU1B`(i3l*,qcfEq!eI0Rl(!YGFI#mL$ReGah%,DdA Lfihk"*c8[,H3!1p+I0qKCN%XaQm4Z)@,lf$@%RU4m6X1ElMi$UDfp@hYYjJp&K, IcG44d(2`ShG"iYZ)GIaGlAFmq*@,Ea4j#69Sr*B!peemdiK00fUr&l,H*,j[r3Y Xe*Ia1i&p)&jm)lr'RT-IL*r4+9emqj%6-LI8q#d&lVMihN&-[%Rl,5-[P2KfTTk (lQ(m6U3q*2QE6SdC63mr%ir%0r*Ib3R41Fhj,I5BP1CEfF[)-@i9(J"IpRK**U+ Q5Bm'IPHhr,*AXeF"M))(`*RN[E-38d*V-XPVJ)-5AqB&kJeSN[!!F%lL1)$F#ld )I)+hL0mfl)'jAIYG3Je-i[X9miI'CDPS2ViEU(R"*AN2,86H1i9F!3k,(jaBr+i J2[e-r-LPq"e,V$%mRILqali0LHq9V$&UQIIS%j!!pdiR6d+(a`ppA2bqb2GqUIf Z)0q3!,cZ32hEp2F4hdh3#9amCj-hd`-#Rb1r%XG#iJ6F$6rUhZ@9RSTIDlqR%2X P[JR%H0j*r$m!N!30%&4ME'&`F'aPFf0bDA"d,VQE&S)!N!J'QaL%6Y`!N"!f-`! !LqN!N!6rN!4069"b3eG*43%!VpMr&l-G%'N!N!8",,%!N!BF23!!PT`!N!Cm``l i"Q9RdaadREpZ'fLaEZ9qEQ1j(5LRf8AEp$Lpc5aYfm"@jXQpPD[IAVqYek*jMEa mbl0[dMRTICFchdkb*le$bd(1HLml6[B%lKGZVr-@[T`c1i'am)UrV!(h((#ec%Y Z6rDPej0I"Q6E!)![!"h`c!H`eQbfhA'FL11%&MLKJ`pd3SG81mkd$SPjH5JF%Y1 FQQaEXL@4bk@bZ9K6,RY@XVAJaeT9MMF3KmSrV,l(QIPacqRbMkV[E2PAU1m+q8p 3hj[NAkQq6mTrS[TZN!$r*#f6HUV8pc!a*U[[*$'QU1md-DDUlqPL6&2I*@*-9pr 9BXa3hh[&Q+Qq,iXa5hfhLc(Eq-+(L('!qSi6BilkRLM'A2APaCLR[S[%Q+qqeiT aS2VH,mC"kVYHM)FBAi6jHDMk$K2MB2@Y%S2Dm@h@qF,h3M&Lk[X,-CJ&I-`0qI& p@ib('eq8HAL%qKD*m8Me0B[a+29Pa$KFI5m5Bi(khLc'%HVlY"L29Yp0BL`d[JT QjNMe(5['8HTMlZ2U1dH-SpAh+M(S!llhL,&BI9m8BiRkIL6'-FBhJ6PCUVlMaAL -qK*L8#qqjiVa@28ahm[8ph%aQ&Pmc-4bikX%&m!SI04'AIM@LA'#qMV&1&&p,a- $R-(hEM&@U1qIa4"Zi2Tq,-E*aMH4HDj4(c@X90q6a+K9hh2%B-Ea[9k-eHVlHc& 184mpUc1q5H$4'[8a'ipAAj-BpHS$maV8"lkHUVkhLG'S[Xq,38jmha2M#FCA"@D Y94rc!clJDa'$ZF$(6)#aq&iUaRVe84pjm(e1M!hUq`ma`%RJ'Y`%%r#"#m`#2[V eC29Y%H-TkJ0(RkUq2aIM$29p4)bRUHpEBS!$8!!i`%EeJ91YkU1q0[@G*8C5IFm 6idcerDNBQp3(6S1hq1!%+IAG+JEjS4MJ2Vh#"hl!&r(4Zl6kQ'p`&GpVa-LU$db #5q*M[TPCU!Sm*kFqm"&1JBpC8Q)jl9PL-)2iAL('-p6hB6(J9[KZ&Q1Vm8fR6p[ 8"eD#`rLBRcp5h`[%H+EkrP+-FpAhGf*3,ll[L('HmFd!KmjA(lMjE28a9r3Fhi9 LJ-Ri`'0Q$GpRa(LqqQi4JpVPc)52AD!qqN4qI23*[S-221#2$ljiXISq*3Em$Ym 2aGKZI,2JACHU$pb(eq"M4Lp6(hfjA(e[%'1(qX"Jm"-I'(1PmFf'+ekP2M$XaFC RF6MJ&(`D(JerKMI$*q(Ei!Pm@AQbbmI"52JJr!Fqc0c48cJFF`h2"DI"$IJXR)! jJYH$0@!-f!+Q`+ZB+qB@,Z9a-lJ$(!VH!fF#(jPc-"+1"Ml#Rq"0m#9i%[`)AJ3 IJJI"Im!!Z!qF"ki$a`(,`3F`!5`!Am%"jTqj"pr!0I!-()2$`&fBIAJ,I!8H"-q "Vi#Ym"0i%PJ"4X1(`'Hi#K`&EJ*Q`%AJ)'!5R!1Z!Bl!-q!Ai"pm!Ki"[`*A`"2 `(5`"3m!1-"jX"p2"FRJpI"jmKF[$iH'mF(mi20`GcSjf!"l$4p!)i#,`GhJlI"f H$Zq"Pm2(iH&J&&J0piC6`,AKf2"(1#VB$@E$CF"Vm&$aHIm"reiYd#'ck8SNq'Y 9%9UPLSlb@PmR!RFmRBJqHMS4IICd)[VMk84JK+F6-EZH6X4FHMS4Xk!kNBX*UK1 j'1$K(hLL1T(c*iU$R,FS(R)qU2hK`'09*h+qT$M*Z9(aNS01S6T4L,kS6K5L"Y@ *3XbckN3Km%peSK!BS6T4#-a3R5M%2+T1&!*$9#F+[9*R&YpIkHcJZeDa!Yq(&%r `d6r9L8*I9@c""jG6R5L%CU%k8CMqU8i8TSqU%iA*UcT4'2a3R5J-[UY1&!Bc95F +Jj@U%i@C5p@*`[49GD)`h&9eS[#l&+I``Be9*`UM"kP1&+CrUK1&Ee--!cUB2G@ *)[4#GD))[9'G+!*QU%i8!Hp9*iU![kS64F")eBNLc*cU4"&d!G@*)Qp9MS-2h9" eSJMm8h@L#,UHkN34H+2U4"&`3R@L+"LR1P%8A&#G+-SFUNi8C3C8*iT5JqT%8AL 3!1*T&2kL1P%8hU%k8441S6T4&"kN1P%8cU3k843HSMT4p(9LU%i8"3Y9*iSbPkS 64Dm63h@Lk'I&8*dSqJda9#H+rN!-eBNU`(69L5V!10@*+TKjeBNX#iIHd612$i* rB*V(2HQ9acrK*[!(jK(X!pI!22!3h!(2`$G`!8i!6f(q2Gl+())Ii!!B!HpKKZ% -c#@c!GBciq!2H!3fJ$rJ'CJ!6S)6F!@2Nc0(m##i!9J0,`$Ai$hJ2eJ2IRYFQCP MaTPYCKVZ`$c$QF!I6rF%0cfZb!&2i8PJ,a`*h)9$`5Y+ZJ(iUKaNl(KmVhKj`VC ``P+jFUIq`dc'D)lmQ@F`5RKqKFb*5c%0CXdjpRf9$j14UT)d8CPpbASH0`9f@M+ IGl3k*"(b0jr13UAih*rVRUT*Tc3N@Np**YU5ZAaFPFMH@[TLr!,9TmIMd6eGd,' F,2qTmTmQrqRbRb(r+I+I+2p+q9I*2aV8TSR$"%3L@",YK'D[Dfe2G(5d*r1YZ94 ()ClIh+jDl0e(dYHl1Gf+9YD[hY#k*GA'VCU@jUBDdm0LqGl-$NfIDE3l+)+CdpF NRT'SD8rNmmPmr*b8UUr&FhTG8fa0pAT3Q+`H@QN"&E5%GVYYX$G!Q&ALP$!N*-- #!h'9'dqqmM((dkrm!%L8+`ji!Djk"3j9Q)&PGQ&IRV)$ir&Q%T5Q6R*lDSq&S,G 5j#rl+5QVY(fq'ZGP@,UAH6a'1UXU5[q"HF9S2YMFK8bZ-p`G8Mk'DVK)lN1B)4` Kjq#'PM-%JDX"m'BA`!hpU&R9F1`b9crS3lhlJ,@V6c)Y"N-86hVB5Jr5Gl1ND3S mVP9e@P0G[#1A2$1P9alZQ'HeX,dEC0J6VceiKLLT*k+BG4e2MV5m(A12`Z8G)Yf J(S48%V5i(F$JGMQZT#Z)B*A$Ja#XY5)4chD@,i#I*+HkU8Q8fC!!h$EJMbUmiAd fK%C4HH!Id8*rTCC0DNMQ0L9MMF1p(clqA!`SIrr$pZm64lVd#&%!S[,R%X0Nq9I *Ii,m+q8r8Il6j$p$rY2P2l0EpR4@TA,j3U`jZ5QGc"5Fj3B5kP-EBhATMQbZ%%0 0D@KU+EP26V5hCl1Cf#R*pJkRS59@Fh60`S8Q88ZX+C&[6E5lhVA*FjbQfP@Pe-Z ,SpIGKqE08R02M+[PE1N*DT)*+l5fLpiX#A1*h,CiUrSEQkZlI$NR8)HSVLj651E 16,3QF6BN#Ql*$FheXE@GQ8)URC65iL[Vkpd3YamD&`rb540MUa),PUE1@0CfK!Q 8E!dYQNS#9)(U,F+%Z4Q$kD+ErJ5T8bF)VrbVmfPR3dhM+Rq-h,ML91&'LRD()5A `pbkRSk2eY6SFcR+*2BV'YN[K-NhGJ4,J"T*4r'B)L9`@Ad459pq@YYd4V0edidf %m@PidGNpZIeaT9TdbNa)ck$G@EPIPh3bR5eNqe#NQ(#m)AfjBXhCcPaVdQRHPLm Ndc&rh%KM*Q03N!#-Gl4ZPVB+)X9Fl&-IlDe2CEBNFaSJcI!#DMVcK@`kp[MNYV1 cZEDm8phDQXcR"4F+QkAHK"3"B"F+UFbQ[1"hHc,@)*eb[5GhTYVEBV9E#lP%hPQ Ch0LjD9-b&c-jR9AVQU5)6,+pe!q0%+b1e@66(9*0MSNACeYbG6,MqPDQmP#Vp%B [@"Z&beXMBL$-,m'iCGG)aZf,JQ,GfPKMKk"KkKa*3FHp+[&e94Q-!bi"2'0VY3B BYAH,Br@*c+E1K$66(iXPEQNaU5fC5a45fBac6,%E5f29E@dTSJ4RD8JfNhHEZES pZe&$LMfk)mJ#HYalpDJ(IJ3hSZ3HhEAcUN@QD03lTTDf`mfkSJCPF1&)ZANLGpH A[m2UKJYSL,emBD(J`TVEElp0pp"BfBlF1abp46"k5VF-0ZL@RJG1epf"dd+AK5D &G@q3!(IFQ`afJ@2AZ%X"F-2r&qYD3,Pjd(9rd*m0pjkdl!mBcm-0b*R&2#2hM3R R&XTBiakm)154qrUPqaMZ(32VkZQlHfGC19Difr(ZmEEhqFF+Xb[(!R$11#0I513 X$j[&3l+"a9pCpGXqfKfDk@d8XXmFDma5UrZ@Z9@i1f'k0KIK0)Z+F))fl'lbpP6 elE$bY[DbNmME6'S,12qp0D&Eb9MHHh@k*lcl*R9hE1r&kTl`lR[@2F&GekjlBNZ AUAH&GYekhK@[Pk"h4AThSAY(S2XLGRqdIa1k0pTFdqk*kVUeh42,iJh@1A6FXG( "K!ifbBeGhp!EY[0HHNm#hBe`ChFer-lfPQkFl`SG(XAJ2[UZ5+kRpi800,rVmRT 2E0Fpr&dbh9k%-cR+-'F5M'#Gb6%-H#C$'I9-JL(S+mDAKkkBT(rbLZ%$FkEc-Jb (T45$S+%TqS$4K*E4d53BJXJJIVL&!f"TBNF4df3CJFfZ((['B!K!Lr&M!ldE5S[ K1r%dL#e25KPC6B)b[*TY-h[a9C18!9BcM##X*KQ'@%e4aPM0-!5b3B,b8!CCqUF bL"mB2@p`KS'f+mFJa(JjqU"@BmYBUaQ'`,D8B%mM"q"@JdIa9Y1-!'jhNT&a'), F)-'qmGi0ZN(m6Y3Y"3q26"Ph08-CH#AjAY3P3aPb#4r"@c)-JbhaCD3PI!KQ[HM b%(STqLI3#akB-(FkKU'eQ'!350`%ID"+B"P4#4q#8cpkU'd$3%VN+)U5B`4#J`c PYJq"TaHpGfKh`kBA["-crFMGFe&'5m+lS&+VL,RS9Cr+$r$HhNe2I6Q+fjrkSVF Z1eD`Vc9TPL%0)rP)V4kc(5a@`mHVC4*'5R9"IE"1BXH,0,h[far9PfIR6UQq,-' HUEl`rYe6r81bVbfDD,3[QQChBc4q[$1-eEkfN!"PY#INf0d3JXHldB0pZQK[YdT iaak[1a@QrBPD8TQeN!#,XU)'!!fVCF6[Vj9%CF@-m$hdI1q)"!V2hRB%HX$GQIC -58!'pLJFih-5C"T@1BBQTBYZ$)b*ap2hYX,MIq0TpNb(4f''q1[iA(KTGR2BdN4 B1NjBAJJ42&("lR)11,bQF@AYiE($9eD[UaDcUDjQR6jpa*CbZ-%@GZqTm334hMa KQpZ"$KiXhi3NN@UeYJ'$K`GL4Lad1r("!h-eSEQcJqhDbr90+cBeP!M``2#$KQ3 KPcdlQGZ5Mc8A%TQf4+j0Yhp[@mk1GlR-JT90Tl1Cj8fG'pY6VE'k6'YlCe[5$JB E!4j%Iii(`L+XC'$3M3F94NpDhT!!c5@jRT@2,Bi[M4pR@e-8!MbBG2m,,Q4(NGd -'Hiq$FeeY62GKfPNj2TblGD1GQ%6pqqMV%ZDY2(N9RdTSRhY6(+L"`kpHQ2rmCq cC3diqpC`Qf-9Z,89lAd*8dKHQ0EchTA&FAfJR6hP52Y&M+V,b&AD4,[F%&b95jL R[YalIVrrcY5r,TP,Tc+*`Ur,GmIBLVV-ch[Bf%'$liMKR6IQl"i@&[,&S%$bReQ HU9*Ni(X`JD"(Z3m`P1G$qNq##(F*-clRN!!m8)ljihPJc`H1jf&jDFc2`e2r"[V $!Y1MaZYK)@Tmm!N8qSaF0`rFDrCi26a2F[VS8bNN$mq@((Y5KH6KDC12(Fr$mbG R@*5ID1%r-5*BqQCG2Ie2HE1V(([F%b2XFJZUI&dJf#YUA6dlAr0SA6Rf1&h!&[0 d-T[C!faX#!pYeHZU[!(PIkqi-bR1lfqh2h$&I@,IkjhY,cX,A2ciGD5A),MGYQm A6k8rJ-@XT4*$!8-TaBe9TXqUS6VH8mPEkCHc-fVZi#08!dLa$#cLq0R)"I5[*&U E&pA+U`4@bRYX-[,#f)%([YY,MJ9'Y$C[qRqFiZ6aZXML"+9I*bS5RU624eqK+(Q bfM8D[e,ce@VFHV9ADGaUIAI3+Hi9@EP%V[@X8BQJA[d0QVG&l9-eIk2fT8Rc2%' hF6P9TcDH@Ye3'krG8$[3AAFeX&ZN''V[&$rkH)+qfplfGQb"'lc#cS46XjQ4i3m e0$4C!1i,`AEFKjN-AcqDD96PhjfRbCme0RD!1QSD,aQl25T2TkDaHh,8Y1IcGS! keTb91c-Zr`IkbNU'KTDDPAD!q9ME[0B#F*''1YE9EPJAhcJLm(3prh[`Z(9X,U3 I'(lQ`khMV*&T['YHh6VfBLI2&4mp2#6p$rJ"!TqHkPMeKcSiEGR@6M[!h1IbZ9B l3"fFZ1LE`bKl9erG1RBpj2fAGBaYBAL)IB,T0$68RcbDTqGjlJ1GEkSI3jMpG9J $'%VMb@[f)@Ih1q2lMk@#kHc&cUihdZqTBq&#@d!G)`hj@4el!2JrkaK&mV[V%*R X$l0[Q1R[jY9RTRZldIdFrR)r1Z6*8CD!1Z5YmErT+jIl[$U'NHKRGA6XBDHMIIA VX!)`GlH1I0)#m&4Tq`6M[ZZUN!!m8QU-9q8,RCD!1MKa'C)(qYS%0J42Y1drPIB *jQkTB+C@!15d+b$9A@GXJiEp3p2C[46KINeRU!klLHTmVaC6AMha#beQV)jlY*L a1Zl4B[E9FEF@-eU(I8','Hc(Vl@BSFEHTm@-eR'2&M0BaUqdQ,%klY9L"JUa%@J a)cR-)qP'FQbSD4cM3q6`9B["'E&qD$UlJHKq6@I2-KilJ+BMladlCNNXH)pBljR k#`BRKHa"Q(XCh&JGpc#iX6VZBA$lkVLE`Bh@dCEmlIde[ijl'GaJ2iS-lKl'0&M (VaM6D"el`9cUF"r`0MSMGJ$NG1YS(hQPGk$mP#GIkXKZ2'ZiMXD0CqfV``UccG! 5F`EINY#e0U9rGB+%G1q)lpkYlQH5+"Bk&(HV$qAKFFS(M1GKDF1Fm6`XP*JlRQI rcRR*`mlj)dChb8X81qFAMGI0M[LaAI+5KahaBl[N*3p%E'bA[2ZfL2&GmT+(44j ,r&hCJhhd!qbV1q)II00XI1KqA2[N"rd2MfZIm+"liA(Y9DicXVDaF9dT3f6efY- mY6`bShPE[T!!6#YM5#@jEc4a99ep,Hq49AX+0V[Le+j8fm[MqXAfr&9"JH'$j'e 1(Kq*#6f*0@m@K9liD4XhPLXdj@3YU8TYebpa8p@H&*38QLSP06CAar,CcPbVAiA d1U,CTUNp3qhT'Kqpm-),(If(&ccU'Xqhqaqe!QaX$1pmVpP[CYXHYd0bhb1pqR$ #$SFG0JT1Ba0iF0CrSH*ST(hfc0(eYADkIGDffe0N6[DlBq2P9(B6ACXcm&K,+92 HEKS99qN*ThFHPXMiV4jZRB@#I[cQ*KZ[TP$E[5KQCEM**VCl*dhXRppN%pYVf%b eh4YY%KIGFG@+,5%!ikHh91kiq(`0Qi0GZH-U4rhce*l[A(rpp9erEm$0V(G"Kcl #e6Ccl$-6BHA"$iX+6l21c(d`UcCER(c`6I1b%d[FIUB92j,(XcVTI+'(bB8@L$a r[X6eU+F6VjD,cX4PZZ-Q5cjRJF5PZZ0L4dT1V5pb3j!!6b!aU[@9iUCr@QVAqNT aLk51#LGGF0AF!,PQ!UhR5aaD4#P1kR"Lk8+q0pmYBXb3!(cd+BJlJ&HV6NNAfV2 GFE-`Y+qPIXcl*jQ$)p-GqCki"G+R#IAT`UDH[XjL2JlUb!PIUjM%UemIBZ)1BNR p)MFZHLjDb800h'1SBiV*9mA,5JifF9HpAh*HBq,129i#$Y(q(5KYUc4affk@J%1 eEP6V!dap(k5CHS0[eRSaUNbqTrbEq"kQFI#+D5EIGrp-I)HCZ2K@U@q#bAIB64, `F-dRFFk**ZldDm6h#)hlC,'1FjmZ[NHDZ-FYNcUqD2)G"HpkP1El!20RiKC`AH4 `%cHE1Z+QMZd[BX"-h195Gl41medT!8GS[Y[%L'UqeiM[d4Uh5)b0*ZjV2a@IXXX 9e,h-a&hh&[(*h,RcK$(9a,e)CXXj5Z[BiFp6aI(d0DlpHlXr6p(h[%&m4jZi%jL j$jPmQei&N!"TR1"(D,l*pc``DE'*1f5*'&HEI20jF5eq1A0Ilmp"aE)EaAH-L9X Rq"h@Z9Rb#3PBDZ)+-LXqAJD,*HBJlAPi'F60AF-`+&k@iLi+m$+)Qr8Y&aF0AJC aXepAa,Q(9`0N*Uj&AZNllAc6lhF5S+adQr6*`lQ6'L6JX5EZ(GF@FDk5Qb##'j` 6[e2%ZFGr4!+1dclpBa(RVRb*q26*%,2qY6LA9h`A!0)q[Dq)6cGr5(aJUCb8B+f (FjZBN41d[[r[iecdeVAiP!I!jddG&BHb)1dN%lG&0Taj1(I)jjJYcBIZBrSG[HQ (iQ0'L!2[&1Gq`TBd[@f5&&caF#lcAJP3V@)f2-(JA%AiSq,6fb#(JRF'jbUUi65 kY'hH+iXiGj2-N!#MUZZmdhbFUeMk-['YeVKR&R%Zqc(aRD*eJfI+'pBcHh8QV[e ,2Xj&Vf(Q`4-jDH%3LR-9Tp-R[A0fp,1+1,IaUH,6fck(-SZ+Fj@[&KqB)1Hm2rC a,RS*f(UULAZVi)52Fm&6JeF`2al1"A'(J!FH,`cL1["j1"I%ZA6T5-@j)1iNX-6 JA240l,PV0('I&Ce)FDjL25mr9ZRRfB,ILR24Ve2l%pb`8'Kl%HF5cj!!#,"&6ZC [I*b,IKibdUapj9A(LR-IJ*rT0VNj0%TalK*LQ'[Qq,)L2NAJE2!q14I)h(Ji9ip Jh@,LX[!KjA02Hl(i0ZKFhPUXBmhPiRZLLE[`A6l14Dq&rjeZiVC2+I+jiliK[LI Tr-(2G,kIbG`m@HG2m%Ka,[Uk-b6J+BVIk*Z+Fa14'F%+14GG8H4cE`6Eb%QI,LR Lh'[QLNpA'XapHC(2r3ZekG+"&Fb%cY0Ai"kUckh!TcKA!6p@rHmLjPljA1JUmE@ CZ)ZC!q9cRk!'[I+iAI35aERS9liZ2Y9VNbmSi[h,H8QdhQUp92$#`lPrJ+ZSR[V PVdPp+jVUm`8RqRhd#G9CjS$h6HPm,cqE)lc3M`Y`DcBi-82d$(K)S(0F)e`f20' YfhN$A&hea4X%Eb*,60`VH%'elR$TQ1hMRh2e+b!!*Zj'i60H(9H!ChVrip[#%l` khL(Fee(pk*,2&1[i'R`DR*AceEF9kh$R8[Ab@k9@VikYm#Gb8JHF@1[i`MI&ThV @pTHkrCDECm9HFbi$GrifRHLp(IL$RmKBZ(V-HEIrm')*d$XZhlX1V$AeYD0"&%c Fpp%'VM4aDpiX2Vf&mL24#d)c60b,iII-JT`I#jmdp6R1Fm$,XdhFEFb*eMIPMH* $9b&1p"k[[Lf#fFif%rF6`AH[[XPIP3#pX[06`4f[[T8IP`$G`ANl@+AeI3Vp!hj ((,a@khXcR2aF`dZ`[ITbk%R`06RrlppP,K@22`DfR+GiJ$kLH2pk0"%NH1,JL"V hcLp!K(3ZjiYaQ)Qli2RLHil'`GX0(Nmi(TlhA)f$ljNk*Ta'lZHCZ'pmAi`GTSj ,d6kS4FlPj&KMiQk#Ui#hdY+(b[cjr82$Z%$VJlGSRcE#Qbr812"Difk'(lp3im! AlGp(`3Pd%ZS'ql9ram)9L)@R-VGDap[4+Z!Ti"cm3r[hHA",q#$RQp5TrIX1-h# TLEY&jYRVhlB25`#D'2A4Gjf2fA!HH"paF$@Yqkqr6B0dMYpGl0peF#Gd,I+"jFV lA`*f`,2)"lrA1Vk#VSRQ*ZHlRbVfl`Ci&6J$AX+[62mQ6!0Vi*,1r`%!N!-0$P4 ME%aTBR*KFQPPFbkjA!DE&S)!N!J'QaL%%3#3%@mm!!$-$J#3"2q3"%e08(*$9dP &!3#[[Qq5Xad3G!#3"3*,e!#3"Mqe!!#ai3#3"J)l"[L1hGEYHFY*)`XM2-R#Rr" eQiYD2Z9dZh$))GYXImFZbSebEe1C4qKeHFZ)(jkY*r0NYdlikY%flBSFGc%p`TI M4cDK#q'AbfQppRPa`KG1&Mh#Lpr#&h),Ar5@)`[CHGEab-)AeR)H@Ci[C"1qm'Z 3!"lCD5jm16Z+&9lAXrVYj@NYl(X*!2Q&r%)f@Cl-0q(,5TE9[[1lhSDGPaHYma- C0[+XMrCfFNHGIClj[Cf6r#lG3TlIQ8%[KG[&bjNj@25bFlJF[k#@CpHHG-+6ped +6`HP$rFP*%XElJJNN!!F*$1i!E!!!Qle'r3f`62lP4fN22C`&pZ3!0mL@FlDE$- AJ)AJ$lMcdqZXe'K8Jb"B%!5jj8(qr'U3!2rr0`6"XPAir&NZRq2SIZP'1GS8YPU 94UX`fQTXLdT*apH5mX@c@SKmQ@T4af'r'!3Rf(hN3m'5e2I4B'&kILc)(mdTSEV Mmh1,cehqr4FPViSH!Lq[hV%Xl'p-(5jim-*pH(@3!21Qh%cZf2`9h5LmE(NZQ*e Y1ra`0UH2Ue(Zb2H"$`6"MmrU9bj1F1`aa8Bp,$81[e%b@"iFPlXr[lYccRmkNjG cMqHA,$JR1)GRH#%)[PS-IV$l-T(M0SkZl@qfSUf9kF1j1[cCfPC&c*0&JL[6Kr9 2#F8UK1FTY"rHfZMmblL4@ah&K&&R&e(iqUEj1-(VLTXZh9#UAKb&jDJe1MVir#Z eI'9jPj&ADVUkP6f*99kdec(0Hr*cp5CeBR9!N!"694m*KV!ll,h@lLe&*lJd[c# rCX(*A4"bFF!Yrk!q1*!!XPIqLFcaCppePmC*Q"i1p'TJF)Nf)Q44chh5XRDpCm% MJalk#mXr%r*[bcrZbjrAX3'3!$-,b(H@-4$,SDL1C'-2B*FH6Q3Ia`PDZA[cTq@ rN8(ZrQETBm19,Df`YA1PG61ULj@i&-`jEUR8a`B,JieDXe+0@RYGleaa2SilSU' SrUcIQNTpqhI$QDC*i,HmA%NDqd+YD06ha@J+ie*B2I!-iU[k-RXVpBPiVqqUF%I i3Y,Q[CG2*ke`Amcd9*`dDS9h4M[Ie@L9prR@PNT4("G'`f4bRf2G9+9DIMkEZ5[ Hq8+4i&GILF-iMQTE[[1N1,G@%'l&adbI-hMQQ3H+`h9YUihd4885bP9&NdUpjE( `khSXR&XI#lHQ04Fpje1XaUE"eA'0XYSE9IFkVSpf(AMAM@&V)NS+ie'522Z`+iK @A3bEcG4clSVY"e!ZF-bMA1!DS&c"6jkpi'DH12!6P!YF0-TPRbH2FUfqQ8S1I,- S9ha[`DA!YB"bJ@m@j3,(,-S&MJ(+&Ibb`&&`EUfJ!1@b,jC$Z4EAYYS3P-Y@KBp b"EqZar*4VZ!'bMAl&+Xa3,R!-BYbJ@-"jE,SN88jm%qe`MC-iYj#jM+HV@`ZieZ JFeP((q#cIJ'DHrQhXV@#FjD5C*ap,TMabC!!`Ba(-kYVIRQIL'9mLl`Zipa-l$+ HcF`ZieQJGPR(CVU8p5k@8i(GH3rA3Zrb[Zh&j"-mVd$b$#rV',jCRZ0Pr3c*bcQ e9@H"jQ8mQhPHaV0)p$aSb'+J+AlYYDB5lq1B$@1&N@C5U99flDH5'Nh@6590ZLr 0ITZ,HhdD`p,)H+%Bm5E&Cfc1-3GCIT)j4mNbip55CS$mf5bEHD!NfHbRFJamLLQ ZrRH`c$VRqD([f8*BI1F#,rGGmm65pm`ablaMRUhP[60d,HrRFE2J`3[XXYRATjH "Vq'A[Nqq3(h2A)8@(0XHaLYHhqPipEBd%PUFfjmcaihcMQ'jCGPahXqPa`@RiP2 R#E,[Q@I)[QGcjmEhcE9ZmSl&j`SBVA+Dhcr3(dp@Rd2$`$F,KS&M!3X$ha`8"Tj C*!`F!b!Xq'8,Xq!X$ee`Dh[R(!LfZ'C!)q[U3Q$JNNA!`$%!`'DriT-Bq!Ym@Y! [m#k!AkY[fc-'d&I`kbS`(rJ+EZ"HXdrV#fG4,h$-JPlJQ-Hm`$@![)*Ikc[P!Dq GqlAc[Ll1em(hfVPH'mm,19k4hl9aZdjHemRT#RbZRFZemEKf$YI-hij`YblHeXA Cf[KDb0@+2+fCSlAaXhCZ&[CY6(ZK2YSb06%4Y3S1(E+q+cD-IVI9$a3YRbj&&0Z qZN#Qd2BST"6iHLN9H[(0+@8E,F9Rm[!VqdjCNYMk8$k0E(NThcPiUMceE(XVmjJ c#X0KI@)U"$ADTKjQTMK3$4$XE)9+)ZXpkm!-b1c#kM)Y9a90S3XiTh,2PP!akm# r*H[!fmmkF'[,1PYMRBqG#G$qfKRhr(0Rr$VHfkr$pJIh!a4Ih(I22VR[erAQcI# fIUS1hpMjl162bQTMLm9ZD@+#f8F$J#r0!GVJeH4IQ-Ni'VdYr`)@Yce3#fS'"C! !*AI(iRH93"CM@aqTL0aH%H5EKmILGj4"(ZHE)eJF[PH`Am4q#IYPl'6X&1ar`Nl &UPR"b*ZaNl$6X61`-l%6X(q1rAhXTGL&f$(BIi2GMYf"[3bl%hXMGLaf((B@GME f,l"cX(1aml$cX8a(MX)Z`0CJ,mC@Bcq0r5Cf02B5l&H`r`(l(l&rKN@jB3rf,l& lX8bihSbp&EXIHaZ@%VX*qehXjl'hB2m!Ha$,c1AYf$Z`Em3bKRdBqbBXNjAI`ri cl0hB0f2[`6)BZ`Yl(rBYf$r%rKIX@l(hBlq!rEIBIiIp)b`6heABVf(lB`GJ88V SLaf)(B3GM+h%IKAlZeJ'E8GLbl'I`Pk0[3DE`Pk,I31@-H)NGJKf+2EVf'&B""N Za!l('Jf%%GL,dNP3Gc6dpl$I`$+TcMMT(f2r"2[[XAq+AB9GMIdfGJff%AXjYJ' l&VX1fi4Pc2YEf-pJ'F'r#PZ2r5cf1Zcef1ABEGJEX,AB1Z`9f2ABricGJ0f)hB6 GM&f"AB6GJVd5ZaLl"2Xjl(H`5fdHGLY@k8p%VXAq#[BGf!H`[i6pPpKhBKr%[Jh lcl'rLRdApYeBTI!4H6rf[GMhBGq2CC6pJpJ2B4r#IKMl-2EYf%H`Mf)I`rikpQ2 BMf1I`Mk0I4cl*2BCl,2Bjl!I`Ai8qca@cGa'lX$q"[BhX5pKAmCq![Z[X,q&r56 fYl(r'[Xlf#Gk(Z"ri9fSEE!1r$0[bc[a[V`VY8-Y8&2J+4J%pS+9B"re3le5mp3 2Y82G8!rJ,$9'6B%"B!Ke"KC3Xf!(p39fJ%R80V8'PS-Mi!9i!(C4Vp3Y1%a0Jp[ 81YK0hB19B$1B!)D"*f!F1!4ZJ&RJ0r`!cJ#'Jqe`"6J"'!q2J#H!@q!8I!,m!R[ "CX-Ci"p`($ii!MJ*2P$le$Qi3"f$!r!L-!+m!PqeJ)T`*[!%6!AM`9!i#rJ%jS* *B#eB"bF")`fQJA9J@B$jF"#$ph!)H"9m#Ji&Ti*(`G[JE)DE`GIJB(!l`rN-(i3 (`JF$$JJRJ*[!3H!Nm""i$R`$(J1hJH-BA)HI`)%-r`(l`2f!rm"M$%FXm%-iTZ' 'B#XB$NF`h!"1!2l$1ArdU9Fl-A9rr&[+9cXk5LdiZcFr+jI`GrPN,PZQqi%-+d# @fDqS95)1[N4+8F4&*$jF+35&"cNTPiaNK8S[LSeKbl$Pf"4f(,B#1aBl'$X`H%f UBL&Cqd)'C!!kNDLQ(VqUX#UDIJ2$jecGM,2D+Qi'C'QM8"cb#`#FVG)J3EUUT[l "rPd9-CIXYhAYD'(GkN[%V0VdFCKUk(Mr`LZ@[L1L,r*Jk%6&1L)qQEbX!4SA43@ I)fq5JD-i6j!!$GVa`9"1&X0C"4"Am-9rM"c+kJFp@qAjc+&FIB6N'Lbc#HVNYcf IMQhQ-m@&V5T'5D[aVULe25kN)c`E6KdVR*%EZ2f@h-$@94Y(#Q-A6`DR&FCeUM[ pP,F(ZI8dEdBrd(I+ZQ#LX&&%r[Jh4CbNAbeTUK'4"DA&d0[S$pH5#9S,-E89-pp 5'Sh4XfV0Q*JjcpT[LLFe$62e((eFV6cS[[lURZB`r[NhMDYPH[LQhF(1*m5U)VN c2pUAZfHp'J5I&fZ+j(rc`m(1VccC5C+@jRcRqBVD-jPA"PNM5jcRJfT@dUc3hle JM[-&jhQVfM'dFGbB8,A"c[1`'Q!d@I5h6+f3!!VRH8KY%pS%VLG0UXmkcbqUq84 c3Ap[SChL(1mm&kJ&4-Y"Ifp9-qUhRHFf0E&SRVJe3rY'mm0)rN6450T,qVZI*NV 8h[-90DaSDZR[!E9+ER#H[kZ@"DdDee-eBbiiaRNZ8Z1(#Y(I`hU21fY*E#+$h[F )N!$[2!)'0([@UQdd[CC8eBE+HG+F0EL4pG6Y'kQEVkL94a[-r@MBM('HrG4NSmR NIP5$[0Ule1+K[H9qa(M3UT!!CM(ejUP`b@H&NB+b!(af"b'b6"R6[V26I'A"JX8 d8DB`fM1e@P%$Z2QMDCGYh&N8UYE2fME4`(,I3[GIY2UFGH)c(E,6$eRiQ0P3Xdq TElX@YljAhH[K!i[Hm1%"5SKqiS$R*3dc28kjG58G@hZVrkmAe'4T@'$if1$6"dF ZA(0kiI3,9fpBcE&TlH!'0BmY+Tme4U!aCEa0$D&fmVE5CarJG5H(1b`%AharKdJ K!qdpfmpRLHMA+*J[M9-%`dQZCF$L5JhY@JpHTiLDUimSS0,+M"la"mUkrGHNmVA KalcKE[8[PEeVli#%k3B-R*ZA%5'3!%,CYAcKr*3YDZbLMKj,'PZ26[)2HbrBiT[ D'Gl"XQ(jIKVcTh&rPZqjZ+rPN@FI62QDk5mQC3h&Cb,A$'J`8D`()Y9(Ni&*A6j '8I3XQ[UBc$CYIbE1QH,P3eR"Y)%CrQ'dM23jZrXG4(*UU6(Kbae6Hc*hk@JFKLP IlTLQPPNk4hNcpFXGdp"-rA+(dJ(6[pbKjX")$AIrJ`26`$`eEmId-(G--M-ac4d 6`AVe"(A(m""e`4h6f%a"FmG80j23h$%ecN3dGdbp-aR0(3S0j-8G)e%b1K99h8Q h*+CmQ*lQMQ%D*ULjBmb'5@VZQ"4RSTSlD$Q6eG`aUFhB%(G-Y%Xl-UDh&mBDNk) &NpIFrAF16'"6cY3BNpMFN3-6fGa"VjR-jSka*8ChZ#0[TV@jBmUFL@hZQ%CRFTX l"V4i3qj3Qf$LQV[['ji!(H!)%pMFmHj-BR2(*$B6fGb"0pacaf3ldpRF-3A2P$C h61P6Tp`a[-A%0RI8(*2Eh&&c6(!$8q#DY!l+9EGk)P6Gm8CdZVNMEe3$Z'-)5KB r+*H+!1S"h$%acl3rG`apS3$!(HSI6#ecKl)&drAF8H[8-[!)MM#Gcaej5aFJSEb ah+%-`+3rGkJ(d&hJ$N8$BD%*$EA*)&a#UKSbqTD3!++)$,YTq*AaYU3`5!EDNUS h'@&,+RmC@NZUcQ4-,5PXNm'dT*39C"3YUFPk'6j,5Y9&aX#5HQmCr%Vq#`FCp8S *IaRZiJjX3Qf"1qU(i6RZm!(IZ'0`84UU+8hF`c@iSmji(qj3kT!!5Ib8P'*%)5% PE%-j!SS"6d$GJ6Y`M9VQMPUP[VJM0j3AZ11p'C6MM[G'HB)le#Y3FH!1*4[CFD" #G5Dp&deKi#2F`3&%G+G5q)AL!hI8YV66+[9H+$a`KaS%Si,F-@1-fJ4hU"$)B(Q PP(43cH$ZVcLJL+'q2Z*DdZ6Y)bk"ZJChi"dib4fecGYbaeZ6,hHS1-LdIamTDD" S`4e+)@!1G``$SVc"hArM3%cep4AhJhG`"kk!MGb"bbKiF!IZS#$"(6@$NJ4hR&' Di!iP#hJ%GbL6--,*(4b4fZIZ"acJGqVV*kk'%JGhm!Bp@+VZ`(f81VJ$(aQhj)l kep2lkSkh4XQ#1qS-p3[Z8!q"4h#(SJimMM[U'aa3Aj8i-$'jJcH!rpa4hf!bGq5 0+JPhi!U$RGa4Rp3AGq32,qD1["Q@j!k&(lJEGkJ484IF-9`,Ye*IIq%CBj[F`HY %[D@rDTda9Zl!EK4!Z!1c'(APMVT&FB8lhK(P&HiB*%9pK6X8Lm"BlP$ZiAfi8k1 r@K&$I32%ce&ei3kFJqGb"pm$*lQ$rm$&Z)-$N!!MGl`(DLrFJ3(`#1jiDhI#+E* 8I3*i$AG`#l#)1c!2p4VZrKF(X%*p!e86a131ESbU$AIJ%2bA1cJ5R*3lm*eK8ql !1'P@$e50S5l&(IkS3R'('K6+3pcp6`kS$UP[N!!i$4b%1lJd[)ml-*ikiJkq39e c"rDJfX3GlmfS-hIN#HC`4ph$@lQMlX&mp3e@$`)9,Hl!'cJ)Gq!k0F)GA)@aE1l !5T5@Z+0@iBEFN30icKfFQ,G9ha#442S$h0%M!(ZjJl[5-q%1RJDAjikk3@Q+1l! -95MZU#9`JcX8Qq"PkKXUcShL&hId2P$RiJlZcCYc"rFM*RIN"jIN$Ra%`BNlDJ9 e*ZiiSlDP[Q(L",`RGf!!Z-dG2%q'f)H*"l""M+hQ8bc5P3he"6bYUjm[CQPV+3! efbY09G[EPqLXMI-2R`9Lr4heH#QRJ+e%Y2mZKFa`)q83[h"iD(0THk8XhHSYikb #G,`meKdC4R6QC%l16Z,r[IjB`'kD@P%TeG6H&C8,EKMaS1Kr0E1*N94hH*HlDfb d)SQX(c`V&H(HPK6HK0rqB'k-F@Uc0"NNT5VaDk[94UQrC,ITbE$HZ9aHhp'jUem reVPE-9JVCjFUeFaP3cf*@P20T1Z`+lYF2YfpA0Y)+PYhGUk9Y2@Zl"R@4h&MUPA +%Y[3+'h[A'j%JcGcZDPHQFiZ$e@URFXeM9$2G##DL+DEcUXfhPQh,1[#Z*e`AD9 1KEPhkHeK9K"TEL4YpH5e&hHZ'SBl9idrD9Hk119GZ&`qh@bjfrS`-Ep-45hI%G@ Y&TC24k@TGJ#[Y+LVY@(lS9G'&Zhb-*kd'lA,aVlfXcA8bp(db*CYl9Y9K[,N$52 YXeFF$51G0'NEQCZ$55F$U4eG5,X-%AL0JjC98,fCS%eK+lEhDYSqB4F(SMKUl@L l(@LA9P-MVNb2*eBKkN+*BfF5SF$&dhZdcD&FpS"Z0`VGTTBETH$##UK)&D3E6Ed '4@1Z0M3Gr(&hHjA(1D6#bD#Mh09(mIDNd5a1+,Q-XlZ(J2)iQ,6UT6#15M8p[#p GAF4M(9m['P,!AUQSYBfk#L'3!*q1!"2l@SRE6%4l9*HN*$kZ31&S$05krXVI69Z *&ZaT*!h3A&af%8!`NZK6`6U$Ifj)$`rPAU[mCj4V*#&G6VAVapF@"[[PbY0X!$1 Zl0aU8,Na,%@kE+5DG!K1)SZYSc4ZXPXZDqB5j@NEDZPM+jI)"F,CIA9+ClHi5E9 E[3"2G5QE$A#VPJQ)Z$8$)TX(4bkkD#i(YD"!F+h60FS1IVT-E$H1EYTlE4+@5dQ B@cmTVNR+E-B3+Bi2GqZ$feb0H2le`m2TV95$FGQ3!*3(1k%,YE-GpIGp8)L$bG5 @&*m1&rBRI&AUN!$2@4%L"4$j5*j6,PSJ1flHeKeUGemi+#&LHBPS&k$,Gc&2'95 pQdhc#dZ5mMMVaY0d"%CFhqVPje8ZA9%qSjZ9kaM8L$`CcfRH5k+l6aT8kiT++pB +%MI9)&Z4P8iASHh*maP9MkI)kf'm$r(C&eX4cVhCSHel8GD[Ndr1&D5'UQ)KH5% dm,5@AkCbiE,#8a9&Z6%Y$`8BK@N!em&ILk+`a89ZHB[mcKDj95fb'eS8PPR),e5 4hk2#ffiKZcK&X+C%mhB5rLZDA55#&55bQdF8&N%*pMYThNr&hr%NNieJPUSU1Jq l8lTDh2QJCFd$Il1$YQ811VAr@jb%a+NqcMBaAQ[FCbEkk3NbL@pdqCRN0$VE6)) aQCrmcmh6cZQFYA[5(Q8'eY0MjX+S$@JpCK9KA#V3E,14&A3N6j9KX+fIFPpcd0G bm1ANHpckraF[UrGX!+1krAm&r!Vp,98#aF'Akp5eIa[AE0k3!)iE(-[$DrpP[q+ ErM32pf1F9lr(JD"41Z'a9F'#mZ2"XU(,mRYQ2jIMhY&`UbH0G[M'YXj(GE$VLVj J39qR`B,[kq1@9@PAUfR6S(@dQZ2EMQDj$'GP'Yi`CG3)6-8c4@eQI&!j-G`943q MP'2fkq"M+Yd`@FB2M9)1#JY'+3F5,%Sj@Ne!P(,dp,iSjHMTGc-Ka,5j+1ASk@k M1Xr8Y#MP4+5#Bj4bH#qMP)1r8FT"h8'8FK`TaBK5MU0*G&(+FD6N)8SjMT4+4#P (Ur@)8SiMj3j4bR(%`d3Taj&+K5MP1&+,%+8F4kS0ST6Mk,d&34fT')K5ML29!&( +F65C,dSjMLEG45R(d65l+18iQLSAT4cR#3kLP1-m`d(BBe3e+8Sj8G@-+19%pBk LP"09A&(+LDUq45NRUJNY8FU*5Ze&P(+L8PS4TCbS*ZP&+5FU&4*4bSQUib&+19% TFBK56P6U'++8Sa@'4#NR+X8#8FU*5V9"P(+L8Nm3TCbS*[+&#%49%k+8%p98[bM PD%8L8FU*2X9"P()dP!P,M`Q$4#NR*S`3TCbBkP#8FQ*k8q&+-H8Q5MNaU3L)8Nj -LL#LP"16iSXSjF5%"k+8%p2d[bMPa06m%D@FQ*3e4#NR*Y8*8FU*#HG%+5HQ@KH PR*J8!S5&aU3b*8SjFG@h+1A%pCDLP"-A0SP56PaB)%SjFG@9+1A%p8DLP"1A-Si SjF5&ED+8%pGELP*1A%SVST36PjU*+1A%T4iL5MPaU8')8NjF5KQLP"0AlBT56Pa +%++8%jI#JM$AZ"30T(m6PcU&0(ZeZT)SjC5*9iK56TRiJ#MPP!P245QR6$JP[,T -Y5Y+1@@U0e(++G-lLP*1QH++8NkC9'a%+DG-+L1LP&-Q[L*+1@95LC!!hNZC9%* %+DG-5KY#AFZN@#&+1@95Pj!!ZFdbiE3SjC4*48Q8FXU&cD+88bjmPa()FZ'GM(# AUjj&+DGFp50+1HA+8j4bbP@MST46VYkL+1@85ee&P(,+aDY%+DGF'#0+1H95V"# PR()T(SP56N+i)NSj#A%58FV4DNqLP*-3YST56N,i*8Sj#H'1+18N9+ZLP*03$BK 56N*[)8Sj#I%N8FT*51e$P()58M`4TCb%&%C%+5HKfK+PR)58G83T*r'[(%3T*bR q*dSj5I%H8FT*UXj%+5FT2L0+18Ra!9(+53T245NR+@`5TCbNX%#8FT+U+e(+5HV Y4#NRU9LLP*183SdSj55Pr#*+1FQZ8Nj5Q#&+18QTLSK56[+V(%3T*iQ'YP(+53R l45NR*5`8TCb8X&q8FP,#IP(+5BPhL9*15QmX5MNT[E%SjD5%hD+8Na*ZLP*15RJ R5MNTiBXSjD48Hk+8Np*lL9*15R&&+5FPa4P4bNQ*UiP56NS+6++8Bfhi,,9+i(D B0@pX#*),CaGLmB%T@`eQ[D2hCk*(rLLIGI8,C!JX,Cmp6[6)CVChM'ac(QAD995 %e&5m'T0Id3UGQN223kTh02-)Ir[Te0hm0dDY'KT"KlkA[KS0bfpC`9I1Q,mDll@ ki)XY3HE,KY$9XJHXCYjG*qfIJKAkBC[b(D'`E#JR(E"cii"!QhdFQX,VXcKCi!V L-!CjTFq(8FLVjr0a"`$G1)bSAH2cCYca`-%iIPd`rRM)af%NjXhcF@4-5-GKl(# ,ciF*JRGQFGVER5S1)j1hU@c8"JFr2*L22DC&heBEf6Yh4l+)#Sr&dPJ`V3bVpZ" RcCl)Dd8%P+h!9Q,lB2YKUl$pX31`!l'$X)1a3l"$XF1`&f![a!l(MX"HK"f*CCI qLl(9f0(B5l#ABXGJaf,(B5r$MXG1`%l%6X*1aNl"6X91`dl(cX$1a-l#cXE1`Fl &cX21abl!eQ!ABKGK&f1AB*GLPf&VXAAB0,BHZa+l'VX'fjL1*NHG@)Jk9+9GXjS *Ta4SE@ZI!CfDH8"'0"lX#AZhB8%H$q*`"FI@%0i`eC6qABh*M0V8!-,JJ@TG13i 221Q9$8PB,iHYFPZ+XLC9(+`*1#R8U"QGfP*&JEDKAUT1PD1HBCKKm%$e$rSj[SJ HiVDNGaYPp2'!GGB8(Y4d0(1Vhp*rA[pE9`CYF@Sl'NEiH1#Z5a8iqKmVGLUl(0Z !AB9GMBeLBeJ@K@6T1IDm5@#6f"5f!PZ*lB2YLkh#pXF1`!l%$X)1aJl"XUr'-1` &f!Za`l%MX"GK4f*(B5r'9Q0(Bbr"ASSGJaf,(BHp$$XH1`%l%6X*1aNl"6X91`d l(6X$1a-l#cXE1`Fl&cX21aql!&Z$ABKGK&f-AB*GLPf'VF9k#dLPJS9,Re1PrEq II8!8m241DPD")3@lR%5&1lI%E"$Rj*dRpb@cXdqBE*Rh'Adf+paReYIZP-GP(Xf XS)b8Q9QcfkcJEGC2,UbGM'aHBAAZiJV0b(+C9F6rCS9QXdjjX%*cjkV,CXePj1! ++bicDfK@k%E1$4Nhj0Y%UXfQm+RL1ibp%cX$qbEX(ZaHl$lXIZaYf!2BJpK$f0Z apGMPf"ABPGM,X3hB9GM9f$AB4ZaDl$TX%rB+l(VX"Za'l#EXCZ`@l*ABUl"EX9G MVm&HLhd$pMVXpGKYf"Z`fl%lX$Za0f*[`Yk-hB@p"AXVPKAaCQ*RB@GMjf$RBZG Kjf-AB'Z`#l',X%Z`5l(,X,AB1Q`8'm01`dl(hS%GKjfdGl1-)[[Yl+bFZh-rJjR J*Bp3@0hDB#Ci#@lD&6!6[!3hHpE10RJ*GKBaXi#AB#@B#9k#Te5'j3%hl6"p$d[ 2"k()3)Hl9@Yf,$YB-p8LmePM0fI+V*0KCrRXF5*5X1-qBb-MRDA"qC*$Ba[EfiS lbelB[8JjVPJl[%Cmf`m@AG6Hb8JeaX3rDZHBRF[X(,GcKCh,lCb`FmV156ZEI#V Yh-I1MAEZCqFU1rHhm`#G'EIbhbQfH'jR*09JNeL$l,c5cS2Y2-613qdmc-iAf2P #1`qhm`JlMl6c4ABHCHH,l9aYjp&f[X61PpTjM*h(fRQFR5qcmhJl6l#cHFH*GTj XjbPfRQVRDADHEZFCGTjTjePfRQhRHADHBqHjGPjMjrPfAQ$R'MX[l0CFr28(Gh2 b-'#4R4IEHBQGPpTjQCeVl9aRjl5G9pZj[TYhm[MjaB)%QY!6NR1X'cDP963bL`F *h+NBilSa+KEKVaF5mR,3m+E1jGdiP8[f,L`Nlkf#k,T@CieekQcm00DTXmBIGGE e6X0FcVTZeIN11p-8ARE-6ppcFh$00GHdEA6jZLIRlYYXfc,%pKHCVR1kDrVV&C% lTlZ@+@1c%jQG6%616V(BZRqV&NPQU$RB*lRc-aYHk!ITcY"#N!#62@2E'0[FD($ VC`PJLrB-0(6ji11'K8rB0LSIY8e8RV5Tk)mCm(rFcNrC"LY2@paR,1kcYVA+FbD QkhVE+0K90&LFE9r6-E)ch)RaRrpB1+1ffE3p1FlRd9JFYMe,`Lqr&P[EecJkE2Z Ap1DaCG$f1cRrVZ[(aqBc2*Z(hXARKXQJ&-F$V20bIl"NA3EDb9[6ZqbHF!B3hRY 6HZH-ldRhip"j(&qCUl3EN!#Aab6E&qBImcMf)2mRMf2V,rdiMk1*R-Q$"I1qI2G Z9kr22c)jqr5UR1i(Xk*)RjfhT3[E)C+C(%Th@A%Hr0dqr&r)2AM2CERhr9#k(ih 1iqK'5#IIJaD(cZ0BHIai4b@eeTSP))qIlEVNITNGP93Hh8MdiefA5[9"a4lpG"i (JmR$1#dlqQQJ0Ui&R'D"[f1CZM'b@rfeIQTA3GNYj[prm)m$FDX(`+*Yj0(6%mM [+YMfXILI(5!22Vh3iFmr*MH%FBHE9YJr'(I,,[rbrB4aKhPB!aMhZJ[@f5C0iCG IFE(YXh``pkjAr3Pc2j((+HCq)Sp6c2eN(MpLlU8m5XbG6jLlFp@bbhS!-2H1phL GZBF2HjDjPr)iaG`ldRL0ZCIbX!J`pjd6re[heJr'V6BQDBra%mEGP3HI*B"aEkR 8Ir6F`[5+mqFCGqTlM%RPF43C6M1Q%hQFBMSRmrJ4dbRPF4V*1r*i$FP,H4`(2C@ (U[Z6c&c[!(VNmcX54bT%jE&[Lqd(e[kT4@a2j*%U[UbFNL`@"fdlY22IUiLR0JQ P%NrQXIXPVUMbB+0MEjh3MSVH%GP'CVh[fXXC-Pck1#FrNdF*1BrA@DBq$KdTXeH rbR5"a5-BdbrY2QkVhdYAUDX,9Ibm,Y5hCcVG4bY!(ZPU(!G!M!+3!+im&0EcVXJ NGrA*GGI3#[!HZYYR"FM$G2ZkmcM6lEXjU9@$1jMS*)m(f)6IZ6Vh-2G$,ar)cGc IC1'*ChCHI-IZh-e[%jJS%EQU1[lhjQkV2j5EH66GR&rRFBZU+(b2RMU6,XZZjU& kTF@LJHK)(QaJ'G'LQVeeVlXX9S"ke9d@+d!HI#kF+E'pRlqVcN194q69qQ"rjU1 8`5N@4hX!+(QK#eLL(T'P[5FQ(p)MeahU6EQIUE(Z6h-B+d!HUlDeY[CMcldVV04 H-E2Br4@j81(cZ0$jq[#id2PklHNiRfJhUdpcS9lm!)'h9TT(*h"khY8qdERQ%dl eLhI9H4cIMEBRMa2,Y)hSr6EMeIfGB6TfT4Q[hXqb011e[hQ%RCEHpI5X@!pccmb +pAi@N!"CX3i!H@e@V!ZTE3'cBLjcehZ1Y3G*p*jJlTB+CQS&3%kl!P,eI#HdVHd I24f,Le*1pfFKk-ABJC4bHMr,NP,1Q9j-Hb)fJPl-X4LLZ(2dXfmTlT6'rb0p[5V Qrdma12Z'MX"TjY@4aq[-+hb3!,2-Uj5(G8)Ii3ccDNr%,U#ci1DK0FUl2T*3#fq jT1")($X!)p"j@#9d(baELY5XB[-"UpF2QN,XKdcjp5&6K[f`+FBqE$%I5CHmBA0 ceqmMGMD+XbrpMr+X'mFScllmXJ)Y(jlEATPZY-&mc0UZ@Rh*DYQUlUTqHRTp`kP MK60b!lIINK[BZQVM5'(XiXRJY-+i6R@RRr,f),HHrGa(2p"hbVTJSV$4GZirrGN 3HRc&0reT(ZlRpqEfP8jiE&@`S2aiX'cSX[bHfFrPZ(H1CqEBic@(El4*c&JKf(9 &Al!Jdal'pr9eBDUd,+%DhNb26G@65Zfjq0DLA86FKAM8BR((9jC9AV#9K)m$5L4 p(0K-bXH"09Ai11Kh9rSiF+Fq2JkXVDq2!c[Vjq2!@kYm(0D*kZrMX(,8!"q(GD3 'q6LX,$ABak&T0m6(BI@TS6i1ke%0mh&BSHS#(iFeUbldF9M&DVL23ipJK)r$5PF Aq6LXI6A5af%eV&%q$ZYMAHcMX'*@YBr$'PUMI4a@eEV%af'GV8Yp(&EH'Z2M`$c (qMLXcMA1af'pVXYm(&E`'ZrMX+EA""q(9EiQqMLXqcA*af(0KFNq$LZ$6I&a@#p XUSr$qQ(6I"cki00p(0BBQq(MX1VB6"q(9FKQq6KXb$,Eak'*1mI(BI@bZ6i1kjR 0mh&Bh@bqMi-Hk3)IKhA3DR`FqY`,I4a@5P[Nil"ffQ)IKpA8P[Ji0)D@qMLXXEE -af%9YYVj1*R9V*8Akl,9qAaBU5hYil#r4,f2JrM2FKq(&Gj@q$M-&DrdFHJEAZl M-"IFi11`3Yal$XEa,e!*H+q2`lcfmcj1)mH"2XjDMTpi*BlhX*P&JBpq&[iiYVk P"qdXhj!!$NA[A'bdFkP4h4&3eLkbf#LU"R4BM-)iYF&N$P-mCJ(8"Z`U,"d@ZLG d2'`LRifA1GRM9Lbemc)R#`9SXJQG1RC1GQFQQ93FC5,&6KbjD)e$rmLE!!rMd&r b*X$$1,R*lM!1r6a[8Mb-3mr2Q`!2ip!Ap#E!`cLjbHi`$[e&Ee)mM%-2dTX!$q2 3Tr3Q`--ip$+p#I!`$Ve1E`)mM%-re*X!$q23-r8Q`--ip&5p#I!`6Qkb1rCLR0a NGaJR0pNGaXP0GSGaFT2GBCcFC(FB*cIC(FE*6AD(FA+6h@'Fh'4h'#Fhf4h'b8e fKh&bNpeKR0aNGaJR0pNGaXP0GSGaFT2GBCcFC(FB*cIC(FE*6AD(FA+6h@'Fh'4 h'#Fhf4h'B@E"QpJ1ic$Ai%f!Kh&bNpeKR0aNGaJR0pNGaXP0GSGaQ-A`*VE$1-a VH"2JBCcFC(FB*cIC(FE*6AD(FCJIm5Da`cM-Q(J6i'%FjP#m#I!`6Qkb1ib6Qq` 1iq3QZm-iZFRZ-%jZXM[qBKcQDl`*jM!1-cMH"(JBKcNGE`)mM--XMcF"(XCKhXH E!!rMj#Dl`cM-$AQ6iQ%FCSZm#I!`$[0(RC2GQ8r&BIkSFl)lL-1-8ZGNGa#(1DE 1bHiJ$V01RC2GcGmrB4!QZqP#4p-HH"N0mmTdhqkD#EGdY,9Ym@kBU'"'c1("RV" h'aENm5!19h"@1TA0$900D4$Af+EP0M@!-(LJ'S9URJBmm24I0b4K[4bfbZf&a'Z NU*TfThfe@U2HN``Q$"kSrS(`JeIa3,%)@aPRm2&!EHY-rk#QXe&pp9[kcqYrkdV YMfC4Bidq(P3i20LHEY9[EfXTqAL3!1`TTrB"$MMMBEddf@"VJEfl3[8C0fi[D0A c15[GjK+k%lfK8QY@S`*VRPF[MbI2EMC,'L@eM''"PI$c@5G66KNR6!!ikY*'Jcr fQBU`mZ#(KD)Sl$@BCX2pM0jD0&LFE4aM,GQphZ+b`jePB@Gk1p!1GpflXl2-fbK 3@qh1VQ[d(hHQYrrXF'F4f*Nq-RNBTfAh1Jh8aV@!drDYhHZ%FBHVm0Sr',F&D"0 Hb`*cY`0Y`Y[0h2Q%Z6YA,EZX"`"cYrpX`QX4B1jUJphHZVH!E,$EX3RkDa[X(YN Sh4,!Z%[V6UCk9@`lDChB8Y)qXFfM&@!,4id`9SQY&e2&&hITGEpNX6MBhNAN&pq VL*GfPAJbMpd[F8@9"jZSSk#d(a'9`Z0Q+RT(p2dplM2[dFXC-Pck1#FrNdF*1Br A@DBq$KeGQIr%9jNZEAJ%BrUPhFGYpA[T+R9eSBUIeiAkpNbRqfJ&b#0GCBGjGjA jVMc-"[,GIA,G0E3#[)IZpPN"mM$G[ZimcR6lp)Er,ikk2"ji%1m(FJpc2r6bJGc -rFhJe0bYc8rIX6YhmpX%*NTK[kU1rlfj@mX2j@BH*9k`iAri(Mee*Pf@AFe$p8U ,4324N6cdK[mXCpPEplV,BJ@S9pePX3,N`HI#Q9*+rrQlkMa8H84HVBqeMIVmBYm QB'0ap,mAN@cq%18Z8Br)dYi6N`rTNHX1pDEFcp4BpkFjM"8JMeAE@P[lXHIH&9C U1GNl@h1KmrAKFD(cp@S2f00CFk&Hr!#"YeDD4bG`HYl92Y'jjK01pBYheANFh`H f*ir5L*F&C$0f#p#-9rGR)GL`h3idipAl@CCQ[-lXHGfHL)eJ`hBe+pEl@8"Qa6S !j,9CX5kNYJA-LVR-[6&U6F`h441p*jLlTB+C@J'3!01ZJ&3pAdNSa`,5dl'i+19 dIaD#AS`G5#QRpl-X+H@FkF@d*f)Mk-8FLb'+1dFrqjEL6QRm2p,AUf,qra5$Xfr S#*aQAKej[-km`JFjbla+H9JRp"(1-+rf41`#1JYZ(MZ2e"P*U2dUA&*`*)iGJ"( S2+`5ZJpkLk'BflC9kA[h5lH-12I)eV"2YYC*p*cEDNQf8V()EE98hUYZUk8X(VM l#qf+HUJKJSm(dIrBDUQZdTYX[DNm(UMqS[$&[pPkUfPU5l95+UbYPkT6j4jK*-, (Jm4rEEeP)`1$("lSVCDXFPY1bGCE&VNYb0LB@4hehMLFh5qHKVMZcT0IpeQ@Neh I%`d51Vp9YVefJ!XhhhR5,ZDUjfPlA([EYjE9apR80-#&[I#&ll$%lY-phA$K6@N 2-SF,Gi%,Mmr1IZ)c2Ga3`Cf*KLq8J`p9[H9QSY'bYGl24&[V0[fem-e%4hUQc85 lQNYfqjP(1paqNGDj(6-YG2cJe+I`iM$f6Z`-,212Gf(hB2GLpf(hBfr$(X!Ha"l #hSkYabl(VX#Za&k1EF#Z`Ul'VX%fBYGLef'EX&GJef-hB$GL0f%hBlGJVm4HKGf +[4Tl$ICDl"Z`ef'[afl$hS$GMYf"hBQp%AX6pQEX,Z`Yf&ZaZl%cXE1`Xl&cX(1 aml$cX3Z`0GL&f%AB*GLPf'AB@Q`G0SU0BDGKTf2[`)l$6ZSCKl'VX1b"B3(BYZ% I2M[0lVepaNC'0X`j*BI'0VE9PTePSke)cI9Ge8T8E[G3F9baGRJ0iCeZX1JLjR6 BMecG$66rU*eMGLkcFpc1&ABZYh2#cLNl*qeXmUQdFaml0pUjRjfVl0cIcJ0d9VS @dHila4B2ZI&6HDY*&QZ3!*eAfRQ`RBIBHDLGKpRj!MYID1IKGKjKjj&f[XM1Sqa mXCfVl6cDcTIBq9)lMl(c@$Z2Xr0PGKj[j`Pf0ZmidFk6l6c&cP2Y2-h1dqdm`mi cl6c,cV2Y2-r1Fq`memjVl$cIcJ[XA'2RKGfDLlqqdj'IR#i8YbdT[)Rk3`hHB-! L1bqfma)l,lAc-M[AfVR1cQNlVlCcI6I[j2(MNj)%hpiS4b5Xa-ch6E9+UD5jKLB PE@(1X@lBe'+J`B`8'EK6-FCeBe3X`Rp2)fPdFp(`TXlPh6L95p"DcmbXQIG@3A4 GUl2'1R8fIKVVe&RMMcVVHSG,beRA,IaDcY0b2`*`[[ZUe-ShIG%0flif&bparFm r'H3AR"'m*[F,lAL@1&kZ&$a1l$eP2Id8mMd"hp0-dG*5!"BjMCC5"+3$4DR"PK$ (cV2a[T0E5-G6(8p%BbN6q96%lTbX&1pXPrQB[P((6APA&`SCF`ALh0@*SaU+N8[ QicMG11-ihYf*8kk`QHqqEYlX[(,eI*a-FLV10)lhq$M61GlVimcJ@0k*NcJ!##V 16)k*JhAKajR&-HRMX!0`bXHC`l(#af'hP%SICal(2Ml1I)jpIC`&(2[j1$3'URb FK4clqcJSL3l`FCC`(16M,18if-G"I'b)Me2,FDL2`ijH`h`FGZHk`-GCc[&#(iF GPSEl1#XjM["af%[h)KqRJH0)(iFTVe%q$T0J&rXi6)Y9qcL0(%Il1'XjAZ,MV10 iUBr$Q-FB(qF+MQ0p("5BarNi'cKHjZ-`fcAHapR%FB+2XjRM4"pR#mG*2Xk9(#I l1&GaR1,ME18ieFHjQZ-d(qFDMY0pR'Xjc["ahX"aTSpc(FGC2JiVB-hfF9KpFik 23`GmVSr$0NIcI*`G(1Il1#cZYm$(BB[@'Kq(h3dAqMKXrl6)apR&FE'2`eC*5h` F0T4GkZ-`SEM-af(lX9SICbr(1Kq(XEDdMm-%Alf2Fa[(j6i1ddFVI"`Qk9Ek1#` PGEQ2`pC9$6l1(4cIiIY6Eq6icNkFa)(qUSTc*mIhq$i@BiM[pA&BU'fJMh-Aadq m%LIcX2D&[Vqe2SkGi[29K#TlkkN*@9qq)GCLXG0-mGPC2RXF$UMT+f8rN!$1+8D #Qp*p)L,""fh6M)GX82A$YT()`iBDM`4,d[1MYX(+BqEhkhEqL1AcZ0drBIPme2* ld[,jQ1AhF6XraGC9I%pEh'FXlV2"XHRjZHl',$fIbU*LrFMkeF8er@XfDq5VpG0 V-ZLde%(1Qh)cZ@2ckYQD,aSXlRYPZGhK[EYffpdHalF(Z@IH'baCUINCpdXf[kP MFEGGjhIZI6)pErqTG'pb#p0ZZp0fVA,eq[`MNl02VmVVI[!AQ0JpI&Zkj1`SZKh *SE5@PHqAXI[cjlblN!$lfTi8i#e,ZqhD"(E5[IN`6XY1ZKUSM@X"TqeE1qN+i`k PXZ`IM$[Fl2mXi`lcX!B`lR8AV%X4Y2YV(0edp$dX(mcpa#EpTjMlL6a1-IF6HCa LlLIcq"&c,q94BZjm`YbG,cdmd!1!ZAHmaq[-[E6CrfRQAXVM&(-rXGRr+HCHbZ- iFeGjR#$[QFhqHq[HqX'ijkl3r(RVpa2'hC8(Rb@!FCI@`%leUYJ#fcUa[E9pBXY T+m"fdKTKV",E3+H+"mF`j%X@Li05fl%!I+mLAYT9iXNmGVr%&98HZm-i6N@EPAa ciA%c&EdMNM+($H"GHcP$KNXIjq4RmLJKjr%kbp6(SCGAQ2rIAq@kF%Gi''2kTGh (rIqiRUj59aHUq(PGU*X+RHkM&5#2G$@1!b"'!8KA(JVVH9FfG1RUNqZZS4AJ2A5 hc`U3!)ITpRARFDEEGh05U`E$-bk2"ak8N!"qG$2h3bmIb#rpQ3G4qjVcaHA$RmS ApMa#b![!TVr%rrIcrqrcRm`[r6RTjEPjh+)U#YqMTmkNbl+VHDKHDE&S)$U5apD eSi@JIpH42(VH3hGCV!$eUVXX9S!mq&`iLhcrAA8HUM`LVpE(fNCGZNRKja5,Scd !p,`C5#a4MmM5hK16$qQ4k`leTYc2e&MhTcQ-&5#29GYD@rZajpi99QU[Q&RXrST FU2"jA1KmIAKFk(bpfJ0Qa63AkX82%(KVTAPd!UIRAHd6R@Xqi95rH&HG"jbUYcj 1E%-`S[IEM&IhGiETf*9Q[(Srbp+-erlQ%ACDHPFE`C5hQKAVr5`JXf)G!2,DV&J A8YX#CX9FjYiBY5EQQk+*hK2-h9,"6+d!b'PA3+UHVb58B`(Tk9KFP(+k2`Y",mB 1T*66qeQ@P(,1p',D%l%5+1iFr84ajqKRhe,F+Bhr4rTk9FcrRf*`pJdGJG2-Ub1 2ejPAq#"RQ9FT$qZ%2X)CjY@HL&e!Cm(03fmZe[@4K0Uee#8&4q,B!4L"cX-USI[ `6dSc*Fl)DlqPXH`pFE+IRG6GM*`-I[Q1B$Aai[*M+flrFmlP-"irY[lf[mh[X6a 8IV((-lpGRd&e3[),r-D3!&r-mJ[mbMl+SD,C3UNKHYI[+f(*Qqh9,h&q,fM68&N EfhNhKm(1Er36h-RDfFi-KhFj[rXdQLMEL%C2jE$+q8hq&5AXqTAI`@'kme[h0h) 3[fpPm@*IjmlGFM55rcF1mjhI2FY8B+jI6"ABerNpVXhFh@e))fIp,8mJH4`@[P4 BAAilHlqq[meGTH8"hJehILpU4YMGiM4bp4p`YGrj[IdMbYAe5i$ScL,Rer42125 c20LqAI*Vq"2ZUXb2VF1PcTj4$'J2IQa5fXrj2AFfG`1FhfA8Uh1-eH9P1!bdH,c C%ZFhAhH$c1qAXM`q*IbL4Y3hi`cbq*VcqiM@2"eLmEkI[G1MbSpG9r&lArC1PHV Z$M1FH*E$CjeIj#6ZP1B!hbcUhcR"q6fT6Fd[G(kc6q6`-HIh$GA5F1HRB@&UkZG m#`b,+)lkjRk+'ZrMiJhm"ac)8AeV`FYbmr[qKh!BkIaH[SlFIpRLMF)"5hh6q+L Z*E(`eGrMpUrrL&*mY*DNRAMIlfhJRh05,DRUlAbr-Qfehjpii+l[&rZ0V$kqqM" h&pZl6Xh`FJ*k$4'E8Sb,RNLGhAmeGk1Ghd6KUH$Pji80i#6["dd6h0V1fdIHD(R m4SDAU5X&k1)(RNQm6lq&Zl(Q"im3[,aI-cEMl&dRChMj13fp8[Y!LYUQhq$P0jA cH)Y(AFMllINelK5HD,m&'9iqT9`R1KS`mXH!SAZGhrZ&IF*mjcq3!1(PEQ%pld! HEmhbZe@a`%$H$qd$UE-De6he"6qJ9J6RrR`GGp1Fhi)rcr$bPi@&@J0$2FXA-la m@,b%'L%2DNMbq)*i,$a,I69reF&,jbPYcMl,iVdMHkI2`3NLjjRIBedmq$4hFjc I4LQ'#9jq%#b2'&2F$UmbH2Qe-4cQ1Ep&GfCiqD!d2HBE([!Z,Pj'Ed'+,++k8pm "H*l"bkpr3`rRqVhar4PHEKII@ZMUXSCfUX(,a-H8X"Y[X6Mc[BDAhQV`cJrmHKF [2Er)p@"*"Lpp[`PkAi1A[TmM(*(k'(f0%REp*SN6#&iqT4J+0rM'IcZV-pe(A'T miM-CAVlpipa4bq3"6JKZrGi3GlAf(USq$2i0&Cl*j%cb,c,mZd[B,(f1U,T2JUp rT(Jbf4)9"NYq!p6'N!"9HAH#d`B[(rdb$Y*"MRiPHlq%FZ"0H#I`5r$b,rkC1eI ebDP$L!EIE[J+CM5iH)IfC(JjAh8-e['Zm!5$PjZiNrQjT0jEkZaZX$aLNdX6p#k #F`rT,4UGhqerRH%PX"9ClrcQ5%Y%m2*YUUeePJIF4I+iATJNECHl`6r$,rH+eej Kl`dhPAIDTEF!kmKMBrC1Ra%CK'HTlalaB-(,UF*@iJ"0U[i0AQj@$VbjqRDSVb* if9pBbCY$+iJYH2PTeIB@jrFHCJ!-AVliHcKFkI`H!e-0AXj3r`#V8[ibp@h`mJZ IaB0q#1R6mc$mdPqjrbdI)1Jh$5pp[`Nr+e!6[26p*YrAa8[2chR2*kRP(E9NBRr rjReXh4mpUpD-L4Ii2IRhiY40`h&#[`4X[GVi0(JMID-JhJI!IQH'[1%m2Upp5(K Jr(cm[N%FIEVj"Hp+[d$UjU2LK0GBhZr+kUrK5pb"#D4%AF5Ghqh#IZU#HJ*hEh" qApV"hA9@(rLjqF919Yp&C#%Q#SrGr',(AFZG#$I%K6H5haq,(dJ[m!kpJH6hIMK La(U0NcrIbDpmd6-#&0G[XrS1ERlPHe3I-MBD[l@6ArP2L%1+CXYp`KFh[r)hh-+ G6!E[&2qrhR$#fmcCZHYpP,h"#Gm[HL1(&kc12,r)1m6[$8liIKq#CcVR'DliIT- %jLl2U,Y2R0$YB6[A5L2U3HIh6[%*YjrSh2ET$[l9c3TchGjRG#(p-X'rZV[9aa, GR2[")H%PG4rr+Jl5aj`Vr(Aa2RhfhGc*c-h%'cTiArIB,h%RrFh*UNqA6p6pXRT R[+2kIShk%9j5phHUHjN+@+cqRmY,dLH+6p!()'rH5r+J24'aIZ[6i+,`NVVle$1 5A[9LF@9jlfm*jk3e29RmaUhlZNmm*),Nq[eAH,2`[235p62!+2@9IE#$"qPhL22 6+`!22YR"JlT(p@Ch'Ul!he`q@[G&p9P9(HQm&Gi,(khl8h%Y'AZDUlK56e0rP6[ CZ(UbqUp56mqpPc[ZeIFXr62K6h@cbZ0ZjdF-i8rT0iSM[YRj[D!HJmZId[hLS[4 $H%EiV9X(kHA##IT4kRX4lLlmUHjfmBclM"r3Ph*jI0fIU5EJ#j3Ur39j[b(LYI4 je2HmhY,PmHNhrl%!4IJ6I8#hcZTZ&NGrQq9(EhK-kPGrQc!,r!IRi*pZ(G4I+Ij "(dCp,iPEZrR9rk%`'!b"cp'IN!!krP0K0(e[H!c[-E8@lqGKNC,k8mB[`&GiB!@ m#PcbicdXITP-miZX9UrS8bl[HG4@l&cR0eZp$(T(m*irkH"dj1[#$ZSAD%AV6I* iR"jR4$a4I6q%RjJmPUQhT8QlHLF`62+i@fp&Rd6P-BAD-RQmSRk2kRrL&kH[Br* iZl$UFeCrm"c*Skr`MpT8m5EaMLD23qSpr)(c5rePPXF2K,Q+4qJm`"'GacfcckJ A!hF!9qM*pDNaIH[9$0pIkGeIUSAIQC!!IK5qjEKqc)"B[AZ`LrS$YcBk[pqL4a) 40eII(2(2Ah0qip3r9[e'hZN*m0ATFhkrSlGiaIR0T%mJq3eFq$3Hp!R"4AS*NTq HY[k5LpGAEb$jI8mFPak[mTY&ACVm(K%2J&G#c45[-1rhS,#%HLFrDPVbfbJZ"#G 9SHDSVbcj0BTI8S2+Ebl[BI,lVM!,E&3Z[dRGQIG,#J1S"HAb%Mc5j2IAHP0ke2M 4Pj,m[L)-8r@,hm[`!C2IH2AZ9Im6[`r"CD11hj6G)Sj%la(H!hm@hMcmYlMlZ[% EZ*(V9rB4eH)h$*rJda)[mK4hUXp!INq"4bDrVi[cJ22!2TaHi[89aeCc(0U2Z36 *lcja$h"!I3qPZ1,'UaB[C(j%jIGK1)I*lk[L%["SF!JH+(PFUaN-qJ2UHlIkb1, hFA'HljJIr92aqi&Q9llVmTY'2C[mAP626[&0r4jJX-4lrRVZ[QGqm%RaZdj[,6f CKqMAQ[G,+cpkLC(r!`!0$3a0B@08Bf`J690-,VQ5V&`'QaD#!*!)"TXBK-,Z!*! 3LqN!N!MrN!4069"b3eG*43%!VjH"CE-G%)3!!!%H!!&@@`#3!fN!!#NKhAR-6!# 3"SEZ%3!)XY&i2U8!iY1-0Q5dTqCS5Pq!I(k5%NT*arjJ*prjf$-VplrHR@26m`+ +hp"Tl31SGm@FIK8YjfVhcp'@0TbVh69(@eCVVRCdMRCfjEQD2NHVa(1e@l-eHhm bR9hMDq-S90r#*!!!"J$&YRj(11'aIB594hKHC#AE)j[G*La#0cPqC%XBZB9XNlB bMamY+P0#"jee55M(8hc5YpEh0[jMjr'1l@0NHf4,0Z[)2XRaMac[b@dMfmXN[*2 XCd8if@3IZAeq*pPNX%eb2,,*lI-*Ed!fZAf%5fk2b'ebfb-,"6Um31Z!qdd)RjL p")$F*L018-!lFTZ5@fh!"PkMR+H0FQ5$(&P[4UpVN!#8RjX0XXmh"jEA1dMV+(I hZ[KQ&rpkl6UrZ@3IfB2XM2GfpZNYAYSJ[5CjkD*GTVqFPbkkR'G'&R+,!&J!!EF q`2V5Yl2@Nllapr[5iVFFqB8XE1XY!$[mHBlmVL#+kXDB&FCikidhp,$a,SDYFK) qqlf#Kk[re8E9F,ZI*,8S+9D5D$i-XSk[)q@,'drIc@DPCjD@fSirA++60KhIlCF hhQ6-MT[i+ar2(,qb($Ap)(Se`kKCEdl`lLhXlGacRmk%ZmGD"0iETp,-6plUbUJ aarPp8HYS#R&H6NAbI@`Yr,+Bf[3Vqm&&S9m0Nl4[lS8%2%414LARb)UeGjX6j&f a+[D$RIjXq&,qPI+[6KFEcr[h(eY-Xl"4U[YT'UE2q[IDe'T@kbqRTj'3!'m3rKq qrP%rQK5EZHImY8m++C)f6cDk`0VLXY&QeYB4,pUZ3bkr3ICkhG,3m1L8r!Dp88p h`8HY"-aXl3`+D!b3!$SRf++TC[b"M6!Q0ZCdf516jX6Fp`+,4C&,F*k-Xcl[MBJ j(pIp1&A'[9B4Tm5qcX#U[[@f@5,EF*l%Z*M9ZCa&!,CTQpbY0a%Ai&Ah**!!D3I X1LmIN!$9K4,Q)#m0eSN#BQ6a@eRQic`a,i-(m1riG&#GXPr"m%Y9afqa-#qrZVS LkPaJ35B0KK@2hQD,P[ll+mVJ,+J$p1[(KLY*1&0EH"EfQiQ+Y(c896(C03Ik59R kPX0N0Lb1[%CFLYpbI#XUPH'm!q+EKbqF$(E@UL5j'mBU*A5h8)*8dYT23$GGLAQ &Xm`G+pE4'$rEH*1+Q`amA#rQT#l9L*`Mm1-lXeGY@)S"`jpRRiVY9h$k*#TLEXI C9lD2X&I&pL$15U92cMjQ4VchN!!ML@d4,J0NUmGPS'aEZ`6#@m"PX'b[83fa[4Q A)E*p!*HKXRd@Pf'bI3ZAi@TiDMT#0U"mT'bJhLMCcX&PY'aE#2YL!lder#[E,EL -NqeYZ&"2E04J['arM8Z9E0r"CB+eaGK,%fA$Kal%4Kp-PZd-A+E)GJNZ8f@l'KI GfFTf-bk#TV'[i6*G0QS`3cCU-&1fKh#CC@fkc@I,4NfVC3-$jXK@KmYFf6EK-Nq fRa0@B(X$,[31YMr$CB&XIiA,3YNH`)AD!LNN[PJfmPiL'l'@b[C#A'TNJe`[Nqf PZ-#8X2dQ,V!YE,IL!Y[#pQN#UGMq(TG6VDdAX@H&E26RDE+4$aL+E6dZe"`EP(f PE$IKXNUfhm2PG0RHK`YpLZec`NaXhmEP,'[V68amJ@cdr0Qb89q`$YYDA-!FE14 pVQbrLXYUfIi%&rS#'c9H)a[B4RbJ'&aH*aZi3$fa89pB*VD0T!eLH`NZ#'cBIKZ A#f5MRf#cf$k$biYNSkiA@9YIi[[&XP&A-!SEr811f-$[5f@l(KF`""XpY&Qf1h! "Bl(p,5l%a2CGm3kS""aJQfaJeQ@bd@0#mbTUZ("LH`8ZPmY'VPI)"LiL-Q,l#Li Lh&3mJFXZDkXN*SNk9NRF8BaIfqL0Uf5l"THpXS&r)Zp8XQq%qe@bEm"UE!rM3Nc ep51(DC)0[)EAB!06i"IBk)%AbrBbA-"EE'!Hr![EKh$j"GQqLJZpV$j0UDk6$Ai LHNGrBL,iLBeq*LpXe1[PXX'Vk&0Xlm5&2X)'PYmJ'aM`5QXE3!aiP@c`Neq5$Eb j86Ek&[c%4Jj`&Qc`a9I,pJPFIPQfEq)#Ve6I3')R')L0[UFqf-"6q"Ffq[beXT( Ekf6lBeaq6EDlF2PefIi"PpGEfb$L*If,$8kP04GPJa[mKQaJ$Af(MCVqPQc[`!A -a2BTA(j(0RMHleVEB(*Dm!FE[IllXX%CrN!fm1X2CD1ArNLfYq,b*YNqMJ[m$KY m'XkV[Z2))pmL'eb4RX)'cb%q0[!AISS0[(LlE05D'Q)$YqJAE*r(KGl("Pq%GkK [#([a6f@M9piP'a`*hSF0A#%AE'$FZf@M9pmM'hQq9lD2iR+EE("%q*6kKT+M[em fq2$YXS&KB$Jf1-B(C3-h`80Xi-@IbdEG2bcEah#"Df#$&pjTEF1SLIb&E'!rfJ8 fq#Ve`3E[qN[Ci!2NJJfm!9Z`N5YpLJdI-!hE0h$jT'`SH'#&qSD6Ji+Vf1#pF$T Xm,HlCB0Mh#-EGB96B!-,d$H`88Hi*cBi$If,$BAb#pBfJ[`*(3!E(2k,XX%Y[b3 ER1G[C!2R[L`E1(+[E23'(!dE2Z5,l4&FlV1fNG4Pi#2Bd"5q*KZmpqpN!e1r,KZ FK(l%"VE5,pMSqIYPSkEJ!lC(F3%$e6H+1JjiMJfGiKpPSiIJ%GM!)6Jb0V$qRf3 $[q!bf1J0X!iEII22eMDD'K"iMJeG!ak($Flm,l,"hrj90ZS(Em8'lRa20QT+MkK [$2@2lmX'4kHHf1J2FRF9I%Vp'!4eY'TNV&LTP)UP$j3fE1J62*Y2+b9D&e)AZDr hV[11,iKrkUqS6D[21d[5NG2PJmK#B!&X##YJ#Y'&"%&8)DJ3CFJ$""9L#L%&R'J XL#H%%c#"B%)X)C3353JNa"&#$@Q%,%)5)35!'5!'H!&D%$d)(X!$kB,834BK+T! !1XJF)!LC"+J!@-!HF)A33H4!#)JEK!fL"N'$Q!(1J"KN$")'qB*d!AU3!&#)&X3 %F!EJ)&L3!!I)%b)+a!E4"$%'iS%)J9L#5)*BJaJ$F!1ZN!!la""!#2%$%S[BJFL "Z!'"3-a!a%#m304"Z%"X3+L!9%--)!33!3J!j!a5"SK$b#"L%$`)(%3-!JEaJJ! #qK!85"e!$JQ$I%'k)#D3!#`)"+3+-J@*JK"!S#"*%#D)%J3*iJJjJK4"EL!,N!! Lb""N!$%D%4VL)B+e&UX4S#'R#$U)fT!!9J4H4%d8(m34a!B)&`)[C"ea"Z%G-6f BDN(i3)K([%HiKS`L9#0')qBK5%1m%483e"&h)2f)'*!!583XL"l#1m3)m4E#M,! ,%8-34YL&f#*d`JS3M"(8%&`4EK&X)I63$J3,4"H%)`4%4!8%9d3aa"*)+q)UJKr L$f3*84X4&2%6`SIBLBJ+@8IX415%U#'b3R34m"!e%5N3-4%[%5d4%K"*%#F4*4% M%H!3(a'[%'-KV!Je#)`L,,CrD[bNUY3(LKAThcSf9#`9Kf[6LCmXQSPQED%ieSV M#*0aQkCafaJZe,+q`2MeHK6`[LZY6Fh8kQ&+ipjD0XHl'KlEbbLEdp"2!VTXEXh -K-P8,B*Y5a!e'Rkc5Y0f[qfdZjP'pC!!aTdq-pZ#C(B%IRdU#@GVF$CZqaEM%2H YY34$P(lXKL4TmNiGI!pMm@0Ukjk)*GT@MrbXlBCYBm22jUCQkkf3!!fJ[&4G0p@ CiFlT0%YUc9QD'KVfYR'Qe3bBamjD'YK8pb$qr*Q86RX`$EUah4PTSjrZ(L5cE`D 'Ue)dNVV[Y6h3'2K0ZMA@CTYqR3D6YQr`de5fI9%pMiIPkMc3rM4XlS*KAkh"LZQ Ve(C,-k[,TJBE6FQ[EYE5V0SeAYXfT80IRD902mqRTJ--e8#%#-kUS3Da!$SHfF6 LlQi@,`VVX5P[Yr4FHbVMDKpP[6+hVJQ[-,L[5"YQXM3b12K8$UX($TTVbS[&3cR AlqJk4$V$8Q+[JA9G8(mkC-iT-MBd-M'*FZVlkI9SfUqc@l@j2Qbf1XE9l0#'T'h H8'Y@Sphd6UHdD12&IA%bIc"hI+imP,PbXIf#ZEkbrD$CG)`BT@1`TVX#FddF"lG fF`Z+V$Y"aE%KU%CMQ-dhiMi@4eG39*5cDmfGB5)(j@`FDPYT&M@+&iH,Zk1NQTV q)!M6&'AC0jHDF4mcB[Z+Bf'@!C%Dc5!3YDVXah&Z2De9UeH,!`YCiUGQFcMGQTd 0Nk+0'E&&VSdD-@+U0,9Cc8,[XSQXUb$&A@(G$)d@4f,!d)iV%%A,2@TQq[5`QG[ UDLP*aFjTTT!!VL)Qe5hqAHDUIDb4V"6iT(+RfLBVE*QXdUf!b@461eKQ$rUmJ6i #dGGRY4a#QVVmT5P!qfKmeKD0cdd"1N)a&fhaD8Z6T4*0(6,3e)ErTJlX0`R1ja@ (rHCX#q1kUFDERaH`#K9X52`-[#KbEVHC&K6lUe@`*M8VI@AH6)SfkGE`35rGAe5 ifFRppTP"5c3B-fL*VQ-',G&6c+!P@SNCY%3I-B1@k"jQd",p`JaDSQ1B38Zd#M0 SLBiQJjCD,j0"5kf*bD#PeKYPd&,VJc*SUE8q'E68'Ti-@QV05`BYYHBPJjCD[j* "5kfTbD#PeJ4&Yr+BX`aDH[5438Z2'T--@RV8P'63dQ-Ib+#P4he)"LdppS%-@RV 8H'63dU-f)i1@(QX[JjBHG8-CY25S%mUJT8Fp8!BY2HUc-QMT8AH938Z2HUS-@RV 86'A3dU2f+B1@(V90'E6df"mbD1P4$j4"5imDR`aDHY3GCG$5Bhr)S'@8Z#"UHC3 p+B1@8ID*$&T'QEm-@NDTVmQJCC3kQ3aD4SN0-QJCTCiPJjC4DPNbD"QPEL@$PP& LJ`aD4UP$bk"PP*Uc$&T'U42,S'@8YCG"bbLe84QdM,,'-QJCT@BXJjC4kXdbD"N MhXQJCB`i)S1@HZK9"LeMV+--@ZUK9aQdM&'rNd(,'(YG"Lhe!+`-@XDSqmUJCBa kZ`aDaULAbk"PM&Uf$&V'U%R,S+8HM*9"baMeA4QdM&'6P8(,1(&C"LhMa$JCY)` 68f638Jr-bU"PR$dJJjCajLb$PR&UM6*S'DIQ,B1@HT!!9JBYip5XCG!bcPN"'E5 -8rqA3FXi0A`CY)a6KjG"bcMV+S1@FIDS$&V'U6r,S'@F@V`-@XCCBaQd6,$'-QL Ck!eDkZ&F'E4-%$GPd$*"M*0"b`4a4263"2YC"Ld6l$%CY%b`lM*SQ@!YC0!b`9J bD*NJBjC"b`3eIKQd6,!RK%dRL0NbD*RJ[)3-@LBicb#$PJR1)XLJCB,B,)1@#HV [-QLCS1B[JjD1JSmDfAN'SbQ6[p'9`3Ek"B`&pqNMX!Zm"'rdTJf+T8kMei-cF%# i(hKMp'hi(cd,pi2c`E[J%dB(Kq24er!8--YUpr3h2!jX-rSiq![rJ,1"L@!Nq!a f``2!9E!!EQIR&35V08l$8m"SX"eq!Dm$Tq%JCSl"k2$dU0ALi5pJQCe,J0q!DI! 'X!AmcFm2J%efGX(-,B$EF"Xi(0`0EJErJTI"aq"K4YX(Pm!Z-!ZX!U2Xh)T`U[E 2AhB4iEkL'-iicJ41YDH(j4D4e6MliUc!@BQc(mlq1!IJ()Kc%-l"1)IJ()U6kF6 K1%IJ()Pc&-l41-IJ()Yc(%jfrBc(@B9c!Xk*1#IKR)ac#XkT1%r!13hRG*`cF-l %13[RE*c911IJR)YcARX&L$SAi&b)Fa(1a6LAi&b+X`ER-T`Ri6`jAh1L0K)j!&! c#Z`c5SB,i%XZ+0(V-IJ8LJlFiZrbYBqRqSUDq%EUZh#S8Yc5[ieB`L+5`0eS+$p D0*,1)C11UNTQC8IV,KC64qAf61PdiEfh)Eq@G&Sq)rS)(RDdNp'UG1Q-J(5SkId Sh)bBGH66Uk8F!2ZPMJ'96iY%)P$Irr4$!JZRfXBZ8KmEBIJF$&AfHPQhlTf4E6j al@@6R6dTpjLQH+&#92Va116Bbm8"LRUl1&$R2Li1p,U[L`0k9EJi824+&`FDhmr &J46eGh'Jr`0F(#5#J5i1G'H3!)X$qJefFC!!)BjcF@!N3e`FC)bK,Jibah!A"aP NK)Z$9$,5a8%q'HAL)+1-GR'3!&V'Z$M)-@0G(#5EF5i1dXha,JkbcRJA"qQRbX9 "rTRJiL!46A4aN!#4*VNi5%b6A4`NU#NZ$R,89"F(bHS%&`GCDjU,Jr3ehF9"(T[ KiL#GcA4aY,cfH"cNb0NZ$T*HYBZ$T$I(a8(bQq[L)!XZIc&1+U![(ClUiL$cVR" aN!"H6h0aN!#$DedFT0MY,Jj5l3iA"bRfFKF('IF+&`Fjp8SA"qPiTiZ$P,l,a8' @hZhLk"e3MmG"bVr+a8&#hq[L)'mh[K%R'8qjf`@I6X8ik(YX2%h*arii`0Rl6l[ qYU@Pal3Vc0(fV3)S",K`c[j65Y"LVY*SU+2Y3qY(eqEHCrmCDkjD@[V$-e-d6br PGD"p(FZjQFN`)j&QhC%GJ65MMhENdB`lSXm()iafc9*j,C)C,63MKHLCD*ASN!" fV"$G$dd2[3iY,PLAC0FNQI9)4cm'$Pd!!hPZ%0"`%!c#pF8BHqYqQ2rih!-MACP F@YEefAC`"hbTDF"NEV*m`HRcZ4kQ'U@0A3K,l2pciEk&,@X$eYA*&SdB6Q"H6G( U0GqpFIE"f4GR"Fj+R2e`pXFj!1G!R)0`$XBj&1F`R-0aMX!j%ZFSR+0aMX%j&ZF iR-IM()qc#ZF%R"0a6X)j'HF8R&0aRS"c'XlT1'IJR)Pc&XlC1+YacX%j&qFmR20 a,X#j%1FLR)Ya,X'j&'F0cQ8i6m*j-Xj6mMFKQ28[lTN[LQPFmaB%jmXhG&eTC22 !ZZ+kcIhMrELZ(LU0Di10+q9caLJIMl%VPm!ki(5lTC8)*d8I*NIXDcBP@%A)hVk NadUXHY[pP-1UU*Rec29$PE(1ZVZFQlrS6RENjAc0jVZdfpl5TA&m@I%jPpEma$1 jP5lYZQQf&K4,IPc-Yd+N&[2P3jJpKDfZa3S&"FdX&8bjXCJLRd8YYJMQ-P",)0G `&f&cTDlGH0jceFHVZA)iY@3V(QC[BXSaf-5BmXcXC%aMJpfrQ(*VAR'BG@dZNee lQ+j'GRpMi0MDjV)b-9eTIl9PD`lLfCU%h3#Cp5U8e1kfc$La(c,RdG+,GQGNbLf c26,PYMCU*8%ijXq%5+9KjR!,Y93Yf*kCKZc-(Nf$#0VVE'aUcD!IqcTpQ5XSNiB cTAhYJIb9mcU[I(#&DJZf@1FX[&M2jJTDjf`4-kjCC,+HQ8i*(,-Y(RLE,JrmNQf G+AJ1[PTm8q#6m483XcjC0Q%p-ahBl0K@Q,EfE1ebkpi-T+h1lHA-`'RJ@'`h#kU "RmE9CUGmUE2SDMfc!'Xp!pjPI628+h$-PmX5X0`5i@C%$2`cS"Ji"lJBq'HK-I$ 1S'2JE!%bljYTfR`!DB5mki&Hb)*PZhX5B*VGIFJ-h$+S'6KEi'ccl5L9JFr!V`9 "J`J"L"Em$j6C3QRHYl-adi#DG`96fr`+AC!!3GE!131ZJA-1A`0h#l&jhd)0-dT (ENY8#rF-!Q6jCq$Gc%'$!$NH'VKRZ@MJRH'MHHFX5FT(5'h@E[%Y0N@1RlElTdK GXlr`e-![be8$l`aIEA-q8,!NE`dF@lPV%++C[aB#&-ZGiE&jjkifc5j!Er(9R,E 0XD-GXY`fm-lbfm!li,L"IiERjTdl5PQ!BGPG(`+a#G%"aFDr"-BQa!%i0J%k!0R i&b$CZRGdZih4dL6@1fb6!p#FMC!!4kYNK'Ci0TiG!'hm#a#GF5m9Va@QM@XR8*X J*DM1K3M,Ai"VkejZiAE)YYijd-ki&KZN!lL0I`Gd'rmLH*X)"ILflXA#&L'm'lj $k1k'l8l)$Z'k"09PQ#j#G!QHZk#j#jEE)6Q%ia)8Kc"FJ1!Hq1f'hQlB,8&Z'@k ,8&Z!f4,%K[!D3QXAV*BJY3LR(9$D,8Q&JP5h(08T4S959%Q)+XY344'U*%&e#9" GmP1lq"4+6bAK+C5G#U*6Mq68,6KebddPXDNX04@&TS,-9"+C3SNT&*Lkj+@5Z&5 8PNV#%Ul"Zcm#2%`qp+-eTC8,3@LIUp&1'%UjDGUDcmdJIjJEqHGIfC%,dI,SMPb !p"XmFTjY6r,)9DQl!S6SV!!"fLZ!ClN#QGjGdfVbm5&jqY$mA*!!9J!Vak!I`aL CAQqYK9%&bMQ8Df'``BAa"")(aCCk9PK3PiiPMfBCU5a4keLLEH1%5l4YR(#*YSd 6,Y'fFF)PfMC1Z%6EaJQAD0Xii4*Y'bGFSQhMK%ZdECa`LED0%bl4YR(#*GSf6VK %fmB*PfME11%5E4XRA)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)jYii6,X@fFJmZa9Cb$bl&9R)2 ,X9@FJmZa9Cb$bl&9(*Eap5c(9R&Bf0Hc(&[&BDPIch*X&BI&Ich,X98FPJ2f,-G @F9JJf,-F@m9Kb@$2FQ`9Kd@%2FZa94b@&IBXaeCa@(VGXaaEa@(TGFpbE,d1bj@ j(2Y3(+9L0@pM+LH9qj*Epp3$KmprjVh1chf2EC8d$bR@RcbfmIR2$I)mP#)4q@p 2Cd"09Q+69ba[Vdh2[ah'0I1CPp4`$Lb('AD&053ldb,(TY3lL06MVqVZ-9Fp9$4 l(MaV,CrC1,D`bj`b9khc+89hMSf2RSPHqh4jB1Z%'YZcr4HpiDrY"elG8lMKLB2 l8U2A,qRa8Dk$VlfQlT*2[cCC[9"D4Y[NlB8eHK@i(QaC'iG"EDB@k!PFcTb24ba jGJHhQL2T"CZhh%i$Z8JqU)j)(!QqmEZQac,@CRLFikDNfRi+TIm84YFCBU6aJ'A 2#JrD1"J$L+iH$ZEX`!1p5ED)"qU4T0IJVZC)MBIc$!q8-TER"cj6h"%ZBpEr(AL Jq)(S"aNm8&ER'5%Si)'HA-!B'adCdB-Er5pfiHK%@c6h6MVmf&ie!,KUD(J!J6h GSlV(G)rVRY#pPqkpGHqMHerG+h5[e,fIl[ee(k$l30d(k6jBpa0e(k,l80dAk$j -pq'kMp"pT1kMG"qYqaMGaqSq6[IMG4q[HjAZ%h5IU2XNh5IV2NAhUEUIS2Y#h4I T[PMh*ES[eEe'pf@kRk6lbEUIdQ[Ak)N((d1FDVjTZNrAIBEZ-h@ITI[XAM+aeFe `Grl'A'8dh9bYqacGjqSq6hGj8UFUaE4blq%IKFpGmr)'2JEjeqKpH'[9+HXdbV9 H$a%i6mpEhD#*Q22eP-),j(H4lKI,reVG,e%H'jAATBUc5APYeRf,iQa9h2fk0mK [Qjl,HPRRi5,fGAXZPLFMr#b"-!QQQ%6cikHGUerZSH)ZPXm*0rfT[kJjL8XXXNp MchfMlBU+Sap[!ei4ahTHmY%mkX[$HTjdmFZpeElYUkm-kpR5ar,B80+cU)r@GFh Bk)XC2T2(ZS(*mElT141Nk9q-pf69V2Q*RJfY[X5lFP[QmIVbH9H2j"TAp-$2QBD IKc`qZZ2,[(Zrm2PjG'e(H6U2VS)mR8HAN!$kSc`k%hNUMiB&QiH4YEd,pYl6IU0 Bc0Z$Kb'rFXY2MIIik4IXrF)*hYl#3l"rZah2bppVU20SIT(G-r9JX%,RdDdcTal XAbbXRiIDm1`)b'2,dFU@kmVH'j0(L%42jE(AX!rAl[Y"hSmAE,c2'hplCeQ3!,F $HiNMhPC[krkk9lk(Mh51`2rI%HG1-qlGreiqjpc2Sp(-[BV6rZlM5!l8bHab1(e qDH3BMb('UYHCc0BSd*1mrrHM)([6j(A@F#L2aVRkX9HkU8h52IbX-@XY%j!!"em eQZ5RG@933"Kh8AjeIc$Z!jVD6aKh-3pR!1-qGp1@BfqJUkpX2eB2a`Gc,bQJ2fE Z2ANFCZipH4aQlSrPFBLjPr23c2f4Dh%Uc)lGJYfC2R2A%l!qFhrKTh[-I5hXbIH 9rKGc,p6M1HCH,1`cc,fFaf(QANMM@HCHcL2(h*HIr'rQ[RcYdmbpBGBF`HN)%Y( 20QKMl[IQ11hmB0b,0[,CpDhI6aMhJ6ci(!'-@cd&iF4cLVeh(H5qrQmbT[-hFQ9 X%I'HC%`pH4aQ1SrPFBMTP22BBk+JI[0eTR$hHR2bp,IJYY(E$IZ`dfk'lISZ)e# 0TKa@M3$aQQlq8Hjrq6HqhXe$-3Y(3"k(Q8@KVXmbLh)Hh5#XmY"2NJKMq(NdT'E $KTHC"8NdT!*2C3I1!J8JLCbP2#b&`jc0ipl,fd1YjGGbTK8E[f%lN!"mpr6mUhQ F1cer,)r+R&+9TKB(j0VCQ[HIj&fppCA+YhkfmNRYc!Q3!%GY28e0Am!(hah)3c@ L(ZB099kYH6N"kU'e+LG!(NDV#[0i5U[DRMAUjK9'S&El[q*p&iN"$0eabb&'F$X ATIYjA-iZ+YEML6i6M@"(I+4Id3L+h0l2JdRd#!IfMr@peJLF!2fU03)R3"iDb6@ F4IjE9jd(q`b1p8IImNZ$Dr)G9aUH'!-CDTKjUr+mUe'Vi*!!UP)HHI@k'FP4`Cd !H@Me@V9Lij%m![8kca9&qqM+)kHZ&I0360S4N!#(SUk1J$bZ6)r@3fhZcVl&-CY (NYXV,FB98!qPaEJ"mP"`&ZC4aV08(NSM1**(8RAHEY,ri'Zb(RX-aCL`2c+Umi( q3'0b"15K0+BMrCV6Q&`!HHa,cIrkV,,h"-kfJ"9L"!pj"rEpaK6ZQM3R2ha9ah[ iTqik@$'b8ABZhS&VmRQDk2qG5YkHBJ51J$`8)h!%j+'3!0`9N!$(RQ8#kVVGa2& EHD6Q2K45(FNMKe62jm&AlEq'(bZIQNL8A&*jE(k`NmIZj3$bU1`pP+N0mAVRUQ( p!hHZq-V8"EN+0ID$I'D'riepj1@(#DKiZP$aJFQXSaSk!I,3+Td6)!qMdS9jj&@ k9"jRFNZ58F8kki%U9Ub(RiG@SC`!GG@6+XIbi$j`G-k2dkLkq")I'QQ4iHlcP`Y !"KG!(NN9UT4(IQY"d)P*&HVrmN#AGJ,8e8Fm&d!H"[%8LAN+m5KY'q*Y`F4,U4l jDI(f2"5MFJ6NS6L`)b!2aB&G!ARX@5DJVXa3(N2b**Fq8Sm-Pck54ij,Z`$bf*Z VBTh-5kd*d%$Gf@H0Vq8Kf`Bkmp$E"Y5S8jK(IYY!N!#(RQZJmBrK[@D86S!m0+2 d'lEB(keE!S+kkYP(*d!HI&UG29*A*VM1LCS[D"lQmmVPbM)!'q$dI%4jUpbBjGr f'S4IAS8+2KI6AS1MRf0TVm'Hq1JZJA*GdeT$jjGAHG[kJrd)aci(b(k%!S!mZaq KY+25$E!IS6`H)I-46S!1FJF`GdF&-h8#)+GE!DQHq-V,)4dJQSl$C6YNq$N)Y"K hd(E))jpMD6[N8eT-Hb)Z!LfQ+iE-IA4qlUdYNq@99j%eEc+idQDI(c1iRM`1-lL H2!icZ-Ib1-6JbRNmbE`+H6c([)S&HBCjPI-ic,`+D6c,[(VbH**jY5IL+0MP9IU #A9iGRaZ!%HJmR"+l[-UV[#,[@(j#@k`GZIE)TX)N-[3mc%2["(-#j((@I$,6Kr1 RGB9C1%id5VeEl'KrT(D,(HeAGi#QShH,(F-2*MB[V-A(0*dRkZUHd(6iC%ICmhA 9HA5rZHCJ([lVqhM*6L*r64R[VkKTq-ZG[CqYkdZrYNjHeqE)HhfIbqIG1mi12&! mAEf#b)(hqMlAff[VNQpk+NhU1Nqrp*ZH1QIV(#EIcek+EhVL08qCckcjGrYm'kI 5c$r+QKd)RfH1-b[H'FI"VGdRK95$3fH#,0IRBUL1Sb&VGmlR"U)!VV4[Q'Ha-[N f$[q`!+U-,KSmGG2dK*[PFr%b6I8'%h@Z`@Zjq0DDeIPp(Gr1TEleH$F4hhP3rrJ f#'(hkAkelYIShU6lqHE%r(k"p1!,jIFLh5p5[KI,ISRbhDMm,e@qQj6rCYfhQ*A jID[L0LMZ0R0mIVpXfBCmqBK!9$,&Lib)6N5b*')&cNUFG%GrR!0`$X6*k-9JR-I K()*c+$Y8RF0aMX!j%ZFSpHSBR'0aMX0j2-la1*Q4Q)"c)Xj*1#IMR)*c+Xi6F%l $14hR$*c-RV&(IME1DTacF,)eGal1q6K2a-RqVB8iQ@GDM(-*cU8iH8V9XQ8#m#H +35eBZa1'Z3pG9aVC2,#ZZ'jcrhJrVUZ(5Z0X@RI+GqE`!$"JpS@M%qhC[GMUCVK lE'KNBK,'a+!08+hl(0hRkMj2prN!h5YSkleRF1qU2GZ)UHVVE9EG-(mJ(-6+mmD cmqARq$YSP!)AMq,SZZX(PbX'11-dq,-aRMc@00,Xm"4ilmXSIbUrh+Mkd2XTQbU rABImiPr%C4VmGKcb'iPiIC4Il)pG[bVip9*qeQmUr+,+crTje%Ela3PHQ6(ShZr 33Ic331GD[iZS`IU+F-6Mkb21XRjc(iA09jBMhTfip,&qLajJiF6[2ELXXhi,"f$ cPHC)J9V`)ZZhrpZ`q8TcT-"ap@VVGaheAepaMK6B&j,IlG5(IH8k8YM9pG[f#'b q-KdTI))em2e@E)@0I2&l@GI[eXr$KKk0h`fih'Mp9[k52H(laD#MHGGB[f@2`3( GQR+K2iqfIMHbaihHGLDEfIIc1++1MUfq)6p'(P(e"mXAk6[Di5BflFiX*4kNZF2 XEk)%I4TC[XmLl6F0I4cj4b1V4iImi[Ha"LSH1*(f@rTGq#jSC,1(mH$N2k(QXaT aLRM@leA3fD0l+m0TKQbSXAjcMFVKFedFX[&14Adpj,H(%rMT["1rlp99X)0[qpp kG8hjH4rkFbq2G,ci%lfkT[e@8EIrM[SJlCGJ2rYp@AI'Cf$6VdL+Q)rG6TM6IV@ l*Z#Jl(b[fBpHp['[pX18RGpUr9lr3fc[f'lphX!ph@qcIL[3hpiUkrG[(%PrZr* QhX$[qpVI23bEkPrYapa!KI9lQ'qD!#IaBhr'!1ZhRrMk6ZYh'Yi9jUfdpC[r16M `4Kl`KMQ%8fbmQiPRB#Cj[,#EalZRB!2$e9H,1RUrYRjh%f08RA8Hh+AHhrmqE2T Y&@SdiT)1lYCqNPLSF)1[#6R&,GlAhXKh#),Rj%(0I"bY1j0BpPljUEk*6&ZrQPr "GT[eQr8pA*EB20l(13[Xj2d3-GAhHqfABAZrkNTI5crGF3!fDS8II5Mpp)[FCI) "kcIcYlKma1BG)criS28l(I-KhUNfA[eRiI!KeH0KBS2[p`lf+(@MIZbhm(P2lCH f`2CKkhF'qLqU[[NU0q,FSAV3*a1YheIq(lBla31B4j(kED@1$ckVEcVVHi[eHj! !H5YHS2Q"iSA#UfVc9jam9(j[lZ,CD-krJ2rUZaGB9A'jp9Yq*4`qC[hZac[6"-r UcQ@Yll*qhlUqLfF['BA$akhI@F!KJfGhF@lQ%qT,pFieU9rG!$(PNkVh&c[p9eI NA-bRe$I`3-'Kfi$PNCpC[hhrkZ"Cl5q)@A"$mZ0G*$kHe9A)Uqj@(QrUj[%S-I) Hb`qU`3-%cqSZ)DIkM1V"(K(TbqXCll2#!qD&"-rH4Cb'[kM[eH!4"XqfI481ReI Hc"hjH&Cl*IR"&kcI5Q+fMfHe)IX$ENKqm!I"X`CL&Ae"hc-I*(Mf&YEb5kSh2%E kD6jl(Qc%Mle(dNp,b(HrE2fJYB*RY4%Aj-!TS+K[l1"ChEE(i3$R95jc@5r"XeZ )@h"ck[G!&mrfliEY2KY[1HDN$*lG`6kQ"pAh!XB@2,Z"2Idem9'9YkRI@R#i#2% @2JI(&6cE5qcmZ[+!hdQIhABME2""PIFCk)1SjHZ4Ma0A[Q(p6X3F@1`FkrGbDJr hU`rS&4rr)RIXJiekURL,2pV0B`0llN(VYh5aQmH,Z@"(Z1SeV,[NF3XjRZ+rQJI 3SrdDf$'8iT!!I$H4*phDm!r[Nr,1kfHck6`Ueh+RcMH&"kIMiZXF&HZ*3r3QI3! q[XlkEH+!$ea'TE!#f11YXAlhF3i0EU9F6N2HNPr&TGI"!hi%,b5fj2F!F`"MeAF cHpV2Vh)P1BrrTJ5[K(k6r#Spe#a#[U0Fk[k1[[&aVYHlUFI3bq!3rH(M3DrEL@F UMUiVqT2i6DEfmehaEl"+r&lk%GLqCr0EpFpZIJ1i,1F4a@-f6q,923QELU2l!ci TIYAN*BqUAlQ,hdR%jKr3krm"!*!$#4S!!!%!N!0AHJ!!9RS!!!*kEf`l$3N*CR- ZF'&b583J25!UC'Pb1`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"QFbj f8Q9Q6R9Y1`d*#5TNDA)J25"QFbj`BA**4$X0#3P1B@eP3fp`H5KQFbjZB@eP,'j KE@8T1`d*#3d*#5ThBA0'EfaNCA*"E'PKFb!p)'Pc4QpXC'9b1`d*#3d*#A*PG(9 bEL"bCA0eE(3l$3Pp$3N0#5Th!!!#L%&%3e)$!!-S$9d,iCE!0Qd2b6Z[IH9Ehp5 Ue9CEkEAkC*9FPqJ9+UeD(CpNDpA*@5)i3-Q)R'5k55HY1-"hcYF,r!1f#E,M5[U MC@C+a!jlH+aC@B3V[%icXLX@fR,DNr0`SMITBMNC8cDC6Z*'D,'pk"KZJpfp@@Y N0fce%Me#6X-#1je1j30JAcZ3!!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*IreFIPcl iY(@PE[`Sl'hl8'rq(IEcAE4D$X)KIUZ@bRMmhLE5"2iFIVC40*TrJM&HU6r)*&a MlDNGr`LGr#[p@MVJ5&qYUk3cVV@a0)lA34GE5X[i1hM(rpDrj$emhrr6A[)FrQm Id,[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 @eLC8PNBMkcLAbb96p2B`aCDaP&9&U@-[5hXk6QI5UA49HN(DD[*0fCDk4QmZA"b hC9*QKDeY8Bq9e54!3"2#XdXQSE`ZSEJ`S5P3&#J)Y)Ab`R#S$SIkd&B5D'e1lV3 f*HZ5PSJk56D-!bP*#TP!2[bb3,EL8QK,"6+"jSS2"5`IY[4X3MD3!)N6iRa#69) '!*!$,d&%3e)$!!"@$8X$RHJ'ApX&YA!,!-!YrkSA!!$3@iYDH!'Kj[m$@)8Habq AC[SF!*!'*lp"4%05!`!rmJp9$AC'!4!aiqGMIjYcMV()-TE9'U0IM"@MlZFhK%X 0M$Q(cV&kM"'6f&`D[K#b%A#b!`R2br85Na)aK#$0iD9FNLE'pSA*#4a,Z66Aaq2 4A%Sje-FeP%XTKkD%BiLe3#RJ!((Ipr[[lr[QCJkplE[hrI`('k5R+%%3*%%52*% "I!+Dpk1@k$81XCK2KMmBkh)ImdEZFT0$AjL%ESQ#Q[A"f+5lUd1X8%03`%TJXZ0 G8#P3K%U%iPa9heDKjeeZFCT8f%RNL[a%6Xl(Kq@H#NEkblD+H`kJd#!9&R6m19E #N!"@#`8L1LLBQkT*bA,EbTI8INfUkU#1afYrX(Z[U%d8m(MZKZ%5'MEBDhm3C0i JK)p5BU8akQ"S@![63Pml6kiTHVpAihr2j32Lf+fkG@ZlZ2qbbrfRcfYiFSC,bG5 Y8d[GbakZ`C*!PqQbISC,9cUh[kq,Qp3XJ@&0&dqqhqhq(hIamEjq6RGIeV6GIBq pj1,qPhCcdd[G20RajrS$`9R3X$UYkqliY"IALYEQ6KjA1h*[iHHed5N0*R[[V!i NhcQ&U81EjPqfE9TdZ9HB2YR2ihfK63fRECZq21eb,hd!JqT8iV&%8@1[1[8Q"(U mB&C#-Z4L!dNfeDUT$R9UF**EDh0$am8D%VjcI3Bl(HC)AEh(&bT[R-U`MaT@Jph SYKeETNk06r)iPN6GqD*Sf))1(1bLli`H9iDUf$lE2P[YrafP#h@UQh(Y)eAQU!L "dYE4-rA'5f-6,@jF-Qe%FM+L3VJ20NjCD2[LY!M#e4HMHX0pp*'1e"CVaQ'`l%a NBCU5(l-J1fM"hCpL`8$3JXIql3+aM&$4Hci))BmbK)3b8IXe[G)kX8DXmGE#9&M +5leI#B-maQ2H"K3Xh1,p5L*fe2eSD8VFMHJJ,'U-N9kHY$IM&A@14GXKc1b`Hlk a#dE#'"h5B*,%,2(+4)Bb"DC5Ha+[)UFl$+3fh58MPq2TKVX`,*Ffh(9Z5fmH6'* kV36NJGU[XHe(eBR)*"IjkhBV*CH*BS&Sc6Z#@4$*j$*aR`5JE-J6C6Ipj21m0$X JhJ(&3pi1JdT0KrXQ%UFk2KPJ`VB,"cZ,'"TZmZ(lPR9cGr$a4m0KCXk*TNYKFSp YHhhhRQ0,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'NMce bMIHiTM)8,Si3q[-$J5YPmE@i8MYGLDH6Jc$mLKi'SNEij!B')[YiVD9UbRj-DG0 1[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$J5[Le6M#a%jGIcYS$XYr,iXcbdKC(G3Q$fUGmKST5B)N(k2K) L(V39,*!!!15+8"J+5V)4'G%bL'$'UYdM6b%m8d5NaGX18lL%KTpj[R"peE$L++d DlUXDpMRmUH(c!4,V(899``%5BijNeA#!4"5Ek8#QP,C5hSp-d"F@e2PQ3jiX'qD ,qILjGK$!Liqdl4Ah)l"e`f'%dRF5Ri@14)kbKYZ6L9))T%24-2H,C441`DF(`TL d-03V[S2N*jXYf4TBBMN+BHf'I'!b,*l%0$(mH0L56,$k(DU3!0%X,G3*FKi3'3Y eLhfXH`X4!ZReSrjd*&f+T!hCc,b%e"8,AcdFFXZ($0qUr8TU),,5NA%NbL0eeYP pif-VZ+Af+erhKBa,h(,6B%rV$#2G(GkR$akADkj4Q'm00Aid1*MPE@CS`#dU)B% MfRKL9"rjGpSdTkGcXpSrh,rlMcbZ3rM#[Icq1h-I8)cYQeAAX)Z'ep,`RqlrHXB $1-bMIrd04*+P40V9dqmDI19Qe$XqG&b0fa&98hY#%r*H3eMH!pBbA*JI[-RpFS8 b1T3Rm[kM!mQ%Y5&2VR!f2iY`XlcRi"PZN[FVaKk`$i"Gl8q%j6)NSrj,XhdJBqq NL3M-`E#mAjV)3arTX,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`MCd*!!NY(FBc"5`c`)0GZbPa)STi*0K@%EQaHR`18J"F$U,1q Yj3MD%YV'R(d4&`*2fha'CjJYeSN)I&NDf2,@l5jAeR+@H"9KLbGad1mj6#'p21q J5clY"[$8i&X!3R0,fekj"JKd!S9(@(+I*hpLKb#T0"ZfJ$8A@EI)qi2-FF0mq33 Y*mEFMk('RY#0'lB!kHb'e835a#CUrkSC*p5Vr@S`UrBd8kSQ*MV!R-X#[jbIa-F rq)kM35QQJ1l3fGXFE'MQRilk2V6I&$iL03Xrc,ZJ@LN`j25icj!!bJ0NAS6NcUS ZiRiS'4Ui"85MIXkG-2A'r(-JVXF`e(Kp50pIaZ11q*`5CGjfZVBkYU,V0#P2&!l f&6Rp!2AbB,,f0!AS@`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&6MR6hT(@f5lHIS!j#*pT%m9"#YpRSp@#k'`"YP%hHb5l9I4$0QTK !Pj'3!)4e&50"baHc$IHaaF@%Q!k6pbNb,80KjjCZTXUr4U!m9rM-HIU%`m8%a') N&46J&&Y5)!QUD!Kr`R!bj[@`j8m4HI`$&F@j#9e@dZY*63k`XL&FhA#3!),AR"2 qFB$`q6m4N!#C3B$-C@3`P0`D!%)!d(RqL8)"%!+`DYKfr[QdV["5(SNX-6VXK#k q)m8!FQMk)-lNPeE394+kTlmPG@)5NcmeVI!aPF%%RjBQRj9"M)H%$fRc#p0C%)$ c,BQfLL-m0j6l[0Y@2HE0mmVN$##+kRMZYPTVED+f"HVPIr&1j+l*A@1`-j%'dir 8*9YIc"0r8Gj)+1%mVkSBVKLTbh)JJdD"L"EaGdi@,RGBAY5A[dX(k-blG8jLmff AEGC)AH[bK'iVhk![hi@I-P+(b[FDE18l0a6`52QqNESM2Q6hJS!5YF'QM4fZJ!U Q(LkMB6M$',[e'r6DT-'QM6#Q,'a@5$X'pBf!G!cU*TYVIiGX3pY4+!hjDhm(Yje EdQHdpRFrq&Yh&TCj62U5%V[TQL9!''Lm#kTIc'(XdQZ0KXAP0EiXTj@TD3R@$&Z "2&Tlj-dDEM%C(5Di5m#4JlF,kKUIj*b5#--@8ZSTF8MVB&Q!FKTe)V'49$Va"T* mZ&)B`Z,AKY$KbLk%BEE'S'lD$PH3!-*jZ%bViVU4&p(%D6I$D(!%kZBK8MVAjIV d!aP1AUT9EFHmEpUd8AkGLQd9@jB3f$L@9SH(3'G+TQN38kmVp1QRD0%l)h9KE'f XPCC%ER,,PKCR+j3i*hjZN[VVYXN3K*i+Al-J'B9"q4TR`rPEBaLZMj!!NPmjNI' m!9F*D5ZK*$r8Z!cCl,F1IfiBcE%IcN@f6@iFma`NKG8qr85'diUK%@QSJSEXrQp L-5ArCkGke%'Gb8)L0E'3!"Jp2%mJ$M-E('YH(Mr4YJ#,#Z11F4L9jlbS"cKj0)f f%Nh"`SQ-)%+F#1hHFeJ@&"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*fHHX'f4UAR-FJr0pa8Kd6bqmH'ZYkMrj"`5YLN$-N!$Q`P%QFe, ('K!fr9Mmkli!S*DhI,h1YqLkkG$K)i1K`h$kDVh'",@i8fhDmFZEK+ba3e)hYic 4J3P#P#1CSa#`X6N#@PT-,(X$aCXI6d2TH0S4AVcaHZh`50hQkHN3LNqKDcU&BA! NR$IkN!"KS#)XmIADNiD3!&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$XG8BcB)"*KTTKhKAk&cMbcUe$80qChXNbE2XSc$**,P&BMMMp2M DZH98$-0qER(5F"B+ULpNVT%QK!PhMqj#"LAEKbYIe*YV*$2,Rf2,#!"I[ZR1UH' %MTrm[Q[BMF+(UedrAf+2NBNk-ClHQRYb%!DpN9I95p6JFFZ`@dQ@VYX-MdKma[E TcqS0!amY%@ZfVB!4-0mdrj8#8BBE&4PiYYS02TMPmP3-LYc%TNUm3SkPq0JmI'B )(bCZ8PS0cl!P*M$(l&%-qc'F4+%84T0RZ$r5adf@G&imeQG*pqMAkAN@)pBFlH2 qcF2fj$SL'ShN$iUQ1eH&ckfa2Y-Bh%6rfcBGpcHSprd($2&YVl6aZ+r2p2Y6pGB qbdEFB8F%aM"R()$2AAF64rId+rQQ''rfjCGUEGfBZKR,G3El4eLZI[TQIRb!ecZ L1BTck-fEI$hhj'3j-eqibGrLL4F+qRY@IBHh1LcS6VjbNhYB+15+ZQViq)9205[ +,Skm5eZY-QI$eDid1ARah-AIGrhXchB)+ccb`@*bpKc19NCKBPq6d*9p0)cKHDI Y5GpTZeA4lUlQkUmDBI`RYK)$JZNm0[+NHK`CT"(X2FVHfdqF1irf5E%ppra0&'k GrkrREk13!1diG`N44Ik*dr'ULX*lrh4,T8,&UDZh8,"N2[Gbi5N8$$BE-9KZRA[ 14SAX3T5S`+8r)-iM`pKLKcrb$(m9,X$@b$0)mD*1IipH5FEk)Mqr8)+-S+!4Ka- LL[HL!@"EKJmI0Y&[5G[lT%eEVhjk&1EjBeX5h`Ul)rVaHVXRSKqXYmI`kS2j86r H"mGD##HB0Zi!1MK+#@e"LJXERGHDd0&4$V'Mr*I5e5kKX9L3!1e-BJPANM3!Gd3 ZcaD3!)&lKYh@HMZACmhM6Zh[rd10SR-H3qCNPVmSZK@K))BHRLES%5AdL%hb,," I&&$4jU'V4Ai@`Bcf#&kP0[pC[3#JV!3$jXd!B(f@k)*XHjbF&VR(Qk'1JfhY6`i ")FY&KLq43h'XhUf2rG#(%)bp'DqNhImMR4,,e5N4iI0Y(3*%ZMM!'3GDU-I*r@@ N%FV*E+!Y%!D1SA!YiR&#Q+N-eV9-rI3&U0EFbKJmZ4q$SARN5D"V"S%63qM*kFr j@$'pr6%5am#3!"&$aU#KT#-V4e(mMUbhP5D-F6$'Q`a&-"5K)8T++*3%%A%[%2M 6N8BFaMJ3)fQkidcQ2KJ'%cPjKe2-%l82i5$m`pP)LU,K$b9Re%qCZ[!8#@beZFJ @%F2VkVKp''lT%iPk"$5MGXmmr98%CFqffC1aqRHA+GTBV%HI'djP'aa$5cS,!NC -I2c"$&,((C`F5N8MM1iJ#!&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')`qM8P1K E!P'SJ'qVIa(q3G`64,ajT2%"ZV4VeBMV8q(D%[Pp),HI!GVN)-f2-k)a!,U,$T3 18MV3#SRiNL$LS(eIGaAa#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)0mh&qlp1"a!U,f(c6M$K-F%Jii2G)LFQB2XdRQpBdVXF!``1V T!eK1NmErjYrL%-R&AGc)A"CR"Y$aT,$Yr@GGUcVkHcXHl1I-p0qRdd9QU%Rh-JT Z9Jp2ZNR*RMMra-ZN[0EQKXG(1kj`YAGS)YqL&2VmpQM-kLkTd#[q@+Dlj2D1jGc R[fpTYppA#TAL$GfS#V(M-[Im5@"4`T&5[Q2lE$-#E&((TXC5'S!,RU[`6PG(GGq UACBf&(453EpU&ip"K0aFh8fL9+PBlF+`6qSHN3Sp%Y[6eIF5ffDaHJ$$&k4Z45V FNYLDUfm5fcUaqJb'mk6ZFe,KGY@89k3T#c"F)R9IP!VCM1@'a(+(QC!!"&0p&Sb Vj1`GSDDjjh8Nekr$058kV,I#FELRPlS`''[S,Cb"KMiD&*UaEE`MK)XqcJi%(5L ,D')8K(0DQG)-pCRI%04RT4iG1j`80SY')Clb)JTP34aI,T!!K8%BM0lcETYjP[I lJb%%Q'SDEHBjU*!!mHqDN!"jfRXfmdbB'M#apmE+ii@Gp'(Hllhah['JiH6Cd-B lbPjdPG%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#qa 3#"-+qkCUB4#-#kSBIp5%dF3BC`Q$!$P*Nd2GjX,N[XAQKCF+ZQcQcmUAi,@m[!A (Y!6(Y$5b'+%2MZj%SKI%mbeBBUk$S28@%pd-l9`DA#J-3Ya"SCdVQE4!BJBEXD3 k%k(bkBdZ'%YQNqX!1F`-3!cJbl"a$"bfb4r$K,)%2p-hf-b9j5eil4-@H,m2BLY C85XJ#aaJSZrLmR5T(Kb@-)b!B"4J93@5Q""`6qf+VZ2QP8$L([0RH'de,m9,-5r I8'!aQCIJ)f5HMYHRjKDm$TTRSi1E'r'K0mpL(62a'M(2B4h69*YjTF28H(*5MbS 6bC1&h,4"Epkh$8,)*e-EfXb9kb'XRi"c`!Qpql2(),*[-*42aq"m$#ikdFB'NdN $0k*M550G&SFb#eIEd&EH`P"PQ)4AZLc3BbrE5*i+lLrUlcUqmEUL"V%FDFT5Zij BK%-e!*N01"cm,$!X0YIKCq&JU(bRpbjHqlcAT9"ChE2Cl2L0`L&54RdAl05TdQB 'MTB0JXa4bQiNk[PZ`[4#KM'$3fa!"rYBik0LR"LkEQkCCMk+c6Y+VM4NmV'6dGF BaP#A69i$aU4$l0+EMkTC,)-4!&8Lj1ip-ZpDTD8%bJ*cN!#$c%%%L(BXB"5b$*! !q-h)5X&N3[&V[$dNDdJ-&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`1NMDNk0 ReFh1P55`eJZ11%H`aDqLZY&Lmi&E-F1@3Gh$6e)6AIY2[R&lM$SGHBdIiN!2T$) m,F)90F5m854Q)0Pb(0JB(9K#RdCie+YJHC`kiIUE2j!!N8UNf-ATD(8q#[V5jQk $)H'Y"$N,5)P1H5*PEUN+lMmf8[H,*B)CJE+T41i,#TKUT0!e"50(kM)253I13Kq EbJD3!06+f04IPl&0XkB-416NCRE#%4JQKZT-r#cVkS#"#N(R,TF8d)i5-SJG$"Q D,Jc$0(88`D2N)+T@aGr[+TKilYc,fPKA`GP98bm!S9)NR[E"2%8U+Z6&*C,4dU6 Gr'qQLY08mVke)5e$#CQ-`$1!c"GN"ej6mXZ'qk`KqDEli8'Ul"#5E9)K,48+T3) IY+6!-Ph!346*&-Vbf'%fP8IPPjR4**k18"JrqID&$!6`*C-+NY*T$6EjPPeP6*Q 8c$9eVCKl"FGj,i5CZQSVVM@!+af5c%flYRme`65lp5db"FP*ZP`J'`VC$aR2+Q@ mERCaLh4aK9em3(jCJa!X,[C-eG925B@`9$JM&5b"UeZZXUYEF29kG[91q@8!Ib( iqNAHl9cIqH1[rim&)h8("ZMkQi`-KHY6drhL-Ph32-T-CCc2&G"YlYbe2(a$B)R H0YP%@IE"K'4QaV*Y+-VfGPqrIC+51&PM9`'Q4TZ*E$6,RQQbbFJR5G[2GQTEf5Y 653U$'fbb6eX2CJ13!-dQZi"U0VP$fiIAK&BA3$Yf!$kl"J6Rf$YTBZI3`9j82(# *+j!!*CG4eSJi`iZC`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(kekR0 R*-aI&(I#F*k%N4a&9VeKjl-VH*Jre)-LUf##*!9,CX"i5L'fIa5BGQ[j3k`i)bF Fk5epp"*9JQbRJAHT+J008H8fNM`UQ5+,dk4BlF686R+-LT8%9dBCTdT59BN*a,S l!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&C cbDbG#d*Va1[5iD!CKQQLl[!dAbr#0dQ3!(p"YV#'&Dl-V'P9cm#XKXD9@iaRHmQ F,B![qi4XCh%(VP38EJpTTqJB!-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,e0YBRDiBjI03*Gka`ap5pNd%hmK@@qX,J#BLLbh82A#)`H,),!"'F *XEJ"cLqfT3,*U0D`@$MiJ3a-9@drFl"Eb-*JU"BbEK3C4qNjfrX'!hNpMQ!XB,3 [KcTbE&rJf'UH9*28P)9,!S-(&J!B)@RMFR[!P#iH*4@L+Pb(N!$q50e[@aRk0GZ Mj'3#B`#3!*-E!k)c*3qNVUcD`kpSG+89bM"6*&G6dM*cfUJqr,RhI2J'Z4M@rKk Z"(rSkCh+U(+FcI+1qcjdcJjbcMa%$RF`9V$Q3c2*Vb1TQ8Z"369dl-XZrE%[m,0 LJfYMYX'fXG9JUmj"H1N+IMLDT8r`8lmY9$l$e#EZX-GJPDhfYr'R%GVHMm4kEfG )GU#`-[)BjrFFX%8RG9436*0&%,)3L$!0851@KU0$1R5X!8h,LXXA"@CFe@U,MNS ,4V&J)j))bb%JiKNimY'#"4LiFIN2)hADph`ADF'P#ck!P9FYC%RY)CBCh$39$"a qDBT'harSF#mP`(b&-D2Ke5jKc+dd$CK,*I)r)PCKdd50!$)H2##!FJDSdCN18G- A[3+8(+2%X%Qc9ScYZ*d+B@h!SCC2DqS8@-U4)$RbS%cMN!"+)-$KXV+M-+R5X6& Mm$d(`P``3%&B*b4mKT!!N!$#V&fpD*`QY$%KmiG$f[VfV'q$(&#[UTV)50fK'Yr G2%r%*[j&LbUC`X'8cjh+`*60T'JI@iiNrdF$'D5XmQ@TTJFErdA$iQ-Vk%#1)6X Fqa+&,mM4M5&QK+QA%D$,&cf,Mhe"TS)Q6S"@##20$A5e1"9rMb*3'+qAb%@[(Lk #%8-KEiFEB$-pm!$'A,Kdr3J"Y%-MkABq",!5!![9D!29q1N3I$Gj,%p,46K1)jZ 8'`11iD`jY$*MBBf[%)c9QRBHSkQ%#GK$&)CH+N#9arDAb%@`(P1@![RQ5YN16GK -V`D"VN-V@D0998NH6IblpMK0kmL%fCK9pFLTFLH%JY@-CS(%Qk6JeTS+[C)VbSp RBikBriD4A#E`F)US[CiF'[*H,5aN,Z-!6h!#dB`(h'5C'8GJ(`-lBb,h#c)(1U8 VL9pUq%"'X'XY1mL66PBC(qBm90Hh5`fP4(Bq((Zdq+Pfk+K#*BS,m92'R$fd31S qE`DF+`U%!DT-LF'eE("ZC$kjlSLI1@G&jM1hRqA1*A!5LpKeM(d[@,r,@0Z&!BQ %L)k$V)-D"Y(1(R4J1!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!NPbHfj`L8qceQbUfXQYV*MQjZP6Y5TH$ZJki1iH,Q#MDG4Q#Nbc- (-B3pK5BLjH4$KPlKD-`,fC+)F'"Q,hdbB$Tp#01S4ArrQS'B&0b0T%@251aAT'R 2#CFeRi%lmPkqNicNJXU(V6R0R+,)l63ARcNS[)e'ZjL#-*,,f0X`3cB2!pA34,m IP"NX%(6L3VBK!5MPPN0,i3J6F("1`T8QU54lHTAC$Tj#GMP1e345&9LZm3)%!aZ q4*8!M`HSm0dTMXI)E0%M@0[&a)S'Z!R'hB@FUKG4*LL%+f%Fj[Tc)CJ$a*-(Tm6 E!,d!S#Z8C6AFe`[hNRcQ%RI0EN`4h3+95#*k!@5QiHGa,0iABX&@XB+4U`'C&JU l%KRRHVJp'C(`Q@Kk(16%50hqDXdiN33j9#Ak,Ki9Jkj62!9Jmd3'Ueba,0KP1RA 9dEP0rNqNR*mGr)0K04T)"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[eQ8E hBjGG[[km0EjqCj`HL0+!#N#h*JGZV,aaGCqLCPS&"PXV'+b*6S(K,+Y3iG2R*Ep jr4[6RjMa[eZHMlBE*cmC+PDmhjMZp!pmVUaTAcH+!69qm[0+226KQ`prFVd5MmH i&%[(@B@5-lePc1'c1Cd&4e#UG$!3MNpNU&NR2rpQb98Z2JQ6qmlYEC*UR2c9k,+ Uelq2PJ5lU,0!'Djj9Rq1UhpAr`l9YTSk"r&3'ULQb(JNU%A[3&L@QVmX5Zch96A E3*)$DjXfd%!e`C5`6jG9iA)QVd5RSi,H&@lUj9R*AJ6ik[b'39f-*TK*9@8d+pK NU&3ZjKPX)J`3BUA2aC4kPm2kpq@VpP520YkBe+H0JcT,Ql!-XYfAh%m$8-jRZQr UbHeX#!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,fiblCNE8MFEqVI)G+M&S#SR`rT8D89#"ATjj%mDap-@'*P@5i Yq`V,P!%D1"ICaiEm0LJRZpCDKi[FIhrdJ9Q,aCfME3T9NZ(LSh$#4q8e0'fS'VH @UdAZCBpQ0a+,RNMX+b%#C`Q3!,0S)&[keN@k88Pq9%hf&)1Y!T@8,dD+bDR5&LH P,RQS!)NiA4DZ"bj*`(i,9CjVX&"c5j2``af0hkYI3iqb@"&m'&Vr6hmB4-cCZSD 1C(HTb+iDVlTU(0I[")[H+B"d&5,NY$@kHm6P0R%rBpj4aEa$h*AFcGZDEN[jPIr [E9NX6[XrfjLKi)hTC"[6fA4MKYki-6eXBkaA1#TkAh@)MGdDIXAbDe[65aekqkH rP2V2MApVr&YL8Vkf$%GfR8fiP`(m)GKkqK2p+l),Qbql%[f6c*hfG,D5a%IbG(C LGbFEZTaGGr'5[kii$bjh24F&4%QK$!*p*i04a[mCS8cN)KXbjI1cZjh6&@k1NaJ V9Z#kILSJG,*lEVCa,VUV&9kcLbh&idCD$b"4HP)`S*0a3Lk!)D1!URJqQMfT9cb M(ErG)qidR-*MTC!!m+jC)BSp[4-h)VeCIPYPbN3ZK(l*+-3U58H%"f&XfN80pa@ Hcrrk'b5dlXH,eBjhIq1*ZIm`p*hre&+hffjF@aVT&d@R(pPk&"ArL`SX$mhhp9r +(-5@$4E4BlRiF,K%DNa1N!$`dY-pm2NA5)5IQ"IX8ZrJ3f"Ufb1rBc992'*UicX D%kMY*(hm8Ip6I"VBCmP2qM3CK+)D9#9T"f[D*R&aQ0STN!!DbCXXX2`k$a8G2)P q((mf*6H6qVljh2V$AQkDiBVdalJ0CLPHTr1EA$[%6VmMXR0arU&Tl+%DpfH[1KB e#89+TXK)D)q4NC!!YUE(*KHX[kXi09EPDV5)FhYBf#`NP6[a'!Lrm,RU506[Fk& jKfY53PV@9k,K5RX6GP-9ZfPll&89cYmA'#RlU2S%,S,M2a*Fe4M9ijLD0QQ6me( T$Jri#mim[cbcrFccm1+UM"0$aQQKM%,KQ4dL5`VQMZVleYhQ(UTbM+lp,![p&3Z fq@'Q')qdmD+VR"rGA@eC2kYYeLpMI14GHMJ!&YmBeIHi2(Mi#+m-$*d9KQB&KU# QNI#q6%S`QP-2#VVrJ4m@#`mZN!!BLjXQ'9Kd)cpV#6,h9$F$MAAG4ee[)"*8BEq +Q$+52dL,NpfScS2PZpMb(rbdbf1"6iHPdHmT)8@UTlHZpbUA[lJQ2AVXrZbAlNC 0E2J)QI5&6&4c,kUk(K!H##"Abh2N#M%LkX8#SEUl`Klq"A6B)hp*kX&J9J`"9RI *)%mE"GA&('1CX"G)rVdRCU8UUV-+VAh#eU0bPT'bprm%SP2P#50c54MiI#9Pf[e TUZ`LLEFETb2a+4%$&D@4h5Y23%'-GYR%LZTjAEh9#j%JUG8V0pJfCPF[-LbZIUp Y6r8R9B)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*&GCMbmm4%&838*RUD!J9b"3)RJ*##45B!ibf'B+-KTJ!N)C8FRrr,[ *CZkTSkQM@Bm[2%4548a#CkQJ)&HJ*5"3iN!N$@!'-KM9Y4!!8FMrq+QM6R8JAc) B0"L`@&I*rrT+3QIq6[!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`!%51Fa!%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%I 1`%K(dSGP#*+#BJ4%J8je8d"Jj%je!*!$A!#3!i!!!!aB!*!$B!#3!b!!!$mm!!1 Tm%&%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@8J9@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"NDA0V)(*PE'&dC@3JCA*bEh)J+&i`+5"SBA-JEf0MGA*bC@3Z!*! $6!!#!*!&-3"R!%8!V33%8A9TG!#3"3S!8!!F!4#)'P9Z8h4eCQCTEQFJGf&c)(0 eBf0PFh0QG@`K!*!&#!!1!#J!,U!#!!%!N!0q!!%!N!96!(-!C`#["!*25`#3"33 !53"&!5k)A8&Z)'PdC@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!0 Z!!%!N!9S!(S!I!#f"!*25`#3"dJ!AJ%PL%j6EfeP)'PdC@ec)(GPFQ8JFfYTF(" PC#"LC@0KGA0P)(4SCANJBA*P)'j[G#"cGA"`Eh*dC@3JBRNJG'KTFb"cC@aQ,@9 iG(*KBh4[FLi!N!0D!!%!N!9G!(!!F3#X"!*25`#3"dS!93%6L$T8D'8JCQPXC5$ 5AM$6)'eKH5"LC5"NB@eKCf9N,L!J8'aPBA0P)(9cC5"TG#"hDA4S)'0KGA4TEfi Z!*!$+!!"!*!&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-!p 6G(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-e2bQAp h[qrELM`EhmbhY8#5eFlXbH4*f,ilNa'5j9ENLDc)laq42j1IbEcCeRB454B6XMF Yb5)S31)(rdjCKT&84$LS#cYiiLGf)5c5J1e3aD%@GK*H(mq1D3bR6lpC+R)6)mR Y[@4[%r6@hmf'R%[)+8FIZEr5&V,ejRAjaL3*5bPTf0kN&a@6NPGC,a$mi-RK`KF HI%V$*QM4BN6+hFfqTX2b,*5j55k)jb(*(2h&i)XDJqim&Fee*9$cG*JIMZ6*i#S GjViNe#Xq)@+3!*h[`af,NK")heX@$ED[(5XhPA-`LA1fRcbNbSE0RBqrZ,m'l)Y Vm[NQUD!A@)"Ck2@aqNDT+'b%UlJKdF4%D4j'8D8QKLJRXm5(8JQR40@4X8N6+L, JmB-'82KL!,85ECR3J#8d%@TbLdfC`eLTT"qR$+aeU)[Di0J#T6DMFe4B`aLflrd NJ-)Z!m3jBTLiESAmcl%RFHbLl9fAJNh,JDRU`pD$+ZFdM(GdeX@!G"Z$#pDfYBX aSNc2)HBbh"2bA1lEQ20L2d(0f,[Q&#I)A'ZQ2(KBb@@qIDUNT-rSkShVZbh3b(2 j4EE#Hi"%aD`5%YXK48JPi!JpjfESS#*')G-lpU&Zma9#N6ZP%AF+hP-PhjBJ16h DlDNc*qDmR%1jlK@TB-cEfPh+FK[jplG1#3aZ,GrmP`rLNbG@J3Mpl)N"@`NmD#E 1Ye,'NV,SJ&0-'N"4lGDH(L15jV)kGQArf*KLjXEBBNT+ilSFVqIQ2L6S6,2!-qd r5A,SM5rZ8%e+qrrFIEa)TAK+(ePf3"KU9mH96KeiJM&J8-CCH2(UplHlTpQ8&pI V!mfS&!eYS22Y"H59K,,GX(5'$iDUN!!D1!1%4[Dm+R'd+EK+q$Ll6eBP[SHY1Jm &+*f0f9@c1LPl$U`!LB0EA#,N"l-#h9`&eEjM4RfXIVf`GZf$Y!rlJeGII3NEUUX [JA!5-Xp,Z*!!K9k#PFalib#6LH[)jR!53fYB8Y@+#cA4e!fZkRA5eL(bC5reTB0 Nq+`1N!#ULm1*SfpKL@KA(V8&MK(J'6fDpK)ZJ-$X$'lTUd'pQXb1L-Hl60lqhlJ 2YkIbbBfVNkBAI5lbXT26-1CCQI@i%dADZX@J'V("P$45$f-VG@mlh@!+D@pipZK GMr,CUC9ZcXXMqF'dI'XXGU%XA8IkajQ+#fPh$2Aj@FVRjqVrINKT#[0r9hl1a'B ar[EhjGLF9@FZ6fPZ&[UQ90aX9RVbi))fT0[hNY60m9Pip++5qIc2PqqBK`c8pE9 GaLXRlhFHm(""&mY9YB2CTqfiUkZ$G385RX(1bd[ERX3qk'4JZaVPpDGj!R%'T[" 3[!PH+Gc$PhJ`"hHqIVA3@F0Eeq31!!!",d&%3e)$!!&Z$98,Sa,3(`,[MX0G"i1 VS')4Q(4+"CeP@S'Clmb(SM82Ip(I(*K(D4A2I'$q&[0K9K8c&"2&r$@V5EkTU*K 9439&phSP6c(*!"1aC5A+J0LHE33'eM"R5Q-Af($455FbMP!J*%5L5"VfFJe#ABT bVcRA4B@a96dp+RHhD`rFF&F@))QYk$RCaCMM3iY@r'%I9"NNRi3H&+6Nb+Ekq,R [CKIQhmVFF$J`VdQ5m'YemhE`p&D5E6j5(VmrPl$l$k3rXTPHl)!0@&jc$0ZABIP &mp&"JI!#DaENdTMml81I`#icTcGeq@6Upd1K&[m+1ImYiqD1UMI2ikh!"rA+h@G FD3IbmLC@e9$jp9!k6JUl9a2!KP1+'B$U)Bc230$[U!%J"*%91SCK"!!!#4G"4%0 5!`!1K3jG#k55),ibhjhrq-jHjTcIRm3X@FlH1F3CSh%X80,b[R0QLXqEJ*aX40@ UcFUD#%5Rl(e8JllrGqBa*dc)b``NKG+`*T5N3Y"1UPMIThV[djD9N!!b0-6@8G9 SS`-*3XV@EJZ,ppfG(@H&VG9l$HjZ05)#-d3M(d0&9JkT3rK[IJhrMG+c8Cl(B+4 U`aFMihF0N!#jkkJ(bAf)aK,IG)P[ca,IG-NC,*)9Q2S@4ApLIjK&+S'Id[Z4`Ve !C&F!hk33*VJjb0NB50)-%!X)p`RCp6"I8pTh4UI[+E8`dFID4ZkGr@lA$AQDlbl dTY[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-bhq8GG`NZPN!#-)R+V%99PNPlh36fhm*9bM*6G5(DLl6*[`RR N%1kYe0apJX"08h9pBpI"UeK@ZP%fDY[@f0f"j$FB'16,"hmb'lqqr(ZIF,[qqr( 8P4F2LPmU8Y6lJ@,C*HD'0C[m5%SlDaYhr0f9c5@RlpTrl%Ba0h%pIrF&([T)hhC PQkhZV!V"p*ICGPYr00)ATYFTIIZZ+Zh!F'lqJ+RpekRmf5JSrZ#`Jfc9YhilkVT Hh9L([6AGJPqp[j5#5'i#SGl@1!l!f0$([Z4B9)JpbTMr8K%pV8&b'lM9+a*8%hV &U'bb498Z@DQS*MRZ&3U9S9IX$jNN*bhPP@UI8TA)Arc+eR608jlGh#RG(Y%mCIV ZHjY0eR5&1qC1dXc90emD5,Ej@(eFD1XV&rqi5CRVdF[i&43@eN[fU#"2lpYa(Vl C*ZUUNZp0XGNQB,2*LUI#aR9CrBK0&Sp+b8*6C1J9E63Tqf"5i25flDL4ELQ!0#R 1JdB29[1P&-F&`EQV34i-5ZXME9iP2CJ#Sq!JM5UKU,HpAUd@9Ujj,Ce3erhrA2Y 0)fVEk2m'%q('2UUC%2HLD&+GqD$mXUXk4$HdCk9'VaEk0mH(e6-fT4pmjRa9e3I 09fm)JH',*UjGkCYBVDUp[eRI+)5dJF4`UL@ija2YP0UeSHUUm2!Y1A!N#i,p%r+ mraE)KC!!h)mYI"M-*-j`h-92m%VhR)6A)GbRK)!S@)q!m3bE39ZF$L3#NlajP54 K$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@N10p%$TmlaarF12*%VqVQP+IbmGAC[Z(*i4%i0ElMdXHT++-Z e+['9N53H0#4Y9,3%Ib#8d),3L422HK!GJGBFY,LYf`X9ljIeI"9HZ54kVCUF308 $Ta+%AGi0FXiSpX5"dhYD$!,RQ3U0(P3fjfdBeq`NrZ'e,erl6RVGI#'mVR"`phb T-2,3[')Sd$cb3&!%V`adK&KR!aa2Y%%,Z,h0rNH#iVJi,$5IJe1*KV4GN8AeTLJ dhii*%jh+4+0lL-6G`Gb!1(p'+l"R#Xqlj[FAI)G0QQ+9i'Uh+QCdXfkhYb)Q$Qa ("&X5L'&#mPXXm@0)Ucd%5eJUcINKX48pJ6d%PbS*K&[ci9Z%V*(I3hJPL`MrdJS I3`D53``T(FqmS[EkqkCA(rKLZIm!-KZ&[1GiTPFGl*ZpSH[blmr0kANl3fU1pr3 DII1R0R@Yr)*!qJH3!1C*GFpaYEH[Hmh&ZN*A@%M6!%pD0diEiCSl$VHQjr`k#`[ 26@IZ9DI$daI6KAA2pN(q9D3Y+FMIp2MMdq%6Qblq,Td1hibPQPH&k,ZJH0C&,1f SJfdU0CD1i33[B404!YdjT'r8eK+UMqe@Db3GV(dcl%e2@"m1dpJq%Rh(6&#9H,q %2[!CM`9RLm[r%li9iPZYi6IUKXJLDiC`*LQ1j@0C1-R3A,AUd"L@,!$X'#)f9Q` GU4qjDTIlE$mqA(M5%LlfVkUm(4R$6f-Y*2qH0D6p36il*,[YSYC3Ef@,rIqX9*l !Ebf0'B$Bc0CR("AbR`1@-IY,[Y#8e9pF9R&@mL*83(aXZ8)Z"La%VB`"J[[p584 Bj!eI5+Z3!-m'FQle8ke"Xl)9E+f!P-EiV3U5Rr1e(UmFZASXGdNpP#jSPS%Mep0 4%N&XLQ8J!kB+PhfShJLZT1Hk&EZ'!AIMZcc23,,Q+,p414k9S,B6,'a82bfhAaY ETNrA%56ja02ZG*T5j4lME!"-qUA2Y$MMJiY4T!6X@Z)k)D`B8d'!AjJ-cVeXTE3 (16-(E(Pb4Q#Tj'@9#%5hl5$Glld`DH2L9KVmeH*EFa9hpIDl1`$QYF(BlY&bTX2 dqBA$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[p iVX)kEUcG1DPY3V0$`62A6#EC@@pc!%i&h!kia8UMBYEe3)A945F$!Zi8m+KTci2 1HV%pT#rHl4bkG*dEl!9mF@EmL(@Qr)X@N!!HQJGM-lYP`%2C`r@*QVC6V('0%[" TN!#F,[k0%(eX#hU3!0aHNqRj@JSe6JF*I04KqTHADUE2Tc,B-J[*j9f1hMkq&-B !U*!!KfX`AB-8B"Ah@IS[4f&li'IQ$1CAe9if%aiqGN!&Q%S4&CiQhDIf@FS1cNU jaA2YaBpQiQbY3i'CP4mCLmX+L8rILUK3`8dZHmjaV0YkRM[jP2ccRlVip*4Me-q APMjP-@A,$9P,I85&#Ulqe@iaGfcqU-aPXh*qlF1-@ZZSlH5C1mA0TJqUQTkf2j& 8)5`qd`4i3-FVSVN)cQ3YT[jL52V`9&+&J$mj!EMGASjQX`p@2&,*6%A`c5D4[Tl 00DT3H*AkL5leI''P)l9im[YlhCrhTp2DG*J[E4#Y4L*[6e`je+K#q,'4%64@!PY K&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!!!!rJ!!!Im!!!2rJ!!(rm!!$rrJ!"rrm!!rrrJ!Irrm!2rrrJ(rr rm$rrrrKrrrrmrj!$rRrrN!-rrrrq(rrrr!rrrrJ(rrr`!rrri!(rrm!!rrq!!(r r!!!rrJ!!(r`!!!ri!!!(m!!!!q!!!!(!!*!$J!#3"#!IU5!a16N`,6Nf)%&XB@4 ND@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`!8j e6Ud!)Q%!!pDTp%ja5S0Q!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!!1bK'Li)##S!"J!%C`BJH!+QS"XX+J!%+LS!#"JU!!5Ae*A8)$V r9U%HCJ!!c#a))$Vr5L)'`VJ$'PK"B3$r8L!krd,!Z!-D3IVr2L#!5S9Q"+%LB!3 J4D!RCJ!!Q#T),cVr!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#K Z!!a(q[jD4IVq@L!8X**Y"#!5+)"+J'm5)&-LEJ!)SLiJ&0'6NC*`!'!%-$crf8c I(!"1ANje6PEreNMR%aJX,J!35IVpmN)(S4SY52rQ5Li!#fF')(J#TU!E,c`!!+$ m6VS#RLe!rqTB6fF!!Ai[,[rU6VS"q%S!@%pR"R!"B!!"FNKZrrK)E[rd5'lrlNk k!j)J,[rdS4iY52r`6qm!$'F!!8JJ,[riS4iY52rmC`!"1LmZrrJ[#%kk!qC+VJ! 88%pQ!!#8@Bm[2%024%9`!$m!U"mQAb!,ChiJ%h)Bd)%[!%kk!Y`-3!!$@%pQDL! 0FLM3J5e!rpSJ%h3Bd))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+@lrkJ!-+@lrm!!3+@lrp!!8+@lrr!!B,c`!!+'B6VS"L#e!rpB [2!!!U*p1ZJ&k)LlreV#"9X0%!dL$5--T3`!F+8B!)#PZ!!`!*%Kkr*!!2cbJr#m m!!#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%k k!2)S3#!-@%pR5#m-6VS!8%S!@%pR2#C-,bX!$$mmS2`[2!!!S2a1ZJ#L@)mI!%k k$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!!&Q22cbSER!"(`"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%j H6R919J!!51FI!$iZ!!T)abm(6VVraKS!F!!3"3a!!!&B6fB3!NF(rdkkrhb`4fi %F!"J+PQ22cbSRh!"(`"1ZJl#+"pCMcm((`91ZJkf,"qiKPI$4!0R"(!!B!)J"Nc Z!2Mrl%jH6R919J!!51F4#$iZ!!iJEJ!)+&"f!(!!-"3-J!!!384Q,R!!-#`!!Jb !!!"$8QBJ$%IrrfFB)#`!"%*!5%$J5#)m!*!$rm+!5-HqJ@B#GJ%3!dcZ%)Mrp%j H6R919J!!F2m[!%KZ!!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!*!$*2rd+'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()%6VS0)R)!-JFAJ"J!F!!`"b"ZrrM3J$''#!"`!$!(%$-)!()"iDR F36!(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'-Mri%jH6R919[rm51F2'#CZ!!`SEJ!83NCJ$R!!-!E3J%*d#!! `"P*'F!!`"R)!-Li!%Y+"XS"ZiN*'H!*J!!#D3N9#4h!!-!BJEJ!)jB!YF!J!rra JE(!"`+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!!51F2'$iZ!!iQEJ!3+'i!#$JZ!"Bk"qC0F!!`"h`(c%"q!(!!-!8 30!J!l#Kb!")!F!(!!A)!%J$HJ5!(d)"b!$)c#!!Z!9*'F!!`"R))XS"Q"N*'-!9 54A!!-!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!"61i3m2rX6Pj1G8j@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!!`,[r b,`![,[rd6VS)I#mZrra`!$!Zrr)[!#mZrr3[,[ri6VVp)Nr[!$"#4f!!!2C+E[r `Cc*`!$!Zrr)[!#mZrra`!$!&,`![#dkkrGjm!"`!F!!`"L"Zrr4b!")`#!$D38r [!""J'R!!-!3[!(!!-!8[!#m,6VVq,M`!fN42l`!-['lrl'B3-!G54h)!-J"#0"J !B!!!MVaZrqjQG%TZrr"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"aQd#!!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[`#50E m!#$@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#KZrmJ YI!!!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!rkj R$#"-)Qlrb#!ZrkkL,LKZrklCl[r)5'lrXLmZrmJJEJ!)6T!!)#lrXV#ZrlC36f3 'F'GJ!!5U(9crah!!%#lradM!d)"63$e!rqa`!$!Zrqc3J$e!rqiJEJ!3)"$3VJ! -,8$re#mZ!"`[,[rF5(J"*#m-6VVmG()!-J"+JGR",bi!(#mZrpK)H!%N,blrh%k k"E`[,[rJ5(J"*#mZrp`[,[rB6VVkCLmZ!"`[,[rFF!!`,[rX,`![$%kkr#jb!$) !5S(C`5mZ!"`[,[rBF!!`,[rX,`![,[rF6VS&FLmZrr"`!$!Zrq`[!#mZrp`[,[r B6VVk'(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!rjT R$#"-)Qlrb#!ZrjUL,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-Bf3Y62q Q,@lrc2qU)!a5J*!!V[qU,8$rSL!ZrkD3!+lrb#e!rjiJ,[qUN!#ZrkBY32qDC`` J6#*ZrmJJ,[qDSLiSE[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!+lrb#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#(!"`)A F3(!!-!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-rkB YE[r-rkSJ$&+!N!#ZrkSY32qL)#lrTT!!V[r),8$rRL!ZrkU3!+lrTLe!rjTR$#" -)Qlrb#!ZrjUL,LKZrjVCl[r)5'lrRLmZrmJJEJ!)6T!!)#lrRV#Zrk*36f3'F'G J!!$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)YLiLC Z!!aJ#L"Zrp"5V[r3%*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!18NDmEJ!1C"*`!$!'FJ!b""!d#!#`0"J!CHC64lK(C"*`!$!(FJ! b""!d#!#`0"J!BZLq4Q0)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-)!(!!-!I 3J()!-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!61iBm2rS6Pj 1G8j@rra)j`mB+'i!&!DZ!!!"*!!8*Qi!&%*'B#"`!$!')'i!#()!-JBCX!J!'!" `!$!'d)!hKJJ!-!C54VaZ!!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)!I ML()"`S@#J#i"iSd`"&0%5N"QkR!!-!E3J()!-M-)!#"Z!"$PJ5'('!!`"P*')#l rr&+ZrrbmEJ!1CB4-lKM`rq41ANje)PmJAk!P,S"U!N+A6Y%LAa)I-"p+!@F%TdC J!U0',SK1d5*I%Km`(b"I5J&R"+C(B!+L4dl4)Pp`!D'B6Y%L,`!%)#m!#%(k!!S bI!!#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)[!!3J,`!)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!@errmJ!#p!!*!&J[rr!!![XJ#3"!2SrrmJ!$!3!*!%"!(rrb!!-$` !N!@#rrmJ!$"-!*!&KIrr*!!`A!%#pP`!Krrr)!!`E!#3"BErrb3!-(`"![CB!)$ rrb!!-)`!N!@"rrmJ!$#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!*!&J2r r)!"!"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 312ef42..0000000
--- a/mac/tclMacResource.c
+++ /dev/null
@@ -1,2209 +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.5 1999/04/16 00:47:21 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);
- }
-
- Tcl_InvalidateStringRep(objPtr);
- if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) {
- oldTypePtr->freeIntRepProc(objPtr);
- }
-
- objPtr->internalRep.longValue = newOSType;
- objPtr->typePtr = &osType;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * 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 3c982c5..0000000
--- a/mac/tclMacTest.c
+++ /dev/null
@@ -1,242 +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.3 1998/11/10 06:49:51 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;
-}
-
-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;
-}
-
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;
-}