mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-20 12:16:40 +00:00
Various fixes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8231 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
40d5e74296
commit
575f20ac18
3 changed files with 253 additions and 49 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2000-11-30 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/NSCalendarDate.m: ([-initWithString:calendarFormat:locale:])
|
||||||
|
Bugfixes to fill in missing information using current date/time and
|
||||||
|
to implement missing format codes.
|
||||||
|
|
||||||
2000-11-27 Richard Frith-Macdonald <rfm@gnu.org>
|
2000-11-27 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSClassDescription.m: New MacOS-X class added.
|
* Source/NSClassDescription.m: New MacOS-X class added.
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <Foundation/NSObjCRuntime.h>
|
#include <Foundation/NSObjCRuntime.h>
|
||||||
|
#include <Foundation/NSData.h>
|
||||||
#include <Foundation/NSDate.h>
|
#include <Foundation/NSDate.h>
|
||||||
#include <Foundation/NSArray.h>
|
#include <Foundation/NSArray.h>
|
||||||
#include <Foundation/NSString.h>
|
#include <Foundation/NSString.h>
|
||||||
|
@ -262,6 +263,14 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define hadY 1
|
||||||
|
#define hadM 2
|
||||||
|
#define hadD 4
|
||||||
|
#define hadh 8
|
||||||
|
#define hadm 16
|
||||||
|
#define hads 32
|
||||||
|
#define hadw 64
|
||||||
|
|
||||||
- (id) initWithString: (NSString *)description
|
- (id) initWithString: (NSString *)description
|
||||||
calendarFormat: (NSString *)fmt
|
calendarFormat: (NSString *)fmt
|
||||||
locale: (NSDictionary *)locale
|
locale: (NSDictionary *)locale
|
||||||
|
@ -283,13 +292,20 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
BOOL twelveHrClock = NO;
|
BOOL twelveHrClock = NO;
|
||||||
int julianWeeks = -1, weekStartsMonday = 0, dayOfWeek = -1;
|
int julianWeeks = -1, weekStartsMonday = 0, dayOfWeek = -1;
|
||||||
const char *source = [description cString];
|
const char *source = [description cString];
|
||||||
int sourceLen = strlen(source);
|
unsigned sourceLen = strlen(source);
|
||||||
const char *format;
|
unichar *format;
|
||||||
int formatLen;
|
unsigned formatLen;
|
||||||
int formatIdx = 0;
|
unsigned formatIdx = 0;
|
||||||
int sourceIdx = 0;
|
unsigned sourceIdx = 0;
|
||||||
char tmpStr[20];
|
char tmpStr[20];
|
||||||
int tmpIdx;
|
int tmpIdx;
|
||||||
|
unsigned had = 0;
|
||||||
|
int pos;
|
||||||
|
BOOL hadPercent = NO;
|
||||||
|
NSString *dForm;
|
||||||
|
NSString *tForm;
|
||||||
|
NSString *TForm;
|
||||||
|
NSMutableData *fd;
|
||||||
|
|
||||||
if (locale == nil)
|
if (locale == nil)
|
||||||
{
|
{
|
||||||
|
@ -302,14 +318,118 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
if (fmt == nil)
|
if (fmt == nil)
|
||||||
fmt = @"";
|
fmt = @"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TForm = [locale objectForKey: NSTimeDateFormatString];
|
||||||
|
if (TForm == nil)
|
||||||
|
TForm = @"%X %x";
|
||||||
|
dForm = [locale objectForKey: NSShortDateFormatString];
|
||||||
|
if (dForm == nil)
|
||||||
|
dForm = @"%y-%m-%d";
|
||||||
|
tForm = [locale objectForKey: NSTimeFormatString];
|
||||||
|
if (tForm == nil)
|
||||||
|
tForm = @"%H-%M-%S";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get format into a buffer, leaving room for expansion in case it has
|
||||||
|
* escapes that need to be converted.
|
||||||
|
*/
|
||||||
|
formatLen = [fmt length];
|
||||||
|
fd = [[NSMutableData alloc]
|
||||||
|
initWithLength: (formatLen + 32) * sizeof(unichar)];
|
||||||
|
format = (unichar*)[fd mutableBytes];
|
||||||
|
[fmt getCharacters: format];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand any sequences to their basic components.
|
||||||
|
*/
|
||||||
|
for (pos = 0; pos < formatLen; pos++)
|
||||||
|
{
|
||||||
|
unichar c = format[pos];
|
||||||
|
|
||||||
|
if (c == '%')
|
||||||
|
{
|
||||||
|
if (hadPercent == YES)
|
||||||
|
{
|
||||||
|
hadPercent = NO;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hadPercent = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (hadPercent == YES)
|
||||||
|
{
|
||||||
|
NSString *sub = nil;
|
||||||
|
|
||||||
|
if (c == 'c')
|
||||||
|
{
|
||||||
|
sub = TForm;
|
||||||
|
}
|
||||||
|
else if (c == 'R')
|
||||||
|
{
|
||||||
|
sub = @"%H:%M";
|
||||||
|
}
|
||||||
|
else if (c == 'r')
|
||||||
|
{
|
||||||
|
sub = @"%I:%M:%S %p";
|
||||||
|
}
|
||||||
|
else if (c == 'X')
|
||||||
|
{
|
||||||
|
sub = tForm;
|
||||||
|
}
|
||||||
|
else if (c == 'x')
|
||||||
|
{
|
||||||
|
sub = dForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub != nil)
|
||||||
|
{
|
||||||
|
unsigned sLen = [sub length];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (sLen > 2)
|
||||||
|
{
|
||||||
|
[fd setLength:
|
||||||
|
(formatLen + sLen - 2) * sizeof(unichar)];
|
||||||
|
format = (unichar*)[fd mutableBytes];
|
||||||
|
for (i = formatLen-1; i > pos; i--)
|
||||||
|
{
|
||||||
|
format[i+sLen-2] = format[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = pos+1; i < formatLen; i++)
|
||||||
|
{
|
||||||
|
format[i+sLen-2] = format[i];
|
||||||
|
}
|
||||||
|
[fd setLength:
|
||||||
|
(formatLen + sLen - 2) * sizeof(unichar)];
|
||||||
|
format = (unichar*)[fd mutableBytes];
|
||||||
|
}
|
||||||
|
[sub getCharacters: &format[pos-1]];
|
||||||
|
formatLen += sLen - 2;
|
||||||
|
pos -= 2; // Re-parse the newly substituted data.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hadPercent = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up calendar format.
|
||||||
|
*/
|
||||||
|
if (formatLen > [fmt length])
|
||||||
|
{
|
||||||
|
fmt = [NSString stringWithCharacters: format length: formatLen];
|
||||||
|
}
|
||||||
ASSIGN(_calendar_format, fmt);
|
ASSIGN(_calendar_format, fmt);
|
||||||
|
|
||||||
format = [fmt cString];
|
|
||||||
formatLen = strlen(format);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// WARNING:
|
// WARNING:
|
||||||
// -%c, %F, %x, %X do NOT work. (NSTimeDateFormatString isn't defined
|
// %F, does NOT work.
|
||||||
// and the underlying call has granularity to the second.
|
// and the underlying call has granularity to the second.
|
||||||
// -Most locale stuff is dubious at best.
|
// -Most locale stuff is dubious at best.
|
||||||
// -Long day and month names depend on a non-alpha character after the
|
// -Long day and month names depend on a non-alpha character after the
|
||||||
|
@ -416,6 +536,7 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dayOfWeek = tmpIdx;
|
dayOfWeek = tmpIdx;
|
||||||
|
had |= hadw;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -448,6 +569,7 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dayOfWeek = tmpIdx;
|
dayOfWeek = tmpIdx;
|
||||||
|
had |= hadw;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -479,6 +601,7 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
month = tmpIdx+1;
|
month = tmpIdx+1;
|
||||||
|
had |= hadM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -512,41 +635,45 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
month = tmpIdx+1;
|
month = tmpIdx+1;
|
||||||
|
had |= hadM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case 'c':
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case 'd': // fall through
|
case 'd': // fall through
|
||||||
case 'e':
|
case 'e':
|
||||||
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
||||||
day = atoi(tmpStr);
|
day = atoi(tmpStr);
|
||||||
|
had |= hadD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case 'F':
|
case 'F':
|
||||||
// break;
|
NSLog(@"%F format ignored when creating date");
|
||||||
|
break;
|
||||||
|
|
||||||
case 'I': // fall through
|
case 'I': // fall through
|
||||||
twelveHrClock = YES;
|
twelveHrClock = YES;
|
||||||
case 'H':
|
case 'H':
|
||||||
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
||||||
hour = atoi(tmpStr);
|
hour = atoi(tmpStr);
|
||||||
|
had |= hadh;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'j':
|
case 'j':
|
||||||
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 3);
|
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 3);
|
||||||
day = atoi(tmpStr);
|
day = atoi(tmpStr);
|
||||||
|
had |= hadD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
||||||
month = atoi(tmpStr);
|
month = atoi(tmpStr);
|
||||||
|
had |= hadM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
||||||
min = atoi(tmpStr);
|
min = atoi(tmpStr);
|
||||||
|
had |= hadm;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
|
@ -581,11 +708,13 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
case 'S':
|
case 'S':
|
||||||
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
|
||||||
sec = atoi(tmpStr);
|
sec = atoi(tmpStr);
|
||||||
|
had |= hads;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w':
|
case 'w':
|
||||||
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 1);
|
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 1);
|
||||||
dayOfWeek = atoi(tmpStr);
|
dayOfWeek = atoi(tmpStr);
|
||||||
|
had |= hadw;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'W': // Fall through
|
case 'W': // Fall through
|
||||||
|
@ -612,11 +741,13 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
{
|
{
|
||||||
year += 2000;
|
year += 2000;
|
||||||
}
|
}
|
||||||
|
had |= hadY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Y':
|
case 'Y':
|
||||||
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 4);
|
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 4);
|
||||||
year = atoi(tmpStr);
|
year = atoi(tmpStr);
|
||||||
|
had |= hadY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'z':
|
case 'z':
|
||||||
|
@ -677,12 +808,18 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
default:
|
default:
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
format: @"Invalid NSCalendar date, "
|
format: @"Invalid NSCalendar date, "
|
||||||
@"specifier %c not recognized in format %s",
|
@"specifier %c not recognized in format %@",
|
||||||
format[formatIdx], format];
|
format[formatIdx], fmt];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
formatIdx++;
|
formatIdx++;
|
||||||
}
|
}
|
||||||
|
RELEASE(fd);
|
||||||
|
|
||||||
|
if (tz == nil)
|
||||||
|
{
|
||||||
|
tz = [NSTimeZone localTimeZone];
|
||||||
|
}
|
||||||
|
|
||||||
if (twelveHrClock == YES)
|
if (twelveHrClock == YES)
|
||||||
{
|
{
|
||||||
|
@ -694,11 +831,29 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
|
|
||||||
if (julianWeeks != -1)
|
if (julianWeeks != -1)
|
||||||
{
|
{
|
||||||
NSTimeZone *gmtZone;
|
NSTimeZone *gmtZone;
|
||||||
NSCalendarDate *d;
|
NSCalendarDate *d;
|
||||||
int currDay;
|
int currDay;
|
||||||
|
|
||||||
gmtZone = [NSTimeZone timeZoneForSecondsFromGMT: 0];
|
gmtZone = [NSTimeZone timeZoneForSecondsFromGMT: 0];
|
||||||
|
|
||||||
|
if ((had & (hadY|hadw)) != (hadY|hadw))
|
||||||
|
{
|
||||||
|
NSCalendarDate *now = [NSCalendarDate date];
|
||||||
|
|
||||||
|
[now setTimeZone: gmtZone];
|
||||||
|
if ((had | hadY) == 0)
|
||||||
|
{
|
||||||
|
year = [now yearOfCommonEra];
|
||||||
|
had |= hadY;
|
||||||
|
}
|
||||||
|
if ((had | hadw) == 0)
|
||||||
|
{
|
||||||
|
dayOfWeek = [now dayOfWeek];
|
||||||
|
had |= hadw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d = [NSCalendarDate dateWithYear: year
|
d = [NSCalendarDate dateWithYear: year
|
||||||
month: 1
|
month: 1
|
||||||
day: 1
|
day: 1
|
||||||
|
@ -726,6 +881,32 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
day = dayOfWeek + (julianWeeks * 7 - (currDay - 1));
|
day = dayOfWeek + (julianWeeks * 7 - (currDay - 1));
|
||||||
|
had |= hadD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use current date/time information for anything missing.
|
||||||
|
*/
|
||||||
|
if ((had & (hadY|hadM|hadD|hadh|hadm|hads))
|
||||||
|
!= (hadY|hadM|hadD|hadh|hadm|hads))
|
||||||
|
{
|
||||||
|
NSCalendarDate *now = [NSCalendarDate date];
|
||||||
|
int Y, M, D, h, m, s;
|
||||||
|
|
||||||
|
[now setTimeZone: tz];
|
||||||
|
[now getYear: &Y month: &M day: &D hour: &h minute: &m second: &s];
|
||||||
|
if ((had & hadY) == 0)
|
||||||
|
year = Y;
|
||||||
|
if ((had & hadM) == 0)
|
||||||
|
month = M;
|
||||||
|
if ((had & hadD) == 0)
|
||||||
|
day = D;
|
||||||
|
if ((had & hadh) == 0)
|
||||||
|
hour = h;
|
||||||
|
if ((had & hadm) == 0)
|
||||||
|
min = m;
|
||||||
|
if ((had & hads) == 0)
|
||||||
|
sec = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [self initWithYear: year
|
return [self initWithYear: year
|
||||||
|
|
|
@ -1306,54 +1306,71 @@ static BOOL deallocNotifications = NO;
|
||||||
|
|
||||||
- (id) storedValueForKey: (NSString*)aKey
|
- (id) storedValueForKey: (NSString*)aKey
|
||||||
{
|
{
|
||||||
SEL sel;
|
SEL sel = 0;
|
||||||
|
const char *type = 0;
|
||||||
|
NSString *name;
|
||||||
|
|
||||||
if ([[self class] useStoredAccessor] == NO)
|
if ([[self class] useStoredAccessor] == NO)
|
||||||
{
|
{
|
||||||
return [self valueForKey: aKey];
|
return [self valueForKey: aKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
sel = NSSelectorFromString([NSString stringWithFormat: @"_get%@",
|
name = [NSString stringWithFormat: @"_get%@", [aKey capitalizedString]];
|
||||||
[aKey capitalizedString]]);
|
sel = NSSelectorFromString(name);
|
||||||
if ([self respondsToSelector: sel] == YES)
|
if ([self respondsToSelector: sel] == NO)
|
||||||
{
|
{
|
||||||
return [self performSelector: sel];
|
name = [NSString stringWithFormat: @"_%@", aKey];
|
||||||
|
sel = NSSelectorFromString(name);
|
||||||
|
if ([self respondsToSelector: sel] == NO)
|
||||||
|
{
|
||||||
|
sel = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sel = NSSelectorFromString([NSString stringWithFormat: @"_%@", aKey]);
|
if (sel == 0)
|
||||||
if ([self respondsToSelector: sel] == YES)
|
|
||||||
{
|
{
|
||||||
return [self performSelector: sel];
|
if ([[self class] accessInstanceVariablesDirectly] == YES)
|
||||||
|
{
|
||||||
|
name = [NSString stringWithFormat: @"_%@", aKey];
|
||||||
|
type = GSInstanceVariableType(self, name);
|
||||||
|
if (type == 0)
|
||||||
|
{
|
||||||
|
name = aKey;
|
||||||
|
type = GSInstanceVariableType(self, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type == 0)
|
||||||
|
{
|
||||||
|
name = [NSString stringWithFormat: @"get%@",
|
||||||
|
[aKey capitalizedString]];
|
||||||
|
sel = NSSelectorFromString(name);
|
||||||
|
if ([self respondsToSelector: sel] == NO)
|
||||||
|
{
|
||||||
|
name = aKey;
|
||||||
|
sel = NSSelectorFromString(name);
|
||||||
|
if ([self respondsToSelector: sel] == NO)
|
||||||
|
{
|
||||||
|
sel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([[self class] accessInstanceVariablesDirectly] == YES)
|
if (sel != 0)
|
||||||
|
{
|
||||||
|
return [self performSelector: sel];
|
||||||
|
}
|
||||||
|
else if (type != 0)
|
||||||
{
|
{
|
||||||
id v;
|
id v;
|
||||||
|
|
||||||
if (GSGetInstanceVariable(self, [NSString stringWithFormat: @"_%@", aKey],
|
GSGetInstanceVariable(self, name, (void*)&v);
|
||||||
(void*)&v) == YES)
|
return v;
|
||||||
{
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
if (GSGetInstanceVariable(self, aKey, (void*)&v) == YES)
|
|
||||||
{
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
sel = NSSelectorFromString([NSString stringWithFormat: @"get%@",
|
|
||||||
[aKey capitalizedString]]);
|
|
||||||
if ([self respondsToSelector: sel] == YES)
|
|
||||||
{
|
{
|
||||||
return [self performSelector: sel];
|
[self handleTakeValue: nil forUnboundKey: aKey];
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
sel = NSSelectorFromString(aKey);
|
|
||||||
if ([self respondsToSelector: sel] == YES)
|
|
||||||
{
|
|
||||||
return [self performSelector: sel];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self handleTakeValue: nil forUnboundKey: aKey];
|
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) takeStoredValue: (id)anObject forKey: (NSString*)aKey
|
- (void) takeStoredValue: (id)anObject forKey: (NSString*)aKey
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue