* configure.ac: Check for tzfile.h

* Source/NSTimeZone.m: Include system tzfile.h if found.
(abbreviationMap): Add abbreviation from systemTimeZone if not
already there.
(systemTimeZone): Update the search list to look for time zone in TZ,
then system location, then tznam.
(getTimeZoneFile:): Look for file in system directory first.
* Source/nstzfile.h: Renamed from tzfile.h


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@20217 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fedor 2004-10-11 03:08:54 +00:00
parent 45122821e9
commit 3718cbfdcd
7 changed files with 403 additions and 193 deletions

View file

@ -1,3 +1,14 @@
2004-10-10 Adam Fedor <fedor@gnu.org>
* configure.ac: Check for tzfile.h
* Source/NSTimeZone.m: Include system tzfile.h if found.
(abbreviationMap): Add abbreviation from systemTimeZone if not
already there.
(systemTimeZone): Update the search list to look for time zone in TZ,
then system location, then tznam.
(getTimeZoneFile:): Look for file in system directory first.
* Source/nstzfile.h: Renamed from tzfile.h
2004-10-09 Fred Kiefer <FredKiefer@gmx.de> 2004-10-09 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSPropertyList.m: * Source/NSPropertyList.m:

View file

@ -303,6 +303,9 @@
/* Define to 1 if you have the <time.h> header file. */ /* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H #undef HAVE_TIME_H
/* Define to 1 if you have the <tzfile.h> header file. */
#undef HAVE_TZFILE_H
/* Define to 1 if you have the `tzset' function. */ /* Define to 1 if you have the `tzset' function. */
#undef HAVE_TZSET #undef HAVE_TZSET
@ -403,9 +406,11 @@
first (like Motorola and SPARC, unlike Intel and VAX). */ first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN #undef WORDS_BIGENDIAN
/* Define as `__inline' if that's what the C compiler calls it, or to nothing /* Define to `__inline__' or `__inline' if that's what the C compiler
if it is not supported. */ calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline #undef inline
#endif
/* Define to `unsigned' if <sys/types.h> does not define. */ /* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t #undef size_t

View file

@ -27,10 +27,12 @@
$Date$ $Revision$ $Date$ $Revision$
*/ */
/* We use a implementation independent of the system, since POSIX /* Use the system time zones if available. In other cases, use an
functions for time zones are woefully inadequate for implementing implementation independent of the system, since POSIX functions for
NSTimeZone, and time zone names can be different from system to time zones are woefully inadequate for implementing NSTimeZone.
system. Time zone names can be different from system to system, but usually
the user has already set up his timezone independant of GNUstep, so we
should respect that information.
We do not use a dictionary for storing time zones, since such a We do not use a dictionary for storing time zones, since such a
dictionary would be VERY large (~500K). And we would have to use a dictionary would be VERY large (~500K). And we would have to use a
@ -44,9 +46,10 @@
2) the GNUSTEP_TZ environment variable 2) the GNUSTEP_TZ environment variable
3) the file LOCAL_TIME_FILE in _time_zone_path() 3) the file LOCAL_TIME_FILE in _time_zone_path()
4) the TZ environment variable 4) the TZ environment variable
5) tzset() & tznam[] for platforms which have it 5) TZDEFAULT defined in tzfile.h on platforms which have it
6) Windows registry, for Win32 systems 6) tzset() & tznam[] for platforms which have it
7) or the fallback time zone (which is UTC) 7) Windows registry, for Win32 systems
8) or the fallback time zone (which is UTC)
with the ones listed first having precedence. with the ones listed first having precedence.
Any time zone must be a file name in ZONES_DIR. Any time zone must be a file name in ZONES_DIR.
@ -66,16 +69,6 @@
(file) localtime {text; time zone eg Australia/Perth} (file) localtime {text; time zone eg Australia/Perth}
(dir) zones (dir) zones
Since NSTimeZone gets the name from LOCAL_TIME_FILE it's sufficient
to symlink this to the time zone name used elsewhere. For example:
Debian uses "/etc/timezone"
A number of POSIX systems have the zone files already installed.
For these systems it is sufficient to symlink ZONES_DIR to the
platform specific location.
For (g)libc6 this is /usr/share/zoneinfo
For Solaris this is /usr/share/lib/zoneinfo
Note that full zone info is required, especially the various "GMT" Note that full zone info is required, especially the various "GMT"
files which are created especially for OPENSTEP compatibility. files which are created especially for OPENSTEP compatibility.
Zone info comes from the Olson time database. Zone info comes from the Olson time database.
@ -115,10 +108,12 @@
#include "GNUstepBase/GSCategories.h" #include "GNUstepBase/GSCategories.h"
#include "GSConfig.h" #include "GSConfig.h"
#ifdef HAVE_TZFILE_H
#include <tzfile.h>
#else
#define NOID #define NOID
#include "tzfile.h" #include "nstzfile.h"
#endif
/* Key for local time zone in user defaults. */ /* Key for local time zone in user defaults. */
#define LOCALDBKEY @"Local Time Zone" #define LOCALDBKEY @"Local Time Zone"
@ -145,6 +140,11 @@
/* Directory that contains the actual time zones. */ /* Directory that contains the actual time zones. */
#define ZONES_DIR @"zones/" #define ZONES_DIR @"zones/"
/* Many systems have this file */
#define SYSTEM_TIME_FILE @"/etc/localtime"
/* Possible location of system time zone files */
static NSString *tzdir = nil;
@class GSAbsTimeZone; @class GSAbsTimeZone;
@class GSTimeZoneDetail; @class GSTimeZoneDetail;
@ -899,15 +899,15 @@ static NSMapTable *absolutes = 0;
/** /**
* <p> * <p>
* The local time zone can be specified by:<br/ > * The local time zone is obtained from, in order of preference:<br/ >
* 1) the user defaults database: NSGlobalDomain "Local Time Zone"<br/ > * 1) the user defaults database: NSGlobalDomain "Local Time Zone"<br/ >
* 2) the GNUSTEP_TZ environment variable<br/ > * 2) the GNUSTEP_TZ environment variable<br/ >
* 3) the file "localtime" in System/Library/Libraries/Resources/NSTimeZone<br/ > * 3) the file "localtime" in System/Library/Libraries/Resources/NSTimeZone<br/ >
* 4) the TZ environment variable<br/ > * 4) the TZ environment variable<br/ >
* 5) tzset and tznam on platforms which have it<br/ > * 5) The system zone settings (typically in /etc/localtime)<br/ >
* 6) Windows registry, on Win32 systems<br/ > * 6) tzset and tznam on platforms which have it<br/ >
* 7) or the fallback time zone (which is UTC)<br/ > * 7) Windows registry, on Win32 systems<br/ >
* with the ones listed first having precedence. * 8) or the fallback time zone (which is UTC)<br/ >
* </p> * </p>
* <p>If the GNUstep time zone datafiles become too out of date, one * <p>If the GNUstep time zone datafiles become too out of date, one
* can download an updated database from <uref * can download an updated database from <uref
@ -925,15 +925,10 @@ static NSMapTable *absolutes = 0;
* abbreviation and offsets from UTC are the same. * abbreviation and offsets from UTC are the same.
* </p> * </p>
* <p>The problems with depending on the OS for providing time zone * <p>The problems with depending on the OS for providing time zone
* info are that some methods for the NSTimeZone classes might be * info are that time zone names may vary
* difficult to implement, and also that time zone names may vary
* wildly between OSes (this could be a big problem when * wildly between OSes (this could be a big problem when
* archiving is used between different systems). * archiving is used between different systems).
* </p> * </p>
* <p>On platforms where the zone info files are already installed
* elsewhere it is sufficient to use a symlink provided the GMT+/-
* zones are added.
* </p>
* <p>Win32: Time zone names read from the registry are different * <p>Win32: Time zone names read from the registry are different
* from other GNUstep installations. Be careful when moving data * from other GNUstep installations. Be careful when moving data
* between platforms in this case. * between platforms in this case.
@ -987,13 +982,27 @@ static NSMapTable *absolutes = 0;
a = [abbreviationDictionary objectForKey: the_abbrev]; a = [abbreviationDictionary objectForKey: the_abbrev];
if (a == nil) if (a == nil)
{ {
a = [[NSMutableArray alloc] init]; a = AUTORELEASE([NSMutableArray new]);
[abbreviationDictionary setObject: a forKey: the_abbrev]; [abbreviationDictionary setObject: a forKey: the_abbrev];
} }
[a addObject: the_name]; [a addObject: the_name];
} }
fclose(file); fclose(file);
/* Special case: Add the system time zone if it doesn't exist in the map */
{
id array;
id the_abbrev = [systemTimeZone abbreviation];
array = [abbreviationDictionary objectForKey: the_abbrev];
if (array == nil)
{
array = AUTORELEASE([NSMutableArray new]);
[abbreviationDictionary setObject: array forKey: the_abbrev];
}
if ([array containsObject: [systemTimeZone timeZoneName]] == NO)
[array addObject: [systemTimeZone timeZoneName]];
}
return abbreviationDictionary; return abbreviationDictionary;
} }
@ -1204,6 +1213,55 @@ static NSMapTable *absolutes = 0;
localZoneString = [localZoneString stringByTrimmingSpaces]; localZoneString = [localZoneString stringByTrimmingSpaces];
} }
} }
/*
* Try to get timezone from standard unix environment variable.
*/
if (localZoneString == nil)
{
localZoneString = [[[NSProcessInfo processInfo]
environment] objectForKey: @"TZ"];
}
if (localZoneString == nil)
{
/* Get the zone name from the localtime file, assuming the file
is a symlink to the time zone. Getting the actual data (which
is easier) doesn't help, since we won't know the name itself. */
#if defined(HAVE_TZFILE_H) && defined(TZDEFAULT)
tzdir = RETAIN([NSString stringWithCString: TZDIR]);
localZoneString = [NSString stringWithCString: TZDEFAULT];
localZoneString = [localZoneString stringByResolvingSymlinksInPath];
#else
NSFileManager *dflt = [NSFileManager defaultManager];
if ([dflt fileExistsAtPath: SYSTEM_TIME_FILE])
{
localZoneString = SYSTEM_TIME_FILE;
localZoneString = [localZoneString stringByResolvingSymlinksInPath];
/* Guess what tzdir is */
tzdir = [localZoneString stringByDeletingLastPathComponent];
while ([tzdir length] > 2
&& [dflt fileExistsAtPath: [tzdir stringByAppendingPathComponent: @"GMT"]] == NO)
tzdir = [tzdir stringByDeletingLastPathComponent];
if ([tzdir length] > 2)
RETAIN(tzdir);
else
{
localZoneString = tzdir = nil;
}
}
#endif
if ( localZoneString != nil && [localZoneString hasPrefix: tzdir] )
{
/* This must be the time zone name */
localZoneString = [[localZoneString mutableCopy] autorelease];
[(NSMutableString *)localZoneString deletePrefix: tzdir];
if ( [localZoneString hasPrefix: @"/"] )
{
[(NSMutableString *)localZoneString deletePrefix: @"/"];
}
}
else
localZoneString = nil;
}
#if HAVE_TZSET #if HAVE_TZSET
/* /*
* Try to get timezone from tzset and tzname * Try to get timezone from tzset and tzname
@ -1214,15 +1272,6 @@ static NSMapTable *absolutes = 0;
if (tzname[0] != NULL && *tzname[0] != '\0') if (tzname[0] != NULL && *tzname[0] != '\0')
localZoneString = [NSString stringWithCString: tzname[0]]; localZoneString = [NSString stringWithCString: tzname[0]];
} }
#else
/*
* Try to get timezone from standard unix environment variable.
*/
if (localZoneString == nil)
{
localZoneString = [[[NSProcessInfo processInfo]
environment] objectForKey: @"TZ"];
}
#endif #endif
#ifdef WIN32 #ifdef WIN32
@ -1254,6 +1303,7 @@ static NSMapTable *absolutes = 0;
if (localZoneString != nil) if (localZoneString != nil)
{ {
NSDebugLLog (@"NSTimeZone", @"Using zone %@", localZoneString);
zone = [defaultPlaceholderTimeZone initWithName: localZoneString]; zone = [defaultPlaceholderTimeZone initWithName: localZoneString];
} }
else else
@ -1652,9 +1702,15 @@ static NSMapTable *absolutes = 0;
*/ */
+ (NSString*) getTimeZoneFile: (NSString *)name + (NSString*) getTimeZoneFile: (NSString *)name
{ {
NSString *dir; NSString *dir = nil;
dir= _time_zone_path (ZONES_DIR); /* Use the system zone info if possible, otherwise, use our installed
info. */
if (tzdir && [[NSFileManager defaultManager] fileExistsAtPath:
[tzdir stringByAppendingPathComponent: name]] == NO)
dir = nil;
if (dir == nil)
dir= _time_zone_path (ZONES_DIR);
return [dir stringByAppendingPathComponent: name]; return [dir stringByAppendingPathComponent: name];
} }
@ -2167,11 +2223,13 @@ newDetailInZoneForType(GSTimeZone *zone, TypeInfo *type)
} }
header = (struct tzhead *)(bytes + pos); header = (struct tzhead *)(bytes + pos);
pos += sizeof(struct tzhead); pos += sizeof(struct tzhead);
#ifdef TZ_MAGIC
if (memcmp(header->tzh_magic, TZ_MAGIC, strlen(TZ_MAGIC)) != 0) if (memcmp(header->tzh_magic, TZ_MAGIC, strlen(TZ_MAGIC)) != 0)
{ {
[NSException raise: fileException [NSException raise: fileException
format: @"TZ_MAGIC is incorrect"]; format: @"TZ_MAGIC is incorrect"];
} }
#endif
n_trans = GSSwapBigI32ToHost(*(gss32*)header->tzh_timecnt); n_trans = GSSwapBigI32ToHost(*(gss32*)header->tzh_timecnt);
n_types = GSSwapBigI32ToHost(*(gss32*)header->tzh_typecnt); n_types = GSSwapBigI32ToHost(*(gss32*)header->tzh_typecnt);
charcnt = GSSwapBigI32ToHost(*(gss32*)header->tzh_charcnt); charcnt = GSSwapBigI32ToHost(*(gss32*)header->tzh_charcnt);

