os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/macosx/tclMacOSXBundle.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
 * tclMacOSXBundle.c --
sl@0
     3
 *
sl@0
     4
 *	This file implements functions that inspect CFBundle structures on
sl@0
     5
 *	MacOS X.
sl@0
     6
 *
sl@0
     7
 * Copyright 2001, Apple Computer, Inc.
sl@0
     8
 * Copyright (c) 2003-2007 Daniel A. Steffen <das@users.sourceforge.net>
sl@0
     9
 *
sl@0
    10
 * See the file "license.terms" for information on usage and redistribution of
sl@0
    11
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
sl@0
    12
 *
sl@0
    13
 *	The following terms apply to all files originating from Apple
sl@0
    14
 *	Computer, Inc. ("Apple") and associated with the software unless
sl@0
    15
 *	explicitly disclaimed in individual files.
sl@0
    16
 *
sl@0
    17
 *	Apple hereby grants permission to use, copy, modify, distribute, and
sl@0
    18
 *	license this software and its documentation for any purpose, provided
sl@0
    19
 *	that existing copyright notices are retained in all copies and that
sl@0
    20
 *	this notice is included verbatim in any distributions. No written
sl@0
    21
 *	agreement, license, or royalty fee is required for any of the
sl@0
    22
 *	authorized uses. Modifications to this software may be copyrighted by
sl@0
    23
 *	their authors and need not follow the licensing terms described here,
sl@0
    24
 *	provided that the new terms are clearly indicated on the first page of
sl@0
    25
 *	each file where they apply.
sl@0
    26
 *
sl@0
    27
 *	IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE SOFTWARE
sl@0
    28
 *	BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
sl@0
    29
 *	CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS
sl@0
    30
 *	DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF APPLE OR THE
sl@0
    31
 *	AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. APPLE,
sl@0
    32
 *	THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
sl@0
    33
 *	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
sl@0
    34
 *	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
sl@0
    35
 *	NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
sl@0
    36
 *	APPLE,THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
sl@0
    37
 *	MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
sl@0
    38
 *
sl@0
    39
 *	GOVERNMENT USE: If you are acquiring this software on behalf of the
sl@0
    40
 *	U.S. government, the Government shall have only "Restricted Rights" in
sl@0
    41
 *	the software and related documentation as defined in the Federal
sl@0
    42
 *	Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are
sl@0
    43
 *	acquiring the software on behalf of the Department of Defense, the
sl@0
    44
 *	software shall be classified as "Commercial Computer Software" and the
sl@0
    45
 *	Government shall have only "Restricted Rights" as defined in Clause
sl@0
    46
 *	252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
sl@0
    47
 *	authors grant the U.S. Government and others acting in its behalf
sl@0
    48
 *	permission to use and distribute the software in accordance with the
sl@0
    49
 *	terms specified in this license.
sl@0
    50
 *
