Get NSTimeZone to work in GNUstep directory structure.

Add GNUstep specific method to NSBundle which will search the GNUstep
directory structure for resource files.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2528 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Scott Christley 1997-10-18 19:49:50 +00:00
parent ab180cbd8c
commit 9db12ac373
9 changed files with 378 additions and 28 deletions

View file

@ -1,3 +1,35 @@
Sat Oct 18 12:27:56 1997 Scott Christley <scottc@net-community.com>
* Get NSTimeZone to work in GNUstep directory structure.
* src/NSTimeZone.m (+getAbbreviationFile): New method.
(+getRegionsFiles, +getLocalTimeFile): New methods.
(+getTimeZoneFile:): New method.
(TIME_ZONE_DIR, ABBREV_DICT, REGIONS_FILE, LOCAL_TIME_FILE, ZONES_DIR):
Correct paths.
(+initialize): Use private method to get resource file name.
(+timeZoneWithName:, +abbreviationMap, +timeZoneArray): Likewise.
* checks/create-abbrevs.m: New file.
* checks/create-regions.m: New file.
* checks/nstimezone.m: New file.
* checks/Makefile: Add new checks.
* src/NSBundle.m
(+pathForResource:ofType:inRootPath:inDirectory:withVersion:):
If no extension then look for file without extension before
calling _bundle_path_for_name() which does not handle the case
where the resource name contains a directory path within it.
* src/NSBundle.m
(+pathForGNUstepResource:ofType:InDirectory:): New method.
* src/include/NSBundle.h
(+pathForGNUstepResource:ofType:InDirectory:): New method.
Fri Oct 17 12:44:18 1997 Scott Christley <scottc@net-community.com>
* src/NotificationDispatcher.m (-init): Make the key callbacks
be NSObject for the notification name map table so that
isEqual: is used for comparison.
Fri Oct 17 09:16:36 1997 Adam Fedor <fedor@doc.com>
* checks/Makefile.postamble: Add English.lproj dir to copy-dist.

View file

