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:
richard 2000-11-30 12:19:50 +00:00
parent 40d5e74296
commit 575f20ac18
3 changed files with 253 additions and 49 deletions

View file

@ -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.

View file

@ -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 = @"";
} }
ASSIGN(_calendar_format, fmt);
format = [fmt cString]; TForm = [locale objectForKey: NSTimeDateFormatString];
formatLen = strlen(format); 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);
// //
// 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)
{ {
@ -699,6 +836,24 @@ static inline int getDigits(const char *from, char *to, int limit)
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

View file

@ -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 ([self respondsToSelector: sel] == YES) if (sel == 0)
{ {
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) else
{ {
return v;
}
}
sel = NSSelectorFromString([NSString stringWithFormat: @"get%@",
[aKey capitalizedString]]);
if ([self respondsToSelector: sel] == YES)
{
return [self performSelector: sel];
}
sel = NSSelectorFromString(aKey);
if ([self respondsToSelector: sel] == YES)
{
return [self performSelector: sel];
}
[self handleTakeValue: nil forUnboundKey: aKey]; [self handleTakeValue: nil forUnboundKey: aKey];
return nil; return nil;
}
} }
- (void) takeStoredValue: (id)anObject forKey: (NSString*)aKey - (void) takeStoredValue: (id)anObject forKey: (NSString*)aKey