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