diff -uNr dmd-0.110/dmd/src/dmd/attrib.c dmd-0.111/dmd/src/dmd/attrib.c --- dmd-0.110/dmd/src/dmd/attrib.c 2004-12-04 17:39:06.000000000 +0100 +++ dmd-0.111/dmd/src/dmd/attrib.c 2005-01-12 02:45:20.000000000 +0100 @@ -109,6 +109,7 @@ { Dsymbol *s; s = (Dsymbol *)d->data[i]; + //printf("AttribDeclaration::inlineScan %s\n", s->toChars()); s->inlineScan(); } } diff -uNr dmd-0.110/dmd/src/dmd/dump.c dmd-0.111/dmd/src/dmd/dump.c --- dmd-0.110/dmd/src/dmd/dump.c 2004-09-15 00:20:36.000000000 +0200 +++ dmd-0.111/dmd/src/dmd/dump.c 2005-01-15 03:36:12.000000000 +0100 @@ -68,6 +68,18 @@ e1->dump(i + 2); } +void SliceExp::dump(int i) +{ + indent(i); + printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1); + if (e1) + e1->dump(i + 2); + if (lwr) + lwr->dump(i + 2); + if (upr) + upr->dump(i + 2); +} + void DotIdExp::dump(int i) { indent(i); diff -uNr dmd-0.110/dmd/src/dmd/expression.h dmd-0.111/dmd/src/dmd/expression.h --- dmd-0.110/dmd/src/dmd/expression.h 2004-11-29 01:50:10.000000000 +0100 +++ dmd-0.111/dmd/src/dmd/expression.h 2005-01-16 01:55:38.000000000 +0100 @@ -654,6 +654,7 @@ Expression *toLvalue(Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); void toCBuffer(OutBuffer *buf); + void dump(int indent); elem *toElem(IRState *irs); int inlineCost(InlineCostState *ics); @@ -715,6 +716,7 @@ Expression *semantic(Scope *sc); Expression *toLvalue(Expression *e); void toCBuffer(OutBuffer *buf); + Expression *doInline(InlineDoState *ids); elem *toElem(IRState *irs); }; diff -uNr dmd-0.110/dmd/src/dmd/inline.c dmd-0.111/dmd/src/dmd/inline.c --- dmd-0.110/dmd/src/dmd/inline.c 2004-11-25 02:04:56.000000000 +0100 +++ dmd-0.111/dmd/src/dmd/inline.c 2005-01-16 02:02:14.000000000 +0100 @@ -484,11 +484,75 @@ } +Expression *IndexExp::doInline(InlineDoState *ids) +{ + IndexExp *are = (IndexExp *)copy(); + + are->e1 = e1->doInline(ids); + + if (lengthVar) + { //printf("lengthVar\n"); + VarDeclaration *vd = lengthVar; + ExpInitializer *ie; + ExpInitializer *ieto; + VarDeclaration *vto; + + vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init); + *vto = *vd; + vto->parent = ids->parent; + vto->csym = NULL; + vto->isym = NULL; + + ids->from.push(vd); + ids->to.push(vto); + + if (vd->init) + { + ie = vd->init->isExpInitializer(); + assert(ie); + ieto = new ExpInitializer(ie->loc, ie->exp->doInline(ids)); + vto->init = ieto; + } + + are->lengthVar = (VarDeclaration *) (void *)vto; + } + are->e2 = e2->doInline(ids); + return are; +} + + Expression *SliceExp::doInline(InlineDoState *ids) { SliceExp *are = (SliceExp *)copy(); are->e1 = e1->doInline(ids); + + if (lengthVar) + { //printf("lengthVar\n"); + VarDeclaration *vd = lengthVar; + ExpInitializer *ie; + ExpInitializer *ieto; + VarDeclaration *vto; + + vto = new VarDeclaration(vd->loc, vd->type, vd->ident, vd->init); + *vto = *vd; + vto->parent = ids->parent; + vto->csym = NULL; + vto->isym = NULL; + + ids->from.push(vd); + ids->to.push(vto); + + if (vd->init) + { + ie = vd->init->isExpInitializer(); + assert(ie); + ieto = new ExpInitializer(ie->loc, ie->exp->doInline(ids)); + vto->init = ieto; + } + + are->lengthVar = (VarDeclaration *) (void *)vto; + } if (lwr) are->lwr = lwr->doInline(ids); if (upr) @@ -557,6 +621,13 @@ return this; } +Statement *ScopeStatement::inlineScan(InlineScanState *iss) +{ + if (statement) + statement = statement->inlineScan(iss); + return this; +} + Statement *WhileStatement::inlineScan(InlineScanState *iss) { condition = condition->inlineScan(iss); @@ -607,6 +678,7 @@ Statement *SwitchStatement::inlineScan(InlineScanState *iss) { + //printf("SwitchStatement::inlineScan()\n"); condition = condition->inlineScan(iss); body = body->inlineScan(iss); if (sdefault) @@ -626,6 +698,7 @@ Statement *CaseStatement::inlineScan(InlineScanState *iss) { + //printf("CaseStatement::inlineScan()\n"); exp = exp->inlineScan(iss); if (statement) statement = statement->inlineScan(iss); @@ -845,13 +918,15 @@ InlineCostState ics; int cost; -#if LOG +#define CANINLINE_LOG 0 + +#if CANINLINE_LOG printf("FuncDeclaration::canInline('%s')\n", toChars()); #endif if (inlineNest || !semanticRun) { -#if LOG +#if CANINLINE_LOG printf("\t1: no, inlineNest = %d, semanticRun = %d\n", inlineNest, semanticRun); #endif return 0; @@ -860,13 +935,13 @@ switch (inlineStatus) { case ILSyes: -#if LOG +#if CANINLINE_LOG printf("\tyes\n"); #endif return 1; case ILSno: -#if LOG +#if CANINLINE_LOG printf("\t2: no\n"); #endif return 0; @@ -915,7 +990,7 @@ memset(&ics, 0, sizeof(ics)); ics.fd = this; cost = fbody->inlineCost(&ics); -#if LOG +#if CANINLINE_LOG printf("cost = %d\n", cost); #endif if (cost >= COST_MAX) @@ -925,14 +1000,14 @@ Lyes: inlineStatus = ILSyes; -#if LOG +#if CANINLINE_LOG printf("\tyes\n"); #endif return 1; Lno: inlineStatus = ILSno; -#if LOG +#if CANINLINE_LOG printf("\tno\n"); #endif return 0; @@ -1028,6 +1103,7 @@ inlineNest--; //eb->type->print(); //eb->print(); +//eb->dump(0); return Expression::combine(e, eb); } diff -uNr dmd-0.110/dmd/src/dmd/mars.c dmd-0.111/dmd/src/dmd/mars.c --- dmd-0.110/dmd/src/dmd/mars.c 2004-12-21 01:08:40.000000000 +0100 +++ dmd-0.111/dmd/src/dmd/mars.c 2005-01-15 00:58:12.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2004 by Digital Mars +// Copyright (c) 1999-2005 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -47,9 +47,9 @@ #error "fix this" #endif - copyright = "Copyright (c) 1999-2004 by Digital Mars"; + copyright = "Copyright (c) 1999-2005 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.110"; + version = "v0.111"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff -uNr dmd-0.110/dmd/src/dmd/module.c dmd-0.111/dmd/src/dmd/module.c --- dmd-0.110/dmd/src/dmd/module.c 2004-12-19 11:30:32.000000000 +0100 +++ dmd-0.111/dmd/src/dmd/module.c 2005-01-12 02:45:36.000000000 +0100 @@ -537,6 +537,9 @@ { Dsymbol *s; s = (Dsymbol *)members->data[i]; + //if (global.params.verbose) + //printf("inline scan symbol %s\n", s->toChars()); + s->inlineScan(); } } diff -uNr dmd-0.110/dmd/src/dmd/statement.h dmd-0.111/dmd/src/dmd/statement.h --- dmd-0.110/dmd/src/dmd/statement.h 2003-12-17 21:46:00.000000000 +0100 +++ dmd-0.111/dmd/src/dmd/statement.h 2005-01-12 02:40:24.000000000 +0100 @@ -152,6 +152,8 @@ void toCBuffer(OutBuffer *buf); Statement *semantic(Scope *sc); + Statement *inlineScan(InlineScanState *iss); + void toIR(IRState *irs); }; diff -uNr dmd-0.110/dmd/src/dmd/struct.c dmd-0.111/dmd/src/dmd/struct.c --- dmd-0.110/dmd/src/dmd/struct.c 2004-12-30 00:18:44.000000000 +0100 +++ dmd-0.111/dmd/src/dmd/struct.c 2005-01-12 02:46:42.000000000 +0100 @@ -79,6 +79,7 @@ for (i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; + //printf("inline scan aggregate symbol '%s'\n", s->toChars()); s->inlineScan(); } } diff -uNr dmd-0.110/dmd/src/phobos/internal/aaA.d dmd-0.111/dmd/src/phobos/internal/aaA.d --- dmd-0.110/dmd/src/phobos/internal/aaA.d 2004-12-30 16:22:50.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/internal/aaA.d 2005-01-19 12:14:22.000000000 +0100 @@ -231,6 +231,7 @@ return cast(void *)(e + 1) + keysize; } + /************************************************* * Determine if key is in aa. * Returns: @@ -253,6 +254,7 @@ uint i; aaA *e; + //printf("_aaIn(), aa.length = %d, .ptr = %x\n", aa.length, cast(uint)aa.ptr); if (aa.length > 1) { key_hash = keyti.getHash(pkey); @@ -281,6 +283,7 @@ return null; } + /************************************************* * Delete key entry in aa[]. * If key is not in aa[], do nothing. diff -uNr dmd-0.110/dmd/src/phobos/internal/critical.c dmd-0.111/dmd/src/phobos/internal/critical.c --- dmd-0.110/dmd/src/phobos/internal/critical.c 2004-12-30 16:22:50.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/internal/critical.c 2005-01-19 12:14:22.000000000 +0100 @@ -97,14 +97,13 @@ static D_CRITICAL_SECTION *dcs_list; static D_CRITICAL_SECTION critical_section; static pthread_mutexattr_t _criticals_attr; -static volatile int inited; void _STI_critical_init(void); void _STD_critical_term(void); void _d_criticalenter(D_CRITICAL_SECTION *dcs) { - if (!inited) + if (!dcs_list) { _STI_critical_init(); atexit(_STD_critical_term); } @@ -125,33 +124,33 @@ void _d_criticalexit(D_CRITICAL_SECTION *dcs) { + //printf("_d_criticalexit(dcs = x%x)\n", dcs); pthread_mutex_unlock(&dcs->cs); } void _STI_critical_init() { - if (!inited) + if (!dcs_list) { //printf("_STI_critical_init()\n"); pthread_mutexattr_init(&_criticals_attr); pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP); // The global critical section doesn't need to be recursive pthread_mutex_init(&critical_section.cs, 0); - inited = 1; + dcs_list = &critical_section; } } void _STD_critical_term() { - if (inited) + if (dcs_list) { //printf("_STI_critical_term()\n"); - inited = 0; while (dcs_list) { + //printf("\tlooping... %x\n", dcs_list); pthread_mutex_destroy(&dcs_list->cs); dcs_list = dcs_list->next; } - pthread_mutex_destroy(&critical_section.cs); } } diff -uNr dmd-0.110/dmd/src/phobos/internal/llmath.d dmd-0.111/dmd/src/phobos/internal/llmath.d --- dmd-0.110/dmd/src/phobos/internal/llmath.d 2004-12-30 16:22:50.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/internal/llmath.d 2005-01-19 12:14:22.000000000 +0100 @@ -224,6 +224,8 @@ // Convert double to ulong +private short roundTo0 = 0xFBF; + ulong __DBLULLNG() { // BUG: should handle NAN's and overflows @@ -232,22 +234,29 @@ push EDX ; push EAX ; fld double ptr [ESP] ; + sub ESP,8 ; fld real ptr adjust ; - fcompp ; + fcomp ; fstsw AX ; + fstcw 8[ESP] ; + fldcw roundTo0 ; sahf ; - jb L1 ; + jae L1 ; fld real ptr adjust ; fsubp ST(1), ST ; fistp qword ptr [ESP] ; pop EAX ; pop EDX ; + fldcw [ESP] ; + add ESP,8 ; add EDX,0x8000_0000 ; ret ; L1: ; fistp qword ptr [ESP] ; pop EAX ; pop EDX ; + fldcw [ESP] ; + add ESP,8 ; ret ; } } @@ -259,10 +268,13 @@ // BUG: should handle NAN's and overflows asm { naked ; - sub ESP,8 ; + sub ESP,16 ; + fstcw 8[ESP] ; + fldcw roundTo0 ; fistp qword ptr [ESP] ; + fldcw 8[ESP] ; pop EAX ; - add ESP,4 ; + add ESP,12 ; ret ; } } diff -uNr dmd-0.110/dmd/src/phobos/internal/object.d dmd-0.111/dmd/src/phobos/internal/object.d --- dmd-0.110/dmd/src/phobos/internal/object.d 2004-12-30 16:22:50.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/internal/object.d 2005-01-19 12:14:24.000000000 +0100 @@ -182,9 +182,12 @@ assert(p); if (xtoHash) + { //printf("getHash() using xtoHash\n"); h = (*xtoHash)(p); + } else { + //printf("getHash() using default hash\n"); // A sorry hash algorithm. // Should use the one for strings. // BUG: relies on the GC not moving objects diff -uNr dmd-0.110/dmd/src/phobos/linux.mak dmd-0.111/dmd/src/phobos/linux.mak --- dmd-0.110/dmd/src/phobos/linux.mak 2004-12-30 16:22:48.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/linux.mak 2005-01-19 12:14:22.000000000 +0100 @@ -56,7 +56,7 @@ crc32.o conv.o arraycast.o errno.o alloca.o cmath2.o \ process.o syserror.o \ socket.o socketstream.o stdarg.o stdio.o format.o \ - perf.o openrj.o \ + perf.o openrj.o uni.o \ ti_wchar.o ti_uint.o ti_short.o ti_ushort.o \ ti_byte.o ti_ubyte.o ti_long.o ti_ulong.o ti_ptr.o \ ti_float.o ti_double.o ti_real.o ti_delegate.o \ @@ -95,7 +95,7 @@ std/intrinsic.d std/array.d std/switcherr.d std/syserror.d \ std/regexp.d std/random.d std/stream.d std/process.d std/recls.d \ std/socket.d std/socketstream.d std/loader.d std/stdarg.d \ - std/stdio.d std/format.d std/perf.d std/openrj.d + std/stdio.d std/format.d std/perf.d std/openrj.d std/uni.d SRC_STD_C= std/c/process.d std/c/stdlib.d std/c/time.d std/c/stdio.d \ std/c/math.d std/c/stdarg.d std/c/stddef.d @@ -554,6 +554,9 @@ uri.o : std/uri.d $(DMD) -c $(DFLAGS) std/uri.d +uni.o : std/uni.d + $(DMD) -c $(DFLAGS) std/uni.d + utf.o : std/utf.d $(DMD) -c $(DFLAGS) std/utf.d diff -uNr dmd-0.110/dmd/src/phobos/std/date.d dmd-0.111/dmd/src/phobos/std/date.d --- dmd-0.110/dmd/src/phobos/std/date.d 2004-12-30 16:22:48.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/std/date.d 2005-01-19 12:14:22.000000000 +0100 @@ -6,7 +6,7 @@ module std.date; -private import std.c.stdio; +private import std.stdio; private import std.dateparse; alias long d_time; @@ -55,6 +55,8 @@ const char[] daystr = "SunMonTueWedThuFriSat"; const char[] monstr = "JanFebMarAprMayJunJulAugSepOctNovDec"; +static int mdays[12] = [ 0,31,59,90,120,151,181,212,243,273,304,334 ]; + /******************************** * Compute ISO 8601 week based year. * Week 1 is first week with Jan 4 in it. @@ -116,14 +118,15 @@ week = (yday - ydaybeg) / 7 + 1; } -d_time floor(d_time d) -{ - return d; -} +/************************************ + * Divide time by divisor. Always round down, even if d is negative. + */ -d_time floor(real d) +d_time floor(d_time d, int divisor) { - return cast(d_time)d; + if (d < 0) + d -= divisor - 1; + return d / divisor; } d_time dmod(d_time n, d_time d) @@ -137,17 +140,17 @@ d_time HourFromTime(d_time t) { - return dmod(floor(t / msPerHour), HoursPerDay); + return dmod(floor(t, msPerHour), HoursPerDay); } d_time MinFromTime(d_time t) { - return dmod(floor(t / msPerMinute), MinutesPerHour); + return dmod(floor(t, msPerMinute), MinutesPerHour); } d_time SecFromTime(d_time t) { - return dmod(floor(t / TicksPerSecond), 60); + return dmod(floor(t, TicksPerSecond), 60); } d_time msFromTime(d_time t) @@ -162,16 +165,12 @@ d_time toInteger(d_time n) { - return (n >= 0) - ? floor(n) - : - floor(-n); + return n; } int Day(d_time t) { - if (t < 0) - t -= msPerDay; // use this if t is not floating point - return cast(int)floor(t / msPerDay); + return floor(t, msPerDay); } int LeapYear(int y) @@ -188,9 +187,9 @@ int DayFromYear(int y) { return cast(int) (365 * (y - 1970) + - floor((y - 1969.0) / 4) - - floor((y - 1901.0) / 100) + - floor((y - 1601.0) / 400)); + floor((y - 1969), 4) - + floor((y - 1901), 100) + + floor((y - 1601), 400)); } d_time TimeFromYear(int y) @@ -340,14 +339,6 @@ d_time MakeTime(d_time hour, d_time min, d_time sec, d_time ms) { - /+ - if (!Port::isfinite(hour) || - !Port::isfinite(min) || - !Port::isfinite(sec) || - !Port::isfinite(ms)) - return d_time_nan; - +/ - if (hour == d_time_nan || min == d_time_nan || sec == d_time_nan || @@ -371,26 +362,19 @@ int y; int m; int leap; - static int mdays[12] = - [ 0,31,59,90,120,151,181,212,243,273,304,334 ]; - -/+ - if (!Port::isfinite(year) || - !Port::isfinite(month) || - !Port::isfinite(date)) - return d_time.init; - +/ if (year == d_time_nan || month == d_time_nan || date == d_time_nan) + { return d_time_nan; + } year = toInteger(year); month = toInteger(month); date = toInteger(date); - y = cast(int)(year + floor(month / 12)); + y = cast(int)(year + floor(month, 12)); m = cast(int)dmod(month, 12); leap = LeapYear(y); @@ -401,18 +385,17 @@ if (YearFromTime(t) != y || MonthFromTime(t) != m || DateFromTime(t) != 1) + { return d_time_nan; + } return Day(t) + date - 1; } d_time MakeDate(d_time day, d_time time) { - /+ - if (!Port::isfinite(day) || - !Port::isfinite(time)) - return d_time.init; - +/ + if (day == d_time_nan || time == d_time_nan) + return d_time_nan; return day * TicksPerDay + time; } @@ -420,12 +403,7 @@ d_time TimeClip(d_time time) { //printf("TimeClip(%g) = %g\n", time, toInteger(time)); - /+ - if (!Port::isfinite(time) || - time > 8.64e15 || - time < -8.64e15) - return d_time_nan; - +/ + return toInteger(time); } @@ -477,6 +455,28 @@ return buffer[0 .. len]; } +char[] toUTCString(d_time t) +{ + // Years are supposed to be -285616 .. 285616, or 7 digits + // "Tue, 02 Apr 1996 02:04:57 GMT" + char[] buffer = new char[25 + 7 + 1]; + int len; + + if (t == d_time_nan) + return "Invalid Date"; + + len = sprintf(buffer, "%.3s, %02d %.3s %d %02d:%02d:%02d UTC", + &daystr[WeekDay(t) * 3], DateFromTime(t), + &monstr[MonthFromTime(t) * 3], + YearFromTime(t), + cast(int)HourFromTime(t), cast(int)MinFromTime(t), cast(int)SecFromTime(t)); + + // Ensure no buggy buffer overflows + assert(len < buffer.length); + + return buffer[0 .. len]; +} + char[] toDateString(d_time time) { d_time t; @@ -561,9 +561,9 @@ { dp.parse(s); - //printf("year = %d, month = %d, day = %d\n", dp.year, dp.month, dp.day); - //printf("%02d:%02d:%02d.%03d\n", dp.hour, dp.minute, dp.second, dp.ms); - //printf("weekday = %d, ampm = %d, tzcorrection = %d\n", dp.weekday, dp.ampm, dp.tzcorrection); + //writefln("year = %d, month = %d, day = %d", dp.year, dp.month, dp.day); + //writefln("%02d:%02d:%02d.%03d", dp.hour, dp.minute, dp.second, dp.ms); + //writefln("weekday = %d, ampm = %d, tzcorrection = %d", dp.weekday, 1, dp.tzcorrection); time = MakeTime(dp.hour, dp.minute, dp.second, dp.ms); if (dp.tzcorrection == Date.tzcorrection.init) @@ -579,7 +579,7 @@ } catch { - n = d_time.init; // erroneous date string + n = d_time_nan; // erroneous date string } return n; } @@ -753,14 +753,49 @@ { tm *tmp; int t; + int dst = 0; - t = cast(int) (dt / TicksPerSecond); // BUG: need range check - tmp = localtime(&t); - if (tmp.tm_isdst > 0) - // BUG: Assume daylight savings time is plus one hour. - return 60 * 60 * TicksPerSecond; - - return 0; + if (dt != d_time_nan) + { + d_time seconds = dt / TicksPerSecond; + t = cast(int) seconds; + if (t == seconds) // if in range + { + tmp = localtime(&t); + if (tmp.tm_isdst > 0) + dst = TicksPerHour; // BUG: Assume daylight savings time is plus one hour. + } + else // out of range for system time, use our own calculation + { // Daylight savings time goes from 2 AM the first Sunday + // in April through 2 AM the last Sunday in October + + dt -= LocalTZA; + + int year = YearFromTime(dt); + int leap = LeapYear(dt); + //writefln("year = %s, leap = %s, month = %s", year, leap, MonthFromTime(dt)); + + d_time start = TimeFromYear(year); // Jan 1 + d_time end = start; + // Move fwd to Apr 1 + start += cast(d_time)(mdays[3] + leap) * TicksPerDay; + // Advance a day at a time until we find Sunday (0) + while (WeekDay(start) != 0) + start += TicksPerDay; + + // Move fwd to Oct 30 + end += cast(d_time)(mdays[9] + leap + 30) * TicksPerDay; + // Back up a day at a time until we find Sunday (0) + while (WeekDay(end) != 0) // 0 is Sunday + end -= TicksPerDay; + + dt -= 2 * TicksPerHour; // 2 AM + if (dt >= start && dt <= end) + dst = TicksPerHour; + //writefln("start = %s, dt = %s, end = %s, dst = %s", start, dt, end, dst); + } + } + return dst; } } diff -uNr dmd-0.110/dmd/src/phobos/std/math.d dmd-0.111/dmd/src/phobos/std/math.d --- dmd-0.110/dmd/src/phobos/std/math.d 2004-12-30 16:22:48.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/std/math.d 2005-01-19 12:14:22.000000000 +0100 @@ -648,13 +648,103 @@ real pow(real x, int n) { if (n < 0) - return std.c.math.powl(x, n); + return pow(x, cast(real)n); else return pow(x, cast(uint)n); } real pow(real x, real y) { + version (linux) // C pow() often does not handle special values correctly + { + if (isnan(y)) + return real.nan; + + if (y == 0) + return 1; // even if x is NAN + if (isnan(x) && y != 0) + return real.nan; + if (isinf(y)) + { + if (fabs(x) > 1) + { + if (signbit(y)) + return +0.0; + else + return real.infinity; + } + else if (fabs(x) == 1) + { + return real.nan; + } + else // < 1 + { + if (signbit(y)) + return real.infinity; + else + return +0.0; + } + } + if (isinf(x)) + { + if (signbit(x)) + { long i; + + i = cast(long)y; + if (y > 0) + { + if (i == y && i & 1) + return -real.infinity; + else + return real.infinity; + } + else if (y < 0) + { + if (i == y && i & 1) + return -0.0; + else + return +0.0; + } + } + else + { + if (y > 0) + return real.infinity; + else if (y < 0) + return +0.0; + } + } + + if (x == 0.0) + { + if (signbit(x)) + { long i; + + i = cast(long)y; + if (y > 0) + { + if (i == y && i & 1) + return -0.0; + else + return +0.0; + } + else if (y < 0) + { + if (i == y && i & 1) + return -real.infinity; + else + return real.infinity; + } + } + else + { + if (y > 0) + return +0.0; + else if (y < 0) + return real.infinity; + } + } + } return std.c.math.powl(x, y); } diff -uNr dmd-0.110/dmd/src/phobos/std/mmfile.d dmd-0.111/dmd/src/phobos/std/mmfile.d --- dmd-0.110/dmd/src/phobos/std/mmfile.d 2004-12-30 16:22:50.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/std/mmfile.d 2005-01-19 12:14:22.000000000 +0100 @@ -8,7 +8,7 @@ * Memory mapped files. */ -module mmfile; +module std.mmfile; private import std.file; private import std.c.stdio; @@ -44,7 +44,7 @@ } -auto class MmFile +class MmFile { enum Mode { Read, // read existing file @@ -65,6 +65,7 @@ this(char[] filename, Mode mode, size_t size, void* address) { this.filename = filename; + this.mMode = mode; version (Win32) { @@ -335,6 +336,12 @@ return data.length; } + Mode mode() + { + debug (MMFILE) printf("MmFile.mode()\n"); + return mMode; + } + void[] opSlice() { debug (MMFILE) printf("MmFile.opSlice()\n"); @@ -363,6 +370,7 @@ private: char[] filename; void[] data; + Mode mMode; version (Win32) { @@ -408,3 +416,4 @@ } */ + diff -uNr dmd-0.110/dmd/src/phobos/std/stream.d dmd-0.111/dmd/src/phobos/std/stream.d --- dmd-0.110/dmd/src/phobos/std/stream.d 2004-12-30 16:22:50.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/std/stream.d 2005-01-19 12:14:22.000000000 +0100 @@ -1307,6 +1307,76 @@ return streamPos-bufferSourcePos+bufferCurPos; } + // reads a line, terminated by either CR, LF, CR/LF, or EOF + // reusing the memory in buffer if result will fit, otherwise + // will reallocate (using concatenation) + template TreadLine(T) { + override T[] readLine(T[] inBuffer) + { + uint lineSize = 0; + bool haveCR = false; + T c = '\0'; + uint idx = 0; + ubyte* pc = cast(ubyte*)&c; + + L0: + for(;;) { + uint start = bufferCurPos; + L1: + foreach(ubyte b; buffer[start .. bufferLen]) { + bufferCurPos++; + pc[idx] = b; + if(idx < T.sizeof - 1) { + idx++; + continue L1; + } else { + idx = 0; + } + if(c == '\n' || haveCR) { + if(haveCR && c != '\n') bufferCurPos--; + break L0; + } else { + if(c == '\r') { + haveCR = true; + } else { + if(lineSize < inBuffer.length) { + inBuffer[lineSize] = c; + } else { + inBuffer ~= c; + } + lineSize++; + } + } + } + flush(); + uint res = s.readBlock(buffer,buffer.length); + if(!res) break L0; // EOF + bufferSourcePos = bufferLen = res; + streamPos += res; + } + + return inBuffer[0 .. lineSize]; + } + } // template TreadLine(T) + + override char[] readLine(char[] inBuffer) + { + if (unget.length > 1) + return super.readLine(inBuffer); + else + return TreadLine!(char).readLine(inBuffer); + } + alias Stream.readLine readLine; + + override wchar[] readLineW(wchar[] inBuffer) + { + if (unget.length > 1) + return super.readLineW(inBuffer); + else + return TreadLine!(wchar).readLine(inBuffer); + } + alias Stream.readLineW readLineW; + override void flush() out { @@ -1937,6 +2007,17 @@ } } + // Correct the byte order of buffer in blocks repeatedly + // size must be even + final void fixBlockBO(void* buffer, uint size, uint repeat) + { + while (repeat--) + { + fixBO(buffer,size); + buffer += size; + } + } + uint readBlock(void* buffer, uint size) { return s.readBlock(buffer,size); @@ -1954,9 +2035,9 @@ void read(out ifloat x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } void read(out idouble x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } void read(out ireal x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } - void read(out cfloat x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } - void read(out cdouble x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } - void read(out creal x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out cfloat x) { readExact(&x, x.sizeof); fixBlockBO(&x,float.sizeof,2); } + void read(out cdouble x) { readExact(&x, x.sizeof); fixBlockBO(&x,double.sizeof,2); } + void read(out creal x) { readExact(&x, x.sizeof); fixBlockBO(&x,real.sizeof,2); } void read(out wchar x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } void read(out dchar x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } @@ -1964,8 +2045,7 @@ { wchar[] result = new wchar[length]; readExact(result, result.length * wchar.sizeof); - while (length--) - fixBO(&result[length],2); + fixBlockBO(&result,2,length); return result; } @@ -1992,9 +2072,9 @@ void write(ifloat x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } void write(idouble x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } void write(ireal x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } - void write(cfloat x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } - void write(cdouble x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } - void write(creal x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(cfloat x) { fixBlockBO(&x,float.sizeof,2); writeExact(&x, x.sizeof); } + void write(cdouble x) { fixBlockBO(&x,double.sizeof,2); writeExact(&x, x.sizeof); } + void write(creal x) { fixBlockBO(&x,real.sizeof,2); writeExact(&x, x.sizeof); } void write(wchar x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } void write(dchar x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } @@ -2169,6 +2249,15 @@ return cur; } + + // returns pointer to stream data + ubyte[] data() { return cast(ubyte[])buf [0 .. len]; } + + override char[] toString() + { + return cast(char[]) data (); + } + } /* Test the TArrayStream */ unittest @@ -2214,20 +2303,13 @@ if (cur + count > buf.length) buf.length = (cur + count) * 2; } - - // returns pointer to stream data - ubyte[] data() { return buf [0 .. len]; } - + override uint writeBlock(void* buffer, uint size) { reserve(size); return super.writeBlock(buffer,size); } - override char[] toString() - { - return cast(char[]) data (); - } - + /* Test the whole class. */ unittest { @@ -2256,18 +2338,56 @@ } -/**************************** - BVH 8/04: - currently fails due to MmFile being auto, so leaving commented out - until MmFile can be used in objects - import std.mmfile; + // stream wrapping memory-mapped files -alias TArrayStream!(MmFile) MmFileStream; +class MmFileStream : TArrayStream!(MmFile) +{ + + // constructor to wrap file + this(MmFile file) + { + super (file); + MmFile.Mode mode = file.mode; + writeable = mode > MmFile.Mode.Read; + } + + override uint readBlock(void* buffer, uint size) + { + if (isopen) + return super.readBlock(buffer,size); + else + return 0; + } + + override uint writeBlock(void* buffer, uint size) + { + if (isopen) + return super.writeBlock(buffer,size); + else + return 0; + } + + // flush stream + override void flush() + { + if (isopen) + buf.flush(); + } + + // close stream + override void close() + { + if (isopen) { + delete buf; + isopen = false; + } + } +} unittest { - MmFile mf = new MmFile("testing.txt"); + MmFile mf = new MmFile("testing.txt",MmFile.Mode.ReadWriteNew,100,null); MmFileStream m; m = new MmFileStream (mf); @@ -2275,18 +2395,26 @@ assert (m.position () == 12); assert (m.seekSet (0) == 0); assert (m.seekCur (4) == 4); - assert (m.seekEnd (-8) == 4); - assert (m.size () == 12); + assert (m.seekEnd (-8) == 92); + assert (m.size () == 100); + assert (m.seekSet (4)); assert (m.readString (4) == "o, w"); m.writeString ("ie"); - assert (cast(char[]) m.data () == "Hello, wield"); - m.seekEnd (0); + assert ((cast(char[]) m.data())[0 .. 12] == "Hello, wield"); + m.seekSet (12); m.writeString ("Foo"); assert (m.position () == 15); m.writeString ("Foo foo foo foo foo foo foo"); assert (m.position () == 42); + m.close(); + mf = new MmFile("testing.txt"); + m = new MmFileStream (mf); + assert (!m.writeable); + char[] str = m.readString(12); + assert (str == "Hello, wield"); + m.close(); + std.file.remove("testing.txt"); } -********************************/ // slices off a portion of another stream, making seeking // relative to the boundaries of the slice. @@ -2519,3 +2647,4 @@ } } + diff -uNr dmd-0.110/dmd/src/phobos/std/string.d dmd-0.111/dmd/src/phobos/std/string.d --- dmd-0.110/dmd/src/phobos/std/string.d 2004-12-30 16:22:48.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/std/string.d 2005-01-19 12:14:22.000000000 +0100 @@ -23,9 +23,11 @@ //debug=string; // uncomment to turn on debugging printf's +private import std.stdio; private import std.c.stdio; private import std.c.stdlib; private import std.utf; +private import std.uni; private import std.array; private import std.format; private import std.ctype; @@ -306,14 +308,17 @@ if (c1 == c2) return i; } - return -1; } + else + { // c is a universal character + dchar c1 = std.uni.toUniLower(c); - // c is a universal character - foreach (int i, dchar c2; s) - { - if (c == c2) - return i; + foreach (int i, dchar c2; s) + { + c2 = std.uni.toUniLower(c2); + if (c1 == c2) + return i; + } } return -1; } @@ -394,7 +399,7 @@ int irfind(char[] s, dchar c) { - int i; + size_t i; if (c <= 0x7F) { // Plain old ASCII @@ -407,14 +412,27 @@ if (c1 == c2) break; } - return i; } + else + { // c is a universal character + dchar c1 = std.uni.toUniLower(c); - // c is a universal character - char[4] buf; - char[] t; - t = std.utf.toUTF8(buf, c); - return irfind(s, t); + for (i = s.length; i-- > 0;) + { char cx = s[i]; + + if (cx <= 0x7F) + continue; // skip, since c is not ASCII + if ((cx & 0xC0) == 0x80) + continue; // skip non-starting UTF-8 chars + + size_t j = i; + dchar c2 = std.utf.decode(s, j); + c2 = std.uni.toUniLower(c2); + if (c1 == c2) + break; + } + } + return i; } unittest @@ -691,19 +709,30 @@ } body { - char c; + dchar c; if (sub.length == 0) return s.length; c = sub[0]; if (sub.length == 1) return irfind(s, c); - c = std.ctype.tolower(c); - for (int i = s.length - sub.length; i >= 0; i--) + if (c <= 0x7F) + { + c = std.ctype.tolower(c); + for (int i = s.length - sub.length; i >= 0; i--) + { + if (std.ctype.tolower(s[i]) == c) + { + if (icmp(s[i + 1 .. i + sub.length], sub[1 .. sub.length]) == 0) + return i; + } + } + } + else { - if (std.ctype.tolower(s[i]) == c) + for (int i = s.length - sub.length; i >= 0; i--) { - if (icmp(s[i + 1 .. i + sub.length], sub[1 .. sub.length]) == 0) + if (icmp(s[i .. i + sub.length], sub) == 0) return i; } } @@ -755,6 +784,7 @@ { int changed; int i; + char[] r = s; changed = 0; for (i = 0; i < s.length; i++) @@ -763,15 +793,30 @@ if ('A' <= c && c <= 'Z') { if (!changed) - { char[] r = new char[s.length]; - r[] = s; - s = r; + { r = s.dup; changed = 1; } - s[i] = c + (cast(char)'a' - 'A'); + r[i] = c + (cast(char)'a' - 'A'); + } + else if (c >= 0x7F) + { + foreach (size_t j, dchar dc; s[i .. length]) + { + if (!changed) + { + if (!std.uni.isUniUpper(dc)) + continue; + + r = s[0 .. i + j].dup; + changed = 1; + } + dc = std.uni.toUniLower(dc); + std.utf.encode(r, dc); + } + break; } } - return s; + return r; } unittest @@ -794,6 +839,7 @@ { int changed; int i; + char[] r = s; changed = 0; for (i = 0; i < s.length; i++) @@ -802,15 +848,30 @@ if ('a' <= c && c <= 'z') { if (!changed) - { char[] r = new char[s.length]; - r[] = s; - s = r; + { r = s.dup; changed = 1; } - s[i] = c - (cast(char)'a' - 'A'); + r[i] = c - (cast(char)'a' - 'A'); + } + else if (c >= 0x7F) + { + foreach (size_t j, dchar dc; s[i .. length]) + { + if (!changed) + { + if (!std.uni.isUniLower(dc)) + continue; + + r = s[0 .. i + j].dup; + changed = 1; + } + dc = std.uni.toUniUpper(dc); + std.utf.encode(r, dc); + } + break; } } - return s; + return r; } unittest @@ -2056,6 +2117,65 @@ return toString(buffer).dup; } +char[] toString(long value, uint radix) +in +{ + assert(radix >= 2 && radix <= 36); +} +body +{ + if (radix == 10) + return toString(value); // handle signed cases only for radix 10 + return toString(cast(ulong)value, radix); +} + +char[] toString(ulong value, uint radix) +in +{ + assert(radix >= 2 && radix <= 36); +} +body +{ + char[value.sizeof * 8] buffer; + uint i = buffer.length; + + if (value < radix && value < hexdigits.length) + return hexdigits[value .. value + 1]; + + do + { ubyte c; + + c = value % radix; + value = value / radix; + i--; + buffer[i] = (c < 10) ? c + '0' : c + 'A' - 10; + } while (value); + return buffer[i .. length].dup; +} + +unittest +{ + debug(string) printf("string.toString(ulong, uint).unittest\n"); + + char[] r; + int i; + + r = toString(-10L, 10u); + assert(r == "-10"); + + r = toString(15L, 2u); + //writefln("r = '%s'", r); + assert(r == "1111"); + + r = toString(1L, 2u); + //writefln("r = '%s'", r); + assert(r == "1"); + + r = toString(0x1234AFL, 16u); + //writefln("r = '%s'", r); + assert(r == "1234AF"); +} + /************************************************* * Convert to char[]. */ @@ -2125,7 +2245,7 @@ } std.format.doFormat(&putc, _arguments, _argptr); - return s; + return s[0 .. i]; } diff -uNr dmd-0.110/dmd/src/phobos/std/uni.d dmd-0.111/dmd/src/phobos/std/uni.d --- dmd-0.110/dmd/src/phobos/std/uni.d 1970-01-01 01:00:00.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/std/uni.d 2005-01-19 12:14:22.000000000 +0100 @@ -0,0 +1,468 @@ + +module uni; + +int isUniLower(dchar c) +{ + if (c <= 0x7F) + return (c >= 'a' && c <= 'z'); + + return isUniAlpha(c) && c == toUniLower(c); +} + +int isUniUpper(dchar c) +{ + if (c <= 0x7F) + return (c >= 'A' && c <= 'Z'); + + return isUniAlpha(c) && c == toUniUpper(c); +} + +dchar toUniLower(dchar c) +{ + if (c >= 'A' && c <= 'Z') + { + c += 32; + } + if (c >= 0x00C0) + { + if ((c >= 0x00C0 && c <= 0x00D6) || (c >= 0x00D8 && c<=0x00DE)) + { + c += 32; + } + else if ((c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178)) + { + if (c == 0x0130) + c = 0x0069; + else if ((c & 1) == 0) + c += 1; + } + else if (c == 0x0178) + { + c = 0x00FF; + } + else if ((c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F)) + { + if (c & 1) + c += 1; + } + else if (c >= 0x0200 && c <= 0x0217) + { + if ((c & 1) == 0) + c += 1; + } + else if ((c >= 0x0401 && c <= 0x040C) || (c>= 0x040E && c <= 0x040F)) + { + c += 80; + } + else if (c >= 0x0410 && c <= 0x042F) + { + c += 32; + } + else if (c >= 0x0460 && c <= 0x047F) + { + if ((c & 1) == 0) + c += 1; + } + else if (c >= 0x0531 && c <= 0x0556) + { + c += 48; + } + else if (c >= 0x10A0 && c <= 0x10C5) + { + c += 48; + } + else if (c >= 0xFF21 && c <= 0xFF3A) + { + c += 32; + } + } + return c; +} + +dchar toUniUpper(dchar c) +{ + if (c >= 'a' && c <= 'z') + { + c -= 32; + } + if (c >= 0x00E0) + { + if ((c >= 0x00E0 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x00FE)) + { + c -= 32; + } + else if (c == 0x00FF) + { + c = 0x0178; + } + else if ((c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178)) + { + if (c == 0x0131) + c = 0x0049; + else if (c & 1) + c -= 1; + } + else if ((c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F)) + { + if ((c & 1) == 0) + c = c-1; + } + else if (c == 0x017F) + { + c = 0x0053; + } + else if (c >= 0x0200 && c <= 0x0217) + { + if (c & 1) + c = c-1; + } + else if (c >= 0x0430 && c<= 0x044F) + { + c -= 32; + } + else if ((c >= 0x0451 && c <= 0x045C) || (c >=0x045E && c<= 0x045F)) + { + c -= 80; + } + else if (c >= 0x0460 && c <= 0x047F) + { + if (c & 1) + c -= 1; + } + else if (c >= 0x0561 && c < 0x0587) + { + c -= 48; + } + else if (c >= 0xFF41 && c <= 0xFF5A) + { + c -= 32; + } + } + return c; +} + + +/******************************* + * Return !=0 if unicode alpha. + */ + +int isUniAlpha(dchar u) +{ + static ushort table[][2] = + [ + [ 'A', 'Z' ], + [ 'a', 'z' ], + [ 0x00AA, 0x00AA ], + [ 0x00B5, 0x00B5 ], + [ 0x00B7, 0x00B7 ], + [ 0x00BA, 0x00BA ], + [ 0x00C0, 0x00D6 ], + [ 0x00D8, 0x00F6 ], + [ 0x00F8, 0x01F5 ], + [ 0x01FA, 0x0217 ], + [ 0x0250, 0x02A8 ], + [ 0x02B0, 0x02B8 ], + [ 0x02BB, 0x02BB ], + [ 0x02BD, 0x02C1 ], + [ 0x02D0, 0x02D1 ], + [ 0x02E0, 0x02E4 ], + [ 0x037A, 0x037A ], + [ 0x0386, 0x0386 ], + [ 0x0388, 0x038A ], + [ 0x038C, 0x038C ], + [ 0x038E, 0x03A1 ], + [ 0x03A3, 0x03CE ], + [ 0x03D0, 0x03D6 ], + [ 0x03DA, 0x03DA ], + [ 0x03DC, 0x03DC ], + [ 0x03DE, 0x03DE ], + [ 0x03E0, 0x03E0 ], + [ 0x03E2, 0x03F3 ], + [ 0x0401, 0x040C ], + [ 0x040E, 0x044F ], + [ 0x0451, 0x045C ], + [ 0x045E, 0x0481 ], + [ 0x0490, 0x04C4 ], + [ 0x04C7, 0x04C8 ], + [ 0x04CB, 0x04CC ], + [ 0x04D0, 0x04EB ], + [ 0x04EE, 0x04F5 ], + [ 0x04F8, 0x04F9 ], + [ 0x0531, 0x0556 ], + [ 0x0559, 0x0559 ], + [ 0x0561, 0x0587 ], + [ 0x05B0, 0x05B9 ], + [ 0x05BB, 0x05BD ], + [ 0x05BF, 0x05BF ], + [ 0x05C1, 0x05C2 ], + [ 0x05D0, 0x05EA ], + [ 0x05F0, 0x05F2 ], + [ 0x0621, 0x063A ], + [ 0x0640, 0x0652 ], + [ 0x0660, 0x0669 ], + [ 0x0670, 0x06B7 ], + [ 0x06BA, 0x06BE ], + [ 0x06C0, 0x06CE ], + [ 0x06D0, 0x06DC ], + [ 0x06E5, 0x06E8 ], + [ 0x06EA, 0x06ED ], + [ 0x06F0, 0x06F9 ], + [ 0x0901, 0x0903 ], + [ 0x0905, 0x0939 ], + [ 0x093D, 0x093D ], + [ 0x093E, 0x094D ], + [ 0x0950, 0x0952 ], + [ 0x0958, 0x0963 ], + [ 0x0966, 0x096F ], + [ 0x0981, 0x0983 ], + [ 0x0985, 0x098C ], + [ 0x098F, 0x0990 ], + [ 0x0993, 0x09A8 ], + [ 0x09AA, 0x09B0 ], + [ 0x09B2, 0x09B2 ], + [ 0x09B6, 0x09B9 ], + [ 0x09BE, 0x09C4 ], + [ 0x09C7, 0x09C8 ], + [ 0x09CB, 0x09CD ], + [ 0x09DC, 0x09DD ], + [ 0x09DF, 0x09E3 ], + [ 0x09E6, 0x09EF ], + [ 0x09F0, 0x09F1 ], + [ 0x0A02, 0x0A02 ], + [ 0x0A05, 0x0A0A ], + [ 0x0A0F, 0x0A10 ], + [ 0x0A13, 0x0A28 ], + [ 0x0A2A, 0x0A30 ], + [ 0x0A32, 0x0A33 ], + [ 0x0A35, 0x0A36 ], + [ 0x0A38, 0x0A39 ], + [ 0x0A3E, 0x0A42 ], + [ 0x0A47, 0x0A48 ], + [ 0x0A4B, 0x0A4D ], + [ 0x0A59, 0x0A5C ], + [ 0x0A5E, 0x0A5E ], + [ 0x0A66, 0x0A6F ], + [ 0x0A74, 0x0A74 ], + [ 0x0A81, 0x0A83 ], + [ 0x0A85, 0x0A8B ], + [ 0x0A8D, 0x0A8D ], + [ 0x0A8F, 0x0A91 ], + [ 0x0A93, 0x0AA8 ], + [ 0x0AAA, 0x0AB0 ], + [ 0x0AB2, 0x0AB3 ], + [ 0x0AB5, 0x0AB9 ], + [ 0x0ABD, 0x0AC5 ], + [ 0x0AC7, 0x0AC9 ], + [ 0x0ACB, 0x0ACD ], + [ 0x0AD0, 0x0AD0 ], + [ 0x0AE0, 0x0AE0 ], + [ 0x0AE6, 0x0AEF ], + [ 0x0B01, 0x0B03 ], + [ 0x0B05, 0x0B0C ], + [ 0x0B0F, 0x0B10 ], + [ 0x0B13, 0x0B28 ], + [ 0x0B2A, 0x0B30 ], + [ 0x0B32, 0x0B33 ], + [ 0x0B36, 0x0B39 ], + [ 0x0B3D, 0x0B3D ], + [ 0x0B3E, 0x0B43 ], + [ 0x0B47, 0x0B48 ], + [ 0x0B4B, 0x0B4D ], + [ 0x0B5C, 0x0B5D ], + [ 0x0B5F, 0x0B61 ], + [ 0x0B66, 0x0B6F ], + [ 0x0B82, 0x0B83 ], + [ 0x0B85, 0x0B8A ], + [ 0x0B8E, 0x0B90 ], + [ 0x0B92, 0x0B95 ], + [ 0x0B99, 0x0B9A ], + [ 0x0B9C, 0x0B9C ], + [ 0x0B9E, 0x0B9F ], + [ 0x0BA3, 0x0BA4 ], + [ 0x0BA8, 0x0BAA ], + [ 0x0BAE, 0x0BB5 ], + [ 0x0BB7, 0x0BB9 ], + [ 0x0BBE, 0x0BC2 ], + [ 0x0BC6, 0x0BC8 ], + [ 0x0BCA, 0x0BCD ], + [ 0x0BE7, 0x0BEF ], + [ 0x0C01, 0x0C03 ], + [ 0x0C05, 0x0C0C ], + [ 0x0C0E, 0x0C10 ], + [ 0x0C12, 0x0C28 ], + [ 0x0C2A, 0x0C33 ], + [ 0x0C35, 0x0C39 ], + [ 0x0C3E, 0x0C44 ], + [ 0x0C46, 0x0C48 ], + [ 0x0C4A, 0x0C4D ], + [ 0x0C60, 0x0C61 ], + [ 0x0C66, 0x0C6F ], + [ 0x0C82, 0x0C83 ], + [ 0x0C85, 0x0C8C ], + [ 0x0C8E, 0x0C90 ], + [ 0x0C92, 0x0CA8 ], + [ 0x0CAA, 0x0CB3 ], + [ 0x0CB5, 0x0CB9 ], + [ 0x0CBE, 0x0CC4 ], + [ 0x0CC6, 0x0CC8 ], + [ 0x0CCA, 0x0CCD ], + [ 0x0CDE, 0x0CDE ], + [ 0x0CE0, 0x0CE1 ], + [ 0x0CE6, 0x0CEF ], + [ 0x0D02, 0x0D03 ], + [ 0x0D05, 0x0D0C ], + [ 0x0D0E, 0x0D10 ], + [ 0x0D12, 0x0D28 ], + [ 0x0D2A, 0x0D39 ], + [ 0x0D3E, 0x0D43 ], + [ 0x0D46, 0x0D48 ], + [ 0x0D4A, 0x0D4D ], + [ 0x0D60, 0x0D61 ], + [ 0x0D66, 0x0D6F ], + [ 0x0E01, 0x0E3A ], + + [ 0x0E40, 0x0E5B ], +// [ 0x0E50, 0x0E59 ], // Digits? Why does this overlap previous? + + [ 0x0E81, 0x0E82 ], + [ 0x0E84, 0x0E84 ], + [ 0x0E87, 0x0E88 ], + [ 0x0E8A, 0x0E8A ], + [ 0x0E8D, 0x0E8D ], + [ 0x0E94, 0x0E97 ], + [ 0x0E99, 0x0E9F ], + [ 0x0EA1, 0x0EA3 ], + [ 0x0EA5, 0x0EA5 ], + [ 0x0EA7, 0x0EA7 ], + [ 0x0EAA, 0x0EAB ], + [ 0x0EAD, 0x0EAE ], + [ 0x0EB0, 0x0EB9 ], + [ 0x0EBB, 0x0EBD ], + [ 0x0EC0, 0x0EC4 ], + [ 0x0EC6, 0x0EC6 ], + [ 0x0EC8, 0x0ECD ], + [ 0x0ED0, 0x0ED9 ], + [ 0x0EDC, 0x0EDD ], + [ 0x0F00, 0x0F00 ], + [ 0x0F18, 0x0F19 ], + [ 0x0F20, 0x0F33 ], + [ 0x0F35, 0x0F35 ], + [ 0x0F37, 0x0F37 ], + [ 0x0F39, 0x0F39 ], + [ 0x0F3E, 0x0F47 ], + [ 0x0F49, 0x0F69 ], + [ 0x0F71, 0x0F84 ], + [ 0x0F86, 0x0F8B ], + [ 0x0F90, 0x0F95 ], + [ 0x0F97, 0x0F97 ], + [ 0x0F99, 0x0FAD ], + [ 0x0FB1, 0x0FB7 ], + [ 0x0FB9, 0x0FB9 ], + [ 0x10A0, 0x10C5 ], + [ 0x10D0, 0x10F6 ], + [ 0x1E00, 0x1E9B ], + [ 0x1EA0, 0x1EF9 ], + [ 0x1F00, 0x1F15 ], + [ 0x1F18, 0x1F1D ], + [ 0x1F20, 0x1F45 ], + [ 0x1F48, 0x1F4D ], + [ 0x1F50, 0x1F57 ], + [ 0x1F59, 0x1F59 ], + [ 0x1F5B, 0x1F5B ], + [ 0x1F5D, 0x1F5D ], + [ 0x1F5F, 0x1F7D ], + [ 0x1F80, 0x1FB4 ], + [ 0x1FB6, 0x1FBC ], + [ 0x1FBE, 0x1FBE ], + [ 0x1FC2, 0x1FC4 ], + [ 0x1FC6, 0x1FCC ], + [ 0x1FD0, 0x1FD3 ], + [ 0x1FD6, 0x1FDB ], + [ 0x1FE0, 0x1FEC ], + [ 0x1FF2, 0x1FF4 ], + [ 0x1FF6, 0x1FFC ], + [ 0x203F, 0x2040 ], + [ 0x207F, 0x207F ], + [ 0x2102, 0x2102 ], + [ 0x2107, 0x2107 ], + [ 0x210A, 0x2113 ], + [ 0x2115, 0x2115 ], + [ 0x2118, 0x211D ], + [ 0x2124, 0x2124 ], + [ 0x2126, 0x2126 ], + [ 0x2128, 0x2128 ], + [ 0x212A, 0x2131 ], + [ 0x2133, 0x2138 ], + [ 0x2160, 0x2182 ], + [ 0x3005, 0x3007 ], + [ 0x3021, 0x3029 ], + [ 0x3041, 0x3093 ], + [ 0x309B, 0x309C ], + [ 0x30A1, 0x30F6 ], + [ 0x30FB, 0x30FC ], + [ 0x3105, 0x312C ], + [ 0x4E00, 0x9FA5 ], + [ 0xAC00, 0xD7A3 ], + [ 0xFF21, 0xFF3A ], + [ 0xFF41, 0xFF5A ], + ]; + + debug + { + for (int i = 0; i < table.length; i++) + { + assert(table[i][0] <= table[i][1]); + if (i < table.length - 1) + { + if (table[i][1] >= table[i + 1][0]) + printf("table[%d][1] = x%x, table[%d][0] = x%x\n", i, table[i][1], i + 1, table[i + 1][0]); + assert(table[i][1] < table[i + 1][0]); + } + } + } + + if (u > 0xD7A3 && u < 0xFF21) + goto Lisnot; + + // Binary search + uint mid; + uint low; + uint high; + + low = 0; + high = table.length - 1; + while (low <= high) + { + mid = (low + high) >> 1; + if (u < table[mid][0]) + high = mid - 1; + else if (u > table[mid][1]) + low = mid + 1; + else + goto Lis; + } + +Lisnot: + debug + { + for (int i = 0; i < table.length; i++) + { + assert(u < table[i][0] || u > table[i][1]); + } + } + return 0; + +Lis: + debug + { + for (int i = 0; i < table.length; i++) + { + if (u >= table[i][0] && u <= table[i][1]) + return 1; + } + assert(0); // should have been in table + } + return 1; +} + + diff -uNr dmd-0.110/dmd/src/phobos/std/utf.d dmd-0.111/dmd/src/phobos/std/utf.d --- dmd-0.110/dmd/src/phobos/std/utf.d 2004-12-30 16:22:48.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/std/utf.d 2005-01-19 12:14:22.000000000 +0100 @@ -24,9 +24,12 @@ // Description of UTF-8 at: // http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 +// http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335 module std.utf; +private import std.stdio; + //debug=utf; // uncomment to turn on debugging printf's class UtfError : Error @@ -47,11 +50,10 @@ * Unicode standard for application internal use, but are not * allowed for interchange. * (thanks to Arcane Jill) - * However, we still mark them as invalid. */ return c < 0xD800 || - (c > 0xDFFF && c <= 0x10FFFF && c != 0xFFFE && c != 0xFFFF); + (c > 0xDFFF && c <= 0x10FFFF /*&& c != 0xFFFE && c != 0xFFFF*/); } unittest @@ -61,6 +63,134 @@ assert(isValidDchar(cast(dchar)0x1FFFFF) == false); } + +/* This array gives the length of a UTF-8 sequence indexed by the value + * of the leading byte. An FF represents an illegal starting value of + * a UTF-8 sequence. + * FF is used instead of 0 to avoid having loops hang. + */ + +ubyte[256] UTF8stride = +[ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF, +]; + +uint stride(char[] s, size_t i) +{ + return UTF8stride[s[i]]; +} + +uint stride(wchar[] s, size_t i) +{ uint u = s[i]; + return 1 + (u >= 0xD800 && u <= 0xDBFF); +} + +uint stride(dchar[] s, size_t i) +{ + return 1; +} + +/******************************************* + * Given an index into an array of char's, + * and assuming that index is at the start of a UTF character, + * determine the number of UCS characters up to that index. + */ + +size_t toUCSindex(char[] s, size_t i) +{ + size_t n; + size_t j; + size_t stride; + + for (j = 0; j < i; j += stride) + { + stride = UTF8stride[s[j]]; + if (stride == 0xFF) + goto Lerr; + n++; + } + if (j > i) + { + Lerr: + throw new UtfError("1invalid UTF-8 sequence", j); + } + return n; +} + +size_t toUCSindex(wchar[] s, size_t i) +{ + size_t n; + size_t j; + + for (j = 0; j < i; ) + { uint u = s[j]; + + j += 1 + (u >= 0xD800 && u <= 0xDBFF); + n++; + } + if (j > i) + { + Lerr: + throw new UtfError("2invalid UTF-16 sequence", j); + } + return n; +} + +size_t toUCSindex(dchar[] s, size_t i) +{ + return i; +} + +/****************************************** + * Given a UCS index into an array of characters, return the UTF index. + */ + +size_t toUTFindex(char[] s, size_t n) +{ + size_t i; + + while (n--) + { + uint j = UTF8stride[s[i]]; + if (j == 0xFF) + throw new UtfError("3invalid UTF-8 sequence", i); + i += j; + } + return i; +} + +size_t toUTFindex(wchar[] s, size_t n) +{ + size_t i; + + while (n--) + { wchar u = s[i]; + + i += 1 + (u >= 0xD800 && u <= 0xDBFF); + } + return i; +} + +size_t toUTFindex(dchar[] s, size_t n) +{ + return n; +} + /* =================== Decode ======================= */ dchar decode(char[] s, inout size_t idx) @@ -146,7 +276,8 @@ return V; Lerr: - throw new UtfError("invalid UTF-8 sequence", i); + //printf("\ndecode: idx = %d, i = %d, length = %d s = \n'%.*s'\n%x\n'%.*s'\n", idx, i, s.length, s, s[i], s[i .. length]); + throw new UtfError("4invalid UTF-8 sequence", i); } unittest @@ -276,7 +407,7 @@ return c; Lerr: - throw new UtfError("invalid UTF-32 value", i); + throw new UtfError("5invalid UTF-32 value", i); } diff -uNr dmd-0.110/dmd/src/phobos/win32.mak dmd-0.111/dmd/src/phobos/win32.mak --- dmd-0.110/dmd/src/phobos/win32.mak 2004-12-30 16:22:48.000000000 +0100 +++ dmd-0.111/dmd/src/phobos/win32.mak 2005-01-19 12:14:22.000000000 +0100 @@ -14,7 +14,9 @@ CP=cp -CFLAGS=-g -mn -6 -r +CFLAGS=-mn -6 -r +#CFLAGS=-g -mn -6 -r + DFLAGS=-O -release #DFLAGS=-unittest -g @@ -62,7 +64,7 @@ iunknown.obj crc32.obj conv.obj arraycast.obj utf.obj uri.obj \ Czlib.obj Dzlib.obj zip.obj process.obj registry.obj recls.obj \ socket.obj socketstream.obj loader.obj stdarg.obj format.obj stdio.obj \ - perf.obj openrj.obj \ + perf.obj openrj.obj uni.obj \ ti_Aa.obj ti_Ag.obj ti_C.obj ti_int.obj ti_char.obj \ ti_wchar.obj ti_uint.obj ti_short.obj ti_ushort.obj \ ti_byte.obj ti_ubyte.obj ti_long.obj ti_ulong.obj ti_ptr.obj \ @@ -85,7 +87,7 @@ std\intrinsic.d std\array.d std\switcherr.d std\syserror.d \ std\regexp.d std\random.d std\stream.d std\process.d std\recls.d \ std\socket.d std\socketstream.d std\loader.d std\stdarg.d std\format.d \ - std\stdio.d std\perf.d std\openrj.d + std\stdio.d std\perf.d std\openrj.d std\uni.d SRC_STD_C= std\c\process.d std\c\stdlib.d std\c\time.d std\c\stdio.d \ std\c\math.d std\c\stdarg.d std\c\stddef.d @@ -517,6 +519,9 @@ thread.obj : std\thread.d $(DMD) -c $(DFLAGS) std\thread.d +uni.obj : std\uni.d + $(DMD) -c $(DFLAGS) std\uni.d + uri.obj : std\uri.d $(DMD) -c $(DFLAGS) std\uri.d