os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/mac/tclMacLibrary.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2  * tclMacLibrary.c --
     3  *
     4  *	This file should be included in Tcl extensions that want to 
     5  *	automatically open their resource forks when the code is linked. 
     6  *	These routines should not be exported but should be compiled 
     7  *	locally by each fragment.  Many thanks to Jay Lieske
     8  *	<lieske@princeton.edu> who provide an initial version of this
     9  *	file.
    10  *
    11  * Copyright (c) 1996 Sun Microsystems, Inc.
    12  *
    13  * See the file "license.terms" for information on usage and redistribution
    14  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    15  *
    16  * RCS: @(#) $Id: tclMacLibrary.c,v 1.5 2001/11/23 01:27:39 das Exp $
    17  */
    18 
    19 /*
    20  * Here is another place that we are using the old routine names...
    21  */
    22 
    23 #include <CodeFragments.h>
    24 #include <Errors.h>
    25 #include <Resources.h>
    26 #include <Strings.h>
    27 #include "tclMacInt.h"
    28 
    29 #if defined(TCL_REGISTER_LIBRARY) && defined(USE_TCL_STUBS)
    30 #error "Can't use TCL_REGISTER_LIBRARY and USE_TCL_STUBS at the same time!"
    31 /*
    32  * Can't register a library with Tcl when using stubs in the current
    33  * implementation, since Tcl_InitStubs hasn't been called yet
    34  *  when OpenLibraryResource is executing. 
    35  */
    36 #endif
    37 
    38 /*
    39  * These function are not currently defined in any header file.  The
    40  * only place they should be used is in the Initialization and
    41  * Termination entry points for a code fragment.  The prototypes
    42  * are included here to avoid compile errors.
    43  */
    44 
    45 OSErr TclMacInitializeFragment _ANSI_ARGS_((
    46 			struct CFragInitBlock* initBlkPtr));
    47 void TclMacTerminateFragment _ANSI_ARGS_((void));
    48 
    49 /*
    50  * Static functions in this file.
    51  */
    52 
    53 static OSErr OpenLibraryResource _ANSI_ARGS_((
    54 			struct CFragInitBlock* initBlkPtr));
    55 static void CloseLibraryResource _ANSI_ARGS_((void));
    56 
    57 /* 
    58  * The refnum of the opened resource fork.
    59  */
    60 static short ourResFile = kResFileNotOpened;
    61 
    62 /*
    63  * This is the resource token for the our resource file.
    64  * It stores the name we registered with the resource facility.
    65  * We only need to use this if we are actually registering ourselves.
    66  */
    67   
    68 #ifdef TCL_REGISTER_LIBRARY
    69 static Tcl_Obj *ourResToken;
    70 #endif
    71 
    72 /*
    73  *----------------------------------------------------------------------
    74  *
    75  * TclMacInitializeFragment --
    76  *
    77  *	Called by MacOS CFM when the shared library is loaded. All this
    78  *	function really does is give Tcl a chance to open and register
    79  *	the resource fork of the library. 
    80  *
    81  * Results:
    82  *	MacOS error code if loading should be canceled.
    83  *
    84  * Side effects:
    85  *	Opens the resource fork of the shared library file.
    86  *
    87  *----------------------------------------------------------------------
    88  */
    89 
    90 OSErr
    91 TclMacInitializeFragment(
    92     struct CFragInitBlock* initBlkPtr)		/* Pointer to our library. */
    93 {
    94     OSErr err = noErr;
    95 
    96 #ifdef __MWERKS__
    97     {
    98     	extern OSErr __initialize( CFragInitBlock* initBlkPtr);
    99     	err = __initialize((CFragInitBlock *) initBlkPtr);
   100     }
   101 #endif
   102     if (err == noErr)
   103     	err = OpenLibraryResource( initBlkPtr);
   104     return err;
   105 }
   106 
   107 /*
   108  *----------------------------------------------------------------------
   109  *
   110  * TclMacTerminateFragment --
   111  *
   112  *	Called by MacOS CFM when the shared library is unloaded.
   113  *
   114  * Results:
   115  *	None.
   116  *
   117  * Side effects:
   118  *	The resource fork of the code fragment is closed.
   119  *
   120  *----------------------------------------------------------------------
   121  */
   122 
   123 void 
   124 TclMacTerminateFragment()
   125 {
   126     CloseLibraryResource();
   127 
   128 #ifdef __MWERKS__
   129     {
   130     	extern void __terminate(void);
   131     	__terminate();
   132     }
   133 #endif
   134 }
   135 
   136 /*
   137  *----------------------------------------------------------------------
   138  *
   139  * OpenLibraryResource --
   140  *
   141  *	This routine can be called by a MacOS fragment's initialiation 
   142  *	function to open the resource fork of the file.  
   143  *	Call it with the same data passed to the initialization function. 
   144  *	If the fragment loading should fail if the resource fork can't 
   145  *	be opened, then the initialization function can pass on this 
   146  *	return value.
   147  *
   148  *      If you #define TCL_REGISTER_RESOURCE before compiling this resource, 
   149  *	then your library will register its open resource fork with the
   150  *      resource command.
   151  *
   152  * Results:
   153  *	It returns noErr on success and a MacOS error code on failure.
   154  *
   155  * Side effects:
   156  *	The resource fork of the code fragment is opened read-only and 
   157  *	is installed at the head of the resource chain.
   158  *
   159  *----------------------------------------------------------------------
   160  */
   161 
   162 static OSErr 
   163 OpenLibraryResource(
   164     struct CFragInitBlock* initBlkPtr)
   165 {
   166     /*
   167      * The 3.0 version of the Universal headers changed CFragInitBlock
   168      * to an opaque pointer type.  CFragSystem7InitBlock is now the
   169      * real pointer.
   170      */
   171      
   172 #if !defined(UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0300)
   173     struct CFragInitBlock *realInitBlkPtr = initBlkPtr;
   174 #else 
   175     CFragSystem7InitBlock *realInitBlkPtr = (CFragSystem7InitBlock *) initBlkPtr;
   176 #endif
   177     FSSpec* fileSpec = NULL;
   178     OSErr err = noErr;
   179     
   180 
   181     if (realInitBlkPtr->fragLocator.where == kDataForkCFragLocator) {
   182     	fileSpec = realInitBlkPtr->fragLocator.u.onDisk.fileSpec;
   183     } else if (realInitBlkPtr->fragLocator.where == kResourceCFragLocator) {
   184     	fileSpec = realInitBlkPtr->fragLocator.u.inSegs.fileSpec;
   185     } else {
   186     	err = resFNotFound;
   187     }
   188 
   189     /*
   190      * Open the resource fork for this library in read-only mode.  
   191      * This will make it the current res file, ahead of the 
   192      * application's own resources.
   193      */
   194     
   195     if (fileSpec != NULL) {
   196 	ourResFile = FSpOpenResFile(fileSpec, fsRdPerm);
   197 	if (ourResFile == kResFileNotOpened) {
   198 	    err = ResError();
   199 	} else {
   200 #ifdef TCL_REGISTER_LIBRARY
   201 	    ourResToken = Tcl_NewObj();
   202 	    Tcl_IncrRefCount(ourResToken);
   203 	    p2cstr(realInitBlkPtr->libName);
   204 	    Tcl_SetStringObj(ourResToken, (char *) realInitBlkPtr->libName, -1);
   205 	    c2pstr((char *) realInitBlkPtr->libName);
   206 	    TclMacRegisterResourceFork(ourResFile, ourResToken,
   207 	            TCL_RESOURCE_DONT_CLOSE);
   208 #endif
   209             SetResFileAttrs(ourResFile, mapReadOnly);
   210 	}
   211     }
   212     
   213     return err;
   214 }
   215 
   216 /*
   217  *----------------------------------------------------------------------
   218  *
   219  * CloseLibraryResource --
   220  *
   221  *	This routine should be called by a MacOS fragment's termination 
   222  *	function to close the resource fork of the file 
   223  *	that was opened with OpenLibraryResource.  
   224  *
   225  * Results:
   226  *	None.
   227  *
   228  * Side effects:
   229  *	The resource fork of the code fragment is closed.
   230  *
   231  *----------------------------------------------------------------------
   232  */
   233 
   234 static void
   235 CloseLibraryResource()
   236 {
   237     if (ourResFile != kResFileNotOpened) {
   238 #ifdef TCL_REGISTER_LIBRARY
   239         int length;
   240         TclMacUnRegisterResourceFork(
   241 	        Tcl_GetStringFromObj(ourResToken, &length),
   242                 NULL);
   243         Tcl_DecrRefCount(ourResToken);
   244 #endif
   245 	CloseResFile(ourResFile);
   246 	ourResFile = kResFileNotOpened;
   247     }
   248 }