tclMacOSXBundle.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:7k
源码类别:

通讯编程

开发平台:

Visual C++

  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. #include "tclPort.h"
  54. #ifdef HAVE_COREFOUNDATION
  55. #include <CoreFoundation/CoreFoundation.h>
  56. #include <mach-o/dyld.h>
  57. #endif /* HAVE_COREFOUNDATION */
  58. /*
  59.  *----------------------------------------------------------------------
  60.  *
  61.  * Tcl_MacOSXOpenBundleResources --
  62.  *
  63.  * Given the bundle name for a shared library, this routine sets
  64.  * libraryPath to the Resources/Scripts directory in the framework
  65.  * package. If hasResourceFile is true, it will also open the main
  66.  * resource file for the bundle.
  67.  *
  68.  * Results:
  69.  * TCL_OK if the bundle could be opened, and the Scripts folder found.
  70.  * TCL_ERROR otherwise.
  71.  *
  72.  * Side effects:
  73.  * libraryVariableName may be set, and the resource file opened.
  74.  *
  75.  *----------------------------------------------------------------------
  76.  */
  77. int
  78. Tcl_MacOSXOpenBundleResources(
  79.     Tcl_Interp *interp,
  80.     CONST char *bundleName,
  81.     int hasResourceFile,
  82.     int maxPathLen,
  83.     char *libraryPath)
  84. {
  85.     return Tcl_MacOSXOpenVersionedBundleResources(interp, bundleName,
  86.     NULL, hasResourceFile, maxPathLen, libraryPath);
  87. }
  88. /*
  89.  *----------------------------------------------------------------------
  90.  *
  91.  * Tcl_MacOSXOpenVersionedBundleResources --
  92.  *
  93.  * Given the bundle and version name for a shared library (version name
  94.  * can be NULL to indicate latest version), this routine sets libraryPath
  95.  * to the Resources/Scripts directory in the framework package. If
  96.  * hasResourceFile is true, it will also open the main resource file for
  97.  * the bundle.
  98.  *
  99.  * Results:
  100.  * TCL_OK if the bundle could be opened, and the Scripts folder found.
  101.  * TCL_ERROR otherwise.
  102.  *
  103.  * Side effects:
  104.  * libraryVariableName may be set, and the resource file opened.
  105.  *
  106.  *----------------------------------------------------------------------
  107.  */
  108. int
  109. Tcl_MacOSXOpenVersionedBundleResources(
  110.     Tcl_Interp *interp,
  111.     CONST char *bundleName,
  112.     CONST char *bundleVersion,
  113.     int hasResourceFile,
  114.     int maxPathLen,
  115.     char *libraryPath)
  116. {
  117. #ifdef HAVE_COREFOUNDATION
  118.     CFBundleRef bundleRef;
  119.     CFStringRef bundleNameRef;
  120.     CFURLRef libURL;
  121.     libraryPath[0] = '';
  122.     bundleNameRef = CFStringCreateWithCString(NULL, bundleName,
  123.     kCFStringEncodingUTF8);
  124.     bundleRef = CFBundleGetBundleWithIdentifier(bundleNameRef);
  125.     CFRelease(bundleNameRef);
  126.     if (bundleVersion && bundleRef) {
  127. /*
  128.  * Create bundle from bundleVersion subdirectory of 'Versions'.
  129.  */
  130. CFBundleRef versionedBundleRef = NULL;
  131. CFURLRef versionedBundleURL = NULL;
  132. CFStringRef bundleVersionRef = CFStringCreateWithCString(NULL,
  133. bundleVersion, kCFStringEncodingUTF8);
  134. CFURLRef bundleURL = CFBundleCopyBundleURL(bundleRef);
  135. if (bundleURL) {
  136.     CFStringRef bundleTailRef = CFURLCopyLastPathComponent(bundleURL);
  137.     if (bundleTailRef) {
  138. if (CFStringCompare(bundleTailRef, bundleVersionRef, 0) ==
  139. kCFCompareEqualTo) {
  140.     versionedBundleRef = bundleRef;
  141. }
  142. CFRelease(bundleTailRef);
  143.     }
  144. }
  145. if (bundleURL && !versionedBundleRef) {
  146.     CFURLRef versURL = CFURLCreateCopyAppendingPathComponent(NULL,
  147.     bundleURL, CFSTR("Versions"), TRUE);
  148.     if (versURL) {
  149. versionedBundleURL = CFURLCreateCopyAppendingPathComponent(
  150. NULL, versURL, bundleVersionRef, TRUE);
  151. CFRelease(versURL);
  152.     }
  153.     CFRelease(bundleURL);
  154. }
  155. CFRelease(bundleVersionRef);
  156. if (versionedBundleURL) {
  157.     versionedBundleRef = CFBundleCreate(NULL, versionedBundleURL);
  158.     CFRelease(versionedBundleURL);
  159. }
  160. bundleRef = versionedBundleRef;
  161.     }
  162.     if (bundleRef) {
  163. if (hasResourceFile) {
  164.     /*
  165.      * Dynamically acquire address for CFBundleOpenBundleResourceMap
  166.      * symbol, since it is only present in full CoreFoundation on Mac
  167.      * OS X and not in CFLite on pure Darwin.
  168.      */
  169.     static int initialized = FALSE;
  170.     static short (*openresourcemap)(CFBundleRef) = NULL;
  171.     if (!initialized) {
  172. NSSymbol nsSymbol = NULL;
  173. if (NSIsSymbolNameDefinedWithHint(
  174. "_CFBundleOpenBundleResourceMap", "CoreFoundation")) {
  175.     nsSymbol = NSLookupAndBindSymbolWithHint(
  176.     "_CFBundleOpenBundleResourceMap","CoreFoundation");
  177.     if (nsSymbol) {
  178. openresourcemap = NSAddressOfSymbol(nsSymbol);
  179.     }
  180. }
  181. initialized = TRUE;
  182.     }
  183.     if (openresourcemap) {
  184. short refNum;
  185. refNum = openresourcemap(bundleRef);
  186.     }
  187. }
  188. libURL = CFBundleCopyResourceURL(bundleRef, CFSTR("Scripts"),
  189. NULL, NULL);
  190. if (libURL) {
  191.     /*
  192.      * FIXME: This is a quick fix, it is probably not right for
  193.      * internationalization.
  194.      */
  195.     CFURLGetFileSystemRepresentation(libURL, TRUE,
  196.     (unsigned char*) libraryPath, maxPathLen);
  197.     CFRelease(libURL);
  198. }
  199.     }
  200.     if (libraryPath[0]) {
  201. return TCL_OK;
  202.     } else {
  203. return TCL_ERROR;
  204.     }
  205. #else  /* HAVE_COREFOUNDATION */
  206.     return TCL_ERROR;
  207. #endif /* HAVE_COREFOUNDATION */
  208. }