path for cocoa compatibility of date formatting.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@28287 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2009-05-16 19:35:20 +00:00
parent e672584425
commit 59851c2ad3
2 changed files with 118 additions and 79 deletions

View file

@ -1,3 +1,9 @@
2009-05-16 Doug Simons <doug@riverrock.org>
* Source/NSCalendarDate.m:
Implement field widths for numeric fields in a date format for
MacOS-X compatibility.
2009-05-16 Richard Frith-Macdonald <rfm@gnu.org> 2009-05-16 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSURL.m: Add support for file URLs on mswindows. The path * Source/NSURL.m: Add support for file URLs on mswindows. The path

View file

@ -1785,6 +1785,21 @@ static void Grow(DescriptionInfo *info, unsigned size)
} }
} }
#define MAX_FLD_WIDTH 99
static void outputValueWithFormat(int v, char *fldfmt, DescriptionInfo *info)
{
char cbuf[MAX_FLD_WIDTH + 1];
int idx = 0;
sprintf((char*)cbuf, fldfmt, v);
Grow(info, strlen((char*)cbuf));
while (cbuf[idx] != '\0')
{
info->t[info->offset++] = cbuf[idx++];
}
}
- (void) _format: (NSString*)fmt - (void) _format: (NSString*)fmt
locale: (NSDictionary*)locale locale: (NSDictionary*)locale
info: (DescriptionInfo*)info info: (DescriptionInfo*)info
@ -1816,11 +1831,27 @@ static void Grow(DescriptionInfo *info, unsigned size)
BOOL mname = NO; BOOL mname = NO;
BOOL dname = NO; BOOL dname = NO;
BOOL twelve = NO; BOOL twelve = NO;
char fldfmt[8];
int fmtlen = 0;
int width = 0;
// Only care about a format specifier // Only care about a format specifier
if (f[i] == '%') if (f[i] == '%')
{ {
i++; i++;
fldfmt[fmtlen++] = '%'; // start format with %
while (fmtlen < 5 && f[i] >= '0' && f[i] <= '9') // field width specified
{
fldfmt[fmtlen++] = f[i];
width = 10 * width + f[i] - '0';
i++;
}
if (fmtlen >= 5 || width > MAX_FLD_WIDTH)
{
// ignore formats that specify field width greater than the max allowed
i -= fmtlen; // set i back so all ignored characters will be copied
}
// check the character that comes after // check the character that comes after
switch (f[i++]) switch (f[i++])
{ {
@ -1877,41 +1908,25 @@ static void Grow(DescriptionInfo *info, unsigned size)
v = info->yd; v = info->yd;
if (ycent) if (ycent)
{ {
if (v >= 0 && v <= 9999) if (fmtlen == 1) // no format width specified; supply default
{ {
Grow(info, 4); fldfmt[fmtlen++] = '0';
info->t[info->offset+3] = (v%10) + '0'; fldfmt[fmtlen++] = '4';
v /= 10;
info->t[info->offset+2] = (v%10) + '0';
v /= 10;
info->t[info->offset+1] = (v%10) + '0';
v /= 10;
info->t[info->offset+0] = (v%10) + '0';
info->offset += 4;
}
else
{
unsigned char tmp[16];
int idx = 0;
sprintf((char*)tmp, "%d", v);
Grow(info, strlen((char*)tmp));
while (tmp[idx] != '\0')
{
info->t[info->offset++] = tmp[idx++];
}
} }
} }
else else
{ {
Grow(info, 2);
if (v < 0) v = -v; if (v < 0) v = -v;
v = v % 100; v = v % 100;
info->t[info->offset+1] = (v%10) + '0'; if (fmtlen == 1) // no format width specified; supply default
v /= 10; {
info->t[info->offset+0] = (v%10) + '0'; fldfmt[fmtlen++] = '0';
info->offset += 2; fldfmt[fmtlen++] = '2';
}
} }
fldfmt[fmtlen++] = 'd';
fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
break; break;
// is it the month // is it the month
@ -1946,39 +1961,41 @@ static void Grow(DescriptionInfo *info, unsigned size)
if (mtag == NO) if (mtag == NO)
{ {
v = info->md; v = info->md;
Grow(info, 2);
v = v % 100; v = v % 100;
info->t[info->offset+1] = (v%10) + '0'; if (fmtlen == 1) // no format width specified; supply default
v /= 10; {
info->t[info->offset+0] = (v%10) + '0'; fldfmt[fmtlen++] = '0';
info->offset += 2; fldfmt[fmtlen++] = '2';
}
fldfmt[fmtlen++] = 'd';
fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
} }
break; break;
case 'd': // day of month with leading zero case 'd': // day of month with leading zero
v = info->dom; v = info->dom;
Grow(info, 2);
v = v % 100; v = v % 100;
info->t[info->offset+1] = (v%10) + '0'; if (fmtlen == 1) // no format width specified; supply default
v /= 10; {
info->t[info->offset+0] = (v%10) + '0'; fldfmt[fmtlen++] = '0';
info->offset += 2; fldfmt[fmtlen++] = '2';
}
fldfmt[fmtlen++] = 'd';
fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
break; break;
case 'e': // day of month with leading space case 'e': // day of month with leading space
v = info->dom; v = info->dom;
Grow(info, 2);
v = v % 100; v = v % 100;
if (v < 10) if (fmtlen == 1) // no format width specified; supply default
{ {
info->t[info->offset] = ' '; fldfmt[fmtlen++] = '1'; // no leading space, just like Cocoa
} }
else fldfmt[fmtlen++] = 'd';
{ fldfmt[fmtlen++] = 0;
info->t[info->offset] = (v/10) + '0'; outputValueWithFormat(v, fldfmt, info);
}
info->t[info->offset+1] = (v%10) + '0';
info->offset += 2;
break; break;
case 'F': // milliseconds case 'F': // milliseconds
@ -1992,24 +2009,26 @@ static void Grow(DescriptionInfo *info, unsigned size)
s *= 1000.0; s *= 1000.0;
v = (NSInteger)(s + 0.5); v = (NSInteger)(s + 0.5);
} }
Grow(info, 3); if (fmtlen == 1) // no format width specified; supply default
info->t[info->offset+2] = (v%10) + '0'; {
v /= 10; fldfmt[fmtlen++] = '0';
info->t[info->offset+1] = (v%10) + '0'; fldfmt[fmtlen++] = '3';
v /= 10; }
info->t[info->offset+0] = (v%10) + '0'; fldfmt[fmtlen++] = 'd';
info->offset += 3; fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
break; break;
case 'j': // day of year case 'j': // day of year
v = [self dayOfYear]; v = [self dayOfYear];
Grow(info, 3); if (fmtlen == 1) // no format width specified; supply default
info->t[info->offset+2] = (v%10) + '0'; {
v /= 10; fldfmt[fmtlen++] = '0';
info->t[info->offset+1] = (v%10) + '0'; fldfmt[fmtlen++] = '3';
v /= 10; }
info->t[info->offset+0] = (v%10) + '0'; fldfmt[fmtlen++] = 'd';
info->offset += 3; fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
break; break;
// is it the week-day // is it the week-day
@ -2045,8 +2064,13 @@ static void Grow(DescriptionInfo *info, unsigned size)
} }
if (dtag == NO) if (dtag == NO)
{ {
info->t[info->offset+0] = (v%10) + '0'; if (fmtlen == 1) // no format width specified; supply default
info->offset += 1; {
fldfmt[fmtlen++] = '1';
}
fldfmt[fmtlen++] = 'd';
fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
} }
} }
break; break;
@ -2067,31 +2091,40 @@ static void Grow(DescriptionInfo *info, unsigned size)
v = v % 12; v = v % 12;
} }
} }
Grow(info, 2); if (fmtlen == 1) // no format width specified; supply default
info->t[info->offset+1] = (v%10) + '0'; {
v /= 10; fldfmt[fmtlen++] = '0';
info->t[info->offset+0] = (v%10) + '0'; fldfmt[fmtlen++] = '2';
info->offset += 2; }
fldfmt[fmtlen++] = 'd';
fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
break; break;
// is it the minute // is it the minute
case 'M': case 'M':
v = info->mnd; v = info->mnd;
Grow(info, 2); if (fmtlen == 1) // no format width specified; supply default
info->t[info->offset+1] = (v%10) + '0'; {
v /= 10; fldfmt[fmtlen++] = '0';
info->t[info->offset+0] = (v%10) + '0'; fldfmt[fmtlen++] = '2';
info->offset += 2; }
fldfmt[fmtlen++] = 'd';
fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
break; break;
// is it the second // is it the second
case 'S': case 'S':
v = info->sd; v = info->sd;
Grow(info, 2); if (fmtlen == 1) // no format width specified; supply default
info->t[info->offset+1] = (v%10) + '0'; {
v /= 10; fldfmt[fmtlen++] = '0';
info->t[info->offset+0] = (v%10) + '0'; fldfmt[fmtlen++] = '2';
info->offset += 2; }
fldfmt[fmtlen++] = 'd';
fldfmt[fmtlen++] = 0;
outputValueWithFormat(v, fldfmt, info);
break; break;
// Is it the am/pm indicator // Is it the am/pm indicator