sl@0
    51
 * RCS: @(#) $Id: tclMacOSXBundle.c,v 1.3.2.6 2007/04/29 02:21:33 das Exp $
sl@0
    52
 */
sl@0
    53
sl@0
    54
#include "tclPort.h"
sl@0
    55
sl@0
    56
#ifdef HAVE_COREFOUNDATION
sl@0
    57
#include <CoreFoundation/CoreFoundation.h>
sl@0
    58
#include <mach-o/dyld.h>
sl@0
    59
#endif /* HAVE_COREFOUNDATION */
sl@0
    60
sl@0
    61
/*
sl@0
    62
 *----------------------------------------------------------------------
sl@0
    63
 *
sl@0
    64
 * Tcl_MacOSXOpenBundleResources --
sl@0
    65
 *
sl@0
    66
 *	Given the bundle name for a shared library, this routine sets
sl@0
    67
 *	libraryPath to the Resources/Scripts directory in the framework
sl@0
    68
 *	package. If hasResourceFile is true, it will also open the main
sl@0
    69
 *	resource file for the bundle.
sl@0
    70
 *
sl@0
    71
 * Results:
sl@0
    72
 *	TCL_OK if the bundle could be opened, and the Scripts folder found.
sl@0
    73
 *	TCL_ERROR otherwise.
sl@0
    74
 *
sl@0
    75
 * Side effects:
sl@0
    76
 *	libraryVariableName may be set, and the resource file opened.
sl@0
    77
 *
sl@0
    78
 *----------------------------------------------------------------------
sl@0
    79
 */
sl@0
    80
sl@0
    81
int
sl@0
    82
Tcl_MacOSXOpenBundleResources(
sl@0
    83
    Tcl_Interp *interp,
sl@0
    84
    CONST char *bundleName,
sl@0
    85
    int hasResourceFile,
sl@0
    86
    int maxPathLen,
sl@0
    87
    char *libraryPath)
sl@0
    88
{
sl@0
    89
    return Tcl_MacOSXOpenVersionedBundleResources(interp, bundleName,
sl@0
    90
	    NULL, hasResourceFile, maxPathLen, libraryPath);
sl@0
    91
}
sl@0
    92

sl@0
    93
/*
sl@0
    94
 *----------------------------------------------------------------------
sl@0
    95
 *
sl@0
    96
 * Tcl_MacOSXOpenVersionedBundleResources --
sl@0
    97
 *
sl@0
    98
 *	Given the bundle and version name for a shared library (version name
sl@0
    99
 *	can be NULL to indicate latest version), this routine sets libraryPath
sl@0
   100
 *	to the Resources/Scripts directory in the framework package. If
sl@0
   101
 *	hasResourceFile is true, it will also open the main resource file for
sl@0
   102
 *	the bundle.
sl@0
   103
 *
sl@0
   104
 * Results:
sl@0
   105
 *	TCL_OK if the bundle could be opened, and the Scripts folder found.
sl@0
   106
 *	TCL_ERROR otherwise.
sl@0
   107
 *
sl@0
   108
 * Side effects:
sl@0
   109
 *	libraryVariableName may be set, and the resource file opened.
sl@0
   110
 *
sl@0
   111
 *----------------------------------------------------------------------
sl@0
   112
 */
sl@0
   113
sl@0
   114
int
sl@0
   115
Tcl_MacOSXOpenVersionedBundleResources(
sl@0
   116
    Tcl_Interp *interp,
sl@0
   117
    CONST char *bundleName,
sl@0
   118
    CONST char *bundleVersion,
sl@0
   119
    int hasResourceFile,
sl@0
   120
    int maxPathLen,
sl@0
   121
    char *libraryPath)
sl@0
   122
{
sl@0
   123
#ifdef HAVE_COREFOUNDATION
sl@0
   124
    CFBundleRef bundleRef;
sl@0
   125
    CFStringRef bundleNameRef;
sl@0
   126
    CFURLRef libURL;
sl@0
   127
sl@0
   128
    libraryPath[0] = '\0';
sl@0
   129
sl@0
   130
    bundleNameRef = CFStringCreateWithCString(NULL, bundleName,
sl@0
   131
	    kCFStringEncodingUTF8);
sl@0
   132
sl@0
   133
    bundleRef = CFBundleGetBundleWithIdentifier(bundleNameRef);
sl@0
   134
    CFRelease(bundleNameRef);
sl@0
   135
sl@0
   136
    if (bundleVersion && bundleRef) {
sl@0
   137
	/*
sl@0
   138
	 * Create bundle from bundleVersion subdirectory of 'Versions'.
sl@0
   139
	 */
sl@0
   140
sl@0
   141
	CFBundleRef versionedBundleRef = NULL;
sl@0
   142
	CFURLRef versionedBundleURL = NULL;
sl@0
   143
	CFStringRef bundleVersionRef = CFStringCreateWithCString(NULL,
sl@0
   144
		bundleVersion, kCFStringEncodingUTF8);
sl@0
   145
	CFURLRef bundleURL = CFBundleCopyBundleURL(bundleRef);
sl@0
   146
sl@0
   147
	if (bundleURL) {
sl@0
   148
	    CFStringRef bundleTailRef = CFURLCopyLastPathComponent(bundleURL);
sl@0
   149
sl@0
   150
	    if (bundleTailRef) {
sl@0
   151
		if (CFStringCompare(bundleTailRef, bundleVersionRef, 0) ==
sl@0
   152
			kCFCompareEqualTo) {
sl@0
   153
		    versionedBundleRef = bundleRef;
sl@0
   154
		}
sl@0
   155
		CFRelease(bundleTailRef);
sl@0
   156
	    }
sl@0
   157
	}
sl@0
   158
sl@0
   159
	if (bundleURL && !versionedBundleRef) {
sl@0
   160
	    CFURLRef versURL = CFURLCreateCopyAppendingPathComponent(NULL,
sl@0
   161
		    bundleURL, CFSTR("Versions"), TRUE);
sl@0
   162
sl@0
   163
	    if (versURL) {
sl@0
   164
		versionedBundleURL = CFURLCreateCopyAppendingPathComponent(
sl@0
   165
			NULL, versURL, bundleVersionRef, TRUE);
sl@0
   166
		CFRelease(versURL);
sl@0
   167
	    }
sl@0
   168
	    CFRelease(bundleURL);
sl@0
   169
	}
sl@0
   170
	CFRelease(bundleVersionRef);
sl@0
   171
	if (versionedBundleURL) {
sl@0
   172
	    versionedBundleRef = CFBundleCreate(NULL, versionedBundleURL);
sl@0
   173
	    CFRelease(versionedBundleURL);
sl@0
   174
	}
sl@0
   175
	bundleRef = versionedBundleRef;
sl@0
   176
    }
sl@0
   177
sl@0
   178
    if (bundleRef) {
sl@0
   179
	if (hasResourceFile) {
sl@0
   180
	    /*
sl@0
   181
	     * Dynamically acquire address for CFBundleOpenBundleResourceMap
sl@0
   182
	     * symbol, since it is only present in full CoreFoundation on Mac
sl@0
   183
	     * OS X and not in CFLite on pure Darwin.
sl@0
   184
	     */
sl@0
   185
sl@0
   186
	    static int initialized = FALSE;
sl@0
   187
	    static short (*openresourcemap)(CFBundleRef) = NULL;
sl@0
   188
sl@0
   189
	    if (!initialized) {
sl@0
   190
		NSSymbol nsSymbol = NULL;
sl@0
   191
		if (NSIsSymbolNameDefinedWithHint(
sl@0
   192
			"_CFBundleOpenBundleResourceMap", "CoreFoundation")) {
sl@0
   193
		    nsSymbol = NSLookupAndBindSymbolWithHint(
sl@0
   194
			    "_CFBundleOpenBundleResourceMap","CoreFoundation");
sl@0
   195
		    if (nsSymbol) {
sl@0
   196
			openresourcemap = NSAddressOfSymbol(nsSymbol);
sl@0
   197
		    }
sl@0
   198
		}
sl@0
   199
		initialized = TRUE;
sl@0
   200
	    }
sl@0
   201
sl@0
   202
	    if (openresourcemap) {
sl@0
   203
		short refNum;
sl@0
   204
sl@0
   205
		refNum = openresourcemap(bundleRef);
sl@0
   206
	    }
sl@0
   207
	}
sl@0
   208
sl@0
   209
	libURL = CFBundleCopyResourceURL(bundleRef, CFSTR("Scripts"),
sl@0
   210
		NULL, NULL);
sl@0
   211
sl@0
   212
	if (libURL) {
sl@0
   213
	    /*
sl@0
   214
	     * FIXME: This is a quick fix, it is probably not right for
sl@0
   215
	     * internationalization.
sl@0
   216
	     */
sl@0
   217
sl@0
   218
	    CFURLGetFileSystemRepresentation(libURL, TRUE,
sl@0
   219
		    (unsigned char*) libraryPath, maxPathLen);
sl@0
   220
	    CFRelease(libURL);
sl@0
   221
	}
sl@0
   222
    }
sl@0
   223
sl@0
   224
    if (libraryPath[0]) {
sl@0
   225
	return TCL_OK;
sl@0
   226
    } else {
sl@0
   227
	return TCL_ERROR;
sl@0
   228
    }
sl@0
   229
#else  /* HAVE_COREFOUNDATION */
sl@0
   230
    return TCL_ERROR;
sl@0
   231
#endif /* HAVE_COREFOUNDATION */
sl@0
   232
}