Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/macosx/tclMacOSXBundle.c @ 42

Last change on this file since 42 was 25, checked in by landauf, 17 years ago

added tcl to libs

File size: 7.4 KB
Line 
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.11 2007/04/23 20:46:13 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
81int
82Tcl_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
114int
115Tcl_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}
233
234/*
235 * Local Variables:
236 * mode: c
237 * c-basic-offset: 4
238 * fill-column: 78
239 * End:
240 */
Note: See TracBrowser for help on using the repository browser.