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