View file

@ -10,15 +10,20 @@
int int
main () main ()
{ {
id detail; NSTimeZone *system;
CREATE_AUTORELEASE_POOL(pool); CREATE_AUTORELEASE_POOL(pool);
printf("time zones for PST:\n%s\n", GSPrintf(stdout, @"System time zone\n");
[[[[NSTimeZone abbreviationMap] objectForKey: @"PST"] description] UTF8String]); system = [NSTimeZone systemTimeZone];
printf("time zones:\n%s\n", GSPrintf(stdout, @" %@\n\n", [system description]);
[[[NSTimeZone timeZoneArray] description] UTF8String]);
printf("local time zone:\n%s\n", GSPrintf(stdout, @"Local time zone:\n %@\n\n",
[[[NSTimeZone localTimeZone] description] UTF8String]); [[NSTimeZone localTimeZone] description]);
GSPrintf(stdout, @"Time zones for PST:\n %@\n",
[[[NSTimeZone abbreviationMap] objectForKey: @"PST"] description]);
RELEASE(pool); RELEASE(pool);
return 0; return 0;
} }

411
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -544,7 +544,7 @@ LIBS="$saved_LIBS"
#-------------------------------------------------------------------- #--------------------------------------------------------------------
dnl AC_REPLACE_FUNCS(getrusage gettimeofday) dnl AC_REPLACE_FUNCS(getrusage gettimeofday)
AC_CHECK_HEADERS(time.h sys/time.h sys/rusage.h ucbinclude/sys/resource.h) AC_CHECK_HEADERS(time.h sys/time.h tzfile.h sys/rusage.h ucbinclude/sys/resource.h)
AC_CHECK_FUNCS(time ctime tzset) AC_CHECK_FUNCS(time ctime tzset)
#-------------------------------------------------------------------- #--------------------------------------------------------------------