@ -83,6 +83,14 @@ extern NSString* NSLoadedClasses;
@end
@interface NSBundle (GNUstep)
+ (NSString *) pathForGNUstepResource: (NSString *)name
ofType: (NSString *)ext
inDirectory: (NSString *)bundlePath;
@end
#define NSLocalizedString(key, comment) \
[[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
#define NSLocalizedStringFromTable(key, tbl, comment) \

View file

@ -576,15 +576,33 @@ _bundle_load_callback(Class theClass, Category *theCategory)
}
else
{
fullpath = _bundle_path_for_name(path, name);
if (fullpath && platform)
struct stat statbuf;
fullpath = [path stringByAppendingPathComponent:
[NSString stringWithFormat: @"%@", name]];
if ( stat([fullpath cString], &statbuf) == 0)
{
NSString* platpath;
platpath = _bundle_path_for_name(path,
[NSString stringWithFormat: @"%@-%@",
name, platform]);
if (platpath)
fullpath = platpath;
if (platform)
{
NSString* platpath;
platpath = [path stringByAppendingPathComponent:
[NSString stringWithFormat: @"%@-%@",
name, platform]];
if ( stat([platpath cString], &statbuf) == 0)
fullpath = platpath;
}
}
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)
@ -757,3 +775,73 @@ _bundle_load_callback(Class theClass, Category *theCategory)
@end
@implementation NSBundle (GNUstep)
/* This is a convenience method for searching for resource files
within the GNUstep directory structure specified by the environment
variables. */
+ (NSString *) pathForGNUstepResource: (NSString *)name
ofType: (NSString *)ext
inDirectory: (NSString *)bundlePath;
{
NSString *user_path, *local_path, *system_path;
NSBundle *user_bundle = nil, *local_bundle = nil, *system_bundle = nil;
NSProcessInfo *pInfo;
NSDictionary *env;
NSMutableString *user, *local, *system;
/*
The path of where to search for the resource files
is based upon environment variables.
GNUSTEP_USER_ROOT
GNUSTEP_LOCAL_ROOT
GNUSTEP_SYSTEM_ROOT
*/
pInfo = [NSProcessInfo processInfo];
env = [pInfo environment];
user = [[[env objectForKey: @"GNUSTEP_USER_ROOT"]
mutableCopy] autorelease];
[user appendString: @"/Libraries"];
local = [[[env objectForKey: @"GNUSTEP_LOCAL_ROOT"]
mutableCopy] autorelease];
[local appendString: @"/Libraries"];
system = [[[env objectForKey: @"GNUSTEP_SYSTEM_ROOT"]
mutableCopy] autorelease];
[system appendString: @"/Libraries"];
if (user)
user_bundle = [NSBundle bundleWithPath: user];
if (local)
local_bundle = [NSBundle bundleWithPath: local];
if (system)
system_bundle = [NSBundle bundleWithPath: system];
/* Gather up the paths */
/* Search user first */
user_path = [user_bundle pathForResource: name
ofType: ext
inDirectory: bundlePath];
if (user_path)
return user_path;
/* Search local second */
local_path = [local_bundle pathForResource: name
ofType: ext
inDirectory: bundlePath];
if (local_path)
return local_path;
/* Search system last */
system_path = [system_bundle pathForResource: name
ofType: ext
inDirectory: bundlePath];
if (system_path)
return system_path;
/* Didn't find it */
return nil;
}
@end

View file

@ -39,7 +39,7 @@
FIXME?: use leap seconds? */
#include <gnustep/base/preface.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@ -56,7 +56,7 @@
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSUtilities.h>
#include <Foundation/NSZone.h>
#include <gnustep/base/config.h>
#include <Foundation/NSBundle.h>
#define NOID
#include "tzfile.h"
@ -71,25 +71,35 @@
#endif
/* Directory that contains the time zone data. */
#define TIME_ZONE_DIR "NSTimeZones/"
#define TIME_ZONE_DIR @"gnustep/NSTimeZones"
/* Location of time zone abbreviation dictionary. It is a text file
with each line comprised of the abbreviation, a whitespace, and the
name. Neither the abbreviation nor the name can contain
whitespace, and each line must not be longer than 80 characters. */
#define ABBREV_DICT TIME_ZONE_DIR "abbreviations"
#define ABBREV_DICT @"abbreviations"
/* File holding regions grouped by latitude. It is a text file with
each line comprised of the latitude region, whitespace, and the
name. Neither the abbreviation not the name can contain
whitespace, and each line must not be longer than 80 characters. */
#define REGIONS_FILE TIME_ZONE_DIR "regions"
#define REGIONS_FILE @"regions"
/* Name of the file that contains the name of the local time zone. */
#define LOCAL_TIME_FILE TIME_ZONE_DIR "localtime"
#define LOCAL_TIME_FILE @"localtime"
/* Directory that contains the actual time zones. */
#define ZONES_DIR TIME_ZONE_DIR "zones/"
#define ZONES_DIR @"zones/"
/* Private methods */
@interface NSTimeZone (Private)
+ (NSString *)getAbbreviationFile;
+ (NSString *)getRegionsFile;
+ (NSString *)getLocalTimeFile;
+ (NSString *)getTimeZoneFile: (NSString *)name;
@end
@class NSInternalTimeTransition;
@ -503,16 +513,22 @@ decode (const void *ptr)
if (localZoneString == nil)
/* Try to get timezone from LOCAL_TIME_FILE. */
{
NSString *f = [NSTimeZone getLocalTimeFile];
char zone_name[80];
FILE *fp;
fp = fopen(LOCAL_TIME_FILE, "r");
if (fp != NULL)
{
fscanf(fp, "%79s", zone_name);
localZoneString = [NSString stringWithCString: zone_name];
fclose(fp);
}
if (f)
{
fp = fopen([f cStringNoCopy], "r");
if (fp != NULL)
{
fscanf(fp, "%79s", zone_name);
localZoneString = [NSString stringWithCString: zone_name];
fclose(fp);
}
}
else
NSLog(@"NSTimeZone unable to find the `%@' file.", LOCAL_TIME_FILE);
}
if (localZoneString != nil)
localTimeZone = [NSTimeZone timeZoneWithName: localZoneString];
@ -580,13 +596,14 @@ decode (const void *ptr)
+ (NSTimeZone*)timeZoneWithName: (NSString*)aTimeZoneName
{
static NSString *fileException = @"fileException";
id zone, fileName, transArray, detailsArray;
id zone, transArray, detailsArray;
int i, n_trans, n_types, names_size;
id *abbrevsArray;
char *trans, *type_idxs, *zone_abbrevs;
struct tzhead header;
struct ttinfo *types; // Temporary array for details
FILE *file;
NSString *fileName;
[zone_mutex lock];
zone = [zoneDictionary objectForKey: aTimeZoneName];
@ -606,7 +623,7 @@ decode (const void *ptr)
return nil;
}
fileName = [NSString stringWithFormat: @"%s%@", ZONES_DIR, aTimeZoneName];
fileName = [NSTimeZone getTimeZoneFile: aTimeZoneName];
file = fopen([fileName cStringNoCopy], "rb");
if (file == NULL)
{
@ -721,13 +738,15 @@ decode (const void *ptr)
static NSMutableDictionary *abbreviationDictionary = nil;
FILE *file; // For the file containing the abbreviation dictionary
char abbrev[80], name[80];
NSString *fileName;
if (abbreviationDictionary != nil)
return abbreviationDictionary;
/* Read dictionary from file. */
abbreviationDictionary = [[NSMutableDictionary alloc] init];
file = fopen(ABBREV_DICT, "r");
fileName = [NSTimeZone getAbbreviationFile];
file = fopen([fileName cStringNoCopy], "r");
if (file == NULL)
[NSException raise: NSInternalInconsistencyException
format: @"Failed to open time zone abbreviation dictionary"];
@ -764,6 +783,7 @@ decode (const void *ptr)
char name[80];
FILE *file;
id temp_array[24];
NSString *fileName;
if (regionsArray != nil)
return regionsArray;
@ -771,7 +791,8 @@ decode (const void *ptr)
for (i = 0; i < 24; i++)
temp_array[i] = [[NSMutableArray alloc] init];
file = fopen(REGIONS_FILE, "r");
fileName = [NSTimeZone getRegionsFile];
file = fopen([fileName cStringNoCopy], "r");
if (file == NULL)
[NSException raise: NSInternalInconsistencyException
format: @"Failed to open regions array file"];
@ -816,8 +837,36 @@ decode (const void *ptr)
@end
@implementation NSTimeZone (Private)
+ (NSString *)getAbbreviationFile
{
return [NSBundle pathForGNUstepResource: ABBREV_DICT
ofType: @""
inDirectory: TIME_ZONE_DIR];
}
+ (NSString *)getRegionsFile
{
return [NSBundle pathForGNUstepResource: REGIONS_FILE
ofType: @""
inDirectory: TIME_ZONE_DIR];
}
+ (NSString *)getLocalTimeFile
{
return [NSBundle pathForGNUstepResource: LOCAL_TIME_FILE
ofType: @""
inDirectory: TIME_ZONE_DIR];
}
+ (NSString *)getTimeZoneFile: (NSString *)name
{
NSString *fileName = [NSString stringWithFormat: @"%@%@",
ZONES_DIR, name];
return [NSBundle pathForGNUstepResource: fileName
ofType: @""
inDirectory: TIME_ZONE_DIR];
}
@end

View file

@ -222,7 +222,7 @@ static NotificationDispatcher *default_notification_dispatcher = nil;
/* Use NSObjectMapKeyCallBacks so we retain the NAME. We also retain
the values, which are LinkedList's. */
_name_2_nr_list =
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
/* Use NSNonOwnedPointerOrNullMapKeyCallBacks so we won't retain

View file

@ -71,7 +71,10 @@ nsdate \
awake \
thread-except \
nscharacterset \
NSData-test
NSData-test \
nstimezone \
create-abbrevs \
create-regions
# The tool Objective-C source files to be compiled
test01_OBJC_FILES = test01.m
@ -116,6 +119,9 @@ awake_OBJC_FILES = awake.m
thread-except_OBJC_FILES = thread-except.m
nscharacterset_OBJC_FILES = nscharacterset.m
NSData-test_OBJC_FILES = NSData-test.m
nstimezone_OBJC_FILES = nstimezone.m
create-abbrevs_OBJC_FILES = create-abbrevs.m
create-regions_OBJC_FILES = create-regions.m
# The bundles to be compiled
BUNDLE_NAME=LoadMe

57
Testing/create-abbrevs.m Normal file
View file

@ -0,0 +1,57 @@
/* create-abbrevs.m - Utility to create a list of time zones and their
associated abbreviations.
Copyright (C) 1997 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSException.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSUtilities.h>
int
main (int argc, char *argv[])
{
int i;
id pool, zone, dict, e, details, name;
pool = [NSAutoreleasePool new];
for (i = 1; i < argc; i++)
{
name = [NSString stringWithCString: argv[i]];
zone = [NSTimeZone timeZoneWithName: name];
if (zone != nil)
{
id detail, abbrev;
dict = [NSMutableDictionary dictionary];
details = [zone timeZoneDetailArray];
e = [details objectEnumerator];
while ((detail = [e nextObject]) != nil)
[dict setObject: name forKey: [detail timeZoneAbbreviation]];
e = [dict keyEnumerator];
while ((abbrev = [e nextObject]) != nil)
printf("%@\t%@\n", abbrev, name);
}
}
[pool release];
return 0;
}

92
Testing/create-regions.m Normal file
View file

@ -0,0 +1,92 @@
/* create-regions.m - Utility to create a list of time zones and their
associated latitudinal region.
Copyright (C) 1997 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSException.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSUtilities.h>
#define HOURSECS (60*60) /* Seconds in 1 hour. */
#define DAYSECS (HOURSECS*24) /* Seconds in 24 hours. */
#define N (360/15) /* Each latitudinal region is separated by 15 degrees */
int
main (int argc, char *argv[])
{
int i;
id pool, name, zone;
id zones[N];
pool = [NSAutoreleasePool new];
for (i = 0; i < N; i++)
zones[i] = nil;
/* Obtain the regions for each latitudinal region. */
for (i = 1; i < argc; i++)
{
name = [NSString stringWithCString: argv[i]];
zone = [NSTimeZone timeZoneWithName: name];
if (zone != nil)
{
int offset, index;
id details, detail, e;
details = [zone timeZoneDetailArray];
/* Get a standard time. */
e = [details objectEnumerator];
while ((detail = [e nextObject]) != nil)
{
if (![detail isDaylightSavingTimeZone])
break;
}
if (detail == nil)
/* If no standard time. */
detail = [details objectAtIndex: 0];
offset = [detail timeZoneSecondsFromGMT];
/* Get index from normalized offset */
index = ((offset+DAYSECS)%DAYSECS)/HOURSECS;
if (zones[index] == nil)
zones[index] = [NSMutableArray array];
[zones[index] addObject: [zone timeZoneName]];
}
}
/* Write regions to file. */
for (i = 0; i < N; i++)
{
id e, name;
if (zones[i] != nil)
{
e = [zones[i] objectEnumerator];
while ((name = [e nextObject]) != nil)
printf("%d %@\n", i, name);
}
}
[pool release];
return 0;
}

18
Testing/nstimezone.m Normal file
View file

@ -0,0 +1,18 @@
/* Test time zone code. */
#include <stdio.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSDictionary.h>
int
main ()
{
id detail;
printf("time zones for PST:\n%@\n",
[[[NSTimeZone abbreviationMap] objectForKey: @"PST"] description]);
printf("time zones:\n%@\n", [[NSTimeZone timeZoneArray] description]);
printf("local time zone:\n%@\n", [[NSTimeZone localTimeZone] description]);
return 0;
}