mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-25 01:31:08 +00:00
Changes by Adam Fedor. See Nov 13 ChangeLog entry
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2018 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
f25cb10514
commit
5b8ea53689
6 changed files with 653 additions and 393 deletions
81
ChangeLog
81
ChangeLog
|
@ -1,3 +1,84 @@
|
||||||
|
Mon Jan 6 16:06:21 1997 Andrew McCallum <mccallum@cs.cmu.edu>
|
||||||
|
|
||||||
|
* src/NSString.m ([NSString -description]): Free DEST to prevent
|
||||||
|
memory leak!
|
||||||
|
(Reported by Wolfgang Baron <wbaron@ixpoint.de>.)
|
||||||
|
|
||||||
|
* src/NSException.m (_NSUncaughtExceptionHandler): Don't declare
|
||||||
|
it static. (Reported by John Hethcox <johnhe@vnet.net>.)
|
||||||
|
|
||||||
|
* src/BinaryCStream.m (BITSPERBYTE): If it hasn't been defined
|
||||||
|
after #include's guess that it's 8.
|
||||||
|
|
||||||
|
* checks/nsscanner.m: Removed RCS keyword.
|
||||||
|
|
||||||
|
Wed Nov 13 14:10:00 1996 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* src/Connection.m ([Connection +rootProxyAtName:onHost:]):
|
||||||
|
Return nil if we fail to create a port for talking to a remote server.
|
||||||
|
([Connection forwardForProxy:selector:argFrame:]):
|
||||||
|
Changes to ensure that ConnectedDecoder is correctly dismissed in the
|
||||||
|
case where a DO method returns an object but does not have any
|
||||||
|
parameter values returned.
|
||||||
|
|
||||||
|
* src/mframe.m (mframe_build_return()):
|
||||||
|
Cooperate with [Connection forwardForProxy:selector:argFrame:] so
|
||||||
|
that it's callback function is called to tell it dismiss the
|
||||||
|
ConnectedDecoder.
|
||||||
|
|
||||||
|
* src/RunLoop.m ([RunLoop -limitDateForMode:]):
|
||||||
|
Various changes to get timeouts working reliably.
|
||||||
|
Ensure that _current_mode is restored correctly on exit.
|
||||||
|
|
||||||
|
* src/RunLoop.m ([RunLoop -acceptInputForMode:beforeDate:]):
|
||||||
|
Ensure that _current_mode is restored correctly on exit.
|
||||||
|
|
||||||
|
Wed Nov 6 11:59:08 1996 Adam Fedor <fedor@boulder.Colorado.edu>
|
||||||
|
|
||||||
|
* src/NSLog.m: New file
|
||||||
|
* src/Makefile.in (GNUSTEP_MFILES): Add NSLog.m
|
||||||
|
* src/include/NSObjCRuntime.h: Add NSLog definitions.
|
||||||
|
|
||||||
|
Mon Nov 4 12:30:05 1996 Adam Fedor <fedor@wave.Colorado.edu>
|
||||||
|
|
||||||
|
* src/objc-load.c: Include <gnustep/base/config.h>.
|
||||||
|
|
||||||
|
Sat Sep 21 15:18:47 1996 Yoo C. Chung <wacko@power1.snu.ac.kr>
|
||||||
|
|
||||||
|
* src/NSZone.m: Use constructor attribute with initialize().
|
||||||
|
|
||||||
|
Thu Sep 19 22:09:08 1996 Yoo C. Chung <wacko@power1.snu.ac.kr>
|
||||||
|
|
||||||
|
* src/DelegatePool.m:
|
||||||
|
Use NSDefaultMallocZone() instead of NS_NOZONE.
|
||||||
|
* src/NSProcessInfo.m: Likewise.
|
||||||
|
|
||||||
|
* src/NSObject.m:
|
||||||
|
Use NSDefaultMallocZone() instead of NS_NOZONE.
|
||||||
|
Use NSZoneFromPointer() instead of NSZoneFromPtr().
|
||||||
|
|
||||||
|
* src/NSProcessInfo.m: Use NSDefaultMallocZone() instead of 0.
|
||||||
|
And cosmetic changes.
|
||||||
|
|
||||||
|
* src/NSHashTable.m: Use NSDefaultMallocZone() instead of 0.
|
||||||
|
* src/NSMapTable.m: Likewise.
|
||||||
|
* src/o_map.m: Likewise.
|
||||||
|
|
||||||
|
* src/NSPage.m:
|
||||||
|
Use valloc() in NSAllocateMemoryPages().
|
||||||
|
Cosmetic style changes.
|
||||||
|
|
||||||
|
* src/NSZone.m: Complete rewrite.
|
||||||
|
* src/include/NSZone.h: Extensive modifications.
|
||||||
|
|
||||||
|
Thu Dec 5 17:20:58 1996 Nick Christopher <nwc@mindspring.com>
|
||||||
|
|
||||||
|
* NSString.m [NSString -componentsSeparatedByString]: Didn't
|
||||||
|
handle strings with separators longer than a single character
|
||||||
|
and in other cases.
|
||||||
|
|
||||||
|
* stringsfile.l: The definition of LABEL needed expanding.
|
||||||
|
|
||||||
Sun Jan 5 17:41:37 1997 Andrew McCallum <mccallum@cs.cmu.edu>
|
Sun Jan 5 17:41:37 1997 Andrew McCallum <mccallum@cs.cmu.edu>
|
||||||
|
|
||||||
Further changes for the NSString implementation.
|
Further changes for the NSString implementation.
|
||||||
|
|
|
@ -28,42 +28,54 @@
|
||||||
|
|
||||||
@class NSString;
|
@class NSString;
|
||||||
@class NSArray;
|
@class NSArray;
|
||||||
|
@class NSDictionary;
|
||||||
|
|
||||||
|
extern NSString* NSBundleDidLoadNotification;
|
||||||
|
extern NSString* NSShowNonLocalizedStrings;
|
||||||
|
extern NSString* NSLoadedClasses;
|
||||||
|
|
||||||
@interface NSBundle : NSObject
|
@interface NSBundle : NSObject
|
||||||
{
|
{
|
||||||
NSString *_path;
|
NSString *_path;
|
||||||
Class _principalClass;
|
NSArray* _bundleClasses;
|
||||||
|
Class _principalClass;
|
||||||
|
id _infoDict;
|
||||||
|
unsigned int _retainCount;
|
||||||
|
unsigned int _bundleType;
|
||||||
BOOL _codeLoaded;
|
BOOL _codeLoaded;
|
||||||
int _bundleVersion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSBundle *)mainBundle;
|
+ (NSBundle *) mainBundle;
|
||||||
+ (NSBundle *)bundleForClass:aClass;
|
+ (NSBundle *) bundleForClass: (Class)aClass;
|
||||||
+ (NSBundle *)bundleWithPath:(NSString *)path;
|
+ (NSBundle *) bundleWithPath: (NSString *)path;
|
||||||
- initWithPath:(NSString *)path;
|
- initWithPath: (NSString *)path;
|
||||||
- (NSString *)bundlePath;
|
- (NSString *) bundlePath;
|
||||||
- classNamed:(NSString *)className;
|
- (Class) classNamed: (NSString *)className;
|
||||||
- principalClass;
|
- (Class) principalClass;
|
||||||
|
|
||||||
+ (NSString *)pathForResource:(NSString *)name
|
- (NSArray *) pathsForResourcesOfType: (NSString *)extension
|
||||||
ofType:(NSString *)ext
|
inDirectory: (NSString *)bundlePath;
|
||||||
inDirectory:(NSString *)bundlePath
|
- (NSString *) pathForResource: (NSString *)name
|
||||||
withVersion:(int)version;
|
ofType: (NSString *)ext
|
||||||
|
inDirectory: (NSString *)bundlePath;
|
||||||
|
- (NSString *) pathForResource: (NSString *)name
|
||||||
|
ofType: (NSString *)ext;
|
||||||
|
- (NSString *) localizedStringForKey: (NSString *)key
|
||||||
|
value: (NSString *)value
|
||||||
|
table: (NSString *)tableName;
|
||||||
|
- (NSString *) resourcePath;
|
||||||
|
|
||||||
- (NSString *)pathForResource:(NSString *)name
|
#ifndef STRICT_OPENSTEP
|
||||||
ofType:(NSString *)ext;
|
- (NSDictionary *) infoDictionary;
|
||||||
|
#endif
|
||||||
+ (void)stripAfterLoading:(BOOL)flag;
|
|
||||||
|
|
||||||
- (NSString *)localizedStringForKey:(NSString *)key
|
|
||||||
value:(NSString *)value
|
|
||||||
table:(NSString *)tableName;
|
|
||||||
|
|
||||||
- (unsigned)bundleVersion;
|
|
||||||
- (void)setBundleVersion:(unsigned)version;
|
|
||||||
|
|
||||||
+ (void)setSystemLanguages:(NSArray *)languages;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#define NSLocalizedString(key, comment) \
|
||||||
|
[[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
|
||||||
|
#define NSLocalizedStringFromTable(key, tbl, comment) \
|
||||||
|
[[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:(tbl)]
|
||||||
|
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
|
||||||
|
[bundle localizedStringForKey:(key) value:@"" table:(tbl)]
|
||||||
|
|
||||||
#endif /* __NSBundle_h_GNUSTEP_BASE_INCLUDE */
|
#endif /* __NSBundle_h_GNUSTEP_BASE_INCLUDE */
|
||||||
|
|
|
@ -51,7 +51,7 @@ YACC = bison
|
||||||
|
|
||||||
# GNUSTEP_INSTALL_PREFIX must be defined here and not in config.h because
|
# GNUSTEP_INSTALL_PREFIX must be defined here and not in config.h because
|
||||||
# the installing person may set it on the `make' command line.
|
# the installing person may set it on the `make' command line.
|
||||||
DEFS = -DGNUSTEP_INSTALL_PREFIX=$(prefix) @DEFS@
|
DEFS= -DGNUSTEP_INSTALL_PREFIX=$(prefix) -DPLATFORM_OS=\"@PLATFORM_OS@\" @DEFS@
|
||||||
|
|
||||||
# File name extensions
|
# File name extensions
|
||||||
OEXT = .o
|
OEXT = .o
|
||||||
|
|
|
@ -37,7 +37,13 @@
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSString.h>
|
#include <Foundation/NSString.h>
|
||||||
#include <Foundation/NSArray.h>
|
#include <Foundation/NSArray.h>
|
||||||
|
#include <Foundation/NSDictionary.h>
|
||||||
#include <Foundation/NSProcessInfo.h>
|
#include <Foundation/NSProcessInfo.h>
|
||||||
|
#include <Foundation/NSObjCRuntime.h>
|
||||||
|
#include <Foundation/NSUserDefaults.h>
|
||||||
|
#include <Foundation/NSNotification.h>
|
||||||
|
#include <Foundation/NSLock.h>
|
||||||
|
#include <Foundation/NSMapTable.h>
|
||||||
|
|
||||||
/* Deal with strchr: */
|
/* Deal with strchr: */
|
||||||
#if STDC_HEADERS || HAVE_STRING_H
|
#if STDC_HEADERS || HAVE_STRING_H
|
||||||
|
@ -56,39 +62,56 @@
|
||||||
/* memory.h and strings.h conflict on some systems. */
|
/* memory.h and strings.h conflict on some systems. */
|
||||||
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||||
|
|
||||||
#ifndef FREE_OBJECT
|
#if HAVE_DIRENT_H
|
||||||
#define FFREE_OBJECT(id) ([id release],id=nil)
|
# include <dirent.h>
|
||||||
#define FREE_OBJECT(id) (id?FFREE_OBJECT(id):nil)
|
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||||
|
#else
|
||||||
|
# define dirent direct
|
||||||
|
# define NAMLEN(dirent) (dirent)->d_namlen
|
||||||
|
# if HAVE_SYS_NDIR_H
|
||||||
|
# include <sys/ndir.h>
|
||||||
|
# endif
|
||||||
|
# if HAVE_SYS_DIR_H
|
||||||
|
# include <sys/dir.h>
|
||||||
|
# endif
|
||||||
|
# if HAVE_NDIR_H
|
||||||
|
# include <ndir.h>
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the extension that NSBundle expect on all bundle names */
|
#define CHECK_LOCK(lock) \
|
||||||
#define BUNDLE_EXT "bundle"
|
if (!lock) lock = [NSLock new]
|
||||||
|
|
||||||
/* By default, we transmorgrify extensions of type "nib" to type "xmib"
|
typedef enum {
|
||||||
which is the common extension for IB files for the GNUStep project
|
NSBUNDLE_BUNDLE = 1, NSBUNDLE_APPLICATION, NSBUNDLE_LIBRARY
|
||||||
*/
|
} bundle_t;
|
||||||
static NSString *bundle_nib_ext = @"nib";
|
|
||||||
static NSString *bundle_xmib_ext = @"xmib";
|
|
||||||
|
|
||||||
/* Class variables - We keep track of all the bundles and all the classes
|
/* Class variables - We keep track of all the bundles */
|
||||||
that are in each bundle
|
static NSBundle* _mainBundle = nil;
|
||||||
*/
|
static NSMapTable* _bundles = NULL;
|
||||||
static NSBundle *_mainBundle = nil;
|
|
||||||
static NSMutableArray *_bundles = nil;
|
|
||||||
static NSMutableArray *_bundleClasses = nil;
|
|
||||||
|
|
||||||
/* List of language preferences */
|
/* This is for bundles that we can't unload, so they shouldn't be
|
||||||
static NSArray *_languages = nil;
|
dealloced. This is true for all bundles right now */
|
||||||
|
static NSMapTable* _releasedBundles = NULL;
|
||||||
|
|
||||||
/* When we are linking in an object file, objc_load_modules calls our
|
/* When we are linking in an object file, objc_load_modules calls our
|
||||||
callback routine for every Class and Category loaded. The following
|
callback routine for every Class and Category loaded. The following
|
||||||
variable stores the bundle that is currently doing the loading so we know
|
variable stores the bundle that is currently doing the loading so we know
|
||||||
where to store the class names.
|
where to store the class names.
|
||||||
FIXME: This should be put into a NSThread dictionary
|
|
||||||
*/
|
*/
|
||||||
static int _loadingBundlePos = -1;
|
static NSBundle* _loadingBundle = nil;
|
||||||
|
static NSLock* load_lock = nil;
|
||||||
|
static BOOL _strip_after_loading = NO;
|
||||||
|
|
||||||
static BOOL _stripAfterLoading;
|
NSString* NSBundleDidLoadNotification = @"NSBundleDidLoadNotification";
|
||||||
|
NSString* NSShowNonLocalizedStrings = @"NSShowNonLocalizedStrings";
|
||||||
|
NSString* NSLoadedClasses = @"NSLoadedClasses";
|
||||||
|
static NSString* platform =
|
||||||
|
#ifdef PLATFORM_OS
|
||||||
|
@PLATFORM_OS;
|
||||||
|
#else
|
||||||
|
nil;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Declaration from find_exec.c */
|
/* Declaration from find_exec.c */
|
||||||
extern char *objc_find_executable(const char *name);
|
extern char *objc_find_executable(const char *name);
|
||||||
|
@ -103,423 +126,546 @@ objc_executable_location( void )
|
||||||
|
|
||||||
/* Get the object file that should be located in the bundle of the same name */
|
/* Get the object file that should be located in the bundle of the same name */
|
||||||
static NSString *
|
static NSString *
|
||||||
bundle_object_name(NSString *path)
|
bundle_object_name(NSString *path, NSString* executable)
|
||||||
{
|
{
|
||||||
NSString *name;
|
NSString *name;
|
||||||
#if 0
|
|
||||||
/* FIXME: This will work when NSString is fully implemented */
|
if (executable)
|
||||||
name = [[path lastPathComponent] stringByDeletingPathExtension];
|
name = [path stringByAppendingPathComponent: executable];
|
||||||
name = [path stringByAppendingPathComponent:name];
|
else
|
||||||
return name;
|
{
|
||||||
#else
|
name = [[path lastPathComponent] stringByDeletingPathExtension];
|
||||||
#define BASENAME(str) ((rindex(str, '/')) ? rindex(str, '/')+1 : str)
|
name = [path stringByAppendingPathComponent:name];
|
||||||
char *s;
|
}
|
||||||
char *output;
|
|
||||||
OBJC_MALLOC(output, char, strlen(BASENAME([path cString]))+20);
|
|
||||||
strcpy(output, BASENAME([path cString]));
|
|
||||||
s = rindex(output, '.');
|
|
||||||
if (s)
|
|
||||||
*s = '\0';
|
|
||||||
name = [NSString stringWithFormat:@"%s/%s", [path cString], output];
|
|
||||||
OBJC_FREE(output);
|
|
||||||
#endif
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct a path from the directory, language, name and extension. Used by
|
/* Construct a path from components */
|
||||||
pathForResource:...
|
|
||||||
*/
|
|
||||||
static NSString *
|
static NSString *
|
||||||
bundle_resource_path(NSString *path, NSString *lang, NSString *name,
|
_bundle_resource_path(NSString *primary, NSString* bundlePath, NSString *lang)
|
||||||
NSString *ext )
|
|
||||||
{
|
{
|
||||||
NSString *fullpath;
|
if (bundlePath)
|
||||||
NSString *name_ext;
|
primary = [primary stringByAppendingPathComponent: bundlePath];
|
||||||
|
if (lang)
|
||||||
#if 0
|
primary = [primary stringByAppendingPathComponent:
|
||||||
/* FIXME: This will work when NSString is fully implemented */
|
[NSString stringWithFormat: @"%@.lproj", lang]];
|
||||||
name_ext = [name pathExtension];
|
return primary;
|
||||||
name = [name stringByDeletingPathExtension];
|
|
||||||
#else
|
|
||||||
char *s;
|
|
||||||
char *output;
|
|
||||||
OBJC_MALLOC(output, char, strlen([name cString])+1);
|
|
||||||
strcpy(output, [name cString]);
|
|
||||||
s = rindex(output, '.');
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
*s = '\0';
|
|
||||||
name_ext = [NSString stringWithCString:(s+1)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
name_ext = nil;
|
|
||||||
name = [NSString stringWithCString:output];
|
|
||||||
OBJC_FREE(output);
|
|
||||||
#endif
|
|
||||||
// FIXME: we could check to see if name_ext and ext match, but what
|
|
||||||
// would we do if they didn't?
|
|
||||||
if (!ext)
|
|
||||||
ext = name_ext;
|
|
||||||
if ([ext isEqual:bundle_nib_ext])
|
|
||||||
ext = bundle_xmib_ext;
|
|
||||||
#if 0
|
|
||||||
/* FIXME: This will work when NSString is fully implemented */
|
|
||||||
if (lang) {
|
|
||||||
fullpath = [NSString stringWithFormat: @"%@/%@.lproj/%@",
|
|
||||||
path, lang, name];
|
|
||||||
} else {
|
|
||||||
fullpath = [NSString stringWithFormat: @"%@/%@", path, name];
|
|
||||||
}
|
|
||||||
if (ext && [ext length] != 0)
|
|
||||||
fullpath = [NSString stringByAppendingPathExtension:ext];
|
|
||||||
#else
|
|
||||||
if (lang) {
|
|
||||||
fullpath = [NSString stringWithFormat: @"%s/%s.lproj/%s",
|
|
||||||
[path cString], [lang cString], [name cString]];
|
|
||||||
} else {
|
|
||||||
fullpath = [NSString stringWithFormat: @"%s/%s",
|
|
||||||
[path cString], [name cString]];
|
|
||||||
}
|
|
||||||
if (ext && [ext length] != 0)
|
|
||||||
fullpath = [NSString stringWithFormat:@"%s.%s",
|
|
||||||
[fullpath cString], [ext cString]];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "Debug (NSBundle): path is %s\n", [fullpath cString]);
|
|
||||||
#endif
|
|
||||||
return fullpath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find the first directory entry with a given name (with any extension) */
|
||||||
|
static NSString *
|
||||||
|
_bundle_path_for_name(NSString* path, NSString* name)
|
||||||
|
{
|
||||||
|
DIR *thedir;
|
||||||
|
struct dirent *entry;
|
||||||
|
NSString *fullname;
|
||||||
|
|
||||||
|
fullname = NULL;
|
||||||
|
thedir = opendir([path cString]);
|
||||||
|
if(thedir)
|
||||||
|
{
|
||||||
|
while ((entry = readdir(thedir)))
|
||||||
|
{
|
||||||
|
if (*entry->d_name != '.'
|
||||||
|
&& strncmp([name cString], entry->d_name, [name length]) == 0)
|
||||||
|
{
|
||||||
|
fullname = [NSString stringWithCString: entry->d_name];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(thedir);
|
||||||
|
}
|
||||||
|
if (!fullname)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
return [path stringByAppendingPathComponent: fullname];
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface NSBundle (Private)
|
||||||
|
- (NSArray *) _bundleClasses;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSBundle (Private)
|
||||||
|
- (NSArray *) _bundleClasses
|
||||||
|
{
|
||||||
|
return _bundleClasses;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
void
|
void
|
||||||
_bundle_load_callback(Class theClass, Category *theCategory)
|
_bundle_load_callback(Class theClass, Category *theCategory)
|
||||||
{
|
{
|
||||||
/* Don't store categories */
|
assert(_loadingBundle);
|
||||||
assert(_loadingBundlePos >= 0);
|
/* Don't store categories */
|
||||||
if (!theCategory)
|
if (!theCategory)
|
||||||
[[_bundleClasses objectAtIndex:_loadingBundlePos]
|
[(NSMutableArray *)[_loadingBundle _bundleClasses] addObject: (id)theClass];
|
||||||
addObject:(id)theClass];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation NSBundle
|
@implementation NSBundle
|
||||||
|
|
||||||
+ (NSBundle *)mainBundle
|
+ (NSBundle *)mainBundle
|
||||||
{
|
{
|
||||||
if ( !_mainBundle ) {
|
|
||||||
char *s;
|
|
||||||
char *output;
|
|
||||||
NSString *path;
|
|
||||||
|
|
||||||
path = [[NSProcessInfo processInfo] processName];
|
CHECK_LOCK(load_lock);
|
||||||
output = objc_find_executable([path cString]);
|
[load_lock lock];
|
||||||
assert(output);
|
|
||||||
path = [NSString stringWithCString: output];
|
|
||||||
OBJC_FREE(output);
|
|
||||||
|
|
||||||
/* Strip off the name of the program */
|
if ( !_mainBundle )
|
||||||
#if 0
|
{
|
||||||
/* FIXME: Should work when NSString is implemented */
|
char *output;
|
||||||
path = [path stringByDeletingLastPathComponent];
|
NSString *path;
|
||||||
#else
|
|
||||||
OBJC_MALLOC(output, char, strlen([path cString])+1);
|
path = [[NSProcessInfo processInfo] processName];
|
||||||
strcpy(output, [path cString]);
|
output = objc_find_executable([path cString]);
|
||||||
s = rindex(output, '/');
|
assert(output);
|
||||||
if (s && s != output) {*s = '\0';}
|
path = [NSString stringWithCString: output];
|
||||||
path = [NSString stringWithCString:output];
|
OBJC_FREE(output);
|
||||||
OBJC_FREE(output);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct a path from the directory, language, name and extension.
|
/* Strip off the name of the program */
|
||||||
Used by */
|
path = [path stringByDeletingLastPathComponent];
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "Debug (NSBundle): Found main in %s\n",
|
fprintf(stderr, "Debug (NSBundle): Found main in %s\n",
|
||||||
[path cString]);
|
[path cString]);
|
||||||
#endif
|
#endif
|
||||||
/* We do alloc and init separately so initWithPath: does not
|
/* We do alloc and init separately so initWithPath: knows
|
||||||
add us to the _bundles list
|
we are the _mainBundle */
|
||||||
*/
|
_mainBundle = [NSBundle alloc];
|
||||||
_mainBundle = [NSBundle alloc];
|
_mainBundle = [_mainBundle initWithPath:path];
|
||||||
_mainBundle = [_mainBundle initWithPath:path];
|
|
||||||
}
|
}
|
||||||
return _mainBundle;
|
|
||||||
|
[load_lock unlock];
|
||||||
|
return _mainBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Due to lazy evaluation, we will not find a class if a either classNamed: or
|
/* Due to lazy evaluation, we will not find a class if either classNamed: or
|
||||||
principalClass has not been called on the particular bundle that contains
|
principalClass has not been called on the particular bundle that contains
|
||||||
the class. (FIXME)
|
the class. (FIXME)
|
||||||
*/
|
*/
|
||||||
+ (NSBundle *)bundleForClass:aClass
|
+ (NSBundle *) bundleForClass: (Class)aClass
|
||||||
{
|
{
|
||||||
int i, count;
|
void* key;
|
||||||
NSBundle *bundle = nil;
|
NSBundle* bundle;
|
||||||
|
NSMapEnumerator enumerate;
|
||||||
|
if (!aClass)
|
||||||
|
return nil;
|
||||||
|
|
||||||
// FIXME: should this be an error if aClass == nil?
|
bundle = nil;
|
||||||
if (!aClass)
|
enumerate = NSEnumerateMapTable(_bundles);
|
||||||
return nil;
|
while (NSNextMapEnumeratorPair(&enumerate, &key, (void **)&bundle))
|
||||||
|
{
|
||||||
count = [_bundleClasses count];
|
int j;
|
||||||
for (i=0; i < count; i++) {
|
j = [[bundle _bundleClasses] indexOfObject: aClass];
|
||||||
int j, class_count;
|
if (j != NSNotFound && [bundle _bundleClasses])
|
||||||
NSArray *classList = [_bundleClasses objectAtIndex:i];
|
break;
|
||||||
class_count = [classList count];
|
bundle = nil;
|
||||||
for (j = 0; j < class_count; j++)
|
|
||||||
if ([aClass isEqual:[classList objectAtIndex:j]]) {
|
|
||||||
bundle = [_bundles objectAtIndex:i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (bundle)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (!bundle) {
|
if (!bundle)
|
||||||
/* Is it in the main bundle? */
|
{
|
||||||
if (class_is_class(aClass))
|
/* Is it in the main bundle? */
|
||||||
bundle = [NSBundle mainBundle];
|
if (class_is_class(aClass))
|
||||||
|
bundle = [NSBundle mainBundle];
|
||||||
}
|
}
|
||||||
|
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSBundle *)bundleWithPath:(NSString *)path
|
+ (NSBundle *)bundleWithPath:(NSString *)path
|
||||||
{
|
{
|
||||||
return [[[NSBundle alloc] initWithPath:path] autorelease];
|
return [[[NSBundle alloc] initWithPath: path] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithPath:(NSString *)path;
|
- initWithPath:(NSString *)path;
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
[super init];
|
[super init];
|
||||||
|
|
||||||
if (!_languages)
|
if (!path || [path length] == 0)
|
||||||
[[self class] setSystemLanguages:NULL];
|
{
|
||||||
|
NSLog(@"No path specified for bundle");
|
||||||
if (!path || [path length] == 0) {
|
return nil;
|
||||||
[NSException raise:NSInvalidArgumentException
|
|
||||||
format:@"No path specified for bundle"];
|
|
||||||
/* NOT REACHED */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we were already initialized for this directory */
|
/* Check if we were already initialized for this directory */
|
||||||
if (_bundles) {
|
if (_bundles)
|
||||||
int i;
|
{
|
||||||
int count;
|
NSBundle* bundle = (NSBundle *)NSMapGet(_bundles, path);
|
||||||
count = [_bundles count];
|
if (bundle)
|
||||||
for (i=0; i < count; i++) {
|
{
|
||||||
if ([path isEqual:[[_bundles objectAtIndex:i] bundlePath]])
|
[self dealloc];
|
||||||
return [_bundles objectAtIndex:i];
|
return [bundle retain]; /* retain - look as if we were alloc'ed */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (_releasedBundles)
|
||||||
|
{
|
||||||
|
NSBundle* loaded = (NSBundle *)NSMapGet(_releasedBundles, path);
|
||||||
|
if (loaded)
|
||||||
|
{
|
||||||
|
NSMapInsert(_bundles, path, loaded);
|
||||||
|
NSMapRemove(_releasedBundles, path);
|
||||||
|
[self dealloc];
|
||||||
|
return [loaded retain]; /* retain - look as if we were alloc'ed */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat([path cString], &statbuf) != 0) {
|
if (stat([path cString], &statbuf) != 0)
|
||||||
[NSException raise:NSGenericException
|
{
|
||||||
format:@"Could not find path %s", [path cString]];
|
NSLog(@"Could not access path %s for bundle", [path cString]);
|
||||||
/* NOT REACHED */
|
return nil;
|
||||||
}
|
}
|
||||||
_path = [path retain];
|
|
||||||
|
|
||||||
if (self == _mainBundle)
|
CHECK_LOCK(load_lock);
|
||||||
return self;
|
[load_lock lock];
|
||||||
|
if (!_bundles)
|
||||||
if (!_bundles) {
|
{
|
||||||
_bundles = [[NSMutableArray arrayWithCapacity:2] retain];
|
_bundles = NSCreateMapTable(NSObjectMapKeyCallBacks,
|
||||||
_bundleClasses = [[NSMutableArray arrayWithCapacity:2] retain];
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
|
_releasedBundles = NSCreateMapTable(NSObjectMapKeyCallBacks,
|
||||||
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
}
|
}
|
||||||
[_bundles addObject:self];
|
[load_lock unlock];
|
||||||
[_bundleClasses addObject:[[NSMutableArray arrayWithCapacity:0] retain]];
|
|
||||||
|
|
||||||
return self;
|
_path = [path copy];
|
||||||
|
_bundleType = (unsigned int)NSBUNDLE_BUNDLE;
|
||||||
|
if (self == _mainBundle)
|
||||||
|
_bundleType = (unsigned int)NSBUNDLE_APPLICATION;
|
||||||
|
|
||||||
|
NSMapInsert(_bundles, _path, self);
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can't really unload the module, since objc_unload_module has
|
/* Some bundles should not be dealloced, such as the main bundle. So we
|
||||||
no idea where we were loaded from, so we just dealloc everything and
|
keep track of our own retain count to avoid this.
|
||||||
don't worry about it.
|
Currently, the objc runtime can't unload modules, so we actually
|
||||||
|
avoid deallocating any bundle */
|
||||||
|
- (oneway void) release
|
||||||
|
{
|
||||||
|
if (self == NSMapGet(_releasedBundles, _path))
|
||||||
|
{
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"Bundle for path %@ released too many times", _path];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSParameterAssert(_retainCount >= 0);
|
||||||
|
if (_retainCount == 0)
|
||||||
|
{
|
||||||
|
/* Cache all bundles */
|
||||||
|
if (_bundleType == NSBUNDLE_APPLICATION
|
||||||
|
|| _bundleType == NSBUNDLE_LIBRARY
|
||||||
|
|| _bundleType == NSBUNDLE_BUNDLE)
|
||||||
|
{
|
||||||
|
NSMapRemove(_bundles, _path);
|
||||||
|
NSMapInsert(_releasedBundles, _path, self);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
[self dealloc];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_retainCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
- retain
|
||||||
|
{
|
||||||
|
_retainCount++;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (unsigned) retainCount
|
||||||
|
{
|
||||||
|
return _retainCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
NSMapRemove(_bundles, _path);
|
||||||
|
[_bundleClasses release];
|
||||||
|
[_infoDict release];
|
||||||
|
[_path release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) bundlePath
|
||||||
|
{
|
||||||
|
return _path;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (Class) classNamed: (NSString *)className
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
Class theClass = Nil;
|
||||||
|
if (!_codeLoaded)
|
||||||
|
{
|
||||||
|
if (self != _mainBundle && ![self principalClass])
|
||||||
|
{
|
||||||
|
NSLog(@"No classes in bundle");
|
||||||
|
return Nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self == _mainBundle)
|
||||||
|
{
|
||||||
|
theClass = NSClassFromString(className);
|
||||||
|
if (theClass && [[self class] bundleForClass:theClass] != _mainBundle)
|
||||||
|
theClass = Nil;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
j = [_bundleClasses indexOfObject: NSClassFromString(className)];
|
||||||
|
if (j != NSNotFound)
|
||||||
|
theClass = [_bundleClasses objectAtIndex: j];
|
||||||
|
}
|
||||||
|
|
||||||
|
return theClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (Class) principalClass
|
||||||
|
{
|
||||||
|
NSString* class_name;
|
||||||
|
|
||||||
|
if (_principalClass)
|
||||||
|
return _principalClass;
|
||||||
|
|
||||||
|
class_name = [[self infoDictionary] objectForKey: @"NSPrincipalClass"];
|
||||||
|
|
||||||
|
if (self == _mainBundle)
|
||||||
|
{
|
||||||
|
_codeLoaded = YES;
|
||||||
|
if (class_name)
|
||||||
|
_principalClass = NSClassFromString(class_name);
|
||||||
|
return _principalClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
[load_lock lock];
|
||||||
|
if (!_codeLoaded)
|
||||||
|
{
|
||||||
|
NSString* object;
|
||||||
|
object = [[self infoDictionary] objectForKey: @"NSExecutable"];
|
||||||
|
object = bundle_object_name(_path, object);
|
||||||
|
_loadingBundle = self;
|
||||||
|
_bundleClasses = [[NSMutableArray arrayWithCapacity:2] retain];
|
||||||
|
if (objc_load_module([object cString],
|
||||||
|
stderr, _bundle_load_callback, NULL, NULL))
|
||||||
|
return Nil;
|
||||||
|
_codeLoaded = YES;
|
||||||
|
_loadingBundle = nil;
|
||||||
|
[[NSNotificationCenter defaultCenter]
|
||||||
|
postNotificationName: NSBundleDidLoadNotification
|
||||||
|
object: self
|
||||||
|
userInfo: [NSDictionary dictionaryWithObjects: &_bundleClasses
|
||||||
|
forKeys: &NSLoadedClasses count: 1]];
|
||||||
|
}
|
||||||
|
[load_lock unlock];
|
||||||
|
|
||||||
|
if (class_name)
|
||||||
|
_principalClass = NSClassFromString(class_name);
|
||||||
|
else if ([_bundleClasses count])
|
||||||
|
_principalClass = [_bundleClasses objectAtIndex:0];
|
||||||
|
return _principalClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This method is the backbone of the resource searching for NSBundle. It
|
||||||
|
constructs an array of paths, where each path is a possible location
|
||||||
|
for a resource in the bundle. The current algorithm for searching goes:
|
||||||
|
|
||||||
|
<main bundle>/Resources/<bundlePath>
|
||||||
|
<main bundle>/Resources/<bundlePath>/<language.lproj>
|
||||||
|
<main bundle>/<bundlePath>
|
||||||
|
<main bundle>/<bundlePath>/<language.lproj>
|
||||||
*/
|
*/
|
||||||
- (void)dealloc
|
- (NSArray *) _bundleResourcePathsWithDirectory: (NSString *)bundlePath
|
||||||
{
|
{
|
||||||
int pos = [_bundles indexOfObject:self];
|
NSString* primary;
|
||||||
|
NSString* language;
|
||||||
|
NSArray* languages;
|
||||||
|
NSMutableArray* array;
|
||||||
|
NSEnumerator* enumerate;
|
||||||
|
|
||||||
if (pos >= 0) {
|
array = [NSMutableArray arrayWithCapacity: 2];
|
||||||
[_bundleClasses removeObjectAtIndex:pos];
|
languages = [NSUserDefaults userLanguages];
|
||||||
[_bundles removeObjectAtIndex:pos];
|
|
||||||
}
|
|
||||||
FREE_OBJECT(_path);
|
|
||||||
[super dealloc];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)bundlePath
|
primary = [self resourcePath];
|
||||||
{
|
[array addObject: _bundle_resource_path(primary, bundlePath, nil)];
|
||||||
return _path;
|
enumerate = [languages objectEnumerator];
|
||||||
}
|
while ((language = [enumerate nextObject]))
|
||||||
|
[array addObject: _bundle_resource_path(primary, bundlePath, language)];
|
||||||
- classNamed:(NSString *)className
|
|
||||||
{
|
|
||||||
int j, class_count;
|
|
||||||
NSArray *classList;
|
|
||||||
Class theClass = Nil;
|
|
||||||
if (!_codeLoaded) {
|
|
||||||
if (self != _mainBundle && ![self principalClass]) {
|
|
||||||
[NSException raise:NSGenericException
|
|
||||||
format:@"No classes in bundle"];
|
|
||||||
/* NOT REACHED */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self == _mainBundle) {
|
|
||||||
theClass = objc_lookup_class([className cString]);
|
|
||||||
if (theClass && [[self class] bundleForClass:theClass] != _mainBundle)
|
|
||||||
theClass = Nil;
|
|
||||||
} else {
|
|
||||||
classList = [_bundleClasses objectAtIndex:
|
|
||||||
[_bundles indexOfObject:self]];
|
|
||||||
class_count = [classList count];
|
|
||||||
for (j = 0; j < class_count; j++) {
|
|
||||||
theClass = [classList objectAtIndex:j];
|
|
||||||
if ([theClass isEqual:objc_lookup_class([className cString])]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
theClass = Nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return theClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
- principalClass
|
|
||||||
{
|
|
||||||
NSArray *classList;
|
|
||||||
if (self == _mainBundle) {
|
|
||||||
_codeLoaded = YES;
|
|
||||||
return nil; // the mainBundle does not have a principal class
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_codeLoaded) {
|
|
||||||
NSString *object = bundle_object_name(_path);
|
|
||||||
/* Link in the object file */
|
|
||||||
_loadingBundlePos = [_bundles indexOfObject:self];
|
|
||||||
if (objc_load_module([object cString],
|
|
||||||
stderr, _bundle_load_callback, NULL, NULL)) {
|
|
||||||
[NSException raise:NSGenericException
|
|
||||||
format:@"Unable to load module %s", [object cString]];
|
|
||||||
/* NOT REACHED */
|
|
||||||
} else
|
|
||||||
_codeLoaded = YES;
|
|
||||||
_loadingBundlePos = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
classList = [_bundleClasses objectAtIndex:[_bundles indexOfObject:self]];
|
|
||||||
if ([classList count])
|
|
||||||
return [classList objectAtIndex:0];
|
|
||||||
else
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)pathForResource:(NSString *)name
|
|
||||||
ofType:(NSString *)ext;
|
|
||||||
{
|
|
||||||
return [[self class] pathForResource:name
|
|
||||||
ofType:ext
|
|
||||||
inDirectory: _path
|
|
||||||
withVersion: 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (NSString *)pathForResource:(NSString *)name
|
|
||||||
ofType:(NSString *)ext
|
|
||||||
inDirectory:(NSString *)bundlePath
|
|
||||||
withVersion:(int)version;
|
|
||||||
{
|
|
||||||
struct stat statbuf;
|
|
||||||
NSString *path = nil;
|
|
||||||
|
|
||||||
if (!name || [name length] == 0) {
|
primary = [self bundlePath];
|
||||||
[NSException raise:NSInvalidArgumentException
|
[array addObject: _bundle_resource_path(primary, bundlePath, nil)];
|
||||||
format:@"No resource name specified."];
|
enumerate = [languages objectEnumerator];
|
||||||
/* NOT REACHED */
|
while ((language = [enumerate nextObject]))
|
||||||
|
[array addObject: _bundle_resource_path(primary, bundlePath, language)];
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) pathForResource: (NSString *)name
|
||||||
|
ofType: (NSString *)ext;
|
||||||
|
{
|
||||||
|
return [self pathForResource: name
|
||||||
|
ofType: ext
|
||||||
|
inDirectory: nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) pathForResource: (NSString *)name
|
||||||
|
ofType: (NSString *)ext
|
||||||
|
inDirectory: (NSString *)bundlePath
|
||||||
|
{
|
||||||
|
NSString *path;
|
||||||
|
NSArray* paths;
|
||||||
|
NSEnumerator* enumerate;
|
||||||
|
|
||||||
|
if (!name || [name length] == 0)
|
||||||
|
{
|
||||||
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
format: @"No resource name specified."];
|
||||||
|
/* NOT REACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_languages) {
|
paths = [self _bundleResourcePathsWithDirectory: bundlePath];
|
||||||
unsigned i, count;
|
enumerate = [paths objectEnumerator];
|
||||||
count = [_languages count];
|
while((path = [enumerate nextObject]))
|
||||||
for (i=0; i < count; i++) {
|
{
|
||||||
path = bundle_resource_path(bundlePath,
|
NSString* fullpath = nil;
|
||||||
[_languages objectAtIndex:i], name, ext );
|
|
||||||
if ( stat([path cString], &statbuf) == 0)
|
|
||||||
break;
|
|
||||||
path = nil;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
path = bundle_resource_path(bundlePath, @"English", name, ext );
|
|
||||||
if ( stat([path cString], &statbuf) != 0) {
|
|
||||||
path = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ext && [ext length] != 0)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
fullpath = [path stringByAppendingPathComponent:
|
||||||
|
[NSString stringWithFormat: @"%@.%@", name, ext]];
|
||||||
|
if ( stat([fullpath cString], &statbuf) == 0)
|
||||||
|
{
|
||||||
|
if (platform)
|
||||||
|
{
|
||||||
|
NSString* platpath;
|
||||||
|
platpath = [path stringByAppendingPathComponent:
|
||||||
|
[NSString stringWithFormat: @"%@-%@.%@",
|
||||||
|
name, platform, ext]];
|
||||||
|
if ( stat([platpath cString], &statbuf) == 0)
|
||||||
|
fullpath = platpath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fullpath = nil;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fullpath = _bundle_path_for_name(path, name);
|
||||||
|
if (fullpath && platform)
|
||||||
|
{
|
||||||
|
NSString* platpath;
|
||||||
|
platpath = _bundle_path_for_name(path,
|
||||||
|
[NSString stringWithFormat: @"%@-%@",
|
||||||
|
name, platform]);
|
||||||
|
if (platpath)
|
||||||
|
fullpath = platpath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fullpath)
|
||||||
|
return fullpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path) {
|
return nil;
|
||||||
path = bundle_resource_path(bundlePath, nil, name, ext );
|
}
|
||||||
if ( stat([path cString], &statbuf) != 0) {
|
|
||||||
path = nil;
|
- (NSArray *) pathsForResourcesOfType: (NSString *)extension
|
||||||
|
inDirectory: (NSString *)bundlePath
|
||||||
|
{
|
||||||
|
NSString *path;
|
||||||
|
NSArray* paths;
|
||||||
|
NSMutableArray* resources;
|
||||||
|
NSEnumerator* enumerate;
|
||||||
|
|
||||||
|
paths = [self _bundleResourcePathsWithDirectory: bundlePath];
|
||||||
|
enumerate = [paths objectEnumerator];
|
||||||
|
resources = [NSMutableArray arrayWithCapacity: 2];
|
||||||
|
while((path = [enumerate nextObject]))
|
||||||
|
{
|
||||||
|
DIR *thedir;
|
||||||
|
struct dirent *entry;
|
||||||
|
|
||||||
|
thedir = opendir([path cString]);
|
||||||
|
if (thedir)
|
||||||
|
{
|
||||||
|
while ((entry = readdir(thedir)))
|
||||||
|
{
|
||||||
|
if (*entry->d_name != '.')
|
||||||
|
{
|
||||||
|
char* ext;
|
||||||
|
ext = strrchr(entry->d_name, '.');
|
||||||
|
if (!extension || [extension length] == 0
|
||||||
|
|| (ext && strcmp(++ext, [extension cString]) == 0))
|
||||||
|
[resources addObject:
|
||||||
|
[path stringByAppendingPathComponent:
|
||||||
|
[NSString stringWithCString: entry->d_name]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(thedir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)stripAfterLoading:(BOOL)flag
|
- (NSString *) localizedStringForKey: (NSString *)key
|
||||||
|
value: (NSString *)value
|
||||||
|
table: (NSString *)tableName
|
||||||
{
|
{
|
||||||
_stripAfterLoading = flag;
|
NSString* new_string;
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)localizedStringForKey:(NSString *)key
|
if (!tableName)
|
||||||
value:(NSString *)value
|
tableName = [self pathForResource: @"Localizable" ofType: @"strings"];
|
||||||
table:(NSString *)tableName
|
if (!tableName)
|
||||||
{
|
{
|
||||||
[self notImplemented:_cmd];
|
NSArray* resources = [self pathsForResourcesOfType: @"strings"
|
||||||
return 0;
|
inDirectory: nil];
|
||||||
}
|
if (resources && [resources count])
|
||||||
|
tableName = [resources objectAtIndex: 0];
|
||||||
- (unsigned)bundleVersion
|
|
||||||
{
|
|
||||||
return _bundleVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setBundleVersion:(unsigned)version
|
|
||||||
{
|
|
||||||
_bundleVersion = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)setSystemLanguages:(NSArray *)languages
|
|
||||||
{
|
|
||||||
// static NSString *separator = @" ";
|
|
||||||
|
|
||||||
if (_languages) {
|
|
||||||
FREE_OBJECT(_languages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If called with a nil array, look in the environment for the
|
|
||||||
language list. The languages should separated by the "separator"
|
|
||||||
string.
|
|
||||||
*/
|
|
||||||
if (!languages) {
|
|
||||||
const char *env_list;
|
|
||||||
// NSString *env;
|
|
||||||
env_list = getenv("LANGUAGES");
|
|
||||||
if (env_list) {
|
|
||||||
#if 0
|
|
||||||
/* FIXME: This will work when NSString is fully implemented */
|
|
||||||
env = [NSString stringWithCString:e];
|
|
||||||
_languages = [[env componentsSeparatedByString:separator] retain];
|
|
||||||
#else
|
|
||||||
/* Just pick out the first one */
|
|
||||||
char *s;
|
|
||||||
s = index(env_list, ' ');
|
|
||||||
if (s)
|
|
||||||
*s = '\0';
|
|
||||||
_languages = [[NSString stringWithCString:env_list] retain];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
_languages = [languages retain];
|
|
||||||
|
|
||||||
|
new_string = value;
|
||||||
|
if (tableName)
|
||||||
|
{
|
||||||
|
NSDictionary* dict;
|
||||||
|
dict = [[[NSDictionary alloc] initWithContentsOfFile: tableName]
|
||||||
|
autorelease];
|
||||||
|
new_string = [dict objectForKey: key];
|
||||||
|
if (!new_string)
|
||||||
|
new_string = value;
|
||||||
|
}
|
||||||
|
if (!new_string || [new_string length] == 0)
|
||||||
|
{
|
||||||
|
NSString* show = [[NSUserDefaults standardUserDefaults]
|
||||||
|
objectForKey: NSShowNonLocalizedStrings];
|
||||||
|
if (!show || [show isEqual: @"YES"])
|
||||||
|
new_string = [key uppercaseString];
|
||||||
|
else
|
||||||
|
new_string = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) stripAfterLoading: (BOOL)flag
|
||||||
|
{
|
||||||
|
_strip_after_loading = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) resourcePath
|
||||||
|
{
|
||||||
|
return [_path stringByAppendingPathComponent: @"Resources"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *) infoDictionary
|
||||||
|
{
|
||||||
|
NSString* path;
|
||||||
|
|
||||||
|
if (_infoDict)
|
||||||
|
return _infoDict;
|
||||||
|
|
||||||
|
path = [self pathForResource: @"Info" ofType: @"plist"];
|
||||||
|
if (path)
|
||||||
|
_infoDict = [[NSDictionary alloc] initWithContentsOfFile: path];
|
||||||
|
else
|
||||||
|
_infoDict = [[NSDictionary dictionary] retain];
|
||||||
|
return _infoDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
7
aclocal.m4
vendored
7
aclocal.m4
vendored
|
@ -156,7 +156,12 @@ elif test $DYNAMIC_LINKER = simple; then
|
||||||
else
|
else
|
||||||
DYNAMIC_BUNDLER_LINKER='$(CC) -nostdlib'
|
DYNAMIC_BUNDLER_LINKER='$(CC) -nostdlib'
|
||||||
fi
|
fi
|
||||||
DYNAMIC_LDFLAGS=""
|
save_LDFLAGS=$LDFLAGS
|
||||||
|
LDFLAGS="-rdynamic"
|
||||||
|
AC_TRY_RUN([], objc_dynamic_ldflag="-rdynamic", objc_dynamic_ldflag="",
|
||||||
|
objc_dynamic_ldflag="")
|
||||||
|
LDFLAGS=$save_LDFLAGS
|
||||||
|
DYNAMIC_LDFLAGS="$objc_dynamic_ldflag"
|
||||||
DYNAMIC_CFLAGS="-fPIC"
|
DYNAMIC_CFLAGS="-fPIC"
|
||||||
elif test $DYNAMIC_LINKER = hpux; then
|
elif test $DYNAMIC_LINKER = hpux; then
|
||||||
DYNAMIC_BUNDLER_LINKER='$(CC) -nostdlib -Xlinker -b'
|
DYNAMIC_BUNDLER_LINKER='$(CC) -nostdlib -Xlinker -b'
|
||||||
|
|
16
configure.in
16
configure.in
|
@ -175,6 +175,16 @@ AC_SUBST(NEXT_INCLUDES)
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
OBJC_SYS_DYNAMIC_FLAGS()
|
OBJC_SYS_DYNAMIC_FLAGS()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# Determine the target platform
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
if test "x$target" = "xNONE"; then
|
||||||
|
PLATFORM_OS=`config.guess`
|
||||||
|
else
|
||||||
|
PLATFORM_OS="$target"
|
||||||
|
fi
|
||||||
|
AC_SUBST(PLATFORM_OS)
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Find some programs
|
# Find some programs
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
|
@ -229,6 +239,12 @@ if [ $HAVE_VSPRINTF ] ; then
|
||||||
AC_DEFINE(VSPRINTF_RETURNS_LENGTH)
|
AC_DEFINE(VSPRINTF_RETURNS_LENGTH)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
# DIR definitions needed by NSBundle.m
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
AC_HEADER_DIRENT
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# This function needed by objc-malloc.c
|
# This function needed by objc-malloc.c
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue