diff -uNr dmd-0.142/dmd/src/dmd/class.c dmd-0.143/dmd/src/dmd/class.c --- dmd-0.142/dmd/src/dmd/class.c 2005-12-23 01:03:58.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/class.c 2006-01-07 18:47:00.000000000 +0100 @@ -516,7 +516,8 @@ if (i) buf->writeByte(','); - buf->writestring(b->base->ident->toChars()); + //buf->writestring(b->base->ident->toChars()); + b->type->toCBuffer(buf, NULL, hgs); } buf->writenl(); buf->writeByte('{'); diff -uNr dmd-0.142/dmd/src/dmd/declaration.h dmd-0.143/dmd/src/dmd/declaration.h --- dmd-0.142/dmd/src/dmd/declaration.h 2005-12-23 01:05:26.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/declaration.h 2006-01-08 01:12:48.000000000 +0100 @@ -376,6 +376,7 @@ void semantic(Scope *sc); void semantic3(Scope *sc); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); + void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs); int overrides(FuncDeclaration *fd); int overloadInsert(Dsymbol *s); FuncDeclaration *overloadExactMatch(Type *t); @@ -430,6 +431,7 @@ FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, enum TOK tok, ForeachStatement *fes); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Dsymbol *syntaxCopy(Dsymbol *); int isNested(); @@ -444,6 +446,7 @@ CtorDeclaration(Loc loc, Loc endloc, Array *arguments, int varargs); Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); char *kind(); char *toChars(); int isVirtual(); @@ -459,6 +462,7 @@ DtorDeclaration(Loc loc, Loc endloc); Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); int addPreInvariant(); int addPostInvariant(); int overloadInsert(Dsymbol *s); @@ -478,6 +482,7 @@ int addPreInvariant(); int addPostInvariant(); void emitComment(Scope *sc); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); StaticCtorDeclaration *isStaticCtorDeclaration() { return this; } }; @@ -493,6 +498,7 @@ int addPreInvariant(); int addPostInvariant(); void emitComment(Scope *sc); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); StaticDtorDeclaration *isStaticDtorDeclaration() { return this; } }; @@ -533,6 +539,7 @@ NewDeclaration(Loc loc, Loc endloc, Array *arguments, int varargs); Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); char *kind(); int isVirtual(); int addPreInvariant(); @@ -548,6 +555,7 @@ DeleteDeclaration(Loc loc, Loc endloc, Array *arguments); Dsymbol *syntaxCopy(Dsymbol *); void semantic(Scope *sc); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); char *kind(); int isDelete(); int isVirtual(); diff -uNr dmd-0.142/dmd/src/dmd/doc.c dmd-0.143/dmd/src/dmd/doc.c --- dmd-0.142/dmd/src/dmd/doc.c 2005-12-12 00:07:30.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/doc.c 2006-01-08 01:02:08.000000000 +0100 @@ -36,6 +36,7 @@ #include "scope.h" #include "hdrgen.h" #include "doc.h" +#include "mtype.h" struct Section { @@ -649,15 +650,10 @@ void CtorDeclaration::toDocBuffer(OutBuffer *buf) { - TypeFunction *tf = (TypeFunction *)type; + HdrGenState hgs; buf->writestring("this"); - if (!tf) - { // Need to create one - tf = new TypeFunction(arguments, Type::tvoid, varargs, LINKd); - } - HdrGenState hgs; - tf->argsToCBuffer(buf, &hgs); + Argument::argsToCBuffer(buf, &hgs, arguments, varargs); buf->writestring(";\n"); } diff -uNr dmd-0.142/dmd/src/dmd/expression.c dmd-0.143/dmd/src/dmd/expression.c --- dmd-0.142/dmd/src/dmd/expression.c 2005-12-29 09:52:12.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/expression.c 2006-01-08 01:39:46.000000000 +0100 @@ -1419,7 +1419,7 @@ if (!s->isFuncDeclaration()) // functions are checked after overloading checkDeprecated(sc, s); s = s->toAlias(); - //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind()); + //printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis()); if (!s->isFuncDeclaration()) checkDeprecated(sc, s); @@ -1427,15 +1427,18 @@ thiscd = sc->func->parent->isClassDeclaration(); // BUG: This should happen after overload resolution for functions, not before - if (s->needThis() && hasThis(sc) /*&& !s->isFuncDeclaration()*/) + if (s->needThis()) { - // Supply an implicit 'this', as in - // this.ident + if (hasThis(sc) /*&& !s->isFuncDeclaration()*/) + { + // Supply an implicit 'this', as in + // this.ident - DotVarExp *de; + DotVarExp *de; - de = new DotVarExp(loc, new ThisExp(loc), s->isDeclaration()); - return de->semantic(sc); + de = new DotVarExp(loc, new ThisExp(loc), s->isDeclaration()); + return de->semantic(sc); + } } em = s->isEnumMember(); @@ -1785,6 +1788,7 @@ memset(&hgs, 0, sizeof(hgs)); toCBuffer(&buf, &hgs); + buf.writeByte(0); p = (char *)buf.data; buf.data = NULL; return p; @@ -2118,9 +2122,17 @@ s = ti->inst->toAlias(); sds2 = s->isScopeDsymbol(); if (!sds2) - { + { Expression *e; + //printf("s = %s, '%s'\n", s->kind(), s->toChars()); - Expression *e = new DsymbolExp(loc, s); + if (ti->withsym) + { + // Same as wthis.s + e = new VarExp(loc, ti->withsym->withstate->wthis); + e = new DotVarExp(loc, e, s->isDeclaration()); + } + else + e = new DsymbolExp(loc, s); e = e->semantic(sc); //printf("-1ScopeExp::semantic()\n"); return e; @@ -5757,6 +5769,7 @@ type = Type::tint32; e = this; } + e->type = e->type->semantic(loc, sc); return e; } return this; diff -uNr dmd-0.142/dmd/src/dmd/func.c dmd-0.143/dmd/src/dmd/func.c --- dmd-0.142/dmd/src/dmd/func.c 2005-12-28 01:08:34.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/func.c 2006-01-10 00:55:52.000000000 +0100 @@ -826,6 +826,12 @@ //printf("FuncDeclaration::toCBuffer() '%s'\n", toChars()); type->toCBuffer(buf, ident, hgs); + bodyToCBuffer(buf, hgs); +} + + +void FuncDeclaration::bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ if (fbody && (!hgs->hdrgen || hgs->tpltMember || canInline(1,1)) ) @@ -1470,6 +1476,20 @@ return (tok == TOKdelegate) ? (char*)"delegate" : (char*)"function"; } +void FuncLiteralDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + static Identifier *idfunc; + static Identifier *iddel; + + if (!idfunc) + idfunc = new Identifier("function", 0); + if (!iddel) + iddel = new Identifier("delegate", 0); + + type->toCBuffer(buf, ((tok == TOKdelegate) ? iddel : idfunc), hgs); + bodyToCBuffer(buf, hgs); +} + /********************************* CtorDeclaration ****************************/ @@ -1566,6 +1586,13 @@ } +void CtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + buf->writestring("this"); + Argument::argsToCBuffer(buf, hgs, arguments, varargs); + bodyToCBuffer(buf, hgs); +} + /********************************* DtorDeclaration ****************************/ DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc) @@ -1620,6 +1647,14 @@ return FALSE; } +void DtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + if (hgs->hdrgen) + return; + buf->writestring("~this()"); + bodyToCBuffer(buf, hgs); +} + /********************************* StaticCtorDeclaration ****************************/ StaticCtorDeclaration::StaticCtorDeclaration(Loc loc, Loc endloc) @@ -1678,6 +1713,14 @@ return FALSE; } +void StaticCtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + if (hgs->hdrgen) + return; + buf->writestring("static this()"); + bodyToCBuffer(buf, hgs); +} + /********************************* StaticDtorDeclaration ****************************/ StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc) @@ -1741,6 +1784,14 @@ return FALSE; } +void StaticDtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + if (hgs->hdrgen) + return; + buf->writestring("static ~this()"); + bodyToCBuffer(buf, hgs); +} + /********************************* InvariantDeclaration ****************************/ InvariantDeclaration::InvariantDeclaration(Loc loc, Loc endloc) @@ -1803,7 +1854,8 @@ { if (hgs->hdrgen) return; - FuncDeclaration::toCBuffer(buf, hgs); + buf->writestring("invariant"); + bodyToCBuffer(buf, hgs); } @@ -1883,7 +1935,8 @@ { if (hgs->hdrgen) return; - FuncDeclaration::toCBuffer(buf, hgs); + buf->writestring("unittest"); + bodyToCBuffer(buf, hgs); } /********************************* NewDeclaration ****************************/ @@ -1964,6 +2017,12 @@ return FALSE; } +void NewDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + buf->writestring("new"); + Argument::argsToCBuffer(buf, hgs, arguments, varargs); + bodyToCBuffer(buf, hgs); +} /********************************* DeleteDeclaration ****************************/ @@ -2046,6 +2105,13 @@ return FALSE; } +void DeleteDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + buf->writestring("delete"); + Argument::argsToCBuffer(buf, hgs, arguments, 0); + bodyToCBuffer(buf, hgs); +} + diff -uNr dmd-0.142/dmd/src/dmd/inline.c dmd-0.143/dmd/src/dmd/inline.c --- dmd-0.142/dmd/src/dmd/inline.c 2005-12-22 20:46:28.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/inline.c 2006-01-07 18:53:18.000000000 +0100 @@ -983,12 +983,21 @@ assert(0); } - assert(type->ty == Tfunction); - TypeFunction *tf = (TypeFunction *)(type); + if (type) + { assert(type->ty == Tfunction); + TypeFunction *tf = (TypeFunction *)(type); + if (tf->varargs == 1) // no variadic parameter lists + goto Lno; + } + else + { CtorDeclaration *ctor = isCtorDeclaration(); + + if (ctor && ctor->varargs == 1) + goto Lno; + } if ( !fbody || - tf->varargs == 1 || // no variadic parameter lists !hdrscan && ( #if 0 diff -uNr dmd-0.142/dmd/src/dmd/mars.c dmd-0.143/dmd/src/dmd/mars.c --- dmd-0.142/dmd/src/dmd/mars.c 2005-12-27 00:20:56.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/mars.c 2006-01-03 01:51:52.000000000 +0100 @@ -53,7 +53,7 @@ copyright = "Copyright (c) 1999-2005 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.142"; + version = "v0.143"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff -uNr dmd-0.142/dmd/src/dmd/mtype.c dmd-0.143/dmd/src/dmd/mtype.c --- dmd-0.142/dmd/src/dmd/mtype.c 2005-12-20 17:37:22.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/mtype.c 2006-01-10 00:58:08.000000000 +0100 @@ -2207,6 +2207,12 @@ int Type::covariant(Type *t) { +#if 0 + printf("Type::covariant(t = %s) %s\n", t->toChars(), toChars()); + printf("deco = %p, %p\n", deco, t->deco); + printf("ty = %d\n", next->ty); +#endif + int inoutmismatch = 0; if (equals(t)) @@ -2339,47 +2345,11 @@ buf->writestring(ident->toHChars2()); } } - argsToCBuffer(buf, hgs); + Argument::argsToCBuffer(buf, hgs, arguments, varargs); if (!ident || ident->toHChars2() == ident->toChars()) next->toCBuffer2(buf, NULL, hgs); } -void TypeFunction::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs) -{ - buf->writeByte('('); - if (arguments) - { int i; - OutBuffer argbuf; - - for (i = 0; i < arguments->dim; i++) - { Argument *arg; - - if (i) - buf->writestring(", "); - arg = (Argument *)arguments->data[i]; - if (arg->inout == Out) - buf->writestring("out "); - else if (arg->inout == InOut) - buf->writestring("inout "); - argbuf.reset(); - arg->type->toCBuffer2(&argbuf, arg->ident, hgs); - if (arg->defaultArg) - { - argbuf.writestring(" = "); - arg->defaultArg->toCBuffer(&argbuf, hgs); - } - buf->write(&argbuf); - } - if (varargs) - { - if (i && varargs == 1) - buf->writeByte(','); - buf->writestring("..."); - } - } - buf->writeByte(')'); -} - Type *TypeFunction::semantic(Loc loc, Scope *sc) { if (deco) // if semantic() already run @@ -2575,7 +2545,7 @@ OutBuffer args; TypeFunction *tf = (TypeFunction *)next; - tf->argsToCBuffer(&args, hgs); + Argument::argsToCBuffer(&args, hgs, tf->arguments, tf->varargs); buf->prependstring(args.toChars()); buf->prependstring(" delegate"); if (ident) @@ -2691,8 +2661,11 @@ Type *t; Expression *e; - //printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); - //printf("\tscopesym = '%s'\n", scopesym->toChars()); +#if 0 + printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); + if (scopesym) + printf("\tscopesym = '%s'\n", scopesym->toChars()); +#endif *pe = NULL; *pt = NULL; *ps = NULL; @@ -2835,6 +2808,11 @@ *ps = s; return; } + if (t->ty == Tinstance && t != this && !t->deco) + { error(loc, "forward reference to '%s'", t->toChars()); + return; + } + if (t->ty == Tident && t != this) { Scope *scx; @@ -4159,3 +4137,40 @@ return buf->toChars(); } +void Argument::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Array *arguments, int varargs) +{ + buf->writeByte('('); + if (arguments) + { int i; + OutBuffer argbuf; + + for (i = 0; i < arguments->dim; i++) + { Argument *arg; + + if (i) + buf->writestring(", "); + arg = (Argument *)arguments->data[i]; + if (arg->inout == Out) + buf->writestring("out "); + else if (arg->inout == InOut) + buf->writestring("inout "); + argbuf.reset(); + arg->type->toCBuffer2(&argbuf, arg->ident, hgs); + if (arg->defaultArg) + { + argbuf.writestring(" = "); + arg->defaultArg->toCBuffer(&argbuf, hgs); + } + buf->write(&argbuf); + } + if (varargs) + { + if (i && varargs == 1) + buf->writeByte(','); + buf->writestring("..."); + } + } + buf->writeByte(')'); +} + + diff -uNr dmd-0.142/dmd/src/dmd/mtype.h dmd-0.143/dmd/src/dmd/mtype.h --- dmd-0.142/dmd/src/dmd/mtype.h 2005-12-26 15:24:44.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/mtype.h 2006-01-08 00:58:58.000000000 +0100 @@ -390,7 +390,6 @@ Type *semantic(Loc loc, Scope *sc); void toDecoBuffer(OutBuffer *buf); void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); - void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs); MATCH deduceType(Type *tparam, Array *parameters, Array *atypes); TypeInfoDeclaration *getTypeInfoDeclaration(); @@ -604,6 +603,7 @@ Argument *syntaxCopy(); static Array *arraySyntaxCopy(Array *args); static char *argsTypesToChars(Array *args, int varargs); + static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Array *arguments, int varargs); }; extern int PTRSIZE; diff -uNr dmd-0.142/dmd/src/dmd/statement.c dmd-0.143/dmd/src/dmd/statement.c --- dmd-0.142/dmd/src/dmd/statement.c 2005-12-28 01:25:00.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/statement.c 2006-01-09 22:59:14.000000000 +0100 @@ -187,7 +187,9 @@ Statement *ExpStatement::semantic(Scope *sc) { if (exp) - exp = exp->semantic(sc); + { exp = exp->semantic(sc); + exp = resolveProperties(sc, exp); + } return this; } diff -uNr dmd-0.142/dmd/src/dmd/template.c dmd-0.143/dmd/src/dmd/template.c --- dmd-0.142/dmd/src/dmd/template.c 2005-12-28 01:55:26.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/template.c 2006-01-06 17:35:30.000000000 +0100 @@ -1263,6 +1263,7 @@ this->argsym = NULL; this->aliasdecl = NULL; this->semanticdone = 0; + this->withsym = NULL; } @@ -1627,6 +1628,8 @@ #if LOG printf("It's an instance of '%s'\n", s->toChars()); #endif + withsym = scopesym->isWithScopeSymbol(); + s = s->toAlias(); for (i = 1; i < idents.dim; i++) { Dsymbol *sm; diff -uNr dmd-0.142/dmd/src/dmd/template.h dmd-0.143/dmd/src/dmd/template.h --- dmd-0.142/dmd/src/dmd/template.h 2005-12-26 23:13:22.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/template.h 2006-01-05 19:27:16.000000000 +0100 @@ -183,6 +183,7 @@ ScopeDsymbol *argsym; // argument symbol table AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its // sole member + WithScopeSymbol *withsym; // if a member of a with statement int semanticdone; // has semantic() been done? int nest; // for recursion detection diff -uNr dmd-0.142/dmd/src/dmd/todt.c dmd-0.143/dmd/src/dmd/todt.c --- dmd-0.142/dmd/src/dmd/todt.c 2005-12-10 00:38:44.000000000 +0100 +++ dmd-0.143/dmd/src/dmd/todt.c 2006-01-03 02:06:32.000000000 +0100 @@ -785,7 +785,10 @@ for (i = 1; i < len; i++) { if (tbn->ty == Tstruct) - pdt = tnext->toDt(pdt); + { pdt = tnext->toDt(pdt); + while (*pdt) + pdt = &((*pdt)->DTnext); + } else pdt = e->toDt(pdt); } diff -uNr dmd-0.142/dmd/src/phobos/internal/arraycat.d dmd-0.143/dmd/src/phobos/internal/arraycat.d --- dmd-0.142/dmd/src/phobos/internal/arraycat.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/internal/arraycat.d 2006-01-11 00:36:00.000000000 +0100 @@ -96,7 +96,7 @@ if (to.length != from.length) { - throw new Error("lengths don't match for array copy"); + throw new Error(std.string.format("lengths don't match for array copy, %s = %s", to.length, from.length)); } else if (cast(byte *)to + to.length * size <= cast(byte *)from || cast(byte *)from + from.length * size <= cast(byte *)to) diff -uNr dmd-0.142/dmd/src/phobos/std/c/linux/linux.d dmd-0.143/dmd/src/phobos/std/c/linux/linux.d --- dmd-0.142/dmd/src/phobos/std/c/linux/linux.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/c/linux/linux.d 2006-01-11 00:36:00.000000000 +0100 @@ -1,5 +1,5 @@ -/* Written by Walter Bright and Christopher E. Miller +/* Written by Walter Bright, Christopher E. Miller, and many others. * www.digitalmars.com * Placed into public domain. */ @@ -12,6 +12,9 @@ alias int off_t; alias uint mode_t; +alias uint uid_t; +alias uint gid_t; + enum : int { SIGHUP = 1, @@ -345,3 +348,21 @@ char* dlerror(); } +extern (C) +{ + /* from + */ + + struct passwd + { + char *pw_name; + char *pw_passwd; + uid_t pw_uid; + gid_t pw_gid; + char *pw_gecos; + char *pw_dir; + char *pw_shell; + } + + int getpwnam_r(char*, passwd*, void*, size_t, passwd**); +} diff -uNr dmd-0.142/dmd/src/phobos/std/c/process.d dmd-0.143/dmd/src/phobos/std/c/process.d --- dmd-0.142/dmd/src/phobos/std/c/process.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/c/process.d 2006-01-11 00:36:00.000000000 +0100 @@ -18,16 +18,6 @@ int system(char *); -int spawnl(int, char *, char *,...); -int spawnle(int, char *, char *,...); -int spawnlp(int, char *, char *,...); -int spawnlpe(int, char *, char *,...); -int spawnv(int, char *, char **); -int spawnve(int, char *, char **, char **); -int spawnvp(int, char *, char **); -int spawnvpe(int, char *, char **, char **); - - enum { _P_WAIT, _P_NOWAIT, _P_OVERLAY }; int execl(char *, char *,...); @@ -45,33 +35,47 @@ int cwait(int *,int,int); int wait(int *); -uint _beginthread(void function(void *),uint,void *); +version (Windows) +{ + uint _beginthread(void function(void *),uint,void *); + + extern (Windows) alias uint (*stdfp)(void *); + + uint _beginthreadex(void* security, uint stack_size, + stdfp start_addr, void* arglist, uint initflag, + uint* thrdaddr); + + void _endthread(); + void _endthreadex(uint); + + int spawnl(int, char *, char *,...); + int spawnle(int, char *, char *,...); + int spawnlp(int, char *, char *,...); + int spawnlpe(int, char *, char *,...); + int spawnv(int, char *, char **); + int spawnve(int, char *, char **, char **); + int spawnvp(int, char *, char **); + int spawnvpe(int, char *, char **, char **); + + + int _wsystem(wchar_t *); + int _wspawnl(int, wchar_t *, wchar_t *, ...); + int _wspawnle(int, wchar_t *, wchar_t *, ...); + int _wspawnlp(int, wchar_t *, wchar_t *, ...); + int _wspawnlpe(int, wchar_t *, wchar_t *, ...); + int _wspawnv(int, wchar_t *, wchar_t **); + int _wspawnve(int, wchar_t *, wchar_t **, wchar_t **); + int _wspawnvp(int, wchar_t *, wchar_t **); + int _wspawnvpe(int, wchar_t *, wchar_t **, wchar_t **); + + int _wexecl(wchar_t *, wchar_t *, ...); + int _wexecle(wchar_t *, wchar_t *, ...); + int _wexeclp(wchar_t *, wchar_t *, ...); + int _wexeclpe(wchar_t *, wchar_t *, ...); + int _wexecv(wchar_t *, wchar_t **); + int _wexecve(wchar_t *, wchar_t **, wchar_t **); + int _wexecvp(wchar_t *, wchar_t **); + int _wexecvpe(wchar_t *, wchar_t **, wchar_t **); +} -extern (Windows) alias uint (*stdfp)(void *); -uint _beginthreadex(void* security, uint stack_size, - stdfp start_addr, void* arglist, uint initflag, - uint* thrdaddr); - -void _endthread(); -void _endthreadex(uint); - - -int _wsystem(wchar_t *); -int _wspawnl(int, wchar_t *, wchar_t *, ...); -int _wspawnle(int, wchar_t *, wchar_t *, ...); -int _wspawnlp(int, wchar_t *, wchar_t *, ...); -int _wspawnlpe(int, wchar_t *, wchar_t *, ...); -int _wspawnv(int, wchar_t *, wchar_t **); -int _wspawnve(int, wchar_t *, wchar_t **, wchar_t **); -int _wspawnvp(int, wchar_t *, wchar_t **); -int _wspawnvpe(int, wchar_t *, wchar_t **, wchar_t **); - -int _wexecl(wchar_t *, wchar_t *, ...); -int _wexecle(wchar_t *, wchar_t *, ...); -int _wexeclp(wchar_t *, wchar_t *, ...); -int _wexeclpe(wchar_t *, wchar_t *, ...); -int _wexecv(wchar_t *, wchar_t **); -int _wexecve(wchar_t *, wchar_t **, wchar_t **); -int _wexecvp(wchar_t *, wchar_t **); -int _wexecvpe(wchar_t *, wchar_t **, wchar_t **); diff -uNr dmd-0.142/dmd/src/phobos/std/c/stdlib.d dmd-0.143/dmd/src/phobos/std/c/stdlib.d --- dmd-0.142/dmd/src/phobos/std/c/stdlib.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/c/stdlib.d 2006-01-11 00:36:00.000000000 +0100 @@ -40,6 +40,8 @@ int (*compare)(void *elem1, void *elem2)); char* getenv(char*); + int setenv(char*, char*, int); + void unsetenv(char*); int rand(); void srand(uint); diff -uNr dmd-0.142/dmd/src/phobos/std/math2.d dmd-0.143/dmd/src/phobos/std/math2.d --- dmd-0.142/dmd/src/phobos/std/math2.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/math2.d 2006-01-11 00:36:00.000000000 +0100 @@ -641,6 +641,7 @@ * Hyperbolic arccosine */ +/+ real acosh(real x) { if (x <= 1) @@ -656,11 +657,13 @@ assert(acosh(0.5) == 0); assert(feq(acosh(cosh(3)), 3)); } ++/ /************************************* * Hyperbolic arcsine */ +/+ real asinh(real x) { if (!x) @@ -683,11 +686,12 @@ assert(asinh(0) == 0); assert(feq(asinh(sinh(3)), 3)); } ++/ /************************************* * Hyperbolic arctangent */ - +/+ real atanh(real x) { if (!x) @@ -710,6 +714,7 @@ assert(atanh(0) == 0); assert(feq(atanh(tanh(0.5)), 0.5)); } ++/ /************************************* * Hyperbolic arccotangent diff -uNr dmd-0.142/dmd/src/phobos/std/math.d dmd-0.143/dmd/src/phobos/std/math.d --- dmd-0.142/dmd/src/phobos/std/math.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/math.d 2006-01-11 00:36:00.000000000 +0100 @@ -7,11 +7,17 @@ * TABLE_SV = * * $0
Special Values
+ * SVH = $(TR $(TH $1) $(TH $2)) + * SV = $(TR $(TD $1) $(TD $2)) * * NAN = $(RED NAN) * SUP = $0 * GAMMA = Γ * INTEGRAL = ∫ + * INTEGRATE = $(BIG ∫$(SMALL $1)$2) + * POWER = $1$2 + * BIGSUM = $(BIG Σ $2$(SMALL $1)) + * CHOOSE = $(BIG () $(SMALL $1)$(SMALL $2) $(BIG )) */ /* @@ -95,6 +101,80 @@ /*********************************** + * Calculates the absolute value + * + * For complex numbers, abs(z) = sqrt( $(POWER z.re, 2) + $(POWER z.im, 2) ) + * = hypot(z.re, z.im). + */ +real abs(real x) +{ + return fabs(x); +} + +/** ditto */ +long abs(long x) +{ + return x>=0 ? x : -x; +} + +/** ditto */ +int abs(int x) +{ + return x>=0 ? x : -x; +} + +/** ditto */ +real abs(creal z) +{ + return hypot(z.re, z.im); +} + +/** ditto */ +real abs(ireal y) +{ + return fabs(y.im); +} + + +unittest +{ + assert(isPosZero(abs(-0.0L))); + assert(isnan(abs(real.nan))); + assert(abs(-real.infinity) == real.infinity); + assert(abs(-3.2Li) == 3.2L); + assert(abs(71.6Li) == 71.6L); + assert(abs(-56) == 56); + assert(abs(2321312L) == 2321312L); + assert(abs(-1+1i) == sqrt(2.0)); +} + +/*********************************** + * Complex conjugate + * + * conj(x + iy) = x - iy + * + * Note that z * conj(z) = $(POWER z.re, 2) - $(POWER z.im, 2) + * is always a real number + */ +creal conj(creal z) +{ + return z.re - z.im*1i; +} + +/** ditto */ +ireal conj(ireal y) +{ + return -y; +} + +unittest +{ + assert(conj(7 + 3i) == 7-3i); + ireal z = -3.2Li; + assert(conj(z) == -z); +} + +/*********************************** * Returns cosine of x. x is in radians. * * $(TABLE_SV @@ -102,6 +182,8 @@ * $(TR $(TD $(NAN)) $(TD $(NAN)) $(TD yes) ) * $(TR $(TD ±∞) $(TD $(NAN)) $(TD yes) ) * ) + * Bugs: + * Results are undefined if |x| >= $(POWER 2,64). */ real cos(real x); /* intrinsic */ @@ -115,6 +197,8 @@ * ±0.0 ±0.0 no * ±∞ $(NAN) yes * ) + * Bugs: + * Results are undefined if |x| >= $(POWER 2,64). */ real sin(real x); /* intrinsic */ @@ -317,6 +401,105 @@ //real asinh(real x) { return std.c.math.asinhl(x); } //real atanh(real x) { return std.c.math.atanhl(x); } +/*********************************** + * Calculates the inverse hyperbolic cosine of x. + * + * Mathematically, acosh(x) = log(x + sqrt( x*x - 1)) + * + * $(TABLE_DOMRG + * $(DOMAIN 1..∞) + * $(RANGE 1..log(real.max), ∞) ) + * $(TABLE_SV + * $(SVH x, acosh(x) ) + * $(SV $(NAN), $(NAN) ) + * $(SV <1, $(NAN) ) + * $(SV 1, 0 ) + * $(SV +∞,+∞) + * ) + */ +real acosh(real x) +{ + if (x > 1/real.epsilon) + return LN2 + log(x); + else + return log(x + sqrt(x*x - 1)); +} + +unittest +{ + assert(isnan(acosh(0.9))); + assert(isnan(acosh(real.nan))); + assert(acosh(1)==0.0); + assert(acosh(real.infinity) == real.infinity); +} + +/*********************************** + * Calculates the inverse hyperbolic sine of x. + * + * Mathematically, + * --------------- + * asinh(x) = log( x + sqrt( x*x + 1 )) // if x >= +0 + * asinh(x) = -log(-x + sqrt( x*x + 1 )) // if x <= -0 + * ------------- + * + * $(TABLE_SV + * $(SVH x, asinh(x) ) + * $(SV $(NAN), $(NAN) ) + * $(SV ±0, ±0 ) + * $(SV ±∞,±∞) + * ) + */ +real asinh(real x) +{ + if (fabs(x) > 1 / real.epsilon) // beyond this point, x*x + 1 == x*x + return copysign(LN2 + log(fabs(x)), x); + else + { + // sqrt(x*x + 1) == 1 + x * x / ( 1 + sqrt(x*x + 1) ) + return copysign(log1p(fabs(x) + x*x / (1 + sqrt(x*x + 1)) ), x); + } +} + +unittest +{ + assert(isPosZero(asinh(0.0))); + assert(isNegZero(asinh(-0.0))); + assert(asinh(real.infinity) == real.infinity); + assert(asinh(-real.infinity) == -real.infinity); + assert(isnan(asinh(real.nan))); +} + +/*********************************** + * Calculates the inverse hyperbolic tangent of x, + * returning a value from ranging from -1 to 1. + * + * Mathematically, atanh(x) = log( (1+x)/(1-x) ) / 2 + * + * + * $(TABLE_DOMRG + * $(DOMAIN -∞..∞) + * $(RANGE -1..1) ) + * $(TABLE_SV + * $(SVH x, acosh(x) ) + * $(SV $(NAN), $(NAN) ) + * $(SV ±0, ±0) + * $(SV -∞, -0) + * ) + */ +real atanh(real x) +{ + // log( (1+x)/(1-x) ) == log ( 1 + (2*x)/(1-x) ) + return 0.5 * log1p( 2 * x / (1 - x) ); +} + +unittest +{ + assert(isPosZero(atanh(0.0))); + assert(isNegZero(atanh(-0.0))); + assert(isnan(atanh(real.nan))); + assert(isNegZero(atanh(-real.infinity))); +} + /***************************************** * Returns x rounded to a long value using the current rounding mode. * If the integer value of x is @@ -628,9 +811,9 @@ * If x is subnormal, it is treated as if it were normalized. * For a positive, finite x: * - *
- * 1 <= x * FLT_RADIX$(SUP -logb(x)) < FLT_RADIX 
- * 
+ * ----- + * 1 <= $(I x) * FLT_RADIX$(SUP -logb(x)) < FLT_RADIX + * ----- * * $(TABLE_SV * x logb(x) Divide by 0? @@ -841,14 +1024,13 @@ * Returns the base e (2.718...) logarithm of the absolute * value of the gamma function of the argument. * - * For reals, lgamma is equivalent to log(fabs(tgamma(x))). + * For reals, lgamma is equivalent to log(fabs(gamma(x))). * * $(TABLE_SV - * x log$(GAMMA)(x) invalid? - * NaN NaN yes + * x lgamma(x) invalid? + * $(NAN) $(NAN) yes * integer <= 0 +∞ yes - * 1, 2 +0.0 no - * ±∞ +∞ no + * ±∞ +∞ no * ) */ /* Documentation prepared by Don Clugston */ @@ -860,26 +1042,28 @@ } /*********************************** - * The gamma function, $(GAMMA)(x) + * The Gamma function, $(GAMMA)(x) * - * Generalizes the factorial function to real and complex numbers. + * $(GAMMA)(x) is a generalisation of the factorial function + * to real and complex numbers. * Like x!, $(GAMMA)(x+1) = x*$(GAMMA)(x). * * Mathematically, if z.re > 0 then * $(GAMMA)(z) =$(INTEGRAL)0tz-1e-tdt * * $(TABLE_SV - * x $(GAMMA)(x) invalid? - * NAN NAN yes - * ±0.0 ±∞ yes - * integer > 0 (x-1)! no - * integer < 0 NAN yes - * +∞ +∞ no - * -∞ NAN yes + * x $(GAMMA)(x) invalid? + * $(NAN) $(NAN) yes + * ±0.0 ±∞ yes + * integer > 0 (x-1)! no + * integer < 0 $(NAN) yes + * +∞ +∞ no + * -∞ $(NAN) yes * ) * * References: - * cephes, $(LINK http://en.wikipedia.org/wiki/Gamma_function) + * $(LINK http://en.wikipedia.org/wiki/Gamma_function), + * $(LINK http://www.netlib.org/cephes/ldoubdoc.html#gamma) */ /* Documentation prepared by Don Clugston */ real tgamma(real x) @@ -956,7 +1140,7 @@ /**************************************************** * Returns the integer portion of x, dropping the fractional portion. * - * This is also know as "chop" rounding. + * This is also known as "chop" rounding. */ real trunc(real x) { return std.c.math.truncl(x); } @@ -1492,11 +1676,17 @@ return fabs(x - y) <= precision; } -private int iabs(int i) +// Returns true if x is +0.0 (This function is used in unit tests) +bit isPosZero(real x) +{ + return (x == 0) && (signbit(x) == 0); +} + +// Returns true if x is -0.0 (This function is used in unit tests) +bit isNegZero(real x) { - return i >= 0 ? i : -i; + return (x == 0) && signbit(x); } - /************************************** * To what precision is x equal to y? diff -uNr dmd-0.142/dmd/src/phobos/std/path.d dmd-0.143/dmd/src/phobos/std/path.d --- dmd-0.142/dmd/src/phobos/std/path.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/path.d 2006-01-11 00:36:00.000000000 +0100 @@ -13,9 +13,17 @@ module std.path; //debug=path; // uncomment to turn on debugging printf's +//private import std.stdio; private import std.string; +version(linux) +{ + private import std.c.stdlib; + private import std.c.linux.linux; + private import std.outofmemory; +} + version(Win32) { @@ -106,6 +114,46 @@ } /************************** + * Get name without extension. + * For example, "d:\path\foo.bat" returns "d:\path\foo". + */ + +char[] getName(char[] fullname) +{ + uint i; + + i = fullname.length; + while (i > 0) + { + if (fullname[i - 1] == '.') + return fullname[0 .. i - 1]; + i--; + version(Win32) + { + if (fullname[i] == ':' || fullname[i] == '\\') + break; + } + version(linux) + { + if (fullname[i] == '/') + break; + } + } + return null; +} + +unittest +{ + debug(path) printf("path.getName.unittest\n"); + int i; + char[] result; + + result = getName("foo.bar"); + i = cmp(result, "foo"); + assert(i == 0); +} + +/************************** * Get base name. * For example, "d:\path\foo.bat" returns "foo.bat". */ @@ -598,3 +646,248 @@ assert(!fnmatch("foo.bar", "[!fg]*bar")); assert(!fnmatch("foo.bar", "[fg]???baz")); } + +/** + * Performs tilde expansion in paths. + * + * There are two ways of using tilde expansion in a path. One + * involves using the tilde alone or followed by a path separator. In + * this case, the tilde will be expanded with the value of the + * environment variable HOME. The second way is putting + * a username after the tilde (i.e. ~john/Mail). Here, + * the username will be searched for in the user database + * (i.e. /etc/passwd on Unix systems) and will expand to + * whatever path is stored there. The username is considered the + * string after the tilde ending at the first instance of a path + * separator. + * + * Note that using the ~user syntax may give different + * values from just ~ if the environment variable doesn't + * match the value stored in the user database. + * + * When the environment variable version is used, the path won't + * be modified if the environment variable doesn't exist. When the + * database version is used, the path won't be modified if the user + * doesn't exist in the database or there is not enough memory to + * perform the query. + * + * Returns: inputPath with the tilde expanded, or just inputPath + * if it could not be expanded. + * For Windows, expandTilde() merely returns its argument inputPath. + * + * Throws: std.OutOfMemory + * + * Examples: + * ----- + * import std.path; + * + * void process_file(char[] filename) + * { + * char[] path = expandTilde(filename); + * ... + * } + * ----- + * + * ----- + * import std.path; + * + * const char[] RESOURCE_DIR_TEMPLATE = "~/.applicationrc"; + * char[] RESOURCE_DIR; // This gets expanded in main(). + * + * int main(char[][] args) + * { + * RESOURCE_DIR = expandTilde(RESOURCE_DIR_TEMPLATE); + * ... + * } + * ----- + * Version: Available since v0.143. + * Authors: Grzegorz Adam Hankiewicz, Thomas Kuehne. + */ + +char[] expandTilde(char[] inputPath) +{ + version(linux) + { + static assert(sep.length == 1); + + // Return early if there is no tilde in path. + if (inputPath.length < 1 || inputPath[0] != '~') + return inputPath; + + if (inputPath.length == 1 || inputPath[1] == sep[0]) + return expandFromEnvironment(inputPath); + else + return expandFromDatabase(inputPath); + } + else version(Windows) + { + // Put here real windows implementation. + return inputPath; + } + else + { + static assert(0); // Guard. Implement on other platforms. + } +} + + +unittest +{ + debug(path) printf("path.expandTilde.unittest\n"); + + version (linux) + { + // Retrieve the current home variable. + char* c_home = getenv("HOME"); + + // Testing when there is no environment variable. + unsetenv("HOME"); + assert(expandTilde("~/") == "~/"); + assert(expandTilde("~") == "~"); + + // Testing when an environment variable is set. + int ret = setenv("HOME", "dmd/test\0", 1); + assert(ret == 0); + assert(expandTilde("~/") == "dmd/test/"); + assert(expandTilde("~") == "dmd/test"); + + // The same, but with a variable ending in a slash. + ret = setenv("HOME", "dmd/test/\0", 1); + assert(ret == 0); + assert(expandTilde("~/") == "dmd/test/"); + assert(expandTilde("~") == "dmd/test"); + + // Recover original HOME variable before continuing. + if (c_home) + setenv("HOME", c_home, 1); + else + unsetenv("HOME"); + + // Test user expansion for root. Are there unices without /root? + assert(expandTilde("~root") == "/root"); + assert(expandTilde("~root/") == "/root/"); + assert(expandTilde("~Idontexist/hey") == "~Idontexist/hey"); + } +} + +version (linux) +{ + +/** + * Replaces the tilde from path with the environment variable HOME. + */ +private char[] expandFromEnvironment(char[] path) +{ + assert(path.length >= 1); + assert(path[0] == '~'); + + // Get HOME and use that to replace the tilde. + char* home = getenv("HOME"); + if (home == null) + return path; + + return combineCPathWithDPath(home, path, 1); +} + + +/** + * Joins a path from a C string to the remainder of path. + * + * The last path separator from c_path is discarded. The result + * is joined to path[char_pos .. length] if char_pos is smaller + * than length, otherwise path is not appended to c_path. + */ +private char[] combineCPathWithDPath(char* c_path, char[] path, int char_pos) +{ + assert(c_path != null); + assert(path.length > 0); + assert(char_pos >= 0); + + // Search end of C string + size_t end = std.string.strlen(c_path); + + // Remove trailing path separator, if any + if (end && c_path[end - 1] == sep[0]) + end--; + + // Create our own copy, as lifetime of c_path is undocumented + char[] cp = c_path[0 .. end].dup; + + // Do we append something from path? + if (char_pos < path.length) + cp ~= path[char_pos .. length]; + + return cp; +} + + +/** + * Replaces the tilde from path with the path from the user database. + */ +private char[] expandFromDatabase(char[] path) +{ + assert(path.length > 2 || (path.length == 2 && path[1] != sep[0])); + assert(path[0] == '~'); + + // Extract username, searching for path separator. + char[] username; + int last_char = find(path, sep[0]); + + if (last_char == -1) + { + username = path[1 .. length] ~ '\0'; + last_char = username.length + 1; + } + else + { + username = path[1 .. last_char] ~ '\0'; + } + assert(last_char > 1); + + // Reserve C memory for the getpwnam_r() function. + passwd result; + int extra_memory_size = 5 * 1024; + void* extra_memory; + + while (1) + { + extra_memory = std.c.stdlib.malloc(extra_memory_size); + if (extra_memory == null) + goto Lerror; + + // Obtain info from database. + passwd *verify; + std.c.stdlib.setErrno(0); + if (getpwnam_r(username, &result, extra_memory, extra_memory_size, + &verify) == 0) + { + // Failure if verify doesn't point at result. + if (verify != &result) + // username is not found, so return path[] + goto Lnotfound; + break; + } + + if (std.c.stdlib.getErrno() != ERANGE) + goto Lerror; + + // extra_memory isn't large enough + std.c.stdlib.free(extra_memory); + extra_memory_size *= 2; + } + + path = combineCPathWithDPath(result.pw_dir, path, last_char); + +Lnotfound: + std.c.stdlib.free(extra_memory); + return path; + +Lerror: + // Errors are going to be caused by running out of memory + if (extra_memory) + std.c.stdlib.free(extra_memory); + _d_OutOfMemory(); + return null; +} + +} diff -uNr dmd-0.142/dmd/src/phobos/std/process.d dmd-0.143/dmd/src/phobos/std/process.d --- dmd-0.142/dmd/src/phobos/std/process.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/process.d 2006-01-11 00:36:00.000000000 +0100 @@ -49,13 +49,16 @@ /* ========================================================== */ -int spawnvp(int mode, char[] pathname, char[][] argv) +version (Windows) { - char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); + int spawnvp(int mode, char[] pathname, char[][] argv) + { + char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); - toAStringz(argv, argv_); + toAStringz(argv, argv_); - return std.c.process.spawnvp(mode, toStringz(pathname), argv_); + return std.c.process.spawnvp(mode, toStringz(pathname), argv_); + } } /* ========================================================== */ diff -uNr dmd-0.142/dmd/src/phobos/std/uri.d dmd-0.143/dmd/src/phobos/std/uri.d --- dmd-0.142/dmd/src/phobos/std/uri.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/uri.d 2006-01-11 00:36:00.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com + * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com * Written by Walter Bright * * This software is provided 'as-is', without any express or implied @@ -25,8 +25,9 @@ * Encode and decode Uniform Resource Identifiers (URIs). * URIs are used in internet transfer protocols. * Valid URI characters consist of letters, digits, - * and the characters ;/?:@&=+$,-_.!~*'(). Escape sequences consist of '%' - * followed by two hex digits. + * and the characters $(B ;/?:@&=+$,-_.!~*'()) + * Reserved URI characters are $(B ;/?:@&=+$,) + * Escape sequences consist of $(B %) followed by two hex digits. * * See_Also: * $(LINK2 http://www.ietf.org/rfc/rfc3986.txt, RFC 3986)
@@ -42,6 +43,7 @@ private import std.ctype; private import std.c.stdlib; private import std.utf; +private import std.stdio; class URIerror : Error { @@ -116,9 +118,13 @@ { char* R2; Rsize *= 2; - R2 = cast(char *)alloca(Rsize * char.sizeof); - if (!R2) - goto LthrowURIerror; + if (Rsize > 1024) + R2 = new char[Rsize]; + else + { R2 = cast(char *)alloca(Rsize * char.sizeof); + if (!R2) + goto LthrowURIerror; + } R2[0..Rlen] = R[0..Rlen]; R = R2; } @@ -187,9 +193,13 @@ { char *R2; Rsize = 2 * (Rlen + L * 3); - R2 = cast(char *)alloca(Rsize * char.sizeof); - if (!R2) - goto LthrowURIerror; + if (Rsize > 1024) + R2 = new char[Rsize]; + else + { R2 = cast(char *)alloca(Rsize * char.sizeof); + if (!R2) + goto LthrowURIerror; + } R2[0..Rlen] = R[0..Rlen]; R = R2; } @@ -241,9 +251,13 @@ // Preallocate result buffer R guaranteed to be large enough for result Rsize = len; - R = cast(dchar *)alloca(Rsize * dchar.sizeof); - if (!R) - goto LthrowURIerror; + if (Rsize > 1024 / dchar.sizeof) + R = new dchar[Rsize]; + else + { R = cast(dchar *)alloca(Rsize * dchar.sizeof); + if (!R) + goto LthrowURIerror; + } Rlen = 0; for (k = 0; k != len; k++) @@ -332,9 +346,9 @@ } /************************************* - * Decodes the URI string encodedURI into a UTF-8 string and returns it. Escape - * sequences that resolve to valid URI characters are not replaced. Escape - * sequences that resolve to the '#' character are not replaced. + * Decodes the URI string encodedURI into a UTF-8 string and returns it. + * Escape sequences that resolve to reserved URI characters are not replaced. + * Escape sequences that resolve to the '#' character are not replaced. */ char[] decode(char[] encodedURI) @@ -393,10 +407,10 @@ char[] r; r = encode(s); - //printf("r = '%.*s'\n", r); + debug(uri) printf("r = '%.*s'\n", r); assert(r == t); r = decode(t); - //printf("r = '%.*s'\n", r); + debug(uri) printf("r = '%.*s'\n", r); assert(r == s); r = encode( decode("%E3%81%82%E3%81%82") ); @@ -405,4 +419,13 @@ r = encodeComponent("c++"); //printf("r = '%.*s'\n", r); assert(r == "c%2B%2B"); + + char[] str = new char[10_000_000]; + str[] = 'A'; + r = encodeComponent(str); + foreach (char c; r) + assert(c == 'A'); + + r = decode("%41%42%43"); + debug(uri) writefln(r); } diff -uNr dmd-0.142/dmd/src/phobos/std/windows/syserror.d dmd-0.143/dmd/src/phobos/std/windows/syserror.d --- dmd-0.142/dmd/src/phobos/std/windows/syserror.d 2005-12-29 11:07:14.000000000 +0100 +++ dmd-0.143/dmd/src/phobos/std/windows/syserror.d 2006-01-11 00:36:00.000000000 +0100 @@ -5,6 +5,7 @@ module std.windows.syserror; +private import std.windows.charset; private import std.c.windows.windows; char[] sysErrorString(uint errcode) @@ -27,7 +28,16 @@ /* Remove \r\n from error string */ if (r >= 2) r -= 2; - result = buffer[0..r].dup; + + /* Create 0 terminated copy on GC heap because fromMBSz() + * may return it. + */ + result = new char[r + 1]; + result[0 .. r] = buffer[0 .. r]; + result[r] = 0; + + result = std.windows.charset.fromMBSz(result.ptr); + LocalFree(cast(HLOCAL)buffer); return result; }