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 Frith-MacDonald 2000-11-30 12:19:50 +00:00
parent d79abf90ee
commit 7961c760c9
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>
* Source/NSClassDescription.m: New MacOS-X class added.

View file

@ -24,6 +24,7 @@
#include <config.h>
#include <math.h>
#include <Foundation/NSObjCRuntime.h>
#include <Foundation/NSData.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSString.h>
@ -262,6 +263,14 @@ static inline int getDigits(const char *from, char *to, int limit)
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
calendarFormat: (NSString *)fmt
locale: (NSDictionary *)locale
@ -283,13 +292,20 @@ static inline int getDigits(const char *from, char *to, int limit)
BOOL twelveHrClock = NO;
int julianWeeks = -1, weekStartsMonday = 0, dayOfWeek = -1;
const char *source = [description cString];
int sourceLen = strlen(source);
const char *format;
int formatLen;
int formatIdx = 0;
int sourceIdx = 0;
unsigned sourceLen = strlen(source);
unichar *format;
unsigned formatLen;
unsigned formatIdx = 0;
unsigned sourceIdx = 0;
char tmpStr[20];
int tmpIdx;
unsigned had = 0;
int pos;
BOOL hadPercent = NO;
NSString *dForm;
NSString *tForm;
NSString *TForm;
NSMutableData *fd;
if (locale == nil)
{
@ -302,14 +318,118 @@ static inline int getDigits(const char *from, char *to, int limit)
if (fmt == nil)
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);
format = [fmt cString];
formatLen = strlen(format);
//
// 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.
// -Most locale stuff is dubious at best.
// -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;
had |= hadw;
}
break;
@ -448,6 +569,7 @@ static inline int getDigits(const char *from, char *to, int limit)
}
}
dayOfWeek = tmpIdx;
had |= hadw;
}
break;
@ -479,6 +601,7 @@ static inline int getDigits(const char *from, char *to, int limit)
}
}
month = tmpIdx+1;
had |= hadM;
}
break;
@ -512,41 +635,45 @@ static inline int getDigits(const char *from, char *to, int limit)
}
}
month = tmpIdx+1;
had |= hadM;
}
break;
// case 'c':
// break;
case 'd': // fall through
case 'e':
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
day = atoi(tmpStr);
had |= hadD;
break;
// case 'F':
// break;
case 'F':
NSLog(@"%F format ignored when creating date");
break;
case 'I': // fall through
twelveHrClock = YES;
case 'H':
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
hour = atoi(tmpStr);
had |= hadh;
break;
case 'j':
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 3);
day = atoi(tmpStr);
had |= hadD;
break;
case 'm':
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
month = atoi(tmpStr);
had |= hadM;
break;
case 'M':
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
min = atoi(tmpStr);
had |= hadm;
break;
case 'p':
@ -581,11 +708,13 @@ static inline int getDigits(const char *from, char *to, int limit)
case 'S':
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 2);
sec = atoi(tmpStr);
had |= hads;
break;
case 'w':
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 1);
dayOfWeek = atoi(tmpStr);
had |= hadw;
break;
case 'W': // Fall through
@ -612,11 +741,13 @@ static inline int getDigits(const char *from, char *to, int limit)
{
year += 2000;
}
had |= hadY;
break;
case 'Y':
sourceIdx += getDigits(&source[sourceIdx], tmpStr, 4);
year = atoi(tmpStr);
had |= hadY;
break;
case 'z':
@ -677,12 +808,18 @@ static inline int getDigits(const char *from, char *to, int limit)
default:
[NSException raise: NSInvalidArgumentException
format: @"Invalid NSCalendar date, "
@"specifier %c not recognized in format %s",
format[formatIdx], format];
@"specifier %c not recognized in format %@",
format[formatIdx], fmt];
}
}
formatIdx++;
}
RELEASE(fd);
if (tz == nil)
{
tz = [NSTimeZone localTimeZone];
}
if (twelveHrClock == YES)
{
@ -694,11 +831,29 @@ static inline int getDigits(const char *from, char *to, int limit)
if (julianWeeks != -1)
{
NSTimeZone *gmtZone;
NSTimeZone *gmtZone;
NSCalendarDate *d;
int currDay;
int currDay;
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
month: 1
day: 1
@ -726,6 +881,32 @@ static inline int getDigits(const char *from, char *to, int limit)
}
}
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

View file

@ -1306,54 +1306,71 @@ static BOOL deallocNotifications = NO;
- (id) storedValueForKey: (NSString*)aKey
{
SEL sel;
SEL sel = 0;
const char *type = 0;
NSString *name;
if ([[self class] useStoredAccessor] == NO)
{
return [self valueForKey: aKey];
}
sel = NSSelectorFromString([NSString stringWithFormat: @"_get%@",
[aKey capitalizedString]]);
if ([self respondsToSelector: sel] == YES)
name = [NSString stringWithFormat: @"_get%@", [aKey capitalizedString]];
sel = NSSelectorFromString(name);
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;
if (GSGetInstanceVariable(self, [NSString stringWithFormat: @"_%@", aKey],
(void*)&v) == YES)
{
return v;
}
if (GSGetInstanceVariable(self, aKey, (void*)&v) == YES)
{
return v;
}
GSGetInstanceVariable(self, name, (void*)&v);
return v;
}
sel = NSSelectorFromString([NSString stringWithFormat: @"get%@",
[aKey capitalizedString]]);
if ([self respondsToSelector: sel] == YES)
else
{
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