diff -uNrp dmd-1.007/src/dmd/aggregate.h gdc-0.23/d/dmd/aggregate.h --- dmd-1.007/src/dmd/aggregate.h 2007-01-26 15:53:22.000000000 +0100 +++ gdc-0.23/d/dmd/aggregate.h 2007-02-18 17:24:46.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #ifndef DMD_AGGREGATE_H #define DMD_AGGREGATE_H @@ -40,9 +46,9 @@ struct AggregateDeclaration : ScopeDsymb unsigned storage_class; enum PROT protection; Type *handle; // 'this' type - unsigned structsize; // size of struct - unsigned alignsize; // size of struct for alignment purposes - unsigned structalign; // struct member alignment in effect + target_size_t structsize; // size of struct + target_size_t alignsize; // size of struct for alignment purposes + target_size_t structalign; // struct member alignment in effect Array fields; // VarDeclaration fields unsigned sizeok; // set when structsize contains valid data // 0: no size @@ -56,6 +62,7 @@ struct AggregateDeclaration : ScopeDsymb NewDeclaration *aggNew; // allocator DeleteDeclaration *aggDelete; // deallocator + Expressions * attributes; // GCC decl/type attributes #ifdef IN_GCC Array methods; // flat list of all methods for debug information #endif @@ -64,8 +71,8 @@ struct AggregateDeclaration : ScopeDsymb void semantic2(Scope *sc); void semantic3(Scope *sc); void inlineScan(); - unsigned size(Loc loc); - static void alignmember(unsigned salign, unsigned size, unsigned *poffset); + target_size_t size(Loc loc); + static void alignmember(target_size_t salign, target_size_t size, target_size_t *poffset); Type *getType(); void addField(Scope *sc, VarDeclaration *v); int isDeprecated(); // is aggregate deprecated? @@ -135,7 +142,7 @@ struct BaseClass enum PROT protection; // protection for the base interface ClassDeclaration *base; - int offset; // 'this' pointer offset + target_ptrdiff_t offset; // 'this' pointer offset Array vtbl; // for interfaces: Array of FuncDeclaration's // making up the vtbl[] @@ -150,7 +157,7 @@ struct BaseClass void copyBaseInterfaces(BaseClasses *); }; -#define CLASSINFO_SIZE (0x3C+8) // value of ClassInfo.size +extern int CLASSINFO_SIZE; // value of ClassInfo.size struct ClassDeclaration : AggregateDeclaration { @@ -190,7 +197,7 @@ struct ClassDeclaration : AggregateDecla int isBaseOf2(ClassDeclaration *cd); #define OFFSET_RUNTIME 0x76543210 - virtual int isBaseOf(ClassDeclaration *cd, int *poffset); + virtual int isBaseOf(ClassDeclaration *cd, target_ptrdiff_t *poffset); Dsymbol *search(Loc, Identifier *ident, int flags); FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); @@ -226,8 +233,8 @@ struct InterfaceDeclaration : ClassDecla InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); Dsymbol *syntaxCopy(Dsymbol *s); void semantic(Scope *sc); - int isBaseOf(ClassDeclaration *cd, int *poffset); - int isBaseOf(BaseClass *bc, int *poffset); + int isBaseOf(ClassDeclaration *cd, target_ptrdiff_t *poffset); + int isBaseOf(BaseClass *bc, target_ptrdiff_t *poffset); char *kind(); int vtblOffset(); diff -uNrp dmd-1.007/src/dmd/attrib.c gdc-0.23/d/dmd/attrib.c --- dmd-1.007/src/dmd/attrib.c 2007-02-16 01:47:36.000000000 +0100 +++ gdc-0.23/d/dmd/attrib.c 2007-03-04 14:27:19.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include #include @@ -746,6 +752,7 @@ Dsymbol *PragmaDeclaration::syntaxCopy(D void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement + Scope sc_save; //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); if (ident == Id::msg) @@ -823,13 +830,133 @@ void PragmaDeclaration::semantic(Scope * if (e->op == TOKstring && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else - error("second argument of GNU_asm must be a char string"); + error("second argument of GNU_asm must be a character string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } + else if (ident == Id::GNU_attribute) + { + sc_save = *sc; + + // An empty list is allowed. + if (args && args->dim) + { + Expressions * a; + + if (sc->attributes) + a = (Expressions *) sc->attributes->copy(); + else + a = new Expressions; + sc->attributes = a; + + for (unsigned i = 0; i < args->dim; i++) + { + Expression * e = (Expression *) args->data[i]; + //e = e->semantic(sc); + + if (e->op == TOKidentifier) { + /* ok */ + } else if (e->op == TOKcall) { + CallExp * c = (CallExp *) e; + if (c->e1->op != TOKidentifier) + error("identifier or call expression expected for attribute"); + if (c->arguments) + for (int unsigned ai = 0; ai < c->arguments->dim; ai++) + { + c->arguments->data[ai] = + ((Expression *) c->arguments->data[ai])->semantic(sc); + } + } + else + { + error("identifier or call expression expected for attribute"); + continue; + } + a->push(e); + } + } + } + else if (ident == Id::GNU_set_attribute) + { + if (!args || args->dim < 1) + error("declaration expected for setting attributes"); + else + { + Array p_attributes_list; // of Expressions** + { + Expression * e = (Expression *) args->data[0]; + Expressions ** pa = NULL; + + e = e->semantic(sc); + if (e->op == TOKvar) + { + Declaration * d = ((VarExp *)e)->var; + if (d->isFuncDeclaration() || d->isVarDeclaration()) + pa = & d->attributes; + } + else if (e->op == TOKtype) + { + Type * t = ((TypeExp *)e)->type; + if (t->ty == Ttypedef) + pa = & ((TypeTypedef *) t)->sym->attributes; + else if (t->ty == Tenum) + pa = & ((TypeEnum *) t)->sym->attributes; + else if (t->ty == Tstruct) + pa = & ((TypeStruct *) t)->sym->attributes; + else if (t->ty == Tclass) + pa = & ((TypeClass *) t)->sym->attributes; + } + + if (pa) + p_attributes_list.push(pa); + else + error("first argument must be a function, variable, or type declaration"); + } + + Expressions * new_attrs = new Expressions; + for (unsigned i = 1; i < args->dim; i++) + { + Expression * e = (Expression *) args->data[i]; + //e = e->semantic(sc); + + if (e->op == TOKidentifier) { + /* ok */ + } else if (e->op == TOKcall) { + CallExp * c = (CallExp *) e; + if (c->e1->op != TOKidentifier) + error("identifier or call expression expected for attribute"); + if (c->arguments) + for (int unsigned ai = 0; ai < c->arguments->dim; ai++) + { + c->arguments->data[ai] = + ((Expression *) c->arguments->data[ai])->semantic(sc); + } + } + else + { + error("identifier or call expression expected for attribute"); + continue; + } + new_attrs->push(e); + } + + for (unsigned i = 0; i < p_attributes_list.dim; ++i) + { + Expressions ** pa = (Expressions **) p_attributes_list.data[i]; + if (*pa) + { + *pa = (Expressions *) (*pa)->copy(); + (*pa)->append(new_attrs); + } + else + *pa = new_attrs; + } + } + goto Lnodecl; + } #endif else error("unrecognized pragma(%s)", ident->toChars()); @@ -843,6 +970,12 @@ void PragmaDeclaration::semantic(Scope * s->semantic(sc); } } + +#if IN_GCC + if (decl) + if (ident == Id::GNU_attribute) + *sc = sc_save; +#endif return; Lnodecl: diff -uNrp dmd-1.007/src/dmd/cast.c gdc-0.23/d/dmd/cast.c --- dmd-1.007/src/dmd/cast.c 2007-02-04 16:35:38.000000000 +0100 +++ gdc-0.23/d/dmd/cast.c 2007-02-18 16:24:29.000000000 +0100 @@ -984,7 +984,7 @@ Expression *DelegateExp::castTo(Scope *s { f = func->overloadExactMatch(tb->next); if (f) - { int offset; + { target_ptrdiff_t offset; if (f->tintro && f->tintro->next->isBaseOf(f->type->next, &offset) && offset) error("%s", msg); e = new DelegateExp(loc, e1, f); @@ -998,7 +998,7 @@ Expression *DelegateExp::castTo(Scope *s e = Expression::castTo(sc, t); } else - { int offset; + { target_ptrdiff_t offset; if (func->tintro && func->tintro->next->isBaseOf(func->type->next, &offset) && offset) error("%s", msg); @@ -1207,7 +1207,7 @@ Expression *BinExp::typeCombine(Scope *s else if (t1n->ty == Tclass && t2n->ty == Tclass) { ClassDeclaration *cd1 = t1n->isClassHandle(); ClassDeclaration *cd2 = t2n->isClassHandle(); - int offset; + target_ptrdiff_t offset; if (cd1->isBaseOf(cd2, &offset)) { diff -uNrp dmd-1.007/src/dmd/class.c gdc-0.23/d/dmd/class.c --- dmd-1.007/src/dmd/class.c 2006-12-31 22:23:20.000000000 +0100 +++ gdc-0.23/d/dmd/class.c 2007-02-18 16:25:35.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include #include @@ -203,7 +209,6 @@ Dsymbol *ClassDeclaration::syntaxCopy(Ds void ClassDeclaration::semantic(Scope *sc) { int i; - unsigned offset; //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); //printf("\tparent = %p, '%s'\n", sc->parent, sc->parent ? sc->parent->toChars() : ""); @@ -244,6 +249,10 @@ void ClassDeclaration::semantic(Scope *s scx = scope; // save so we don't make redundant copies scope = NULL; } + if (attributes) + attributes->append(sc->attributes); + else + attributes = sc->attributes; #ifdef IN_GCC methods.setDim(0); #endif @@ -481,6 +490,7 @@ void ClassDeclaration::semantic(Scope *s sc = sc->push(this); sc->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated); + sc->attributes = NULL; sc->parent = this; sc->inunion = 0; @@ -497,8 +507,8 @@ void ClassDeclaration::semantic(Scope *s // sc->offset += PTRSIZE; // room for uplevel context pointer } else - { sc->offset = 8; // allow room for vptr[] and monitor - alignsize = 4; + { sc->offset = PTRSIZE * 2; // allow room for vptr[] and monitor + alignsize = PTRSIZE; } structsize = sc->offset; Scope scsave = *sc; @@ -683,7 +693,7 @@ int ClassDeclaration::isBaseOf2(ClassDec * Determine if 'this' is a base class of cd. */ -int ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) +int ClassDeclaration::isBaseOf(ClassDeclaration *cd, target_ptrdiff_t *poffset) { //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); if (poffset) @@ -921,6 +931,11 @@ void InterfaceDeclaration::semantic(Scop scope = NULL; } + if (attributes) + attributes->append(sc->attributes); + else + attributes = sc->attributes; + // Expand any tuples in baseclasses[] for (i = 0; i < baseclasses.dim; ) { BaseClass *b = (BaseClass *)baseclasses.data[0]; @@ -1037,12 +1052,13 @@ void InterfaceDeclaration::semantic(Scop } sc = sc->push(this); + sc->attributes = NULL; sc->parent = this; if (isCOMclass()) sc->linkage = LINKwindows; sc->structalign = 8; structalign = sc->structalign; - sc->offset = 8; + sc->offset = PTRSIZE * 2; for (i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; @@ -1065,7 +1081,7 @@ void InterfaceDeclaration::semantic(Scop * 1 is a base */ -int InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) +int InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, target_ptrdiff_t *poffset) { unsigned j; @@ -1102,7 +1118,7 @@ int InterfaceDeclaration::isBaseOf(Class } -int InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset) +int InterfaceDeclaration::isBaseOf(BaseClass *bc, target_ptrdiff_t *poffset) { //printf("%s.InterfaceDeclaration::isBaseOf(bc = '%s')\n", toChars(), bc->base->toChars()); for (unsigned j = 0; j < bc->baseInterfaces_dim; j++) diff -uNrp dmd-1.007/src/dmd/constfold.c gdc-0.23/d/dmd/constfold.c --- dmd-1.007/src/dmd/constfold.c 2007-02-20 16:05:12.000000000 +0100 +++ gdc-0.23/d/dmd/constfold.c 2007-03-05 00:35:22.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -25,9 +31,6 @@ #ifdef IN_GCC #include "d-gcc-real.h" - -/* %% fix? */ -extern "C" bool real_isnan (const real_t *); #endif static real_t zero; // work around DMC bug for now @@ -722,7 +725,11 @@ Expression *Equal(enum TOK op, Type *typ #if __DMC__ cmp = (r1 == r2); #else +# if IN_GCC + if (r1.isNan() || r2.isNan()) // if unordered +# else if (isnan(r1) || isnan(r2)) // if unordered +# endif { cmp = 0; } @@ -814,7 +821,7 @@ Expression *Cmp(enum TOK op, Type *type, #else // Don't rely on compiler, handle NAN arguments separately #if IN_GCC - if (real_isnan(&r1) || real_isnan(&r2)) // if unordered + if (r1.isNan() || r2.isNan()) // if unordered #else if (isnan(r1) || isnan(r2)) // if unordered #endif @@ -946,7 +953,22 @@ Expression *Cast(Type *type, Type *to, E { if (e1->type->isfloating()) { integer_t result; +#ifdef IN_GCC + Type * rt = e1->type; + if (rt->iscomplex()) + { + switch (rt->toBasetype()->ty) + { + case Tcomplex32: rt = Type::tfloat32; break; + case Tcomplex64: rt = Type::tfloat64; break; + case Tcomplex80: rt = Type::tfloat80; break; + default: assert(0); + } + } + d_int64 r = e1->toReal().toInt(rt, type); +#else real_t r = e1->toReal(); +#endif switch (type->toBasetype()->ty) { @@ -1035,7 +1057,7 @@ Expression *Index(Type *type, Expression uinteger_t i = e2->toInteger(); if (i >= es1->len) - e1->error("string index %ju is out of bounds [0 .. %ju]", i, es1->len); + e1->error("string index %"PRIuMAX" is out of bounds [0 .. %"PRIuSIZE"]", i, es1->len); else { integer_t value; @@ -1066,7 +1088,7 @@ Expression *Index(Type *type, Expression uinteger_t i = e2->toInteger(); if (i >= length) - { error("array index %ju is out of bounds [0 .. %ju]", i, length); + { error("array index %"PRIuMAX" is out of bounds [0 .. %"PRIuMAX"]", i, length); } else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; @@ -1097,7 +1119,7 @@ Expression *Slice(Type *type, Expression uinteger_t iupr = upr->toInteger(); if (iupr > es1->len || ilwr > iupr) - e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr); + e1->error("string slice [%"PRIuMAX" .. %"PRIuMAX"] is out of bounds", ilwr, iupr); else { integer_t value; void *s; @@ -1124,7 +1146,7 @@ Expression *Slice(Type *type, Expression uinteger_t iupr = upr->toInteger(); if (iupr > es1->elements->dim || ilwr > iupr) - e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr); + e1->error("array slice [%"PRIuMAX" .. %"PRIuMAX"] is out of bounds", ilwr, iupr); else { Expressions *elements = new Expressions(); @@ -1165,7 +1187,13 @@ Expression *Cat(Type *type, Expression * integer_t v = e->toInteger(); s = mem.malloc((len + 1) * sz); - memcpy((unsigned char *)s, &v, sz); + switch (sz) + { + case 1: *(d_uns8*)s = v; break; + case 2: *(d_uns16*)s = v; break; + case 4: *(d_uns32*)s = v; break; + default: assert(0); + } // Add terminating 0 memset((unsigned char *)s + len * sz, 0, sz); @@ -1218,6 +1246,7 @@ Expression *Cat(Type *type, Expression * { // Concatenate the strings void *s; + void *sch; StringExp *es1 = (StringExp *)e1; StringExp *es; Type *t; @@ -1227,7 +1256,14 @@ Expression *Cat(Type *type, Expression * s = mem.malloc((len + 1) * sz); memcpy(s, es1->string, es1->len * sz); - memcpy((unsigned char *)s + es1->len * sz, &v, sz); + sch = (unsigned char *)s + es1->len * sz; + switch (sz) + { + case 1: *(d_uns8*)sch = v; break; + case 2: *(d_uns16*)sch = v; break; + case 4: *(d_uns32*)sch = v; break; + default: assert(0); + } // Add terminating 0 memset((unsigned char *)s + len * sz, 0, sz); @@ -1251,7 +1287,13 @@ Expression *Cat(Type *type, Expression * integer_t v = e1->toInteger(); s = mem.malloc((len + 1) * sz); - memcpy((unsigned char *)s, &v, sz); + switch (sz) + { + case 1: *(d_uns8*)s = v; break; + case 2: *(d_uns16*)s = v; break; + case 4: *(d_uns32*)s = v; break; + default: assert(0); + } memcpy((unsigned char *)s + sz, es2->string, es2->len * sz); // Add terminating 0 diff -uNrp dmd-1.007/src/dmd/declaration.c gdc-0.23/d/dmd/declaration.c --- dmd-1.007/src/dmd/declaration.c 2007-02-16 01:22:06.000000000 +0100 +++ gdc-0.23/d/dmd/declaration.c 2007-03-04 14:46:20.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include @@ -32,6 +38,7 @@ Declaration::Declaration(Identifier *id) storage_class = STCundefined; protection = PROTundefined; linkage = LINKdefault; + attributes = NULL; } void Declaration::semantic(Scope *sc) @@ -43,7 +50,7 @@ char *Declaration::kind() return "declaration"; } -unsigned Declaration::size(Loc loc) +target_size_t Declaration::size(Loc loc) { assert(type); return type->size(); @@ -208,6 +215,10 @@ void TypedefDeclaration::semantic(Scope basetype = basetype->semantic(loc, sc); sem = 2; type = type->semantic(loc, sc); + if (attributes) + attributes->append(sc->attributes); + else + attributes = sc->attributes; if (sc->parent->isFuncDeclaration() && init) semantic2(sc); } @@ -603,6 +614,10 @@ void VarDeclaration::semantic(Scope *sc) this->parent = sc->parent; //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); protection = sc->protection; + if (attributes) + attributes->append(sc->attributes); + else + attributes = sc->attributes; //printf("sc->stc = %x\n", sc->stc); //printf("storage_class = %x\n", storage_class); @@ -642,7 +657,7 @@ void VarDeclaration::semantic(Scope *sc) { Argument *arg = Argument::getNth(tt->arguments, i); OutBuffer buf; - buf.printf("_%s_field_%zu", ident->toChars(), i); + buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i); buf.writeByte(0); char *name = (char *)buf.extractData(); Identifier *id = new Identifier(name, TOKidentifier); @@ -800,7 +815,7 @@ void VarDeclaration::semantic(Scope *sc) { Expression *e1; Type *t; - int dim; + sinteger_t dim; //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); if (!ei) diff -uNrp dmd-1.007/src/dmd/declaration.h gdc-0.23/d/dmd/declaration.h --- dmd-1.007/src/dmd/declaration.h 2007-02-20 13:32:10.000000000 +0100 +++ gdc-0.23/d/dmd/declaration.h 2007-03-04 16:21:12.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #ifndef DMD_DECLARATION_H #define DMD_DECLARATION_H @@ -81,11 +87,12 @@ struct Declaration : Dsymbol unsigned storage_class; enum PROT protection; enum LINK linkage; + Expressions * attributes; // GCC decl/type attributes Declaration(Identifier *id); void semantic(Scope *sc); char *kind(); - unsigned size(Loc loc); + target_size_t size(Loc loc); void emitComment(Scope *sc); void toDocBuffer(OutBuffer *buf); @@ -203,7 +210,7 @@ struct AliasDeclaration : Declaration struct VarDeclaration : Declaration { Initializer *init; - unsigned offset; + target_size_t offset; int noauto; // no auto semantics int nestedref; // referenced by a lexically nested function int inuse; @@ -415,6 +422,7 @@ struct FuncDeclaration : Declaration VarDeclaration *vthis; // 'this' parameter (member and nested) VarDeclaration *v_arguments; // '_arguments' parameter #if IN_GCC + VarDeclaration *v_arguments_var; // '_arguments' variable VarDeclaration *v_argptr; // '_argptr' variable #endif Dsymbols *parameters; // Array of VarDeclaration's for parameters @@ -485,11 +493,13 @@ struct FuncDeclaration : Declaration char *kind(); void toDocBuffer(OutBuffer *buf); - static FuncDeclaration *genCfunc(Type *treturn, char *name); - static FuncDeclaration *genCfunc(Type *treturn, Identifier *id); + static FuncDeclaration *genCfunc(Type *treturn, char *name, + Type *t1 = 0, Type *t2 = 0, Type *t3 = 0); + static FuncDeclaration *genCfunc(Type *treturn, Identifier *id, + Type *t1 = 0, Type *t2 = 0, Type *t3 = 0); Symbol *toSymbol(); - Symbol *toThunkSymbol(int offset); // thunk version + Symbol *toThunkSymbol(target_ptrdiff_t offset); // thunk version void toObjFile(); // compile to .obj file int cvMember(unsigned char *p); diff -uNrp dmd-1.007/src/dmd/dsymbol.c gdc-0.23/d/dmd/dsymbol.c --- dmd-1.007/src/dmd/dsymbol.c 2007-02-04 15:47:56.000000000 +0100 +++ gdc-0.23/d/dmd/dsymbol.c 2007-02-15 13:38:36.000000000 +0100 @@ -278,7 +278,7 @@ void Dsymbol::toCBuffer(OutBuffer *buf, buf->writestring(toChars()); } -unsigned Dsymbol::size(Loc loc) +target_size_t Dsymbol::size(Loc loc) { error("Dsymbol '%s' has no size\n", toChars()); return 0; diff -uNrp dmd-1.007/src/dmd/dsymbol.h gdc-0.23/d/dmd/dsymbol.h --- dmd-1.007/src/dmd/dsymbol.h 2007-02-04 15:48:44.000000000 +0100 +++ gdc-0.23/d/dmd/dsymbol.h 2007-02-15 13:36:30.000000000 +0100 @@ -130,7 +130,7 @@ struct Dsymbol : Object #endif virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); virtual void toDocBuffer(OutBuffer *buf); - virtual unsigned size(Loc loc); + virtual target_size_t size(Loc loc); virtual int isforwardRef(); virtual void defineRef(Dsymbol *s); virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member diff -uNrp dmd-1.007/src/dmd/dump.c gdc-0.23/d/dmd/dump.c --- dmd-1.007/src/dmd/dump.c 2006-11-30 22:09:48.000000000 +0100 +++ gdc-0.23/d/dmd/dump.c 2006-12-06 09:20:33.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include #include @@ -52,7 +58,7 @@ void Expression::dump(int i) void IntegerExp::dump(int i) { indent(i); - printf("%p %jd type=%s\n", this, (intmax_t)value, type_print(type)); + printf("%p %"PRIdMAX" type=%s\n", this, (intmax_t)value, type_print(type)); } void IdentifierExp::dump(int i) diff -uNrp dmd-1.007/src/dmd/enum.c gdc-0.23/d/dmd/enum.c --- dmd-1.007/src/dmd/enum.c 2007-01-01 00:39:58.000000000 +0100 +++ gdc-0.23/d/dmd/enum.c 2007-01-03 06:28:37.000000000 +0100 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include @@ -26,6 +32,7 @@ EnumDeclaration::EnumDeclaration(Loc loc maxval = 0; minval = 0; defaultval = 0; + attributes = NULL; } Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s) @@ -57,6 +64,10 @@ void EnumDeclaration::semantic(Scope *sc if (!memtype) memtype = Type::tint32; parent = sc->scopesym; + if (attributes) + attributes->append(sc->attributes); + else + attributes = sc->attributes; memtype = memtype->semantic(loc, sc); /* Check to see if memtype is forward referenced diff -uNrp dmd-1.007/src/dmd/enum.h gdc-0.23/d/dmd/enum.h --- dmd-1.007/src/dmd/enum.h 2006-10-05 16:03:52.000000000 +0200 +++ gdc-0.23/d/dmd/enum.h 2006-12-26 00:25:25.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #ifndef DMD_ENUM_H #define DMD_ENUM_H @@ -32,6 +38,7 @@ struct EnumDeclaration : ScopeDsymbol integer_t maxval; integer_t minval; integer_t defaultval; // default initializer + Expressions * attributes; // GCC decl/type attributes EnumDeclaration(Loc loc, Identifier *id, Type *memtype); Dsymbol *syntaxCopy(Dsymbol *s); diff -uNrp dmd-1.007/src/dmd/expression.c gdc-0.23/d/dmd/expression.c --- dmd-1.007/src/dmd/expression.c 2007-02-20 13:28:38.000000000 +0100 +++ gdc-0.23/d/dmd/expression.c 2007-03-04 14:47:46.000000000 +0100 @@ -8,6 +8,15 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + +// Issues with using -include total.h (defines integer_t) and then complex.h fails... +#undef integer_t + #include #include #include @@ -15,19 +24,14 @@ #include #include -#if _WIN32 && __DMC__ -extern "C" char * __cdecl __locale_decpoint; -#endif - -#if IN_GCC -// Issues with using -include total.h (defines integer_t) and then complex.h fails... -#undef integer_t -#endif - #ifdef __APPLE__ #define integer_t dmd_integer_t #endif +#if _WIN32 && __DMC__ +extern "C" char * __cdecl __locale_decpoint; +#endif + #if IN_GCC #include "mem.h" #elif _WIN32 @@ -35,7 +39,6 @@ extern "C" char * __cdecl __locale_decpo #elif linux #include "../root/mem.h" #endif - #include "port.h" #include "mtype.h" #include "init.h" @@ -376,7 +379,7 @@ void functionArguments(Loc loc, Scope *s size_t nparams = Argument::dim(tf->parameters); if (nargs > nparams && tf->varargs == 0) - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) @@ -400,7 +403,7 @@ void functionArguments(Loc loc, Scope *s { if (tf->varargs == 2 && i + 1 == nparams) goto L2; - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); break; } arg = p->defaultArg->copy(); @@ -414,7 +417,7 @@ void functionArguments(Loc loc, Scope *s if (arg->implicitConvTo(p->type)) { if (nargs != nparams) - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); goto L1; } L2: @@ -1004,7 +1007,7 @@ char *IntegerExp::toChars() { static char buffer[sizeof(value) * 3 + 1]; - sprintf(buffer, "%jd", value); + sprintf(buffer, "%"PRIdMAX, value); return buffer; } @@ -1178,11 +1181,11 @@ void IntegerExp::toCBuffer(OutBuffer *bu break; case Tint64: - buf->printf("%jdL", v); + buf->printf("%"PRIdMAX"L", v); break; case Tuns64: - buf->printf("%juLU", v); + buf->printf("%"PRIuMAX"LU", v); break; case Tbit: @@ -1204,17 +1207,17 @@ void IntegerExp::toCBuffer(OutBuffer *bu } } else if (v & 0x8000000000000000LL) - buf->printf("0x%jx", v); + buf->printf("0x%"PRIxMAX, v); else - buf->printf("%jd", v); + buf->printf("%"PRIdMAX, v); } void IntegerExp::toMangleBuffer(OutBuffer *buf) { if ((sinteger_t)value < 0) - buf->printf("N%jd", -value); + buf->printf("N%"PRIdMAX, -value); else - buf->printf("%jd", value); + buf->printf("%"PRIdMAX, value); } /******************************** RealExp **************************/ @@ -1287,11 +1290,15 @@ complex_t RealExp::toComplex() int RealEquals(real_t x1, real_t x2) { +#ifndef IN_GCC return (isnan(x1) && isnan(x2)) || /* In some cases, the REALPAD bytes get garbage in them, * so be sure and ignore them. */ memcmp(&x1, &x2, REALSIZE - REALPAD) == 0; +#else + return (x1.isNan() && x2.isNan()) || x1.isIdenticalTo(x2); +#endif } int RealExp::equals(Object *o) @@ -1326,14 +1333,27 @@ int RealExp::isBool(int result) #endif } -void floatToBuffer(OutBuffer *buf, Type *type, real_t value) +void floatToBuffer(OutBuffer *buf, Type *type, const real_t & value) { /* In order to get an exact representation, try converting it * to decimal then back again. If it matches, use it. * If it doesn't, fall back to hex, which is * always exact. */ - char buffer[25]; + char buffer[48]; +#ifdef IN_GCC + real_t parsed_value; + + value.format(buffer, sizeof(buffer)); + parsed_value = real_t::parse(buffer, real_t::LongDouble); + if (parsed_value.isIdenticalTo( value )) + buf->writestring(buffer); + else + { + value.formatHex(buffer, sizeof(buffer)); + buf->writestring(buffer); + } +#else sprintf(buffer, "%Lg", value); assert(strlen(buffer) < sizeof(buffer)); #if _WIN32 && __DMC__ @@ -1348,6 +1368,7 @@ void floatToBuffer(OutBuffer *buf, Type buf->writestring(buffer); else buf->printf("%La", value); // ensure exact duplication +#endif if (type) { @@ -1392,13 +1413,25 @@ void realToMangleBuffer(OutBuffer *buf, * 0X1.9P+2 => 19P2 */ +#ifdef IN_GCC + if (value.isNan()) + buf->writestring("NAN"); // no -NAN bugs + else if (value.isInf()) + buf->writestring(value.isNegative()?"NINF":"INF"); +#else if (isnan(value)) buf->writestring("NAN"); // no -NAN bugs +#endif else { - char buffer[32]; + char buffer[64]; +#ifdef IN_GCC + value.formatHex(buffer, sizeof(buffer)); + int n = strlen(buffer); +#else int n = sprintf(buffer, "%LA", value); assert(n > 0 && n < sizeof(buffer)); +#endif for (int i = 0; i < n; i++) { char c = buffer[i]; @@ -1409,6 +1442,7 @@ void realToMangleBuffer(OutBuffer *buf, break; case '+': + case 'x': case 'X': case '.': break; @@ -1497,10 +1531,15 @@ int ComplexExp::equals(Object *o) if (this == o || (((Expression *)o)->op == TOKcomplex80 && ((ne = (ComplexExp *)o), type->equals(ne->type)) && - RealEquals(creall(value), creall(ne->value)) && - RealEquals(cimagl(value), cimagl(ne->value)) +#ifndef IN_GCC + RealEquals(creall(value), creall(ne->value)) && + RealEquals(cimagl(value), cimagl(ne->value)) +#else + RealEquals(value.re, ne->value.re) && + RealEquals(value.im, ne->value.im) +#endif + ) ) - ) return 1; return 0; } @@ -2382,8 +2421,8 @@ void StringExp::toMangleBuffer(OutBuffer { char m; OutBuffer tmp; char *p; - unsigned c; - unsigned u; + dchar_t c; + size_t u; unsigned char *q; unsigned qlen; @@ -2516,7 +2555,7 @@ void ArrayLiteralExp::toCBuffer(OutBuffe void ArrayLiteralExp::toMangleBuffer(OutBuffer *buf) { size_t dim = elements ? elements->dim : 0; - buf->printf("A%u", dim); + buf->printf("A%"PRIuSIZE, dim); for (size_t i = 0; i < dim; i++) { Expression *e = (Expression *)elements->data[i]; e->toMangleBuffer(buf); @@ -2859,7 +2898,7 @@ Lagain: f = cd->aggNew; // Prepend the uint size argument to newargs[] - e = new IntegerExp(loc, cd->size(loc), Type::tuns32); + e = new IntegerExp(loc, cd->size(loc), Type::tsize_t); if (!newargs) newargs = new Expressions(); newargs->shift(e); @@ -2893,7 +2932,7 @@ Lagain: Expression *e; // Prepend the uint size argument to newargs[] - e = new IntegerExp(loc, sd->size(loc), Type::tuns32); + e = new IntegerExp(loc, sd->size(loc), Type::tsize_t); if (!newargs) newargs = new Expressions(); newargs->shift(e); @@ -3053,7 +3092,7 @@ void NewAnonClassExp::toCBuffer(OutBuffe /********************** SymOffExp **************************************/ -SymOffExp::SymOffExp(Loc loc, Declaration *var, unsigned offset) +SymOffExp::SymOffExp(Loc loc, Declaration *var, target_size_t offset) : Expression(loc, TOKsymoff, sizeof(SymOffExp)) { assert(var); @@ -3096,7 +3135,7 @@ void SymOffExp::checkEscape() void SymOffExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { if (offset) - buf->printf("(& %s+%u)", var->toChars(), offset); + buf->printf("(& %s+%"PRIuTSIZE")", var->toChars(), offset); else buf->printf("& %s", var->toChars()); } @@ -5326,7 +5365,7 @@ Lcheckargs: if (f && f->tintro) { Type *t = type; - int offset = 0; + target_ptrdiff_t offset = 0; if (f->tintro->next->isBaseOf(t, &offset) && offset) { @@ -5968,7 +6007,7 @@ Expression *SliceExp::semantic(Scope *sc } else { - error("string slice [%ju .. %ju] is out of bounds", i1, i2); + error("string slice [%"PRIuMAX" .. %"PRIuMAX"] is out of bounds", i1, i2); e = e1; } return e; @@ -6323,7 +6362,7 @@ Expression *IndexExp::semantic(Scope *sc } else { - error("array index [%ju] is outside array bounds [0 .. %zu]", + error("array index [%"PRIuMAX"] is outside array bounds [0 .. %"PRIuSIZE"]", index, length); e = e1; } diff -uNrp dmd-1.007/src/dmd/expression.h gdc-0.23/d/dmd/expression.h --- dmd-1.007/src/dmd/expression.h 2007-02-20 13:46:54.000000000 +0100 +++ gdc-0.23/d/dmd/expression.h 2007-03-04 14:49:16.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef DMD_EXPRESSION_H #define DMD_EXPRESSION_H @@ -453,9 +459,9 @@ struct NewAnonClassExp : Expression struct SymOffExp : Expression { Declaration *var; - unsigned offset; + target_size_t offset; - SymOffExp(Loc loc, Declaration *var, unsigned offset); + SymOffExp(Loc loc, Declaration *var, target_size_t offset); Expression *semantic(Scope *sc); void checkEscape(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); diff -uNrp dmd-1.007/src/dmd/func.c gdc-0.23/d/dmd/func.c --- dmd-1.007/src/dmd/func.c 2007-02-20 13:32:10.000000000 +0100 +++ gdc-0.23/d/dmd/func.c 2007-03-04 16:21:36.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include @@ -51,6 +57,7 @@ FuncDeclaration::FuncDeclaration(Loc loc v_arguments = NULL; #if IN_GCC v_argptr = NULL; + v_arguments_var = NULL; #endif parameters = NULL; labtab = NULL; @@ -128,6 +135,10 @@ void FuncDeclaration::semantic(Scope *sc } protection = sc->protection; storage_class |= sc->stc; + if (attributes) + attributes->append(sc->attributes); + else + attributes = sc->attributes; //printf("function storage_class = x%x\n", storage_class); Dsymbol *parent = toParent(); @@ -315,7 +326,7 @@ void FuncDeclaration::semantic(Scope *sc /* Only need to have a tintro if the vptr * offsets differ */ - int offset; + target_ptrdiff_t offset; if (fdv->type->next->isBaseOf(type->next, &offset)) { tintro = fdv->type; @@ -394,7 +405,7 @@ void FuncDeclaration::semantic(Scope *sc /* Only need to have a tintro if the vptr * offsets differ */ - int offset; + target_ptrdiff_t offset; if (fdv->type->next->isBaseOf(type->next, &offset)) { ti = fdv->type; @@ -599,6 +610,7 @@ void FuncDeclaration::semantic3(Scope *s sc2->fes = fes; sc2->linkage = LINKd; sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated); + sc2->attributes = NULL; sc2->protection = PROTpublic; sc2->explicitProtection = 0; sc2->structalign = 8; @@ -713,7 +725,7 @@ void FuncDeclaration::semantic3(Scope *s { //error("no identifier for parameter %d of %s", i + 1, toChars()); OutBuffer buf; - buf.printf("_param_%zu", i); + buf.printf("_param_%"PRIuSIZE, i); char *name = (char *)buf.extractData(); id = new Identifier(name, TOKidentifier); arg->ident = id; @@ -1068,6 +1080,10 @@ void FuncDeclaration::semantic3(Scope *s if (_arguments) { +#if IN_GCC + v_arguments_var = _arguments; + v_arguments_var->init = new VoidInitializer(loc); +#endif /* Advance to elements[] member of TypeInfo_Tuple with: * _arguments = v_arguments.elements; */ @@ -1709,12 +1725,14 @@ int FuncDeclaration::addPostInvariant() * Generate a FuncDeclaration for a runtime library function. */ -FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, char *name) +FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, char *name, + Type *t1, Type *t2, Type *t3) { - return genCfunc(treturn, Lexer::idPool(name)); + return genCfunc(treturn, Lexer::idPool(name), t1, t2, t3); } -FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, Identifier *id) +FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, Identifier *id, + Type *t1, Type *t2, Type *t3) { FuncDeclaration *fd; TypeFunction *tf; @@ -1736,7 +1754,19 @@ FuncDeclaration *FuncDeclaration::genCfu } else { - tf = new TypeFunction(NULL, treturn, 0, LINKc); + Arguments * args = 0; + if (t1) { + args = new Arguments; + args->push(new Argument(In,t1,0,0)); + if (t2) + { + args->push(new Argument(In,t2,0,0)); + if (t3) + args->push(new Argument(In,t3,0,0)); + } + } + + tf = new TypeFunction(args, treturn, 0, LINKc); fd = new FuncDeclaration(0, 0, id, STCstatic, tf); fd->protection = PROTpublic; fd->linkage = LINKc; @@ -2357,7 +2387,8 @@ void NewDeclaration::semantic(Scope *sc) else { Argument *a = Argument::getNth(tf->parameters, 0); - if (!a->type->equals(Type::tuns32)) + if (!a->type->equals(Type::tuns32) && + (! global.params.isX86_64 || !a->type->equals(Type::tuns64))) error("first argument must be type uint, not %s", a->type->toChars()); } diff -uNrp dmd-1.007/src/dmd/html.c gdc-0.23/d/dmd/html.c --- dmd-1.007/src/dmd/html.c 2006-11-19 19:56:40.000000000 +0100 +++ gdc-0.23/d/dmd/html.c 2006-11-12 19:30:57.000000000 +0100 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 + Modified by Thomas Kuehne, November 2004 +*/ /* HTML parser */ @@ -16,19 +22,17 @@ #include #include #include -#include +//#include #include "mars.h" #include "html.h" #include #include "root.h" -#include "../mars/mars.h" +//#include "../mars/mars.h" extern int HtmlNamedEntity(unsigned char *p, int length); -static int isLineSeparator(const unsigned char* p); - /********************************** * Determine if beginning of tag identifier * or a continuation of a tag identifier. @@ -36,7 +40,7 @@ static int isLineSeparator(const unsigne inline int istagstart(int c) { - return (isalpha(c) || c == '_'); + return (isalpha(c) || c == '_' || c == '!'); } inline int istag(int c) @@ -44,12 +48,41 @@ inline int istag(int c) return (isalnum(c) || c == '_'); } +/** + * identify DOS, Linux, Mac, Next and Unicode line endings + * 0 if this is no line seperator + * >0 the length of the seperator + * Note: input has to be UTF-8 + */ +static int isLineSeperator(const unsigned char* p){ + // Linux + if( p[0]=='\n'){ + return 1; + } + + // Mac & Dos + if( p[0]=='\r'){ + return (p[1]=='\n') ? 2 : 1; + } + + // Unicode (line || paragarph sep.) + if( p[0]==0xE2 && p[1]==0x80 && (p[2]==0xA8 || p[2]==0xA9)){ + return 3; + } + + // Next + if( p[0]==0xC2 && p[1]==0x85){ + return 2; + } + + return 0; +} + /********************************************** */ Html::Html(const char *sourcename, unsigned char *base, unsigned length) { - //printf("Html::Html()\n"); this->sourcename = sourcename; this->base = base; p = base; @@ -67,18 +100,19 @@ void Html::error(const char *format, ... { if (!global.gag) { - printf("%s(%d) : HTML Error: ", sourcename, linnum); + fprintf(stderr, "%s:%d: HTML Error: ", sourcename, linnum); va_list ap; va_start(ap, format); - vprintf(format, ap); + vfprintf(stderr, format, ap); va_end(ap); - printf("\n"); - fflush(stdout); + fprintf(stderr, "\n"); + fflush(stderr); } global.errors++; + fatal(); } /********************************************** @@ -102,12 +136,23 @@ void Html::extractCode(OutBuffer *buf) case '\'': skipString(); continue; + */ #endif case '<': + //-OLDOLDREMOVE// if (p[1] == '!' && p[2] == '-' && p[3] == '-') if (p[1] == '!' && isCommentStart()) { // Comments start with of comment"); break; default: - Ldefault: + // Ldefault: + int lineSepLength = isLineSeperator(p); + if( lineSepLength>0 ){ + linnum++; // remember to count lines + // Always extract new lines, so that D lexer counts + // the lines right. + dbuf->writeByte('\n'); // BUG: wchar + p+=lineSepLength-1; + continue; + } scangt = 0; // it's not --> continue; } @@ -446,7 +542,7 @@ void Html::scanComment() //printf("*p = '%c'\n", *p); } -/******************************************** + /******************************************** * Determine if we are at the start of a comment. * Input: * p is on the opening '<' @@ -524,7 +620,7 @@ void Html::scanCDATA() { while(*p && *p != 0x1A) { - int lineSepLength = isLineSeparator(p); + int lineSepLength = isLineSeperator(p); if (lineSepLength>0) { /* Always extract new lines, so that D lexer counts the lines @@ -577,6 +673,7 @@ int Html::charEntity() } else hex = 0; + if (p[1] == ';') goto Linvalid; while (1) @@ -680,40 +777,11 @@ int Html::charEntity() // Kludge to convert non-breaking space to ascii space if (c == 160) - c = ' '; - + c = 32; return c; - Lignore: //printf("Lignore\n"); p = pstart + 1; return '&'; } -/** - * identify DOS, Linux, Mac, Next and Unicode line endings - * 0 if this is no line separator - * >0 the length of the separator - * Note: input has to be UTF-8 - */ -static int isLineSeparator(const unsigned char* p) -{ - // Linux - if( p[0]=='\n') - return 1; - - // Mac & Dos - if( p[0]=='\r') - return (p[1]=='\n') ? 2 : 1; - - // Unicode (line || paragraph sep.) - if( p[0]==0xE2 && p[1]==0x80 && (p[2]==0xA8 || p[2]==0xA9)) - return 3; - - // Next - if( p[0]==0xC2 && p[1]==0x85) - return 2; - - return 0; -} - diff -uNrp dmd-1.007/src/dmd/identifier.c gdc-0.23/d/dmd/identifier.c --- dmd-1.007/src/dmd/identifier.c 2006-11-21 02:12:48.000000000 +0100 +++ gdc-0.23/d/dmd/identifier.c 2006-12-03 16:19:10.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, May 2005 +*/ + #include #include diff -uNrp dmd-1.007/src/dmd/idgen.c gdc-0.23/d/dmd/idgen.c --- dmd-1.007/src/dmd/idgen.c 2007-02-20 13:39:16.000000000 +0100 +++ gdc-0.23/d/dmd/idgen.c 2007-03-04 14:55:11.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, January 2007 +*/ + // Program to generate string files in d data structures. // Saves much tedious typing, and eliminates typo problems. // Generates: @@ -26,7 +32,7 @@ struct Msgtable char *name; // name in D executable }; -Msgtable msgtable[] = +struct Msgtable msgtable[] = { { "IUnknown" }, { "Object" }, @@ -200,6 +206,8 @@ Msgtable msgtable[] = { "lib" }, { "msg" }, { "GNU_asm" }, + { "GNU_attribute" }, + { "GNU_set_attribute" }, // For toHash/toString { "tohash", "toHash" }, diff -uNrp dmd-1.007/src/dmd/impcnvgen.c gdc-0.23/d/dmd/impcnvgen.c --- dmd-1.007/src/dmd/impcnvgen.c 2006-02-22 09:52:16.000000000 +0100 +++ gdc-0.23/d/dmd/impcnvgen.c 2007-01-31 01:02:30.000000000 +0100 @@ -7,9 +7,16 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, January 2007 +*/ + #include #include +#define ENUM_TY_ONLY #include "mtype.h" enum TY impcnvResult[TMAX][TMAX]; diff -uNrp dmd-1.007/src/dmd/init.c gdc-0.23/d/dmd/init.c --- dmd-1.007/src/dmd/init.c 2007-02-13 23:27:24.000000000 +0100 +++ gdc-0.23/d/dmd/init.c 2007-03-04 14:55:17.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include @@ -346,9 +352,9 @@ Initializer *ArrayInitializer::semantic( if (length > dim) dim = length; } - unsigned long amax = 0x80000000; - if ((unsigned long) dim * t->next->size() >= amax) - error(loc, "array dimension %u exceeds max of %ju", dim, amax / t->next->size()); + uintmax_t amax = 0x80000000; + if ((uintmax_t) dim * t->next->size() >= amax) + error(loc, "array dimension %"PRIuTSIZE" exceeds max of %"PRIuMAX, dim, amax / t->next->size()); return this; } diff -uNrp dmd-1.007/src/dmd/init.h gdc-0.23/d/dmd/init.h --- dmd-1.007/src/dmd/init.h 2006-11-30 01:05:02.000000000 +0100 +++ gdc-0.23/d/dmd/init.h 2007-02-18 17:11:07.000000000 +0100 @@ -84,7 +84,7 @@ struct ArrayInitializer : Initializer { Array index; // of Expression *'s Array value; // of Initializer *'s - unsigned dim; // length of array being initialized + target_size_t dim; // length of array being initialized Type *type; // type that array will be used to initialize int sem; // !=0 if semantic() is run diff -uNrp dmd-1.007/src/dmd/lexer.c gdc-0.23/d/dmd/lexer.c --- dmd-1.007/src/dmd/lexer.c 2007-02-09 00:18:40.000000000 +0100 +++ gdc-0.23/d/dmd/lexer.c 2007-03-04 14:56:31.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + /* Lexical Analyzer */ #include @@ -15,7 +21,7 @@ #include #include #include -#include +//#include #include #include #include @@ -130,16 +136,16 @@ char *Token::toChars() #if IN_GCC sprintf(buffer,"%uU",(d_uns32)uns64value); #else - sprintf(buffer,"%uU",uns32value); + sprintf(buffer,"%uU",uns32value); #endif break; case TOKint64v: - sprintf(buffer,"%jdL",int64value); + sprintf(buffer,"%"PRIdMAX"L",int64value); break; case TOKuns64v: - sprintf(buffer,"%juUL",uns64value); + sprintf(buffer,"%"PRIuMAX"UL",uns64value); break; #if IN_GCC @@ -181,6 +187,7 @@ char *Token::toChars() break; #endif + case TOKstring: #if CSTRINGS p = string; @@ -328,7 +335,7 @@ void Lexer::error(const char *format, .. fprintf(stdmsg, "\n"); fflush(stdmsg); - + if (global.errors >= 20) // moderate blizzard of cascading messages fatal(); } diff -uNrp dmd-1.007/src/dmd/mangle.c gdc-0.23/d/dmd/mangle.c --- dmd-1.007/src/dmd/mangle.c 2006-12-14 19:16:56.000000000 +0100 +++ gdc-0.23/d/dmd/mangle.c 2006-12-26 21:57:51.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include #include @@ -206,7 +212,7 @@ char *Dsymbol::mangle() p += 2; buf.writestring(p); } - buf.printf("%zu%s", strlen(id), id); + buf.printf("%"PRIuSIZE"%s", strlen(id), id); id = buf.toChars(); buf.data = NULL; return id; diff -uNrp dmd-1.007/src/dmd/mars.h gdc-0.23/d/dmd/mars.h --- dmd-1.007/src/dmd/mars.h 2007-02-08 16:11:02.000000000 +0100 +++ gdc-0.23/d/dmd/mars.h 2007-03-04 14:56:50.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #ifndef DMD_MARS_H #define DMD_MARS_H @@ -17,6 +23,9 @@ #include #include +#define __STDC_FORMAT_MACROS 1 +#include +#include #ifdef IN_GCC /* Changes for the GDC compiler by David Friedman */ @@ -80,7 +89,7 @@ struct Param Array *versionids; // version identifiers bool dump_source; - + // Hidden debug switches char debuga; char debugb; @@ -169,12 +178,13 @@ typedef d_uns8 d_char; typedef d_uns16 d_wchar; typedef d_uns32 d_dchar; +typedef uinteger_t target_size_t; +typedef sinteger_t target_ptrdiff_t; #ifdef IN_GCC #include "d-gcc-real.h" #else typedef long double real_t; #endif - // Modify OutBuffer::writewchar to write the correct size of wchar #if _WIN32 #define writewchar writeword @@ -187,6 +197,21 @@ typedef long double real_t; #include "d-gcc-complex_t.h" #endif +#if __MSVCRT__ +#define PRIuSIZE "Iu" +#define PRIxSIZE "Ix" +#elif __NEWLIB_H__ +#define PRIuSIZE "u" +#define PRIxSIZE "x" +#else +#define PRIuSIZE "zu" +#define PRIxSIZE "zx" +#endif + +#define PRIdTSIZE PRIdMAX +#define PRIuTSIZE PRIuMAX +#define PRIxTSIZE PRIxMAX + struct Module; //typedef unsigned Loc; // file location diff -uNrp dmd-1.007/src/dmd/mem.c gdc-0.23/d/dmd/mem.c --- dmd-1.007/src/dmd/mem.c 2005-04-27 00:21:12.000000000 +0200 +++ gdc-0.23/d/dmd/mem.c 2006-06-03 04:57:43.000000000 +0200 @@ -2,11 +2,19 @@ /* Copyright (c) 2000 Digital Mars */ /* All Rights Reserved */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, May 2005 +*/ + #include #include #include -#if linux +#if IN_GCC +#include "mem.h" +#elif linux #include "../root/mem.h" #else #include "mem.h" @@ -110,7 +118,7 @@ void *Mem::mallocdup(void *o, size_t siz void Mem::error() { - printf("Error: out of memory\n"); + fprintf(stderr, "Error: out of memory\n"); exit(EXIT_FAILURE); } @@ -130,7 +138,7 @@ void * operator new(size_t m_size) void *p = malloc(m_size); if (p) return p; - printf("Error: out of memory\n"); + fprintf(stderr, "Error: out of memory\n"); exit(EXIT_FAILURE); return p; } diff -uNrp dmd-1.007/src/dmd/mem.h gdc-0.23/d/dmd/mem.h --- dmd-1.007/src/dmd/mem.h 2006-10-25 14:33:40.000000000 +0200 +++ gdc-0.23/d/dmd/mem.h 2006-06-03 04:57:43.000000000 +0200 @@ -1,10 +1,16 @@ // Copyright (C) 2000-2001 by Chromium Communications // All Rights Reserved +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef ROOT_MEM_H #define ROOT_MEM_H -#include // for size_t +#include // for size_t typedef void (*FINALIZERPROC)(void* pObj, void* pClientData); diff -uNrp dmd-1.007/src/dmd/mtype.c gdc-0.23/d/dmd/mtype.c --- dmd-1.007/src/dmd/mtype.c 2007-02-20 13:39:54.000000000 +0100 +++ gdc-0.23/d/dmd/mtype.c 2007-03-04 15:01:34.000000000 +0100 @@ -8,6 +8,15 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + +// Issues with using -include total.h (defines integer_t) and then complex.h fails... +#undef integer_t + #define __USE_ISOC99 1 // so signbit() gets defined #include @@ -15,15 +24,21 @@ #include #include +#include "gdc_alloca.h" + #ifdef __DMC__ #include #endif +// TODO%% this undefines signbit and includes is the wrong complex.h anyway +// -- not sure why this is needed, anyway +// don't need to worry about all this if the 'nan negative by default' issue is resolved #if _MSC_VER #include #include #include #elif __DMC__ +// includes the wrong complex.h in C++ #include #else //#define signbit 56 @@ -34,11 +49,26 @@ static double zero = 0; #elif __GNUC__ #include -#include -#include +// %% shouldn't be necessary +//#include +//#include static double zero = 0; #endif +#ifndef NAN +#define NAN (nan("0")) +#endif +#ifndef INFINITY +#define INFINITY (infinity()) +#endif + + + +#ifdef __APPLE__ +#define integer_t dmd_integer_t +#endif + + #include "mem.h" #include "dsymbol.h" @@ -78,6 +108,8 @@ int REALPAD = 0; #endif int Tsize_t = Tuns32; int Tptrdiff_t = Tint32; +int Tindex = Tint32; +int CLASSINFO_SIZE = 0x3c+8; /***************************** Type *****************************/ @@ -224,6 +256,7 @@ void Type::init() REALSIZE = 8; Tsize_t = Tuns64; Tptrdiff_t = Tint64; + Tindex = Tint64; } else { @@ -238,6 +271,7 @@ void Type::init() Tsize_t = Tuns32; Tptrdiff_t = Tint32; } + CLASSINFO_SIZE = 17 * PTRSIZE; } d_uns64 Type::size() @@ -490,7 +524,7 @@ int Type::isZeroInit() return 0; // assume not } -int Type::isBaseOf(Type *t, int *poffset) +int Type::isBaseOf(Type *t, target_ptrdiff_t *poffset) { return 0; // assume not } @@ -595,7 +629,7 @@ Expression *Type::dotExp(Scope *sc, Expr Loffset: if (v->storage_class & STCfield) { - e = new IntegerExp(e->loc, v->offset, Type::tint32); + e = new IntegerExp(e->loc, v->offset, Type::tsize_t); return e; } } @@ -994,6 +1028,38 @@ Expression *TypeBasic::getProperty(Loc l case Tcomplex32: case Timaginary32: +#ifdef IN_GCC + // %% lazy, fix +#define FLT_MAX real_t_properties[real_t::Float].maxval; +#define DBL_MAX real_t_properties[real_t::Double].maxval; +#define LDBL_MAX real_t_properties[real_t::LongDouble].maxval; +#define FLT_MIN real_t_properties[real_t::Float].minval; +#define DBL_MIN real_t_properties[real_t::Double].minval; +#define LDBL_MIN real_t_properties[real_t::LongDouble].minval; +#define FLT_DIG real_t_properties[real_t::Float].dig; +#define DBL_DIG real_t_properties[real_t::Double].dig; +#define LDBL_DIG real_t_properties[real_t::LongDouble].dig; +#define FLT_MANT_DIG real_t_properties[real_t::Float].mant_dig; +#define DBL_MANT_DIG real_t_properties[real_t::Double].mant_dig; +#define LDBL_MANT_DIG real_t_properties[real_t::LongDouble].mant_dig; +#define FLT_MAX_10_EXP real_t_properties[real_t::Float].max_10_exp; +#define DBL_MAX_10_EXP real_t_properties[real_t::Double].max_10_exp; +#define LDBL_MAX_10_EXP real_t_properties[real_t::LongDouble].max_10_exp; +#define FLT_MIN_10_EXP real_t_properties[real_t::Float].min_10_exp; +#define DBL_MIN_10_EXP real_t_properties[real_t::Double].min_10_exp; +#define LDBL_MIN_10_EXP real_t_properties[real_t::LongDouble].min_10_exp; +#define FLT_MAX_EXP real_t_properties[real_t::Float].max_exp; +#define DBL_MAX_EXP real_t_properties[real_t::Double].max_exp; +#define LDBL_MAX_EXP real_t_properties[real_t::LongDouble].max_exp; +#define FLT_MIN_EXP real_t_properties[real_t::Float].min_exp; +#define DBL_MIN_EXP real_t_properties[real_t::Double].min_exp; +#define LDBL_MIN_EXP real_t_properties[real_t::LongDouble].min_exp; +#define FLT_EPSILON real_t_properties[real_t::Float].epsilonval; +#define DBL_EPSILON real_t_properties[real_t::Double].epsilonval; +#define LDBL_EPSILON real_t_properties[real_t::LongDouble].epsilonval; + + +#endif case Tfloat32: fvalue = FLT_MAX; goto Lfvalue; case Tcomplex64: case Timaginary64: @@ -1260,7 +1326,7 @@ Expression *TypeBasic::dotExp(Scope *sc, case Timaginary64: t = tfloat64; goto L2; case Timaginary80: t = tfloat80; goto L2; L2: - e = new RealExp(0, 0.0, t); + e = new RealExp(0, 0, t); break; default: @@ -1290,7 +1356,7 @@ Expression *TypeBasic::dotExp(Scope *sc, case Tfloat32: case Tfloat64: case Tfloat80: - e = new RealExp(0, 0.0, this); + e = new RealExp(0, 0, this); break; default: @@ -1492,7 +1558,7 @@ Expression *TypeArray::dotExp(Scope *sc, static char *name[2] = { "_adReverseChar", "_adReverseWchar" }; nm = name[n->ty == Twchar]; - fd = FuncDeclaration::genCfunc(Type::tindex, nm); + fd = FuncDeclaration::genCfunc(Type::tindex, nm, Type::tvoid->arrayOf()); ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1509,7 +1575,7 @@ Expression *TypeArray::dotExp(Scope *sc, static char *name[2] = { "_adSortChar", "_adSortWchar" }; nm = name[n->ty == Twchar]; - fd = FuncDeclaration::genCfunc(Type::tindex, nm); + fd = FuncDeclaration::genCfunc(Type::tindex, nm, Type::tvoid->arrayOf()); ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1522,12 +1588,17 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *ec; FuncDeclaration *fd; Expressions *arguments; - int size = next->size(e->loc); + target_size_t size = next->size(e->loc); int dup; assert(size); dup = (ident == Id::dup); - fd = FuncDeclaration::genCfunc(Type::tindex, dup ? Id::adDup : Id::adReverse); + if (dup) + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::adDup, + Type::typeinfo->type, Type::tvoid->arrayOf()); + else + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::adReverse, + Type::tvoid->arrayOf(), Type::tsize_t); ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1535,7 +1606,7 @@ Expression *TypeArray::dotExp(Scope *sc, arguments->push(getTypeInfo(sc)); arguments->push(e); if (!dup) - arguments->push(new IntegerExp(0, size, Type::tint32)); + arguments->push(new IntegerExp(0, size, Type::tsize_t)); e = new CallExp(e->loc, ec, arguments); e->type = next->arrayOf(); } @@ -1546,7 +1617,9 @@ Expression *TypeArray::dotExp(Scope *sc, Expressions *arguments; fd = FuncDeclaration::genCfunc(tint32->arrayOf(), - (char*)(n->ty == Tbit ? "_adSortBit" : "_adSort")); + (char*)(n->ty == Tbit ? "_adSortBit" : "_adSort"), + Type::tvoid->arrayOf(), + n->ty == Tbit ? NULL : Type::tvoid->pointerTo()); ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1659,7 +1732,7 @@ d_uns64 TypeSArray::size(Loc loc) return sz; Loverflow: - error(loc, "index %jd overflow for static array", sz); + error(loc, "index %"PRIdMAX" overflow for static array", sz); return 1; } @@ -1713,7 +1786,7 @@ void TypeSArray::resolve(Loc loc, Scope sc = sc->pop(); if (d >= td->objects->dim) - { error(loc, "tuple index %ju exceeds %u", d, td->objects->dim); + { error(loc, "tuple index %"PRIuMAX" exceeds %u", d, td->objects->dim); goto Ldefault; } @@ -1781,7 +1854,7 @@ Type *TypeSArray::semantic(Loc loc, Scop if (n && n2 / n != d2) { Loverflow: - error(loc, "index %jd overflow for static array", d1); + error(loc, "index %"PRIdMAX" overflow for static array", d1); dim = new IntegerExp(0, 1, tsize_t); } } @@ -1795,7 +1868,7 @@ Type *TypeSArray::semantic(Loc loc, Scop uinteger_t d = dim->toUInteger(); if (d >= tt->arguments->dim) - { error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); + { error(loc, "tuple index %"PRIuMAX" exceeds %u", d, tt->arguments->dim); return Type::terror; } Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; @@ -1816,7 +1889,7 @@ void TypeSArray::toDecoBuffer(OutBuffer { buf->writeByte(mangleChar[ty]); if (dim) - buf->printf("%ju", dim->toInteger()); + buf->printf("%"PRIuMAX, dim->toInteger()); if (next) next->toDecoBuffer(buf); } @@ -1876,7 +1949,7 @@ int TypeSArray::implicitConvTo(Type *to) return 1; } if (to->ty == Tarray) - { int offset = 0; + { target_ptrdiff_t offset = 0; if (next->equals(to->next) || (to->next->isBaseOf(next, &offset) && offset == 0) || @@ -2045,7 +2118,7 @@ int TypeDArray::implicitConvTo(Type *to) } if (to->ty == Tarray) - { int offset = 0; + { target_ptrdiff_t offset = 0; if ((to->next->isBaseOf(next, &offset) && offset == 0) || to->next->ty == Tvoid) @@ -2189,7 +2262,7 @@ Expression *TypeAArray::dotExp(Scope *sc FuncDeclaration *fd; Expressions *arguments; - fd = FuncDeclaration::genCfunc(Type::tsize_t, "_aaLen"); + fd = FuncDeclaration::genCfunc(Type::tsize_t, "_aaLen", Type::tvoid->arrayOf()); ec = new VarExp(0, fd); arguments = new Expressions(); arguments->push(e); @@ -2214,7 +2287,8 @@ Expression *TypeAArray::dotExp(Scope *sc else #endif strcpy(aakeys, "_aaKeys"); - fd = FuncDeclaration::genCfunc(Type::tindex, aakeys); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), aakeys, + Type::tvoid->arrayOf(), Type::tsize_t); ec = new VarExp(0, fd); arguments = new Expressions(); arguments->push(e); @@ -2229,12 +2303,13 @@ Expression *TypeAArray::dotExp(Scope *sc FuncDeclaration *fd; Expressions *arguments; - fd = FuncDeclaration::genCfunc(Type::tindex, "_aaValues"); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), "_aaValues", + Type::tvoid->arrayOf(), Type::tsize_t, Type::tsize_t); ec = new VarExp(0, fd); arguments = new Expressions(); arguments->push(e); size_t keysize = key->size(e->loc); - keysize = (keysize + 3) & ~3; // BUG: 64 bit pointers? + keysize = (keysize + (PTRSIZE-1)) & ~(PTRSIZE-1); arguments->push(new IntegerExp(0, keysize, Type::tsize_t)); arguments->push(new IntegerExp(0, next->size(e->loc), Type::tsize_t)); e = new CallExp(e->loc, ec, arguments); @@ -2246,7 +2321,7 @@ Expression *TypeAArray::dotExp(Scope *sc FuncDeclaration *fd; Expressions *arguments; - fd = FuncDeclaration::genCfunc(Type::tint64, "_aaRehash"); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), "_aaRehash"); ec = new VarExp(0, fd); arguments = new Expressions(); arguments->push(e->addressOf(sc)); @@ -2953,7 +3028,19 @@ Expression *TypeDelegate::dotExp(Scope * #endif if (ident == Id::ptr) { +#ifndef IN_GCC e->type = tvoidptr; +#else + if (e->op == TOKdelegate || e->op == TOKcast) + e = e->castTo(sc, tvoidptr); // Not an lvalue + else + { + e = e->addressOf(sc); + e = e->castTo(sc, tvoidptr->pointerTo()); + e = new PtrExp(e->loc, e); + e->type = tvoidptr; + } +#endif return e; } else if (ident == Id::funcptr) @@ -4072,7 +4159,7 @@ d_uns64 TypeStruct::size(Loc loc) } unsigned TypeStruct::alignsize() -{ unsigned sz; +{ target_size_t sz; sym->size(0); // give error for forward references sz = sym->alignsize; @@ -4250,7 +4337,7 @@ L1: accessCheck(e->loc, sc, e, d); b = new AddrExp(e->loc, e); b->type = e->type->pointerTo(); - b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tint32)); + b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tsize_t)); b->type = v->type->pointerTo(); e = new PtrExp(e->loc, b); e->type = v->type; @@ -4596,7 +4683,7 @@ int TypeClass::isauto() return sym->isauto; } -int TypeClass::isBaseOf(Type *t, int *poffset) +int TypeClass::isBaseOf(Type *t, target_ptrdiff_t *poffset) { if (t->ty == Tclass) { ClassDeclaration *cd; @@ -4776,7 +4863,13 @@ void TypeTuple::toDecoBuffer(OutBuffer * OutBuffer buf2; Argument::argsToDecoBuffer(&buf2, arguments); unsigned len = buf2.offset; +#if __NEWLIB_H__ + // newlib bug as of 1.14.0 + char * p = (char*) buf2.extractData(); + buf->printf("%c%d%.*s", mangleChar[ty], len, len, p ? p : ""); +#else buf->printf("%c%d%.*s", mangleChar[ty], len, len, (char *)buf2.extractData()); +#endif } Expression *TypeTuple::getProperty(Loc loc, Identifier *ident) @@ -4837,7 +4930,7 @@ Type *TypeSlice::semantic(Loc loc, Scope uinteger_t i2 = upr->toUInteger(); if (!(i1 <= i2 && i2 <= tt->arguments->dim)) - { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt->arguments->dim); + { error(loc, "slice [%"PRIuMAX"..%"PRIuMAX"] is out of range of [0..%u]", i1, i2, tt->arguments->dim); return Type::terror; } @@ -4882,7 +4975,7 @@ void TypeSlice::resolve(Loc loc, Scope * sc = sc->pop(); if (!(i1 <= i2 && i2 <= td->objects->dim)) - { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, td->objects->dim); + { error(loc, "slice [%"PRIuMAX"u..%"PRIuMAX"u] is out of range of [0..%u]", i1, i2, td->objects->dim); goto Ldefault; } diff -uNrp dmd-1.007/src/dmd/mtype.h gdc-0.23/d/dmd/mtype.h --- dmd-1.007/src/dmd/mtype.h 2007-02-04 16:01:04.000000000 +0100 +++ gdc-0.23/d/dmd/mtype.h 2007-02-18 16:28:49.000000000 +0100 @@ -8,9 +8,17 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, January 2007 +*/ + #ifndef DMD_MTYPE_H #define DMD_MTYPE_H +#ifndef ENUM_TY_ONLY + #ifdef __DMC__ #pragma once #endif /* __DMC__ */ @@ -46,6 +54,8 @@ typedef struct TYPE type; #endif struct Symbol; +#endif + enum TY { Tarray, // dynamic array @@ -97,10 +107,13 @@ enum TY TMAX }; +#ifndef ENUM_TY_ONLY + #define Tascii Tchar extern int Tsize_t; extern int Tptrdiff_t; +extern int Tindex; enum MATCH { @@ -153,7 +166,7 @@ struct Type : Object #define tshiftcnt tint32 // right side of shift expression // #define tboolean tint32 // result of boolean expression #define tboolean tbool // result of boolean expression - #define tindex tint32 // array/ptr index + #define tindex basic[Tindex] // array/ptr index static Type *tvoidptr; // void* #define terror basic[Terror] // for error recovery @@ -222,7 +235,7 @@ struct Type : Object Type *arrayOf(); virtual Dsymbol *toDsymbol(Scope *sc); virtual Type *toBasetype(); - virtual int isBaseOf(Type *t, int *poffset); + virtual int isBaseOf(Type *t, target_ptrdiff_t *poffset); virtual int implicitConvTo(Type *to); virtual ClassDeclaration *isClassHandle(); virtual Expression *getProperty(Loc loc, Identifier *ident); @@ -615,7 +628,7 @@ struct TypeClass : Type void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); ClassDeclaration *isClassHandle(); - int isBaseOf(Type *t, int *poffset); + int isBaseOf(Type *t, target_ptrdiff_t *poffset); int implicitConvTo(Type *to); Expression *defaultInit(); int isZeroInit(); @@ -687,4 +700,6 @@ extern int REALPAD; extern int Tsize_t; extern int Tptrdiff_t; +#endif + #endif /* DMD_MTYPE_H */ diff -uNrp dmd-1.007/src/dmd/opover.c gdc-0.23/d/dmd/opover.c --- dmd-1.007/src/dmd/opover.c 2007-02-13 13:08:44.000000000 +0100 +++ gdc-0.23/d/dmd/opover.c 2007-03-04 15:02:01.000000000 +0100 @@ -8,6 +8,16 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + + +// Issues with using -include total.h (defines integer_t) and then complex.h fails... +#undef integer_t + #include #include #include diff -uNrp dmd-1.007/src/dmd/optimize.c gdc-0.23/d/dmd/optimize.c --- dmd-1.007/src/dmd/optimize.c 2007-02-18 01:01:42.000000000 +0100 +++ gdc-0.23/d/dmd/optimize.c 2007-03-04 15:17:21.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include #include @@ -194,7 +200,7 @@ Expression *AddrExp::optimize(int result TypeSArray *ts = (TypeSArray *)ve->type; integer_t dim = ts->dim->toInteger(); if (index < 0 || index >= dim) - error("array index %jd is out of bounds [0..%jd]", index, dim); + error("array index %"PRIdMAX" is out of bounds [0..%"PRIdMAX"]", index, dim); e = new SymOffExp(loc, ve->var, index * ts->next->size()); e->type = type; return e; @@ -217,8 +223,13 @@ Expression *PtrExp::optimize(int result) e = ex; else { +#ifndef IN_GCC e = ex->copy(); e->type = type; +#else + // Stuffing types does not always work in GCC + return this; +#endif } return e; } @@ -273,7 +284,7 @@ Expression *CastExp::optimize(int result // See if we can remove an unnecessary cast ClassDeclaration *cdfrom; ClassDeclaration *cdto; - int offset; + target_ptrdiff_t offset; cdfrom = e1->type->isClassHandle(); cdto = type->isClassHandle(); @@ -404,7 +415,7 @@ Expression *ShlExp::optimize(int result) { integer_t i2 = e2->toInteger(); if (i2 < 0 || i2 > e1->type->size() * 8) - { error("shift left by %jd exceeds %zu", i2, e2->type->size() * 8); + { error("shift left by %"PRIdMAX" exceeds %"PRIuSIZE, i2, e2->type->size() * 8); e2 = new IntegerExp(0); } if (e1->isConst() == 1) @@ -535,7 +546,6 @@ Expression *IdentityExp::optimize(int re e1 = e1->optimize(WANTvalue | (result & WANTinterpret)); e2 = e2->optimize(WANTvalue | (result & WANTinterpret)); e = this; - if (this->e1->isConst() && this->e2->isConst()) { e = Identity(op, type, this->e1, this->e2); diff -uNrp dmd-1.007/src/dmd/parse.c gdc-0.23/d/dmd/parse.c --- dmd-1.007/src/dmd/parse.c 2007-02-18 01:32:16.000000000 +0100 +++ gdc-0.23/d/dmd/parse.c 2007-03-04 15:17:41.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include @@ -3083,6 +3089,14 @@ Statement *Parser::parseStatement(int fl // Defer parsing of AsmStatements until semantic processing. nextToken(); +#if GDC_EXTENDED_ASM_SYNTAX + if (token.value == TOKlparen) + { + nextToken(); + s = parseExtAsm(1); + break; + } +#endif check(TOKlcurly); toklist = NULL; ptoklist = &toklist; @@ -3136,6 +3150,17 @@ Statement *Parser::parseStatement(int fl error("matching '}' expected, not end of file"); break; + case TOKlparen: + case TOKstring: + // If the first token is a string or '(', parse as extended asm. + if (! toklist) + { + s = parseExtAsm(0); + statements->push(s); + continue; + } + // ...else, drop through. + default: Ldefault: *ptoklist = new Token(); @@ -3171,6 +3196,114 @@ Statement *Parser::parseStatement(int fl return s; } +Statement *Parser::parseExtAsm(int expect_rparen) +{ + Expression * insnTemplate; + Expressions * args = NULL; + Array * argNames = NULL; + Expressions * argConstraints = NULL; + int nOutputArgs = 0; + Expressions * clobbers = NULL; + enum InOut phase = Out; + + insnTemplate = parseExpression(); + if (token.value == TOKrparen || token.value == TOKsemicolon) + goto Ldone; + check(TOKcolon); + while (1) { + Expression * arg = NULL; + Identifier * name = NULL; + Expression * constraint = NULL; + + switch (token.value) + { + case TOKsemicolon: + case TOKrparen: + goto Ldone; + + case TOKcolon: + nextToken(); + goto LnextPhase; + + case TOKeof: + error("unterminated statement"); + + case TOKlbracket: + nextToken(); + if (token.value == TOKidentifier) + { + name = token.ident; + nextToken(); + } + else + error("expected identifier after '['"); + check(TOKrbracket); + // drop through + default: + constraint = parsePrimaryExp(); + if (constraint->op != TOKstring) + error("expected constant string constraint for operand"); + arg = parseAssignExp(); + if (! args) + { + args = new Expressions; + argConstraints = new Expressions; + argNames = new Array; + } + args->push(arg); + argNames->push(name); + argConstraints->push(constraint); + if (phase == Out) + nOutputArgs++; + + if (token.value == TOKcomma) + nextToken(); + break; + } + continue; + LnextPhase: + if (phase == Out) + phase = In; + else + break; + } + + while (1) + { + Expression * clobber; + + switch (token.value) + { + case TOKsemicolon: + case TOKrparen: + goto Ldone; + + case TOKeof: + error("unterminated statement"); + + default: + clobber = parseAssignExp(); + if (clobber->op != TOKstring) + error("expected constant string constraint for clobber name"); + if (! clobbers) + clobbers = new Expressions; + clobbers->push(clobber); + + if (token.value == TOKcomma) + nextToken(); + break; + } + } + Ldone: + if (expect_rparen) + check(TOKrparen); + else + check(TOKsemicolon); + + return new ExtAsmStatement(loc, insnTemplate, args, argNames, + argConstraints, nOutputArgs, clobbers); +} + void Parser::check(enum TOK value) { if (token.value != value) @@ -3707,12 +3840,12 @@ Expression *Parser::parsePrimaryExp() break; case TOKint32v: - e = new IntegerExp(loc, token.int32value, Type::tint32); + e = new IntegerExp(loc, (d_int32)token.int64value, Type::tint32); nextToken(); break; case TOKuns32v: - e = new IntegerExp(loc, token.uns32value, Type::tuns32); + e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::tuns32); nextToken(); break; @@ -3772,17 +3905,17 @@ Expression *Parser::parsePrimaryExp() break; case TOKcharv: - e = new IntegerExp(loc, token.uns32value, Type::tchar); + e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::tchar); nextToken(); break; case TOKwcharv: - e = new IntegerExp(loc, token.uns32value, Type::twchar); + e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::twchar); nextToken(); break; case TOKdcharv: - e = new IntegerExp(loc, token.uns32value, Type::tdchar); + e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::tdchar); nextToken(); break; diff -uNrp dmd-1.007/src/dmd/parse.h gdc-0.23/d/dmd/parse.h --- dmd-1.007/src/dmd/parse.h 2007-02-18 01:30:20.000000000 +0100 +++ gdc-0.23/d/dmd/parse.h 2007-03-04 15:17:46.000000000 +0100 @@ -96,6 +96,7 @@ struct Parser : Lexer Array *parseDeclarations(); void parseContracts(FuncDeclaration *f); Statement *parseStatement(int flags); + Statement *parseExtAsm(int expect_rparen); Initializer *parseInitializer(); void check(enum TOK value); void check(enum TOK value, char *string); diff -uNrp dmd-1.007/src/dmd/port.h gdc-0.23/d/dmd/port.h --- dmd-1.007/src/dmd/port.h 2004-03-26 23:11:52.000000000 +0100 +++ gdc-0.23/d/dmd/port.h 2006-06-03 04:57:44.000000000 +0200 @@ -13,7 +13,7 @@ #ifndef TYPEDEFS #define TYPEDEFS -#include +//#include #if _MSC_VER typedef __int64 longlong; @@ -45,14 +45,14 @@ struct Port static ulonglong strtoull(const char *p, char **pend, int base); static char *ull_to_string(char *buffer, ulonglong ull); - static wchar_t *ull_to_string(wchar_t *buffer, ulonglong ull); + // static wchar_t *ull_to_string(wchar_t *buffer, ulonglong ull); // Convert ulonglong to double static double ull_to_double(ulonglong ull); // Get locale-dependent list separator static char *list_separator(); - static wchar_t *wlist_separator(); + // static wchar_t *wlist_separator(); }; #endif diff -uNrp dmd-1.007/src/dmd/root.c gdc-0.23/d/dmd/root.c --- dmd-1.007/src/dmd/root.c 2006-12-01 00:46:32.000000000 +0100 +++ gdc-0.23/d/dmd/root.c 2006-12-27 16:16:11.000000000 +0100 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include #include @@ -14,16 +20,14 @@ #include #include -#if _MSC_VER -#include -#endif +#include "gdc_alloca.h" #if _WIN32 #include #include #endif -#if linux +#ifndef _WIN32 #include #include #include @@ -46,6 +50,7 @@ extern "C" void __cdecl _assert(void *e, } #endif +#ifndef IN_GCC /************************************* * Convert wchar string to ascii string. */ @@ -82,6 +87,7 @@ int wcharIsAscii(wchar_t *us, unsigned l } return 1; } +#endif /*********************************** @@ -117,11 +123,11 @@ void error(const char *format, ...) va_list ap; va_start(ap, format); - printf("Error: "); - vprintf(format, ap); + fprintf(stderr, "Error: "); + vfprintf(stderr, format, ap); va_end( ap ); - printf("\n"); - fflush(stdout); + fprintf(stderr, "\n"); + fflush(stderr); exit(EXIT_FAILURE); } @@ -132,11 +138,11 @@ void error(const dchar *format, ...) va_list ap; va_start(ap, format); - printf("Error: "); - vwprintf(format, ap); + fprintf(stderr, "Error: "); + vfwprintf(stderr, format, ap); va_end( ap ); - printf("\n"); - fflush(stdout); + printf(stderr, "\n"); + fflush(stderr); exit(EXIT_FAILURE); } @@ -156,11 +162,11 @@ void warning(const char *format, ...) va_list ap; va_start(ap, format); - printf("Warning: "); - vprintf(format, ap); + fprintf(stderr, "Warning: "); + vfprintf(stderr, format, ap); va_end( ap ); - printf("\n"); - fflush(stdout); + fprintf(stderr, "\n"); + fflush(stderr); } /****************************** Object ********************************/ @@ -182,7 +188,7 @@ int Object::compare(Object *obj) void Object::print() { - printf("%s %p\n", toChars(), this); + fprintf(stderr, "%s %p\n", toChars(), this); } char *Object::toChars() @@ -300,7 +306,7 @@ char *String::toChars() void String::print() { - printf("String '%s'\n",str); + fprintf(stderr, "String '%s'\n",str); } @@ -322,14 +328,14 @@ char *FileName::combine(char *path, char namelen = strlen(name); f = (char *)mem.malloc(pathlen + 1 + namelen + 1); memcpy(f, path, pathlen); -#if linux +#ifndef _WIN32 if (path[pathlen - 1] != '/') { f[pathlen] = '/'; pathlen++; } #endif #if _WIN32 - if (path[pathlen - 1] != '\\' && path[pathlen - 1] != ':') + if (path[pathlen - 1] != '\\' && path[pathlen - 1] != ':' && path[pathlen - 1] != '/') { f[pathlen] = '\\'; pathlen++; } @@ -376,7 +382,7 @@ Array *FileName::splitPath(const char *p #if _WIN32 case ';': #endif -#if linux +#ifndef _WIN32 case ':': #endif p++; @@ -390,7 +396,7 @@ Array *FileName::splitPath(const char *p case '\r': continue; // ignore carriage returns -#if linux +#ifndef _WIN32 case '~': buf.writestring(getenv("HOME")); continue; @@ -490,7 +496,7 @@ int FileName::absolute(const char *name) (*name == '/') || (*name && name[1] == ':'); #endif -#if linux +#ifndef _WIN32 return (*name == '/'); #endif } @@ -511,11 +517,12 @@ char *FileName::ext(const char *str) switch (*e) { case '.': return e + 1; -#if linux +#ifndef _WIN32 case '/': break; #endif #if _WIN32 + case '/': case '\\': case ':': break; @@ -549,11 +556,12 @@ char *FileName::name(const char *str) { switch (*e) { -#if linux +#ifndef _WIN32 case '/': return e + 1; #endif #if _WIN32 + case '/': case '\\': case ':': return e + 1; @@ -586,12 +594,12 @@ char *FileName::path(const char *str) if (n > str) { -#if linux +#ifndef _WIN32 if (n[-1] == '/') n--; #endif #if _WIN32 - if (n[-1] == '\\') + if (n[-1] == '\\' || n[-1] == '/') n--; #endif } @@ -622,14 +630,14 @@ char *FileName::replaceName(char *path, namelen = strlen(name); f = (char *)mem.malloc(pathlen + 1 + namelen + 1); memcpy(f, path, pathlen); -#if linux +#ifndef _WIN32 if (path[pathlen - 1] != '/') { f[pathlen] = '/'; pathlen++; } #endif #if _WIN32 - if (path[pathlen - 1] != '\\' && path[pathlen - 1] != ':') + if (path[pathlen - 1] != '\\' && path[pathlen - 1] != ':' && path[pathlen - 1] != '/') { f[pathlen] = '\\'; pathlen++; } @@ -698,7 +706,7 @@ int FileName::equalsExt(const char *ext) return 1; if (!e || !ext) return 0; -#if linux +#ifndef _WIN32 return strcmp(e,ext) == 0; #endif #if _WIN32 @@ -717,7 +725,7 @@ void FileName::CopyTo(FileName *to) #if _WIN32 file.touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA)); // keep same file time #endif -#if linux +#ifndef _WIN32 file.touchtime = mem.malloc(sizeof(struct stat)); // keep same file time #endif file.readv(); @@ -759,7 +767,7 @@ char *FileName::searchPath(Array *path, int FileName::exists(const char *name) { -#if linux +#ifndef _WIN32 struct stat st; if (stat(name, &st) < 0) @@ -813,8 +821,7 @@ void FileName::ensurePathExists(const ch //printf("mkdir(%s)\n", path); #if _WIN32 if (mkdir(path)) -#endif -#if linux +#else if (mkdir(path, 0777)) #endif error("cannot create directory %s", path); @@ -870,7 +877,7 @@ void File::mark() int File::read() { -#if linux +#ifndef _WIN32 off_t size; ssize_t numread; int fd; @@ -894,21 +901,21 @@ int File::read() //printf("\tfile opened\n"); if (fstat(fd, &buf)) { - printf("\tfstat error, errno = %d\n",errno); + fprintf(stderr, "\tfstat error, errno = %d\n",errno); goto err2; } size = buf.st_size; buffer = (unsigned char *) mem.malloc(size + 2); if (!buffer) { - printf("\tmalloc error, errno = %d\n",errno); + fprintf(stderr, "\tmalloc error, errno = %d\n",errno); goto err2; } numread = ::read(fd, buffer, size); if (numread != size) { - printf("\tread error, errno = %d\n",errno); + fprintf(stderr, "\tread error, errno = %d\n",errno); goto err2; } @@ -917,7 +924,7 @@ int File::read() if (close(fd) == -1) { - printf("\tclose error, errno = %d\n",errno); + fprintf(stderr, "\tclose error, errno = %d\n",errno); goto err; } @@ -1002,7 +1009,7 @@ err1: int File::mmread() { -#if linux +#ifndef _WIN32 return read(); #endif #if _WIN32 @@ -1056,7 +1063,7 @@ Lerr: int File::write() { -#if linux +#ifndef _WIN32 int fd; ssize_t numwritten; char *name; @@ -1129,7 +1136,7 @@ err: int File::append() { -#if linux +#ifndef _WIN32 return 1; #endif #if _WIN32 @@ -1209,7 +1216,7 @@ void File::appendv() int File::exists() { -#if linux +#ifndef _WIN32 return 0; #endif #if _WIN32 @@ -1234,7 +1241,7 @@ int File::exists() void File::remove() { -#if linux +#ifndef _WIN32 ::remove(this->name->toChars()); #endif #if _WIN32 @@ -1249,7 +1256,7 @@ Array *File::match(char *n) Array *File::match(FileName *n) { -#if linux +#ifndef _WIN32 return NULL; #endif #if _WIN32 @@ -1287,7 +1294,7 @@ Array *File::match(FileName *n) int File::compareTime(File *f) { -#if linux +#ifndef _WIN32 return 0; #endif #if _WIN32 @@ -1301,7 +1308,7 @@ int File::compareTime(File *f) void File::stat() { -#if linux +#ifndef _WIN32 if (!touchtime) { touchtime = mem.calloc(1, sizeof(struct stat)); @@ -1325,7 +1332,7 @@ void File::stat() void File::checkoffset(size_t offset, size_t nbytes) { if (offset > len || offset + nbytes > len) - error("Corrupt file '%s': offset x%zx off end of file",toChars(),offset); + error("Corrupt file '%s': offset x%"PRIxSIZE" off end of file",toChars(),offset); } char *File::toChars() @@ -1396,7 +1403,7 @@ void OutBuffer::writebstring(unsigned ch write(string,*string + 1); } -void OutBuffer::writestring(char *string) +void OutBuffer::writestring(const char *string) { write(string,strlen(string)); } @@ -1554,7 +1561,7 @@ void OutBuffer::writeUTF16(unsigned w) void OutBuffer::write4(unsigned w) { reserve(4); - *(unsigned long *)(this->data + offset) = w; + *(uint32_t *)(this->data + offset) = w; offset += 4; } @@ -1595,19 +1602,21 @@ void OutBuffer::vprintf(const char *form char *p; unsigned psize; int count; + va_list args_copy; p = buffer; psize = sizeof(buffer); for (;;) { + va_copy(args_copy, args); #if _WIN32 - count = _vsnprintf(p,psize,format,args); + count = _vsnprintf(p,psize,format,args_copy); if (count != -1) break; psize *= 2; #endif -#if linux - count = vsnprintf(p,psize,format,args); +#ifndef _WIN32 + count = vsnprintf(p,psize,format,args_copy); if (count == -1) psize *= 2; else if (count >= psize) @@ -1627,19 +1636,20 @@ void OutBuffer::vprintf(const wchar_t *f dchar *p; unsigned psize; int count; + va_list args_copy; p = buffer; psize = sizeof(buffer) / sizeof(buffer[0]); for (;;) { #if _WIN32 - count = _vsnwprintf(p,psize,format,args); + count = _vsnwprintf(p,psize,format,args_copy); if (count != -1) break; psize *= 2; #endif -#if linux - count = vsnwprintf(p,psize,format,args); +#ifndef _WIN32 + count = vsnwprintf(p,psize,format,args_copy); if (count == -1) psize *= 2; else if (count >= psize) diff -uNrp dmd-1.007/src/dmd/root.h gdc-0.23/d/dmd/root.h --- dmd-1.007/src/dmd/root.h 2006-11-21 02:22:14.000000000 +0100 +++ gdc-0.23/d/dmd/root.h 2006-12-09 20:35:20.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef ROOT_H #define ROOT_H @@ -29,9 +35,11 @@ int wcharIsAscii(wchar_t *, unsigned len int bstrcmp(unsigned char *s1, unsigned char *s2); char *bstr2str(unsigned char *b); +#ifndef GCC_SAFE_DMD void error(const char *format, ...); void error(const wchar_t *format, ...); void warning(const char *format, ...); +#endif #ifndef TYPEDEFS #define TYPEDEFS @@ -263,7 +271,7 @@ struct OutBuffer : Object void reset(); void write(const void *data, unsigned nbytes); void writebstring(unsigned char *string); - void writestring(char *string); + void writestring(const char *string); void writedstring(const char *string); void writedstring(const wchar_t *string); void prependstring(char *string); diff -uNrp dmd-1.007/src/dmd/scope.c gdc-0.23/d/dmd/scope.c --- dmd-1.007/src/dmd/scope.c 2007-02-03 21:02:36.000000000 +0100 +++ gdc-0.23/d/dmd/scope.c 2007-02-08 18:58:10.000000000 +0100 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include @@ -58,6 +64,7 @@ Scope::Scope() this->protection = PROTpublic; this->explicitProtection = 0; this->stc = 0; + this->attributes = NULL; this->offset = 0; this->inunion = 0; this->incontract = 0; @@ -91,6 +98,7 @@ Scope::Scope(Scope *enclosing) this->protection = enclosing->protection; this->explicitProtection = enclosing->explicitProtection; this->stc = enclosing->stc; + this->attributes = enclosing->attributes; this->offset = 0; this->inunion = enclosing->inunion; this->incontract = enclosing->incontract; diff -uNrp dmd-1.007/src/dmd/scope.h gdc-0.23/d/dmd/scope.h --- dmd-1.007/src/dmd/scope.h 2006-11-21 01:36:34.000000000 +0100 +++ gdc-0.23/d/dmd/scope.h 2007-02-15 01:45:25.000000000 +0100 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #ifndef DMD_SCOPE_H #define DMD_SCOPE_H @@ -48,7 +54,7 @@ struct Scope Statement *sbreak; // enclosing statement that supports "break" Statement *scontinue; // enclosing statement that supports "continue" ForeachStatement *fes; // if nested function for ForeachStatement, this is it - unsigned offset; // next offset to use in aggregate + target_size_t offset; // next offset to use in aggregate int inunion; // we're processing members of a union int incontract; // we're inside contract code int nofree; // set if shouldn't free it @@ -71,6 +77,7 @@ struct Scope int explicitProtection; // set if in an explicit protection attribute unsigned stc; // storage class + Expressions * attributes; // GCC decl/type attributes unsigned flags; #define SCOPEctor 1 // constructor type diff -uNrp dmd-1.007/src/dmd/statement.c gdc-0.23/d/dmd/statement.c --- dmd-1.007/src/dmd/statement.c 2007-02-16 01:47:36.000000000 +0100 +++ gdc-0.23/d/dmd/statement.c 2007-03-04 15:18:00.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -1162,9 +1168,9 @@ Statement *ForeachStatement::semantic(Sc if (arg->inout != In) error("no storage class for %s", arg->ident->toChars()); TY keyty = arg->type->ty; - if ((keyty != Tint32 && keyty != Tuns32) || - (global.params.isX86_64 && - keyty != Tint64 && keyty != Tuns64) + if ((keyty != Tint32 && keyty != Tuns32) && + (! global.params.isX86_64 || + (keyty != Tint64 && keyty != Tuns64)) ) { error("foreach: key type must be int or uint, not %s", arg->type->toChars()); @@ -1297,9 +1303,9 @@ Statement *ForeachStatement::semantic(Sc error("foreach: value cannot be out and type bit"); if (key && - ((key->type->ty != Tint32 && key->type->ty != Tuns32) || - (global.params.isX86_64 && - key->type->ty != Tint64 && key->type->ty != Tuns64) + ((key->type->ty != Tint32 && key->type->ty != Tuns32) && + (! global.params.isX86_64 || + (key->type->ty != Tint64 && key->type->ty != Tuns64)) ) ) { @@ -1419,18 +1425,20 @@ Statement *ForeachStatement::semantic(Sc * _aaApply(aggr, keysize, flde) */ if (dim == 2) - fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2"); + fdapply = FuncDeclaration::genCfunc(Type::tint32, "_aaApply2", + Type::tvoid->arrayOf(), Type::tsize_t, flde->type); // flde->type is not generic else - fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply"); + fdapply = FuncDeclaration::genCfunc(Type::tint32, "_aaApply", + Type::tvoid->arrayOf(), Type::tsize_t, flde->type); // flde->type is not generic); ec = new VarExp(0, fdapply); Expressions *exps = new Expressions(); exps->push(aggr); size_t keysize = taa->key->size(); - keysize = (keysize + 3) & ~3; - exps->push(new IntegerExp(0, keysize, Type::tint32)); + keysize = (keysize + (PTRSIZE-1)) & ~(PTRSIZE-1); + exps->push(new IntegerExp(0, keysize, Type::tsize_t)); exps->push(flde); e = new CallExp(loc, ec, exps); - e->type = Type::tindex; // don't run semantic() on e + e->type = Type::tint32; // don't run semantic() on e } else if (tab->ty == Tarray || tab->ty == Tsarray) { @@ -1462,7 +1470,8 @@ Statement *ForeachStatement::semantic(Sc const char *r = (op == TOKforeach_reverse) ? "R" : ""; int j = sprintf(fdname, "_aApply%s%.*s%d", r, 2, fntab[flag], dim); assert(j < sizeof(fdname)); - fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname); + fdapply = FuncDeclaration::genCfunc(Type::tint32, fdname, + Type::tvoid->arrayOf(), flde->type); // flde->type is not generic ec = new VarExp(0, fdapply); Expressions *exps = new Expressions(); @@ -1471,7 +1480,7 @@ Statement *ForeachStatement::semantic(Sc exps->push(aggr); exps->push(flde); e = new CallExp(loc, ec, exps); - e->type = Type::tindex; // don't run semantic() on e + e->type = Type::tint32; // don't run semantic() on e } else if (tab->ty == Tdelegate) { @@ -2184,7 +2193,7 @@ DefaultStatement::DefaultStatement(Loc l { this->statement = s; #if IN_GCC -+ cblock = NULL; + cblock = NULL; #endif } diff -uNrp dmd-1.007/src/dmd/statement.h gdc-0.23/d/dmd/statement.h --- dmd-1.007/src/dmd/statement.h 2007-02-14 19:30:44.000000000 +0100 +++ gdc-0.23/d/dmd/statement.h 2007-03-04 15:18:05.000000000 +0100 @@ -739,4 +739,26 @@ struct AsmStatement : Statement void toIR(IRState *irs); }; + +#ifdef IN_GCC + +// Assembler instructions with D expression operands +struct ExtAsmStatement : Statement +{ + Expression *insnTemplate; + Expressions *args; + Array *argNames; // of NULL or Identifier* + Expressions *argConstraints; // of StringExp* + unsigned nOutputArgs; + Expressions *clobbers; // of StringExp* + + ExtAsmStatement(Loc loc, Expression *insnTemplate, Expressions *args, Array *argNames, + Expressions *argConstraints, int nOutputArgs, Expressions *clobbers); + Statement *syntaxCopy(); + Statement *semantic(Scope *sc); + void toIR(IRState *irs); +}; + +#endif + #endif /* DMD_STATEMENT_H */ diff -uNrp dmd-1.007/src/dmd/struct.c gdc-0.23/d/dmd/struct.c --- dmd-1.007/src/dmd/struct.c 2007-01-25 23:47:40.000000000 +0100 +++ gdc-0.23/d/dmd/struct.c 2007-02-15 14:03:29.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + #include #include @@ -40,6 +46,8 @@ AggregateDeclaration::AggregateDeclarati aggNew = NULL; aggDelete = NULL; + attributes = NULL; + stag = NULL; sinit = NULL; scope = NULL; @@ -100,7 +108,7 @@ void AggregateDeclaration::inlineScan() } } -unsigned AggregateDeclaration::size(Loc loc) +target_size_t AggregateDeclaration::size(Loc loc) { //printf("AggregateDeclaration::size() = %d\n", structsize); if (!members) @@ -127,7 +135,7 @@ int AggregateDeclaration::isDeprecated() * Align sizes of 0, as we may not know array sizes yet. */ -void AggregateDeclaration::alignmember(unsigned salign, unsigned size, unsigned *poffset) +void AggregateDeclaration::alignmember(target_size_t salign, target_size_t size, target_size_t *poffset) { //printf("salign = %d, size = %d, offset = %d\n",salign,size,offset); if (salign > 1) @@ -157,9 +165,9 @@ void AggregateDeclaration::alignmember(u void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v) { - unsigned memsize; // size of member - unsigned memalignsize; // size of member for alignment purposes - unsigned xalign; // alignment boundaries + target_size_t memsize; // size of member + target_size_t memalignsize; // size of member for alignment purposes + target_size_t xalign; // alignment boundaries //printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars()); @@ -248,6 +256,9 @@ void StructDeclaration::semantic(Scope * scx = scope; // save so we don't make redundant copies scope = NULL; } +#ifdef IN_GCC + methods.setDim(0); +#endif parent = sc->parent; handle = type->pointerTo(); @@ -256,6 +267,10 @@ void StructDeclaration::semantic(Scope * assert(!isAnonymous()); if (sc->stc & STCabstract) error("structs, unions cannot be abstract"); + if (attributes) + attributes->append(sc->attributes); + else + attributes = sc->attributes; if (sizeok == 0) // if not already done the addMember step { @@ -270,6 +285,7 @@ void StructDeclaration::semantic(Scope * sizeok = 0; sc2 = sc->push(this); sc2->stc = 0; + sc2->attributes = NULL; sc2->parent = this; if (isUnionDeclaration()) sc2->inunion = 1; diff -uNrp dmd-1.007/src/dmd/template.c gdc-0.23/d/dmd/template.c --- dmd-1.007/src/dmd/template.c 2007-02-14 21:20:56.000000000 +0100 +++ gdc-0.23/d/dmd/template.c 2007-03-04 15:18:12.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, December 2006 +*/ + // Handle template implementation #include @@ -1674,7 +1680,7 @@ Lnomatch: void TemplateTypeParameter::print(Object *oarg, Object *oded) { - printf(" %s\n", ident->toChars()); + fprintf(stderr, " %s\n", ident->toChars()); Type *t = isType(oarg); Type *ta = isType(oded); @@ -1682,11 +1688,11 @@ void TemplateTypeParameter::print(Object assert(ta); if (specType) - printf("\tSpecialization: %s\n", specType->toChars()); + fprintf(stderr, "\tSpecialization: %s\n", specType->toChars()); if (defaultType) - printf("\tDefault: %s\n", defaultType->toChars()); - printf("\tArgument: %s\n", t ? t->toChars() : "NULL"); - printf("\tDeduced Type: %s\n", ta->toChars()); + fprintf(stderr, "\tDefault: %s\n", defaultType->toChars()); + fprintf(stderr, "\tArgument: %s\n", t ? t->toChars() : "NULL"); + fprintf(stderr, "\tDeduced Type: %s\n", ta->toChars()); } @@ -1872,12 +1878,12 @@ Lnomatch: void TemplateAliasParameter::print(Object *oarg, Object *oded) { - printf(" %s\n", ident->toChars()); + fprintf(stderr, " %s\n", ident->toChars()); Dsymbol *sa = isDsymbol(oded); assert(sa); - printf("\tArgument alias: %s\n", sa->toChars()); + fprintf(stderr, "\tArgument alias: %s\n", sa->toChars()); } void TemplateAliasParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs) @@ -2105,13 +2111,13 @@ Lnomatch: void TemplateValueParameter::print(Object *oarg, Object *oded) { - printf(" %s\n", ident->toChars()); + fprintf(stderr, " %s\n", ident->toChars()); Expression *ea = isExpression(oded); if (specValue) - printf("\tSpecialization: %s\n", specValue->toChars()); - printf("\tArgument Value: %s\n", ea ? ea->toChars() : "NULL"); + fprintf(stderr, "\tSpecialization: %s\n", specValue->toChars()); + fprintf(stderr, "\tArgument Value: %s\n", ea ? ea->toChars() : "NULL"); } @@ -2313,6 +2319,9 @@ TemplateInstance::TemplateInstance(Loc l this->semanticdone = 0; this->withsym = NULL; this->nest = 0; +#ifdef IN_GCC + this->objFileModule = NULL; +#endif this->havetempdecl = 0; this->isnested = 0; this->errors = 0; @@ -2335,6 +2344,9 @@ TemplateInstance::TemplateInstance(Loc l this->semanticdone = 0; this->withsym = NULL; this->nest = 0; +#ifdef IN_GCC + this->objFileModule = NULL; +#endif this->havetempdecl = 1; this->isnested = 0; this->errors = 0; @@ -2382,6 +2394,10 @@ void TemplateInstance::addIdent(Identifi idents.push(ident); } +#ifdef IN_GCC +#include "d-dmd-gcc.h" +#endif + void TemplateInstance::semantic(Scope *sc) { if (global.errors) @@ -2398,6 +2414,17 @@ void TemplateInstance::semantic(Scope *s #if LOG printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); #endif +#ifdef IN_GCC + /* + fprintf(stderr, "ti '%s' (%p), belongs in '%s'\n", toChars(), this, + sc->module->toPrettyChars()); + if (inst) { + fprintf(stderr, " -- really '%s' (%p)\n", inst->toChars(), inst); + } else { + fprintf(stderr, " -- doing semantic\n"); + } + */ +#endif if (inst) // if semantic() was already run { #if LOG @@ -2500,11 +2527,45 @@ void TemplateInstance::semantic(Scope *s int dosemantic3 = 0; { Array *a; int i; +#ifdef IN_GCC + /* For "all" and "private" template modes, templates are always + emitted. Problem: This picks up templates that aren't even + needed in the current module. */ + + if (d_gcc_force_templates()) + { + //fprintf(stderr, "\t0: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars()); + objFileModule = d_gcc_get_output_module(); + a = objFileModule->members; + } + else +#endif if (sc->scopesym && sc->scopesym->members && !sc->scopesym->isTemplateMixin()) { //printf("\t1: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars()); a = sc->scopesym->members; +#ifdef IN_GCC + { + Dsymbol * p = sc->scopesym; + Module * m; + TemplateInstance * i; + + while (p) { + if ( (i = p->isTemplateInstance()) ) { + if (i->objFileModule) { + objFileModule = i->objFileModule; + break; + } + } else if ( (m = p->isModule()) ) { + objFileModule = m; // %% importedFrom ? + break; + } + p = p->parent; + } + // fprintf(stderr, "\t1: adding %s to module %s via %s %s\n", tempdecl->toChars(), objFileModule?objFileModule->toChars():"", sc->scopesym->kind(), sc->scopesym->toChars()); + } + #endif } else { Module *m = sc->module->importedFrom; @@ -2512,6 +2573,9 @@ void TemplateInstance::semantic(Scope *s a = m->members; if (m->semanticdone >= 3) dosemantic3 = 1; +#ifdef IN_GCC + objFileModule = m; +#endif } for (i = 0; 1; i++) { @@ -2593,10 +2657,12 @@ void TemplateInstance::semantic(Scope *s //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars()); sc2->parent = /*isnested ? sc->parent :*/ this; +#ifndef IN_GCC #if _WIN32 __try { #endif +#endif for (int i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; @@ -2609,6 +2675,7 @@ void TemplateInstance::semantic(Scope *s //printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); sc2->module->runDeferredSemantic(); } +#ifndef IN_GCC #if _WIN32 } __except (__ehfilter(GetExceptionInformation())) @@ -2618,6 +2685,7 @@ void TemplateInstance::semantic(Scope *s fatal(); } #endif +#endif /* If any of the instantiation members didn't get semantic() run * on them due to forward references, we cannot run semantic2() @@ -3057,7 +3125,7 @@ Identifier *TemplateInstance::genIdent() //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); id = tempdecl->ident->toChars(); - buf.printf("__T%zu%s", strlen(id), id); + buf.printf("__T%"PRIuSIZE"%s", strlen(id), id); args = tiargs; for (int i = 0; i < args->dim; i++) { Object *o = (Object *)args->data[i]; @@ -3123,7 +3191,7 @@ Identifier *TemplateInstance::genIdent() else { char *p = sa->mangle(); - buf.printf("%zu%s", strlen(p), p); + buf.printf("%"PRIuSIZE"%s", strlen(p), p); } } else if (va) diff -uNrp dmd-1.007/src/dmd/tocsym.c gdc-0.23/d/dmd/tocsym.c --- dmd-1.007/src/dmd/tocsym.c 2007-01-15 00:57:18.000000000 +0100 +++ gdc-0.23/d/dmd/tocsym.c 2007-02-02 16:44:19.000000000 +0100 @@ -12,6 +12,7 @@ #include #include #include +#include "gdc_alloca.h" #include "mars.h" #include "module.h" @@ -96,7 +97,7 @@ Symbol *Dsymbol::toSymbolX(const char *p Symbol *Dsymbol::toSymbol() { - printf("Dsymbol::toSymbol() '%s', kind = '%s'\n", toChars(), kind()); + fprintf(stderr, "Dsymbol::toSymbol() '%s', kind = '%s'\n", toChars(), kind()); #ifdef DEBUG halt(); #endif @@ -237,7 +238,7 @@ Symbol *VarDeclaration::toSymbol() break; default: - printf("linkage = %d\n", linkage); + fprintf(stderr, "linkage = %d\n", linkage); assert(0); } type_setmangle(&t, m); @@ -339,7 +340,7 @@ Symbol *FuncDeclaration::toSymbol() break; default: - printf("linkage = %d\n", linkage); + fprintf(stderr, "linkage = %d\n", linkage); assert(0); } } diff -uNrp dmd-1.007/src/dmd/todt.c gdc-0.23/d/dmd/todt.c --- dmd-1.007/src/dmd/todt.c 2007-01-09 00:54:14.000000000 +0100 +++ gdc-0.23/d/dmd/todt.c 2007-02-17 17:27:15.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* A dt_t is a simple structure representing data to be added * to the data segment of the output object file. As such, * it is a list of initialized bytes, 0 data, and offsets from @@ -16,12 +22,17 @@ * be written to the data segment. */ +#undef integer_t #include #include #include #include #include +#ifdef __APPLE__ +#define integer_t dmd_integer_t +#endif + #include "lexer.h" #include "mtype.h" #include "expression.h" @@ -32,12 +43,14 @@ // Back end +#ifndef IN_GCC #include "cc.h" #include "el.h" #include "oper.h" #include "global.h" #include "code.h" #include "type.h" +#endif #include "dt.h" extern Symbol *static_sym(); @@ -70,7 +83,7 @@ dt_t *StructInitializer::toDt() dt_t *dt; dt_t *d; dt_t **pdtend; - unsigned offset; + target_size_t offset; //printf("StructInitializer::toDt('%s')\n", toChars()); dts.setDim(ad->fields.dim); @@ -117,8 +130,8 @@ dt_t *StructInitializer::toDt() } else if (v->offset >= offset) { - unsigned k; - unsigned offset2 = v->offset + v->type->size(); + target_size_t k; + target_size_t offset2 = v->offset + v->type->size(); // Make sure this field does not overlap any explicitly // initialized field. for (k = j + 1; 1; k++) @@ -140,12 +153,12 @@ dt_t *StructInitializer::toDt() if (v->offset < offset) error(loc, "duplicate union initialization for %s", v->toChars()); else - { unsigned sz = dt_size(d); - unsigned vsz = v->type->size(); - unsigned voffset = v->offset; + { target_size_t sz = dt_size(d); + target_size_t vsz = v->type->size(); + target_size_t voffset = v->offset; assert(sz <= vsz); - unsigned dim = 1; + target_size_t dim = 1; for (Type *vt = v->type->toBasetype(); vt->ty == Tsarray; vt = vt->next->toBasetype()) @@ -153,7 +166,7 @@ dt_t *StructInitializer::toDt() dim *= tsa->dim->toInteger(); } - for (size_t i = 0; i < dim; i++) + for (target_size_t i = 0; i < dim; i++) { if (offset < voffset) pdtend = dtnzeros(pdtend, voffset - offset); @@ -306,8 +319,6 @@ dt_t *ArrayInitializer::toDtBit() dt_t **pdtend; Type *tb = type->toBasetype(); - //printf("ArrayInitializer::toDtBit('%s')\n", toChars()); - Bits databits; Bits initbits; @@ -368,7 +379,11 @@ dt_t *ArrayInitializer::toDtBit() } d = NULL; +#ifdef IN_GCC + pdtend = dtnbits(&d, databits.allocdim * size, (char *)databits.data, sizeof(databits.data[0])); +#else pdtend = dtnbytes(&d, databits.allocdim * size, (char *)databits.data); +#endif switch (tb->ty) { case Tsarray: @@ -431,6 +446,8 @@ dt_t **Expression::toDt(dt_t **pdt) return pdt; } +#ifndef IN_GCC + dt_t **IntegerExp::toDt(dt_t **pdt) { unsigned sz; @@ -474,7 +491,7 @@ dt_t **RealExp::toDt(dt_t **pdt) break; default: - printf("%s\n", toChars()); + fprintf(stderr, "%s\n", toChars()); type->print(); assert(0); break; @@ -521,6 +538,9 @@ dt_t **ComplexExp::toDt(dt_t **pdt) return pdt; } + +#endif + dt_t **NullExp::toDt(dt_t **pdt) { assert(type); @@ -537,14 +557,22 @@ dt_t **StringExp::toDt(dt_t **pdt) { case Tarray: dtdword(pdt, len); +#ifndef IN_GCC pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string); +#else + pdt = dtawords(pdt, len + 1, string, sz); +#endif break; case Tsarray: { TypeSArray *tsa = (TypeSArray *)type; integer_t dim; +#ifndef IN_GCC pdt = dtnbytes(pdt, len * sz, (const char *)string); +#else + pdt = dtnwords(pdt, len, string, sz); +#endif if (tsa->dim) { dim = tsa->dim->toInteger(); @@ -557,11 +585,15 @@ dt_t **StringExp::toDt(dt_t **pdt) break; } case Tpointer: +#ifndef IN_GCC pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string); +#else + pdt = dtawords(pdt, len + 1, string, sz); +#endif break; default: - printf("StringExp::toDt(type = %s)\n", type->toChars()); + fprintf(stderr, "StringExp::toDt(type = %s)\n", type->toChars()); assert(0); } return pdt; @@ -648,7 +680,7 @@ void ClassDeclaration::toDt2(dt_t **pdt, } else { - offset = 8; + offset = PTRSIZE * 2; } // Note equivalence of this loop to struct's @@ -711,7 +743,7 @@ void ClassDeclaration::toDt2(dt_t **pdt, assert(csymoffset != ~0); dtxoff(pdt, csym, csymoffset, TYnptr); #endif - offset = b->offset + 4; + offset = b->offset + PTRSIZE; } if (offset < structsize) @@ -722,6 +754,12 @@ void ClassDeclaration::toDt2(dt_t **pdt, void StructDeclaration::toDt(dt_t **pdt) { + if (zeroInit) + { + dtnzeros(pdt, structsize); + return; + } + unsigned offset; unsigned i; dt_t *dt; @@ -812,8 +850,13 @@ dt_t **TypeSArray::toDtElem(dt_t **pdt, databits.resize(len); if (e->toInteger()) databits.set(); +#ifdef IN_GCC + pdt = dtnbits(pdt, databits.allocdim * sizeof(databits.data[0]), + (char *)databits.data, sizeof(databits.data[0])); +#else pdt = dtnbytes(pdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data); +#endif } else { diff -uNrp dmd-1.007/src/dmd/toobj.c gdc-0.23/d/dmd/toobj.c --- dmd-1.007/src/dmd/toobj.c 2007-02-03 20:52:50.000000000 +0100 +++ gdc-0.23/d/dmd/toobj.c 2007-02-13 17:16:49.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2004 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include #include @@ -26,6 +32,7 @@ #include "template.h" #include +#ifndef IN_GCC #include "cc.h" #include "global.h" #include "oper.h" @@ -35,9 +42,56 @@ #include "cgcv.h" #include "outbuf.h" #include "irstate.h" +#else +#include "dt.h" +#endif + +#ifdef IN_GCC +#include "d-dmd-gcc.h" +#endif void obj_lzext(Symbol *s1,Symbol *s2); +#ifdef IN_GCC +#if 0 +static bool m_in_a(Module * m, Array * a) { + for (unsigned i = 0; i < a->dim; i++) + if ( m == (Module *) a->data[i] ) + return true; + return false; +} +static void find_module_deps(Module * the_module, Array * out_deps) +{ + Array work; + unsigned wi = 0; + + work.push(the_module); + while (wi < work.dim) { + Module * a_module = (Module *) work.data[wi]; + for (unsigned i = 0; i < a_module->aimports.dim; i++) { + Module * an_imp = (Module*) a_module->aimports.data[i]; + if (! an_imp->needModuleInfo() || + m_in_a(an_imp, & work) || m_in_a(an_imp, out_deps)) + continue; + if (an_imp->strictlyneedmoduleinfo) + { + out_deps->push(an_imp); + fprintf(stderr, "idep: %s -> %s", the_module->toPrettyChars(), + an_imp->toPrettyChars()); + if (a_module != the_module) + fprintf(stderr, " (via %s)", a_module->toPrettyChars()); + fprintf(stderr, "\n"); + } + else + work.push(an_imp); + } + wi++; + } +} +#endif +#endif + + /* ================================================================== */ // Put out instance of ModuleInfo for this Module @@ -95,6 +149,18 @@ void Module::genmoduleinfo() // importedModules[] int aimports_dim = aimports.dim; +#ifdef IN_GCC +#if 0 + Array adeps; + + if (! d_gcc_supports_weak()) + { + find_module_deps(this, & adeps); + aimports_dim = adeps.dim; + } + else +#endif +#endif for (i = 0; i < aimports.dim; i++) { Module *m = (Module *)aimports.data[i]; if (!m->needModuleInfo()) @@ -114,9 +180,9 @@ void Module::genmoduleinfo() dtdword(&dt, 0); if (needmoduleinfo) - dtdword(&dt, 0); // flags (4 means MIstandalone) + dti32(&dt, 0); // flags (4 means MIstandalone) else - dtdword(&dt, 4); // flags (4 means MIstandalone) + dti32(&dt, 4); // flags (4 means MIstandalone) if (sctor) dtxoff(&dt, sctor, 0, TYnptr); @@ -135,6 +201,22 @@ void Module::genmoduleinfo() ////////////////////////////////////////////// +#ifdef IN_GCC +#if 0 + if (! d_gcc_supports_weak()) + for (i = 0; i < adeps.dim; i++) + { + Module *m; + Symbol *s; + + m = (Module *) adeps.data[i]; + s = m->toSymbol(); + s->Sflags |= SFLweak; // doesn't do anything yet, but see d-decls.cc:Module::toSymbol + dtxoff(&dt, s, 0, TYnptr); + } + else +#endif +#endif for (i = 0; i < aimports.dim; i++) { Module *m; @@ -168,13 +250,33 @@ void Module::genmoduleinfo() } /* ================================================================== */ - void Dsymbol::toObjFile() { //printf("Dsymbol::toObjFile('%s')\n", toChars()); // ignore +#ifdef IN_GCC + TupleDeclaration * td = this->isTupleDeclaration(); + if (td) + { + for (unsigned i = 0; i < td->objects->dim; i++) + { + Object * o = (Object *) td->objects->data[i]; + Expression * e; + Dsymbol *ds; + Declaration *d; + if ((o->dyncast() == DYNCAST_EXPRESSION) && + ((Expression *) o)->op == TOKdsymbol) + { + ds = ((DsymbolExp *) o)->s; + d = ds->isDeclaration(); + if (d) + d->toObjFile(); + } + + } + } +#endif } - /* ================================================================== */ void ClassDeclaration::toObjFile() @@ -194,15 +296,10 @@ void ClassDeclaration::toObjFile() assert(!scope); // semantic() should have been run to completion - scclass = SCglobal; - for (Dsymbol *parent = this->parent; parent; parent = parent->parent) - { - if (parent->isTemplateInstance()) - { - scclass = SCcomdat; - break; - } - } + if (parent && parent->isTemplateInstance()) + scclass = SCcomdat; + else + scclass = SCglobal; // Put out the members for (i = 0; i < members->dim; i++) @@ -214,6 +311,7 @@ void ClassDeclaration::toObjFile() } // Build destructor by aggregating dtors[] +#ifndef IN_GCC switch (dtors.dim) { case 0: // No destructors for this class @@ -270,6 +368,9 @@ void ClassDeclaration::toObjFile() writefunc(sdtor); } } +#else + sdtor = d_gcc_aggregate_dtors(this); +#endif // Generate C symbols toSymbol(); @@ -383,7 +484,7 @@ void ClassDeclaration::toObjFile() } flags |= 2; // no pointers L2: - dtdword(&dt, flags); + dti32(&dt, flags); // deallocator @@ -693,15 +794,10 @@ void InterfaceDeclaration::toObjFile() if (global.params.symdebug) toDebug(); - scclass = SCglobal; - for (Dsymbol *parent = this->parent; parent; parent = parent->parent) - { - if (parent->isTemplateInstance()) - { - scclass = SCcomdat; - break; - } - } + if (parent && parent->isTemplateInstance()) + scclass = SCcomdat; + else + scclass = SCglobal; // Put out the members for (i = 0; i < members->dim; i++) @@ -782,7 +878,7 @@ void InterfaceDeclaration::toObjFile() dtdword(&dt, 0); // flags - dtdword(&dt, 4 | com); + dti32(&dt, 4 | com); // deallocator dtdword(&dt, 0); @@ -968,6 +1064,7 @@ void VarDeclaration::toObjFile() if (tb->next->toBasetype()->ty == Tbit) { integer_t value; +#ifndef IN_GCC value = ie->exp->toInteger(); value = (value & 1) ? ~(integer_t)0 : (integer_t)0; if (value == 0) @@ -987,6 +1084,18 @@ void VarDeclaration::toObjFile() dtnbytes(&s->Sdt, 4, (char *)&value); } } +#else + + s->Sdt = NULL; + if (ie->exp->toInteger()) { + Bits databits; + databits.resize(dim); + databits.set(); + dtnbits(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); + } else { + dtnzeros(&s->Sdt, ((unsigned)dim + 31) / 32 * 4); + } +#endif } else { @@ -1035,6 +1144,15 @@ void VarDeclaration::toObjFile() obj_export(s,0); } } +#ifdef IN_GCC + else { + // This is needed for VarDeclarations in mixins that are to be + // local variables of a function. Otherwise, it would be + // enough to make a check for isVarDeclaration() in + // DeclarationExp::toElem. + d_gcc_emit_local_variable(this); + } +#endif } /* ================================================================== */ @@ -1070,7 +1188,8 @@ void TypedefDeclaration::toObjFile() #if ELFOBJ // Burton sinit->Sseg = CDATA; #endif /* ELFOBJ */ - sinit->Sdt = tc->sym->init->toDt(); + if (! sinit->Sdt) + sinit->Sdt = tc->sym->init->toDt(); outdata(sinit); } } diff -uNrp dmd-1.007/src/dmd/total.h gdc-0.23/d/dmd/total.h --- dmd-1.007/src/dmd/total.h 2006-10-05 16:04:10.000000000 +0200 +++ gdc-0.23/d/dmd/total.h 2006-11-11 21:52:33.000000000 +0100 @@ -19,7 +19,7 @@ #include #include #include -#include +//#include #include "root.h" #include "stringtable.h" diff -uNrp dmd-1.007/src/dmd/typinf.c gdc-0.23/d/dmd/typinf.c --- dmd-1.007/src/dmd/typinf.c 2007-02-09 00:13:28.000000000 +0100 +++ gdc-0.23/d/dmd/typinf.c 2007-03-04 15:19:14.000000000 +0100 @@ -8,6 +8,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #include #include @@ -28,6 +34,7 @@ #include "aggregate.h" #include +#ifndef IN_GCC #include "cc.h" #include "global.h" #include "oper.h" @@ -37,6 +44,11 @@ #include "cgcv.h" #include "outbuf.h" #include "irstate.h" +#else +#include "symbol.h" +#include "dt.h" +#include "d-dmd-gcc.h" +#endif extern Symbol *static_sym(); @@ -494,7 +506,7 @@ void TypeInfoStructDeclaration::toDt(dt_ dtdword(pdt, 0); // uint m_flags; - dtdword(pdt, tc->hasPointers()); + dti32(pdt, tc->hasPointers()); // name[] dtnbytes(pdt, namelen + 1, name); @@ -700,7 +712,11 @@ Expression *createTypeInfoArray(Scope *s buf.writeByte(0); id = Lexer::idPool((char *)buf.data); +#ifdef IN_GCC + Module *m = d_gcc_get_output_module(); +#else Module *m = sc->module; +#endif Dsymbol *s = m->symtab->lookup(id); if (s && s->parent == m) diff -uNrp dmd-1.007/src/phobos/acinclude.m4 gdc-0.23/d/phobos/acinclude.m4 --- dmd-1.007/src/phobos/acinclude.m4 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/acinclude.m4 2007-02-28 22:14:56.000000000 +0100 @@ -0,0 +1,222 @@ +dnl Unix-specific configuration +AC_DEFUN([DPHOBOS_CONFIGURE_UNIX],[ + +AC_CHECK_HEADERS(pthread.h,:, + [AC_MSG_ERROR([can't find pthread.h. Pthreads is the only supported thread library.])]) + +AC_MSG_CHECKING([for recursive mutex name]) +AC_TRY_COMPILE([#include ],[ +pthread_mutexattr_t attr; +pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);], + [AC_DEFINE(HAVE_PTHREAD_MUTEX_RECURSIVE,1,[Determines how to declared recursive mutexes]) + AC_MSG_RESULT([PTHREAD_MUTEX_RECURSIVE])], + [AC_MSG_RESULT([PTHREAD_MUTEX_RECURSIVE_NP])]) + +AC_CHECK_TYPES([pthread_barrier_t, pthread_barrierattr_t, + pthread_rwlock_t, pthread_rwlockattr_t, + pthread_spinlock_t],,,[#include ]) + +AC_CHECK_TYPES([clockid_t],,,[#include ]) + +dnl BSD socket configuration + +AC_CHECK_TYPES([socklen_t, siginfo_t],[],[],[ +#include +#include +#include ]) + +AC_MSG_CHECKING([for sa_len]) +AC_TRY_COMPILE([ +#include +#include ],[ +struct sockaddr s; s.sa_len = 0;], + [AC_MSG_RESULT([yes]) + DCFG_SA_LEN=GNU_BsdSockets_salen], + [AC_MSG_RESULT([no]) + DCFG_SA_LEN=""]) + +if test -n "$DCFG_SA_LEN"; then + AC_MSG_CHECKING([size of sa_len]) + AC_TRY_COMPILE([ +#include +#include ],[ + struct sockaddr s; + struct Test { + int x: sizeof(s.sa_len)==1; + };], + [AC_MSG_RESULT([one byte])], + [AC_MSG_RESULT([not one byte]) + AC_MSG_ERROR([Can not handle layout of sockaddr. Please report this so your system can be supported.])]) +else + AC_MSG_CHECKING([size of sa_family]) + AC_TRY_COMPILE([ +#include +#include ],[ + struct sockaddr s; + struct Test { + int x: sizeof(s.sa_family)==2; + };], + [AC_MSG_RESULT([two bytes])], + [AC_MSG_RESULT([not two bytes]) + AC_MSG_ERROR([Can not handle layout of sockaddr. Please report this so your system can be supported.])]) +fi + +AC_SEARCH_LIBS(sem_init, pthread rt posix4) + +DCFG_PTHREAD_SUSPEND= +AC_SUBST(DCFG_PTHREAD_SUSPEND) + +if true; then + AC_CHECK_HEADERS(semaphore.h) + AC_CHECK_FUNC(sem_init) + AC_CHECK_FUNC(semaphore_create) + AC_CHECK_FUNC(pthread_cond_wait) + + if test -z "$d_sem_impl"; then + # Probably need to test what actually works. sem_init is defined + # on AIX and Darwin but does not actually work. + # For now, test for Mach semaphores first so it overrides Posix. AIX + # is a special case. + if test "$ac_cv_func_semaphore_create" = "yes"; then + d_sem_impl="mach" + elif test "$ac_cv_func_sem_init" = "yes" && \ + test "$ac_cv_header_semaphore_h" = "yes" && \ + test -z "$d_is_aix"; then + d_sem_impl="posix" + elif test "$ac_cv_func_pthread_cond_wait" = "yes"; then + d_sem_impl="pthreads" + fi + fi + + dnl TODO: change this to using pthreads? if so, define usepthreads + dnl and configure semaphore + + case "$d_sem_impl" in + posix) DCFG_SEMAPHORE_IMPL="GNU_Semaphore_POSIX" ;; + mach) DCFG_SEMAPHORE_IMPL="GNU_Semaphore_Mach" + d_module_mach=1 ;; + pthreads) DCFG_SEMAPHORE_IMPL="GNU_Sempahore_Pthreads" ;; + skyos) DCFG_SEMAPHORE_IMPL="GNU_Sempahore_Pthreads" + D_EXTRA_OBJS="$D_EXTRA_OBJS std/c/skyos/compat.o" + ;; + *) AC_MSG_ERROR([No usable semaphore implementation]) ;; + esac +else + dnl Need to be able to query thread state for this method to be useful + AC_CHECK_FUNC(pthread_suspend_np) + AC_CHECK_FUNC(pthread_continue_np) + + if test "$ac_cv_func_pthread_suspend_np" = "yes" && \ + test "$ac_cv_func_pthread_continue_np" = "yes" ; then + # TODO: need to test that these actually work. + DCFG_PTHREAD_SUSPEND=GNU_pthread_suspend + else + AC_MSG_ERROR([TODO]) + fi +fi + +AC_DEFINE(PHOBOS_USE_PTHREADS,1,[Define if using pthreads]) + +AC_CHECK_FUNC(mmap,DCFG_MMAP="GNU_Unix_Have_MMap",[]) + +AC_CHECK_FUNC(getpwnam_r,DCFG_GETPWNAM_R="GNU_Unix_Have_getpwnam_r",[]) + + +D_EXTRA_OBJS="gcc/configunix.o gcc/cbridge_fdset.o std/c/unix/unix.o $D_EXTRA_OBJS" +# Add "linux" module for compatibility even if not Linux +D_EXTRA_OBJS="std/c/linux/linux.o $D_EXTRA_OBJS" +D_PREREQ_SRCS="$D_PREREQ_SRCS "'$(configunix_d_src)' +DCFG_UNIX="Unix" + +]) + +dnl Garbage collection configuration +AC_DEFUN([DPHOBOS_CONFIGURE_GC],[ + +D_GC_MODULES=internal/gc/gcgcc.o + +d_gc_alloc= +d_gc_stack= +d_gc_data= + +case "$d_target_os" in + aix*) d_gc_data="$d_gc_data GC_Use_Data_Fixed" + ;; + cygwin*) d_gc_data="$d_gc_data GC_Use_Data_Fixed" + ;; + darwin*) D_GC_MODULES="$D_GC_MODULES internal/gc/gc_dyld.o" + d_gc_stack=GC_Use_Stack_Fixed + d_gc_data="$d_gc_data GC_Use_Data_Dyld" + ;; + freebsd*) D_GC_MODULES="$D_GC_MODULES internal/gc/gc_freebsd.o" + d_gc_stack=GC_Use_Stack_FreeBSD + d_gc_data="$d_gc_data GC_Use_Data_Fixed" + dnl maybe just GC_Use_Stack_ExternC + ;; + linux*) + #d_gc_stack=GC_Use_Stack_Proc_Stat + d_gc_data="$d_gc_data GC_Use_Data_Fixed" + #have_proc_maps=1 + ;; + skyos*) d_gc_data="$d_gc_data GC_Use_Data_Fixed" + ;; + *) D_GC_MODULES=internal/gc/gcgcc.o + ;; +esac + +if test -z "$d_gc_alloc"; then + AC_CHECK_FUNC(mmap,d_gc_alloc=GC_Use_Alloc_MMap,[]) +fi +if test -z "$d_gc_alloc"; then + AC_CHECK_FUNC(valloc,d_gc_alloc=GC_Use_Alloc_Valloc,[]) +fi +if test -z "$d_gc_alloc"; then + # Use malloc as a fallback + d_gc_alloc=GC_Use_Alloc_Malloc +fi +#if test -z "$d_gc_alloc"; then +# AC_MSG_ERROR([No usable memory allocation routine]) +#fi + +if test -z "$d_gc_stack"; then + AC_MSG_CHECKING([for __libc_stack_end]) + AC_TRY_LINK([],[ + extern long __libc_stack_end; + return __libc_stack_end == 0;], + [AC_MSG_RESULT(yes) + d_gc_stack=GC_Use_Stack_GLibC], + [AC_MSG_RESULT(no)]) +fi +if test -z "$d_gc_stack"; then + d_gc_stack=GC_Use_Stack_Guess + D_GC_MODULES="$D_GC_MODULES internal/gc/gc_guess_stack.o" +fi +if test -z "$d_gc_stack"; then + AC_MSG_ERROR([No usable stack origin information]) +fi + +dnl if test -z "$d_gc_data"; then +dnl AC_MSG_CHECKING([for __data_start and _end]) +dnl AC_TRY_LINK([],[ +dnl extern int __data_start; +dnl extern int _end; +dnl return & _end - & __data_start;], +dnl [AC_MSG_RESULT(yes) +dnl d_gc_data="$d_gc_data GC_Use_Data_Data_Start_End"], +dnl [AC_MSG_RESULT(no)]) +dnl fi +if test -n "$have_proc_maps" && test "$enable_proc_maps" = auto; then + enable_proc_maps=yes +fi +if test "$enable_proc_maps" = yes; then + d_gc_data="$d_gc_data GC_Use_Data_Proc_Maps" +fi +if test -z "$d_gc_data"; then + AC_MSG_ERROR([No usable data segment information]) +fi + +f="-fversion=$d_gc_alloc -fversion=$d_gc_stack" +for m in $d_gc_data; do f="$f -fversion=$m"; done +D_GC_FLAGS=$f + +]) diff -uNrp dmd-1.007/src/phobos/aclocal.m4 gdc-0.23/d/phobos/aclocal.m4 --- dmd-1.007/src/phobos/aclocal.m4 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/aclocal.m4 2007-02-28 22:37:12.000000000 +0100 @@ -0,0 +1,780 @@ +# generated automatically by aclocal 1.9.4 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# -*- Autoconf -*- +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Generated from amversion.in; do not edit by hand. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.4])]) + +# AM_AUX_DIR_EXPAND + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 6 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 11 + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# -*- Autoconf -*- +# Copyright (C) 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# -*- Autoconf -*- + + +# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. + +# Copyright (C) 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 4 + +# AM_ENABLE_MULTILIB([MAKEFILE], [REL-TO-TOP-SRCDIR]) +# --------------------------------------------------- +# Add --enable-multilib to configure. +AC_DEFUN([AM_ENABLE_MULTILIB], +[# Default to --enable-multilib +AC_ARG_ENABLE(multilib, +[ --enable-multilib build many library versions (default)], +[case "$enableval" in + yes) multilib=yes ;; + no) multilib=no ;; + *) AC_MSG_ERROR([bad value $enableval for multilib option]) ;; + esac], + [multilib=yes]) + +# We may get other options which we leave undocumented: +# --with-target-subdir, --with-multisrctop, --with-multisubdir +# See config-ml.in if you want the gory details. + +if test "$srcdir" = "."; then + if test "$with_target_subdir" != "."; then + multi_basedir="$srcdir/$with_multisrctop../$2" + else + multi_basedir="$srcdir/$with_multisrctop$2" + fi +else + multi_basedir="$srcdir/$2" +fi +AC_SUBST(multi_basedir) + +AC_OUTPUT_COMMANDS([ +# Only add multilib support code if we just rebuilt the top-level +# Makefile. +case " $CONFIG_FILES " in + *" ]m4_default([$1],Makefile)[ "*) + ac_file=]m4_default([$1],Makefile)[ . ${multi_basedir}/config-ml.in + ;; +esac], + [ +srcdir="$srcdir" +host="$host" +target="$target" +with_multisubdir="$with_multisubdir" +with_multisrctop="$with_multisrctop" +with_target_subdir="$with_target_subdir" +ac_configure_args="${multilib_arg} ${ac_configure_args}" +multi_basedir="$multi_basedir" +CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +CC="$CC"])])dnl + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff -uNrp dmd-1.007/src/phobos/crc32.d gdc-0.23/d/phobos/crc32.d --- dmd-1.007/src/phobos/crc32.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/crc32.d 2007-02-24 17:49:27.000000000 +0100 @@ -73,7 +73,7 @@ uint update_crc32(char val, uint crc) uint strcrc32(char[] s) { uint crc = init_crc32(); - for (int i = 0; i < s.length; i++) + for (size_t i = 0; i < s.length; i++) crc = update_crc32(s[i], crc); return crc; } diff -uNrp dmd-1.007/src/phobos/etc/c/zlib.d gdc-0.23/d/phobos/etc/c/zlib.d --- dmd-1.007/src/phobos/etc/c/zlib.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/etc/c/zlib.d 2007-02-17 20:03:09.000000000 +0100 @@ -1,12 +1,16 @@ /* zlib.d: modified from zlib.h by Walter Bright */ -/* updated from 1.2.1 to 1.2.3 by Thomas Kuehne */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, February 2007 +*/ module etc.c.zlib; /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 + version 1.2.1, November 17th, 2003 - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,10 +37,11 @@ module etc.c.zlib; (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ +private import std.stdint; + extern (C): -char[] ZLIB_VERSION = "1.2.3"; -const ZLIB_VERNUM = 0x1230; +char[] ZLIB_VERSION = "1.2.1"; /* The 'zlib' compression library provides in-memory compression and @@ -51,22 +56,24 @@ const ZLIB_VERNUM = 0x1230; application must provide more input and/or consume the output (providing more output space) before each call. - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. + The compressed data format used by the in-memory functions is the zlib + format, which is a zlib wrapper documented in RFC 1950, wrapped around a + deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - This library can optionally read and write gzip streams in memory as well. - The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. + This library does not provide any functions to write gzip files in memory. + However such functions could be easily written using zlib's deflate function, + the documentation in the gzip RFC, and the examples in gzio.c. + The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. @@ -79,11 +86,11 @@ struct z_stream { ubyte *next_in; /* next input byte */ uint avail_in; /* number of bytes available at next_in */ - uint total_in; /* total nb of input bytes read so far */ + Culong_t total_in; /* total nb of input bytes read so far */ ubyte *next_out; /* next output byte should be put there */ uint avail_out; /* remaining free space at next_out */ - uint total_out; /* total nb of bytes output so far */ + Culong_t total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ void* state; /* not visible by applications */ @@ -92,38 +99,15 @@ struct z_stream free_func zfree; /* used to free the internal state */ void* opaque; /* private data object passed to zalloc and zfree */ - int data_type; /* best guess about the data type: binary or text */ - uint adler; /* adler32 value of the uncompressed data */ - uint reserved; /* reserved for future use */ + int data_type; /* best guess about the data type: ascii or binary */ + Culong_t adler; /* adler32 value of the uncompressed data */ + Culong_t reserved; /* reserved for future use */ } alias z_stream* z_streamp; /* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -struct gz_header { - int text; /* true if compressed data believed to be text */ - ulong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - byte *extra; /* pointer to extra field or Z_NULL if none */ - uint extra_len; /* extra field length (valid if extra != Z_NULL) */ - uint extra_max; /* space at extra (only when reading header) */ - byte *name; /* pointer to zero-terminated file name or Z_NULL */ - uint name_max; /* space at name (only when reading header) */ - byte *comment; /* pointer to zero-terminated comment or Z_NULL */ - uint comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} - -alias gz_header* gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has + The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the @@ -197,7 +181,6 @@ enum Z_FILTERED = 1, Z_HUFFMAN_ONLY = 2, Z_RLE = 3, - Z_FIXED = 4, Z_DEFAULT_STRATEGY = 0, } /* compression strategy; see deflateInit2() below for details */ @@ -205,10 +188,8 @@ enum enum { Z_BINARY = 0, - Z_TEXT = 1, + Z_ASCII = 1, Z_UNKNOWN = 2, - - Z_ASCII = Z_TEXT } /* Possible values of the data_type field (though see inflate()) */ @@ -284,10 +265,6 @@ int deflate(z_streamp strm, int flush); and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to - maximize compression. - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular @@ -299,7 +276,7 @@ int deflate(z_streamp strm, int flush); Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. + the compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated @@ -324,8 +301,8 @@ int deflate(z_streamp strm, int flush); deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. @@ -409,11 +386,11 @@ int inflate(z_streamp strm, int flush); The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. + if and when it get to the next deflate block boundary. When decoding the zlib + or gzip format, this will cause inflate() to return immediately after the + header and before the first block. When doing a raw inflate, inflate() will + go ahead and process the first block, and will return when it gets to the end + of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. Also to assist in this, on return inflate() will set strm->data_type to the @@ -445,7 +422,7 @@ int inflate(z_streamp strm, int flush); because Z_BLOCK is used. If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary + below), inflate sets strm-adler to the adler32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the adler32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described @@ -525,8 +502,7 @@ int deflateInit2(z_streamp strm, 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. + no header crc, and the operating system will be set to 255 (unknown). The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but @@ -545,9 +521,7 @@ int deflateInit2(z_streamp strm, Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. + compressed output even if it is not set appropriately. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid @@ -574,9 +548,7 @@ int deflateSetDictionary(z_streamp strm, deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size in deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. + put at the end of the dictionary, not at the front. Upon return of this function, strm->adler is set to the adler32 value of the dictionary; the decompressor may later use this value to determine @@ -620,59 +592,6 @@ int deflateReset(z_streamp strm); stream state was inconsistent (such as zalloc or state being NULL). */ -int inflatePrime(z_streamp strm, int bits, int value); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -int inflateGetHeader(z_streamp strm, gz_headerp head); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - int deflateParams(z_streamp strm, int level, int strategy); /* Dynamically update the compression level and compression strategy. The @@ -692,21 +611,7 @@ int deflateParams(z_streamp strm, int le if strm->avail_out was zero. */ -int deflateTune(z_streamp strm, int good_length, int max_lazy, int nice_length, - int max_chain); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -int deflateBound(z_streamp strm, uint sourceLen); +uint deflateBound(z_streamp strm, uint Culong_t); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() @@ -728,29 +633,6 @@ int deflatePrime(z_streamp strm, int bit stream state was inconsistent. */ -int deflateSetHeader(z_streamp strm, gz_headerp head); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - int inflateInit2(z_streamp strm, int windowBits) { return inflateInit2_(strm, windowBits, ZLIB_VERSION.ptr, z_stream.sizeof); @@ -784,28 +666,24 @@ int inflateInit2(z_streamp strm, int win windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. + return a Z_DATA_ERROR). inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) -/ + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ int inflateSetDictionary(z_streamp strm, ubyte* dictionary, uint dictLength); /* Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is @@ -1013,9 +891,9 @@ uint zlibCompileFlags(); */ int compress(ubyte* dest, - uint* destLen, + Culong_t* destLen, ubyte* source, - uint sourceLen); + Culong_t sourceLen); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total @@ -1030,9 +908,9 @@ int compress(ubyte* dest, */ int compress2(ubyte* dest, - uint* destLen, + Culong_t* destLen, ubyte* source, - uint sourceLen, + Culong_t sourceLen, int level); /* Compresses the source buffer into the destination buffer. The level @@ -1047,7 +925,7 @@ int compress2(ubyte* dest, Z_STREAM_ERROR if the level parameter is invalid. */ -uint compressBound(uint sourceLen); +uint compressBound(Culong_t sourceLen); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before @@ -1055,9 +933,9 @@ uint compressBound(uint sourceLen); */ int uncompress(ubyte* dest, - uint* destLen, + uint* Culong_t, ubyte* source, - uint sourceLen); + uint Culong_t); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total @@ -1231,12 +1109,6 @@ int gzeof(gzFile file); input stream, otherwise zero. */ -int gzdirect(gzFile file); -/* - Returns 1 if file is being read directly without decompression, otherwise - zero. -*/ - int gzclose(gzFile file); /* Flushes all pending output if necessary, closes the compressed file @@ -1268,7 +1140,7 @@ void gzclearerr (gzFile file); compression library. */ - uint adler32 (uint adler, ubyte *buf, uint len); + Culong_t adler32 (Culong_t adler, ubyte *buf, uint len); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and @@ -1285,20 +1157,12 @@ void gzclearerr (gzFile file); if (adler != original_adler) error(); */ -uint adler32_combine(uint adler1, uint adler2, z_off_t len2); -/* - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -uint crc32(uint crc, ubyte *buf, uint len); +Culong_t crc32(Culong_t crc, ubyte *buf, uint len); /* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. Usage example: uint crc = crc32(0L, Z_NULL, 0); @@ -1309,16 +1173,6 @@ uint crc32(uint crc, ubyte *buf, uint le if (crc != original_crc) error(); */ -uint crc32_combine (uint crc1, uint crc2, z_off_t len2); - -/* - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - /* various hacks, don't look :) */ @@ -1356,4 +1210,4 @@ int inflateInit2_(z_streamp strm, char* zError(int err); int inflateSyncPoint(z_streamp z); -uint* get_crc_table(); +Culong_t* get_crc_table(); diff -uNrp dmd-1.007/src/phobos/etc/gamma.d gdc-0.23/d/phobos/etc/gamma.d --- dmd-1.007/src/phobos/etc/gamma.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/etc/gamma.d 2006-11-11 14:18:34.000000000 +0100 @@ -1,8 +1,3 @@ -/* - * Cephes code Copyright 1994 by Stephen L. Moshier - * Converted to D by Don Clugston. - */ - /** Macros: GAMMA = Γ @@ -10,71 +5,93 @@ Macros: */ module etc.gamma; -import std.math; +private import std.math; private import std.stdio; -//import etc.realtest; //------------------------------------------------------------------ const real SQRT2PI = 2.50662827463100050242E0L; // sqrt(2pi) -const real MAXGAMMA = 1755.455L; // exp(tgamma(x)) == inf if x>MAXGAMMA +// exp(tgamma(x)) == inf if x>MAXGAMMA +const real MAXGAMMA = 1755.455L; // Polynomial approximations for gamma and loggamma. static real GammaNumeratorCoeffs[] = [ - 0x1p+0, // 1 - 0x1.acf42d903366539ep-1, // 0.83780043015731267283 - 0x1.73a991c8475f1aeap-2, // 0.36295154366402391688 - 0x1.c7e918751d6b2a92p-4, // 0.1113062816019361559 - 0x1.86d162cca32cfe86p-6, // 0.023853632434611082525 - 0x1.0c378e2e6eaf7cd8p-8, // 0.0040926668283940355009 - 0x1.dc5c66b7d05feb54p-12, // 0.00045429319606080091555 - 0x1.616457b47e448694p-15 // 4.2127604874716220134e-05 + 0x1p+0, // 1 + 0x1.acf42d903366539ep-1, // 0.83780043015731267283 + 0x1.73a991c8475f1aeap-2, // 0.36295154366402391688 + 0x1.c7e918751d6b2a92p-4, // 0.1113062816019361559 + 0x1.86d162cca32cfe86p-6, // 0.023853632434611082525 + 0x1.0c378e2e6eaf7cd8p-8, // 0.0040926668283940355009 + 0x1.dc5c66b7d05feb54p-12, // 0.00045429319606080091555 + 0x1.616457b47e448694p-15 // 4.2127604874716220134e-05 ]; static real GammaDenominatorCoeffs[] = [ - 0x1p+0, // 1 - 0x1.a8f9faae5d8fc8b0p-2, // 0.41501609505884554346 - -0x1.cb7895a6756eebdep-3, // -0.22435109056703291645 - -0x1.7b9bab006d30652ap-5, // -0.046338876712445342138 - 0x1.c671af78f312082ep-6, // 0.027737065658400729792 - -0x1.a11ebbfaf96252dcp-11, // -0.00079559336824947383209 - -0x1.447b4d2230a77ddap-10, // -0.0012377992466531522311 - 0x1.ec1d45bb85e06696p-13, // 0.00023465840591606352443 - -0x1.d4ce24d05bd0a8e6p-17 // -1.3971485174761704409e-05 + 0x1p+0, // 1 + 0x1.a8f9faae5d8fc8bp-2, // 0.41501609505884554346 + -0x1.cb7895a6756eebdep-3, // -0.22435109056703291645 + -0x1.7b9bab006d30652ap-5, // -0.046338876712445342138 + 0x1.c671af78f312082ep-6, // 0.027737065658400729792 + -0x1.a11ebbfaf96252dcp-11, // -0.00079559336824947383209 + -0x1.447b4d2230a77ddap-10, // -0.0012377992466531522311 + 0x1.ec1d45bb85e06696p-13, // 0.00023465840591606352443 + -0x1.d4ce24d05bd0a8e6p-17 // -1.3971485174761704409e-05 +]; + +static real SmallStirlingCoeffs[] = [ + 0x1.55555555555543aap-4, // 0.083333333333333318004 + 0x1.c71c71c720dd8792p-9, // 0.0034722222222300753277 + -0x1.5f7268f0b5907438p-9, // -0.0026813271618763044182 + -0x1.e13cd410e0477de6p-13, // -0.00022947197478731854057 + 0x1.9b0f31643442616ep-11, // 0.00078403348427447530038 + 0x1.2527623a3472ae08p-14, // 6.9893322606231931717e-05 + -0x1.37f6bc8ef8b374dep-11, // -0.00059502375540563301557 + -0x1.8c968886052b872ap-16, // -2.3638488095017590616e-05 + 0x1.76baa9c6d3eeddbcp-11 // 0.0007147391378143610789 +]; + +static real LargeStirlingCoeffs[] = [ + 1.0L, + 8.33333333333333333333E-2L, + 3.47222222222222222222E-3L, + -2.68132716049382716049E-3L, + -2.29472093621399176955E-4L, + 7.84039221720066627474E-4L, + 6.97281375836585777429E-5L ]; static real GammaSmallCoeffs[] = [ - 0x1p+0, // 1 - 0x1.2788cfc6fb618f52p-1, // 0.57721566490153286082 + 0x1p+0, // 1 + 0x1.2788cfc6fb618f52p-1, // 0.57721566490153286082 -0x1.4fcf4026afa2f7ecp-1, // -0.65587807152025406846 -0x1.5815e8fa24d7e306p-5, // -0.042002635034033440541 - 0x1.5512320aea2ad71ap-3, // 0.16653861137208052067 - -0x1.59af0fb9d82e2160p-5, // -0.042197733607059154702 + 0x1.5512320aea2ad71ap-3, // 0.16653861137208052067 + -0x1.59af0fb9d82e216p-5, // -0.042197733607059154702 -0x1.3b4b61d3bfdf244ap-7, // -0.0096220233604062716456 - 0x1.d9358e9d9d69fd34p-8, // 0.0072205994780369096722 + 0x1.d9358e9d9d69fd34p-8, // 0.0072205994780369096722 -0x1.38fc4bcbada775d6p-10 // -0.0011939450513815100956 ]; static real GammaSmallNegCoeffs[] = [ - -0x1p+0, // -1 - 0x1.2788cfc6fb618f54p-1, // 0.57721566490153286086 - 0x1.4fcf4026afa2bc4cp-1, // 0.65587807152025365473 + -0x1p+0, // -1 + 0x1.2788cfc6fb618f54p-1, // 0.57721566490153286086 + 0x1.4fcf4026afa2bc4cp-1, // 0.65587807152025365473 -0x1.5815e8fa2468fec8p-5, // -0.042002635034021129105 -0x1.5512320baedaf4b6p-3, // -0.16653861139444135193 -0x1.59af0fa283baf07ep-5, // -0.042197733437311917216 - 0x1.3b4a70de31e05942p-7, // 0.0096219111550359767339 - 0x1.d9398be3bad13136p-8, // 0.0072208372618931703258 - 0x1.291b73ee05bcbba2p-10 // 0.001133374167243894382 + 0x1.3b4a70de31e05942p-7, // 0.0096219111550359767339 + 0x1.d9398be3bad13136p-8, // 0.0072208372618931703258 + 0x1.291b73ee05bcbba2p-10 // 0.001133374167243894382 ]; static real logGammaStirlingCoeffs[] = [ - 0x1.5555555555553f98p-4, // 0.083333333333333314473 - -0x1.6c16c16c07509b10p-9, // -0.0027777777777503496034 - 0x1.a01a012461cbf1e4p-11, // 0.00079365077958550707556 - -0x1.3813089d3f9d1640p-11, // -0.00059523458517656885149 - 0x1.b911a92555a277b8p-11, // 0.00084127232973224980805 + 0x1.5555555555553f98p-4, // 0.083333333333333314473 + -0x1.6c16c16c07509b1p-9, // -0.0027777777777503496034 + 0x1.a01a012461cbf1e4p-11, // 0.00079365077958550707556 + -0x1.3813089d3f9d164p-11, // -0.00059523458517656885149 + 0x1.b911a92555a277b8p-11, // 0.00084127232973224980805 -0x1.ed0a7b4206087b22p-10, // -0.0018808019381193769072 - 0x1.402523859811b308p-8 // 0.0048850261424322707812 + 0x1.402523859811b308p-8 // 0.0048850261424322707812 ]; static real logGammaNumerator[] = [ @@ -95,58 +112,34 @@ static real logGammaDenominator[] = [ -0x1.301303b99a614a0ap+19, // -622744.11640662195015 -0x1.09e76ab41ae965p+15, // -34035.708405343046707 -0x1.00f95ced9e5f54eep+9, // -513.94814844353701437 - 0x1p+0 // 1 + 0x1p+0 // 1 ]; -/* **************************************************** - * Helper function: Gamma function computed by Stirling's formula. - * - * Stirling's formula for the gamma function is: - * - * $(GAMMA)(x) = sqrt(2 π) xx-0.5 exp(-x) (1 + 1/x P(1/x)) - * - */ -private real gammaStirling(real x) +/* +Helper function: Gamma function computed by Stirling's formula. + +Stirling's formula for the gamma function is: + +$(GAMMA)(x) = sqrt(2 π) xx-0.5 exp(-x) (1 + 1/x P(1/x)) + +*/ +real gammaStirling(real x) { - static real SmallStirlingCoeffs[] = [ - 0x1.55555555555543aap-4, // 0.083333333333333318004 - 0x1.c71c71c720dd8792p-9, // 0.0034722222222300753277 - -0x1.5f7268f0b5907438p-9, // -0.0026813271618763044182 - -0x1.e13cd410e0477de6p-13, // -0.00022947197478731854057 - 0x1.9b0f31643442616ep-11, // 0.00078403348427447530038 - 0x1.2527623a3472ae08p-14, // 6.9893322606231931717e-05 - -0x1.37f6bc8ef8b374dep-11, // -0.00059502375540563301557 - -0x1.8c968886052b872ap-16, // -2.3638488095017590616e-05 - 0x1.76baa9c6d3eeddbcp-11 // 0.0007147391378143610789 - ]; - - static real LargeStirlingCoeffs[] = [ - 1.0L, - 8.33333333333333333333E-2L, - 3.47222222222222222222E-3L, - -2.68132716049382716049E-3L, - -2.29472093621399176955E-4L, - 7.84039221720066627474E-4L, - 6.97281375836585777429E-5L - ]; - - real w = 1.0L / x; - real y = exp(x); - if (x > 1024.0L) - { - // For large x, use rational coefficients from the analytical expansion. - w = poly(w, LargeStirlingCoeffs); - // Avoid overflow in pow() - real v = pow( x, 0.5L * x - 0.25L ); - y = v * (v / y); - } - else - { - w = 1.0L + w * poly(w, SmallStirlingCoeffs); - y = pow( x, x - 0.5L ) / y; - } - y = SQRT2PI * y * w; - return y; + real w = 1.0L/x; + real y = exp(x); + if ( x > 1024.0L ) { + // For large x, use rational coefficients from the analytical expansion. + w = poly(w, LargeStirlingCoeffs); + // Avoid overflow in pow() + real v = pow( x, 0.5L * x - 0.25L ); + y = v * (v / y); + } + else { + w = 1.0L + w * poly( w, SmallStirlingCoeffs); + y = pow( x, x - 0.5L ) / y; + } + y = SQRT2PI * y * w; + return y; } /***************************************************** @@ -177,125 +170,106 @@ private real gammaStirling(real x) */ real tgamma(real x) { - /* Author: Don Clugston. Based on code from the CEPHES library. - * - * Arguments |x| <= 13 are reduced by recurrence and the function - * approximated by a rational function of degree 7/8 in the - * interval (2,3). Large arguments are handled by Stirling's - * formula. Large negative arguments are made positive using - * a reflection formula. - */ - - real q, z; - - if (isnan(x)) - return x; - if (x == -x.infinity) - return real.nan; - if ( fabs(x) > MAXGAMMA ) - return real.infinity; - if (x == 0) - return 1.0 / x; // +- infinity depending on sign of x, create an exception. - - q = fabs(x); - - if ( q > 13.0L ) - { - // Large arguments are handled by Stirling's - // formula. Large negative arguments are made positive using - // the reflection formula. +/* Author: Don Clugston. Based on code from the CEPHES library. + * + * Arguments |x| <= 13 are reduced by recurrence and the function + * approximated by a rational function of degree 7/8 in the + * interval (2,3). Large arguments are handled by Stirling's + * formula. Large negative arguments are made positive using + * a reflection formula. + */ + + real q, z; + if (isnan(x)) return x; + if (x==-x.infinity) return real.nan; + if ( fabs(x) > MAXGAMMA ) return real.infinity; + if (x==0) return 1.0/x; // +- infinity depending on sign of x, create an exception. + + q = fabs(x); + + if ( q > 13.0L ) { + // Large arguments are handled by Stirling's + // formula. Large negative arguments are made positive using + // the reflection formula. + + if ( x < 0.0L ) { + int sgngam = 1; // sign of gamma. + real p = floor(q); + if ( p == q ) return real.nan; // poles for all integers <0. + int intpart = cast(int)(p); + if ( (intpart & 1) == 0 ) + sgngam = -1; + z = q - p; + if ( z > 0.5L ) { + p += 1.0L; + z = q - p; + } + z = q * sin( PI * z ); + z = fabs(z) * gammaStirling(q); + if ( z <= PI/real.max ) return sgngam * real.infinity; + return sgngam * PI/z; + } else { + return gammaStirling(x); + } + } + + // Arguments |x| <= 13 are reduced by recurrence and the function + // approximated by a rational function of degree 7/8 in the + // interval (2,3). - if ( x < 0.0L ) - { - int sgngam = 1; // sign of gamma. - real p = floor(q); - if ( p == q ) - return real.nan; // poles for all integers <0. - int intpart = cast(int)(p); - if ( (intpart & 1) == 0 ) - sgngam = -1; - z = q - p; - if ( z > 0.5L ) - { - p += 1.0L; - z = q - p; - } - z = q * sin( PI * z ); - z = fabs(z) * gammaStirling(q); - if ( z <= PI / real.max ) - return sgngam * real.infinity; - return sgngam * PI / z; - } - else - return gammaStirling(x); - } - - // Arguments |x| <= 13 are reduced by recurrence and the function - // approximated by a rational function of degree 7/8 in the - // interval (2,3). - - z = 1.0L; - while ( x >= 3.0L ) - { - x -= 1.0L; - z *= x; - } - - while ( x < -0.03125L ) - { - z /= x; - x += 1.0L; - } - - if ( x <= 0.03125L ) - { - if ( x == 0.0L ) - return real.nan; - else if ( x < 0.0L ) - { - x = -x; - return z / (x * poly( x, GammaSmallNegCoeffs )); + z = 1.0L; + while ( x >= 3.0L ) { + x -= 1.0L; + z *= x; } - else - { - return z / (x * poly( x, GammaSmallCoeffs )); + + while ( x < -0.03125L ) { + z /= x; + x += 1.0L; + } + + if ( x <= 0.03125L ) { + if ( x == 0.0L ) return real.nan; + else { + if ( x < 0.0L ) { + x = -x; + return z / (x * poly( x, GammaSmallNegCoeffs )); + } else { + return z / (x * poly( x, GammaSmallCoeffs )); + } + } + } + + while ( x < 2.0L ) { + z /= x; + x += 1.0L; } - } - - while ( x < 2.0L ) - { - z /= x; - x += 1.0L; - } - if ( x == 2.0L ) - return z; - - x -= 2.0L; - return z * poly( x, GammaNumeratorCoeffs ) / poly( x, GammaDenominatorCoeffs ); + if ( x == 2.0L ) return z; + + x -= 2.0L; + return z * poly( x, GammaNumeratorCoeffs ) / poly( x, GammaDenominatorCoeffs ); } -unittest -{ - // gamma(n) = factorial(n-1) if n is an integer. - double fact = 1.0L; - for (int i = 1; fact < real.max; ++i) - { - // Require exact equality for small factorials - if (i < 14) - assert(tgamma(i * 1.0L)==fact); - assert(feqrel(tgamma(i * 1.0L), fact) > real.mant_dig - 15); - //writefln(i, " %a ---> %a %a ", i*1.0L, tgamma(i * 1.0L), fact, feqrel(tgamma(i*1.0L), fact)); - fact *= (i * 1.0L); - } - assert(tgamma(0.0) == real.infinity); - assert(tgamma(-0.0) == -real.infinity); - assert(isnan(tgamma(-1.0))); - assert(isnan(tgamma(real.nan))); - assert(tgamma(real.infinity) == real.infinity); - assert(isnan(tgamma(-real.infinity))); - assert(tgamma(real.min * real.epsilon) == real.infinity); - - assert(feqrel(tgamma(0.5), sqrt(PI)) > real.mant_dig - 3); +version(X86) // requires feqrel +unittest { + // gamma(n) = factorial(n-1) if n is an integer. + double fact=1.0L; + for (int i=1; factreal.mant_dig-15); + //writefln(i, " %a ---> %a %a ", i*1.0L, tgamma(i*1.0L), fact, feqrel(tgamma(i*1.0L), fact)); + fact*=(i*1.0L); + } + assert(tgamma(0.0)==real.infinity); + assert(tgamma(-0.0)==-real.infinity); + assert(isnan(tgamma(-1.0))); + assert(isnan(tgamma(real.nan))); + assert(tgamma(real.infinity)==real.infinity); + assert(isnan(tgamma(-real.infinity))); + assert(tgamma(real.min*real.epsilon)==real.infinity); + + assert(feqrel(tgamma(0.5),sqrt(PI))>real.mant_dig-3); } /***************************************************** @@ -318,160 +292,221 @@ unittest */ real lgamma(real x) { - /* Author: Don Clugston. Based on code from the CEPHES library. - * - * For arguments greater than 33, the logarithm of the gamma - * function is approximated by the logarithmic version of - * Stirling's formula using a polynomial approximation of - * degree 4. Arguments between -33 and +33 are reduced by - * recurrence to the interval [2,3] of a rational approximation. - * The cosecant reflection formula is employed for arguments - * less than -33. - */ - real q, w, z, f, nx; - - if (isnan(x)) - return x; - if (fabs(x) == x.infinity) - return x.infinity; - - if ( x < -34.0L ) - { - q = -x; - w = lgamma(q); - real p = floor(q); - if ( p == q ) - return real.infinity; - int intpart = cast(int)(p); - real sgngam = 1; - if ( (intpart & 1) == 0 ) - sgngam = -1; - z = q - p; - if ( z > 0.5L ) - { - p += 1.0L; - z = p - q; + /* Author: Don Clugston. Based on code from the CEPHES library. + * + * For arguments greater than 33, the logarithm of the gamma + * function is approximated by the logarithmic version of + * Stirling's formula using a polynomial approximation of + * degree 4. Arguments between -33 and +33 are reduced by + * recurrence to the interval [2,3] of a rational approximation. + * The cosecant reflection formula is employed for arguments + * less than -33. + */ + real p, q, w, z, f, nx; + + if (isnan(x)) return x; + if (fabs(x)==x.infinity) return x.infinity; + + if( x < -34.0L ) { + q = -x; + w = lgamma(q); + real p = floor(q); + if ( p == q ) return real.infinity; + int intpart = cast(int)(p); + real sgngam = 1; + if ( (intpart & 1) == 0 ) + sgngam = -1; + z = q - p; + if ( z > 0.5L ) { + p += 1.0L; + z = p - q; + } + z = q * sin( PI * z ); + if ( z == 0.0L ) return sgngam * real.infinity; + /* z = LOGPI - logl( z ) - w; */ + z = log( PI/z ) - w; + return( z ); } - z = q * sin( PI * z ); - if ( z == 0.0L ) - return sgngam * real.infinity; - /* z = LOGPI - logl( z ) - w; */ - z = log( PI / z ) - w; - return z; - } - if ( x < 13.0L ) - { - z = 1.0L; - nx = floor( x + 0.5L ); - f = x - nx; - while ( x >= 3.0L ) - { - nx -= 1.0L; - x = nx + f; - z *= x; - } - while ( x < 2.0L ) - { - if( fabs(x) <= 0.03125 ) - { - if ( x == 0.0L ) - return real.infinity; - if ( x < 0.0L ) - { - x = -x; - q = z / (x * poly( x, GammaSmallNegCoeffs)); + if( x < 13.0L ) { + z = 1.0L; + nx = floor( x + 0.5L ); + f = x - nx; + while ( x >= 3.0L ) { + nx -= 1.0L; + x = nx + f; + z *= x; } - else - q = z / (x * poly( x, GammaSmallCoeffs)); - return log( fabs(q) ); - } - z /= nx + f; - nx += 1.0L; - x = nx + f; - } - z = fabs(z); - if ( x == 2.0L ) - return log(z); - x = (nx - 2.0L) + f; - real p = x * poly( x, logGammaNumerator ) / poly( x, logGammaDenominator); - return ( log(z) + p ); - } - + while ( x < 2.0L ) { + if( fabs(x) <= 0.03125 ) { + if ( x == 0.0L ) return real.infinity; + if ( x < 0.0L ) { + x = -x; + q = z / (x * poly( x, GammaSmallNegCoeffs)); + } else + q = z / (x * poly( x, GammaSmallCoeffs)); + return log( fabs(q) ); + } + z /= nx + f; + nx += 1.0L; + x = nx + f; + } + z = fabs(z); + if ( x == 2.0L ) + return log(z); + x = (nx - 2.0L) + f; + p = x * poly( x, logGammaNumerator ) / poly( x, logGammaDenominator); + return ( log(z) + p ); + } + //const real MAXLGM = 1.04848146839019521116e+4928L; - //if ( x > MAXLGM ) return sgngaml * real.infinity; + // if( x > MAXLGM ) return sgngaml * real.infinity; - /* log( sqrt( 2*pi ) ) */ - const real LOGSQRT2PI = 0.91893853320467274178L; - - q = ( x - 0.5L ) * log(x) - x + LOGSQRT2PI; - if (x > 1.0e10L) return q; - real p = 1.0L/(x*x); - q += poly( p, logGammaStirlingCoeffs ) / x; - return q ; + /* log( sqrt( 2*pi ) ) */ + const real LOGSQRT2PI = 0.91893853320467274178L; + + q = ( x - 0.5L ) * log(x) - x + LOGSQRT2PI; + if (x > 1.0e10L) return q; + p = 1.0L/(x*x); + q += poly( p, logGammaStirlingCoeffs ) / x; + return q ; } -unittest -{ - assert(isnan(lgamma(real.nan))); - assert(lgamma(real.infinity) == real.infinity); - assert(lgamma(-1.0) == real.infinity); - assert(lgamma(0.0) == real.infinity); - assert(std.math.isPosZero(lgamma(1.0L))); - assert(std.math.isPosZero(lgamma(2.0L))); +version(X86) // requires feqrel +unittest { + assert(isnan(lgamma(real.nan))); + assert(lgamma(real.infinity)==real.infinity); + assert(lgamma(-1.0)==real.infinity); + assert(lgamma(0.0)==real.infinity); + assert(isPosZero(lgamma(1.0L))); + assert(isPosZero(lgamma(2.0L))); - // x, correct loggamma(x), correct d/dx loggamma(x). - static real[] testpoints = - [ - 8.0L, 8.525146484375L + 1.48766904143001655310E-5, 2.01564147795560999654E0L, - 8.99993896484375e-1L, 6.6375732421875e-2L + 5.11505711292524166220E-6L, -7.54938684259372234258E-1, - 7.31597900390625e-1L, 2.2369384765625e-1 + 5.21506341809849792422E-6L, -1.13355566660398608343E0L, - 2.31639862060546875e-1L, 1.3686676025390625L + 1.12609441752996145670E-5L, -4.56670961813812679012E0, - 1.73162841796875L, -8.88214111328125e-2L + 3.36207740803753034508E-6L, 2.33339034686200586920E-1L, - 1.23162841796875L, -9.3902587890625e-2L + 1.28765089229009648104E-5L, -2.49677345775751390414E-1L, - 7.3786976294838206464e19L, 3.301798506038663053312e21L - 1.656137564136932662487046269677E5L, + // x, correct loggamma(x), correct d/dx loggamma(x). + static real[] testpoints = [ + 8.0L, 8.525146484375L + 1.48766904143001655310E-5, 2.01564147795560999654E0L, + 8.99993896484375e-1L, 6.6375732421875e-2L + 5.11505711292524166220E-6L, -7.54938684259372234258E-1, + 7.31597900390625e-1L, 2.2369384765625e-1 + 5.21506341809849792422E-6L, -1.13355566660398608343E0L, + 2.31639862060546875e-1L, 1.3686676025390625L + 1.12609441752996145670E-5L, -4.56670961813812679012E0, + 1.73162841796875L, -8.88214111328125e-2L + 3.36207740803753034508E-6L, 2.33339034686200586920E-1L, + 1.23162841796875L, -9.3902587890625e-2L + 1.28765089229009648104E-5L, -2.49677345775751390414E-1L, + 7.3786976294838206464e19L, 3.301798506038663053312e21L - 1.656137564136932662487046269677E5L, 4.57477139169563904215E1L, - 1.08420217248550443401E-19L, 4.36682586669921875e1L + 1.37082843669932230418E-5L, + 1.08420217248550443401E-19L, 4.36682586669921875e1L + 1.37082843669932230418E-5L, -9.22337203685477580858E18L, -// 1.0L, 0.0L, -5.77215664901532860607E-1L, -// 2.0L, 0.0L, 4.22784335098467139393E-1L, - -0.5L, 1.2655029296875L + 9.19379714539648894580E-6L, 3.64899739785765205590E-2L, - -1.5L, 8.6004638671875e-1L + 6.28657731014510932682E-7L, 7.03156640645243187226E-1L, - -2.5L, -5.6243896484375E-2L + 1.79986700949327405470E-7, 1.10315664064524318723E0L, - -3.5L, -1.30902099609375L + 1.43111007079536392848E-5L, 1.38887092635952890151E0L - ]; - - // TODO: test derivatives as well. - - for (int i=0; i real.mant_dig-5); - } - - static real logabsgamma(real x) - { - // For poles, tgamma(x) returns nan, but lgamma() returns infinity. - if (x < 0 && x == floor(x)) - return real.infinity; - return log(fabs(tgamma(x))); - } - - static real exploggamma(real x) - { - return exp(lgamma(x)); - } - - static real absgamma(real x) - { - if (x < 0 && x == floor(x)) - return real.infinity; - return fabs(tgamma(x)); - } - - // Check that loggamma(x) = log(gamma(x)) provided x is not -1, -2, -3, ... - //assert(consistencyTwoFuncs(&lgamma, &logabsgamma, -1000, 1700) > real.mant_dig-7); - //assert(consistencyTwoFuncs(&exploggamma, &absgamma, -2000, real.infinity) > real.mant_dig-16); +// 1.0L, 0.0L, -5.77215664901532860607E-1L, +// 2.0L, 0.0L, 4.22784335098467139393E-1L, + -0.5L, 1.2655029296875L + 9.19379714539648894580E-6L, 3.64899739785765205590E-2L, + -1.5L, 8.6004638671875e-1L + 6.28657731014510932682E-7L, 7.03156640645243187226E-1L, + -2.5L, -5.6243896484375E-2L + 1.79986700949327405470E-7, 1.10315664064524318723E0L, + -3.5L, -1.30902099609375L + 1.43111007079536392848E-5L, 1.38887092635952890151E0L + ]; + // TODO: test derivatives as well. + for (int i=0; i real.mant_dig-5); + } + + static real logabsgamma(real x) + { + // For poles, tgamma(x) returns nan, but lgamma() returns infinity. + if (x<0 && x==floor(x)) return real.infinity; + return log(fabs(tgamma(x))); + } + static real exploggamma(real x) + { + return exp(lgamma(x)); + } + static real absgamma(real x) + { + if (x<0 && x==floor(x)) return real.infinity; + return fabs(tgamma(x)); + } + + // Check that loggamma(x) = log(gamma(x)) provided x is not -1, -2, -3, ... + //assert(consistencyTwoFuncs(&lgamma, &logabsgamma, -1000, 1700) > real.mant_dig-7); + //assert(consistencyTwoFuncs(&exploggamma, &absgamma, -2000, real.infinity) > real.mant_dig-16); } +/** + Test the consistency of a real function which can be calculated in two ways. + + Returns the worst (minimum) value of feqrel(firstfunc(x), secondfunc(x)) + for all x in the domain. +Params: + firstfunc, secondfunc Functions to be compared + domain A sequence of pairs of numbers giving the first and last +points which are valid for the function. +eg. (-real.infinity, real.infinity) ==> valid everywhere + (-real.infinity, -real.min, real.min, real.infinity) ==> valid for x!=0. + Returns: + number of bits for which firstfunc(x) and secondfunc(x) are equal for + every point x in the domain. + -1 = at least one point is wrong by a factor of 2 or more. +*/ +version(X86) // requires feqrel +int consistencyTwoFuncs(real function (real) firstfunc, + real function (real) secondfunc, real [] domain ...) +{ + /* Author: Don Clugston. License: Public Domain + */ + assert(domain.length>=2); // must have at least one valid range + assert((domain.length & 1) == 0); // must have even number of endpoints. + + int worsterror=real.mant_dig+1; + real worstx=domain[0]; // where does the biggest discrepancy occur? + + void testPoint(real x) { + for (int i=0; i=domain[i] && x<=domain[i+1]) { + int u=feqrel(secondfunc(x), firstfunc(x)); + if (u 1) { @@ -110,7 +116,7 @@ extern (C) long _adReverseChar(char[] a) hi = hi - 1 + (stridehi - stridelo); } } - return *cast(long*)(&a); + return *cast(Array*)(&a); } unittest @@ -146,7 +152,7 @@ unittest * reversed. */ -extern (C) long _adReverseWchar(wchar[] a) +extern (C) Array _adReverseWchar(wchar[] a) { if (a.length > 1) { @@ -204,7 +210,7 @@ extern (C) long _adReverseWchar(wchar[] hi = hi - 1 + (stridehi - stridelo); } } - return *cast(long*)(&a); + return *cast(Array*)(&a); } unittest @@ -224,15 +230,163 @@ unittest assert(r == "c\U00012345ba"); } +// %% Had to move _adCmpChar to the beginning of the file +// due to a extern/static symbol conflict on darwin... +/*************************************** + * Support for array compare test. + */ + +extern (C) int _adCmpChar(Array a1, Array a2) +{ +version (Asm86) +{ + asm + { naked ; + + push EDI ; + push ESI ; + + mov ESI,a1+4[4+ESP] ; + mov EDI,a2+4[4+ESP] ; + + mov ECX,a1[4+ESP] ; + mov EDX,a2[4+ESP] ; + + cmp ECX,EDX ; + jb GotLength ; + + mov ECX,EDX ; + +GotLength: + cmp ECX,4 ; + jb DoBytes ; + + // Do alignment if neither is dword aligned + test ESI,3 ; + jz Aligned ; + + test EDI,3 ; + jz Aligned ; +DoAlign: + mov AL,[ESI] ; //align ESI to dword bounds + mov DL,[EDI] ; + + cmp AL,DL ; + jnz Unequal ; + + inc ESI ; + inc EDI ; + + test ESI,3 ; + + lea ECX,[ECX-1] ; + jnz DoAlign ; +Aligned: + mov EAX,ECX ; + + // do multiple of 4 bytes at a time + + shr ECX,2 ; + jz TryOdd ; + + repe ; + cmpsd ; + + jnz UnequalQuad ; + +TryOdd: + mov ECX,EAX ; +DoBytes: + // if still equal and not end of string, do up to 3 bytes slightly + // slower. + + and ECX,3 ; + jz Equal ; + + repe ; + cmpsb ; + + jnz Unequal ; +Equal: + mov EAX,a1[4+ESP] ; + mov EDX,a2[4+ESP] ; + + sub EAX,EDX ; + pop ESI ; + + pop EDI ; + ret ; + +UnequalQuad: + mov EDX,[EDI-4] ; + mov EAX,[ESI-4] ; + + cmp AL,DL ; + jnz Unequal ; + + cmp AH,DH ; + jnz Unequal ; + + shr EAX,16 ; + + shr EDX,16 ; + + cmp AL,DL ; + jnz Unequal ; + + cmp AH,DH ; +Unequal: + sbb EAX,EAX ; + pop ESI ; + + or EAX,1 ; + pop EDI ; + + ret ; + } +} +else +{ + int len; + int c; + + //printf("adCmpChar()\n"); + len = a1.length; + if (a2.length < len) + len = a2.length; + c = std.string.memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len); + if (!c) + c = cast(int)a1.length - cast(int)a2.length; + return c; +} +} + +unittest +{ + debug(adi) printf("array.CmpChar unittest\n"); + + char[] a = "hello"; + + assert(a > "hel"); + assert(a >= "hel"); + assert(a < "helloo"); + assert(a <= "helloo"); + assert(a > "betty"); + assert(a >= "betty"); + assert(a == "hello"); + assert(a <= "hello"); + assert(a >= "hello"); +} + /********************************************** * Support for array.reverse property. */ -extern (C) long _adReverse(Array a, size_t szelem) +extern (C) Array _adReverse(Array a, size_t szelem) out (result) { - assert(result is *cast(long*)(&a)); + assert(result is a); } body { @@ -271,7 +425,7 @@ extern (C) long _adReverse(Array a, size //delete tmp; } } - return *cast(long*)(&a); + return a; } unittest @@ -363,7 +517,7 @@ unittest * Sort array of chars. */ -extern (C) long _adSortChar(char[] a) +extern (C) char[] _adSortChar(char[] a) { if (a.length > 1) { @@ -378,14 +532,14 @@ extern (C) long _adSortChar(char[] a) } delete da; } - return *cast(long*)(&a); + return a; } /********************************************** * Sort array of wchars. */ -extern (C) long _adSortWchar(wchar[] a) +extern (C) wchar[] _adSortWchar(wchar[] a) { if (a.length > 1) { @@ -400,7 +554,7 @@ extern (C) long _adSortWchar(wchar[] a) } delete da; } - return *cast(long*)(&a); + return a; } /********************************************** @@ -510,12 +664,12 @@ unittest version (none) { extern (C) int _adEqBit(Array a1, Array a2) -{ size_t i; +{ int i; if (a1.length != a2.length) return 0; // not equal - auto p1 = cast(byte*)a1.ptr; - auto p2 = cast(byte*)a2.ptr; + auto p1 = cast(ubyte*)a1.ptr; + auto p2 = cast(ubyte*)a2.ptr; auto n = a1.length / 8; for (i = 0; i < n; i++) { @@ -599,151 +753,6 @@ unittest assert(a >= "hello"); } -/*************************************** - * Support for array compare test. - */ - -extern (C) int _adCmpChar(Array a1, Array a2) -{ -version (X86) -{ - asm - { naked ; - - push EDI ; - push ESI ; - - mov ESI,a1+4[4+ESP] ; - mov EDI,a2+4[4+ESP] ; - - mov ECX,a1[4+ESP] ; - mov EDX,a2[4+ESP] ; - - cmp ECX,EDX ; - jb GotLength ; - - mov ECX,EDX ; - -GotLength: - cmp ECX,4 ; - jb DoBytes ; - - // Do alignment if neither is dword aligned - test ESI,3 ; - jz Aligned ; - - test EDI,3 ; - jz Aligned ; -DoAlign: - mov AL,[ESI] ; //align ESI to dword bounds - mov DL,[EDI] ; - - cmp AL,DL ; - jnz Unequal ; - - inc ESI ; - inc EDI ; - - test ESI,3 ; - - lea ECX,[ECX-1] ; - jnz DoAlign ; -Aligned: - mov EAX,ECX ; - - // do multiple of 4 bytes at a time - - shr ECX,2 ; - jz TryOdd ; - - repe ; - cmpsd ; - - jnz UnequalQuad ; - -TryOdd: - mov ECX,EAX ; -DoBytes: - // if still equal and not end of string, do up to 3 bytes slightly - // slower. - - and ECX,3 ; - jz Equal ; - - repe ; - cmpsb ; - - jnz Unequal ; -Equal: - mov EAX,a1[4+ESP] ; - mov EDX,a2[4+ESP] ; - - sub EAX,EDX ; - pop ESI ; - - pop EDI ; - ret ; - -UnequalQuad: - mov EDX,[EDI-4] ; - mov EAX,[ESI-4] ; - - cmp AL,DL ; - jnz Unequal ; - - cmp AH,DH ; - jnz Unequal ; - - shr EAX,16 ; - - shr EDX,16 ; - - cmp AL,DL ; - jnz Unequal ; - - cmp AH,DH ; -Unequal: - sbb EAX,EAX ; - pop ESI ; - - or EAX,1 ; - pop EDI ; - - ret ; - } -} -else -{ - int len; - int c; - - //printf("adCmpChar()\n"); - len = a1.length; - if (a2.length < len) - len = a2.length; - c = string.memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len); - if (!c) - c = cast(int)a1.length - cast(int)a2.length; - return c; -} -} - -unittest -{ - debug(adi) printf("array.CmpChar unittest\n"); - - char[] a = "hello"; - - assert(a > "hel"); - assert(a >= "hel"); - assert(a < "helloo"); - assert(a <= "helloo"); - assert(a > "betty"); - assert(a >= "betty"); - assert(a == "hello"); - assert(a <= "hello"); - assert(a >= "hello"); -} /*************************************** * Support for array compare test. diff -uNrp dmd-1.007/src/phobos/internal/arraycat.d gdc-0.23/d/phobos/internal/arraycat.d --- dmd-1.007/src/phobos/internal/arraycat.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/arraycat.d 2007-02-13 20:40:39.000000000 +0100 @@ -25,6 +25,12 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, November 2006 +*/ + module arraycat; import object; @@ -34,7 +40,7 @@ import std.c.stdio; import std.c.stdarg; extern (C) -byte[] _d_arraycopy(uint size, byte[] from, byte[] to) +byte[] _d_arraycopy(size_t size, byte[] from, byte[] to) { //printf("f = %p,%d, t = %p,%d, size = %d\n", (void*)from, from.length, (void*)to, to.length, size); diff -uNrp dmd-1.007/src/phobos/internal/cast.d gdc-0.23/d/phobos/internal/cast.d --- dmd-1.007/src/phobos/internal/cast.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/cast.d 2007-02-15 16:58:23.000000000 +0100 @@ -80,7 +80,7 @@ Object _d_interface_cast(void* p, ClassI Object _d_dynamic_cast(Object o, ClassInfo c) { ClassInfo oc; - uint offset = 0; + size_t offset = 0; //printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name); @@ -99,7 +99,7 @@ Object _d_dynamic_cast(Object o, ClassIn return o; } -int _d_isbaseof2(ClassInfo oc, ClassInfo c, inout uint offset) +int _d_isbaseof2(ClassInfo oc, ClassInfo c, inout size_t offset) { int i; if (oc is c) diff -uNrp dmd-1.007/src/phobos/internal/cmain.d gdc-0.23/d/phobos/internal/cmain.d --- dmd-1.007/src/phobos/internal/cmain.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/cmain.d 2006-06-03 04:57:26.000000000 +0200 @@ -0,0 +1,6 @@ +private extern (C) int _d_run_main(int argc, char **argv, void * p); +int main(); +extern (C) int main(int argc, char **argv) +{ + return _d_run_main(argc, argv, & main); +} diff -uNrp dmd-1.007/src/phobos/internal/critical.c gdc-0.23/d/phobos/internal/critical.c --- dmd-1.007/src/phobos/internal/critical.c 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/critical.c 2006-11-11 22:07:38.000000000 +0100 @@ -4,6 +4,14 @@ * www.digitalmars.com */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + +#include "config.h" + /* ================================= Win32 ============================ */ #if _WIN32 @@ -75,16 +83,22 @@ void _STD_critical_term() /* ================================= linux ============================ */ -#if linux +#if linux || PHOBOS_USE_PTHREADS + -#include -#include #include +#ifndef HAVE_PTHREAD_MUTEX_RECURSIVE +#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +#endif + + /****************************************** * Enter/exit critical section. */ + + /* We don't initialize critical sections unless we actually need them. * So keep a linked list of the ones we do use, and in the static destructor * code, walk the list and release them. @@ -117,7 +131,11 @@ void _d_criticalenter(D_CRITICAL_SECTION { dcs->next = dcs_list; dcs_list = dcs; - pthread_mutex_init(&dcs->cs, &_criticals_attr); +#ifndef PTHREAD_MUTEX_ALREADY_RECURSIVE + pthread_mutex_init(&dcs->cs, & _criticals_attr); +#else + pthread_mutex_init(&dcs->cs, NULL); +#endif } pthread_mutex_unlock(&critical_section.cs); } @@ -126,7 +144,7 @@ void _d_criticalenter(D_CRITICAL_SECTION void _d_criticalexit(D_CRITICAL_SECTION *dcs) { - //printf("_d_criticalexit(dcs = x%x)\n", dcs); + //printf("_d_criticalexit(dcs = x%x)\n", dcs); pthread_mutex_unlock(&dcs->cs); } @@ -134,8 +152,10 @@ void _STI_critical_init() { if (!dcs_list) { //printf("_STI_critical_init()\n"); +#ifndef PTHREAD_MUTEX_ALREADY_RECURSIVE pthread_mutexattr_init(&_criticals_attr); - pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE); +#endif // The global critical section doesn't need to be recursive pthread_mutex_init(&critical_section.cs, 0); diff -uNrp dmd-1.007/src/phobos/internal/dgccmain2.d gdc-0.23/d/phobos/internal/dgccmain2.d --- dmd-1.007/src/phobos/internal/dgccmain2.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/dgccmain2.d 2006-11-18 16:17:14.000000000 +0100 @@ -0,0 +1,107 @@ + +/* NOTE: This file is based on dmain2.d from the original DMD distribution. + +*/ + +import object; +import std.c.stdio; +import std.c.stdlib; +import std.c.string; +version (GNU) +{ + private import gcc.config; + private import gc_guess_stack; +} + +extern (C) void _STI_monitor_staticctor(); +extern (C) void _STD_monitor_staticdtor(); +extern (C) void _STI_critical_init(); +extern (C) void _STD_critical_term(); +extern (C) void gc_init(); +extern (C) void gc_term(); +extern (C) void _minit(); +extern (C) void _moduleCtor(); +extern (C) void _moduleDtor(); +extern (C) void _moduleUnitTests(); + +extern (C) bool no_catch_exceptions; + +/*********************************** + * The D main() function supplied by the user's program + */ +//int main(char[][] args); +extern (C) alias int function(char[][] args) main_type; + +/*********************************** + * Substitutes for the C main() function. + * It's purpose is to wrap the call to the D main() + * function and catch any unhandled exceptions. + */ + +/* Note that this is not the C main function, nor does it refer + to the D main function as in the DMD version. The actual C + main is in cmain.d + + This serves two purposes: + 1) Special applications that have a C main declared elsewhere. + + 2) It is possible to create D shared libraries that can be used + by non-D executables. (TODO: Not complete, need a general library + init routine.) +*/ + +extern (C) int _d_run_main(int argc, char **argv, main_type main_func) +{ + char[] *am; + char[][] args; + int i; + int result; + + version (GC_Use_Stack_Guess) + stackOriginGuess = &argv; + version (GNU_CBridge_Stdio) + _d_gnu_cbridge_init_stdio(); + // Win32: original didn't do this -- what about Gcc? + _STI_monitor_staticctor(); + _STI_critical_init(); + gc_init(); + am = cast(char[] *) malloc(argc * (char[]).sizeof); + + void go() + { + _moduleCtor(); + _moduleUnitTests(); + + for (i = 0; i < argc; i++) + { + int len = strlen(argv[i]); + am[i] = argv[i][0 .. len]; + } + + args = am[0 .. argc]; + + result = main_func(args); + _moduleDtor(); + gc_term(); + } + + if (no_catch_exceptions) + go(); + else + { + try + go(); + catch (Object o) + { + printf("Error: "); + o.print(); + exit(EXIT_FAILURE); + } + } + + free(am); + _STD_critical_term(); + _STD_monitor_staticdtor(); + + return result; +} diff -uNrp dmd-1.007/src/phobos/internal/fpmath.d gdc-0.23/d/phobos/internal/fpmath.d --- dmd-1.007/src/phobos/internal/fpmath.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/fpmath.d 2007-02-20 02:04:53.000000000 +0100 @@ -0,0 +1,184 @@ +module gcc.fpmath; + +enum +{ + FP_NAN = 1, + FP_INFINITE, + FP_ZERO, + FP_SUBNORMAL, + FP_NORMAL, +} + +enum RealFormat +{ + SameAsDouble, + DoubleDouble, + Intel80, +} + +struct Info { + static if (real.sizeof == double.sizeof) { + static const RealFormat realFormat = RealFormat.SameAsDouble; + } else version (PPC) { + static const RealFormat realFormat = RealFormat.DoubleDouble; + union real_rec { + real f; + struct { double hd, ld; } + } + } else version (PPC64) { + static const RealFormat realFormat = RealFormat.DoubleDouble; + union real_rec { + real f; + struct { double hd, ld; } + } + } else version (X86) { + static const RealFormat realFormat = RealFormat.Intel80; + union real_rec { + real f; + struct { uint li, mi, hi; } + } + } else version (X86_64) { + static const RealFormat realFormat = RealFormat.Intel80; + union real_rec { + real f; + struct { uint li, mi, hi; } + } + } else { + static assert(0); + } +} + +union float_rec { + float f; + uint i; +} + +int signbit(float f) +{ + float_rec r = void; + r.f = f; + return r.i & 0x80000000; +} + +int fpclassify(float f) +{ + float_rec r = void; + r.f = f; + uint i = r.i & 0x7fffffff; + + if (! i) + return FP_ZERO; + else if (i < 0x00800000) + return FP_SUBNORMAL; + else if (i < 0x7f800000) + return FP_NORMAL; + else if (i < 0x7f800001) + return FP_INFINITE; + else + return FP_NAN; +} + +union double_rec { + double f; + struct { + version (BigEndian) + uint hi, li; + else + uint li, hi; + } +} + +int signbit(double f) +{ + double_rec r = void; + r.f = f; + return r.hi & 0x80000000; +} + +int fpclassify(double f) +{ + double_rec r = void; + r.f = f; + uint i = r.hi & 0x7fffffff; + + if (! (i | r.li)) + return FP_ZERO; + else if (i < 0x00100000) + return FP_SUBNORMAL; + else if (i < 0x7ff00000) + return FP_NORMAL; + else if (i == 0x7ff00000 && ! r.li) + return FP_INFINITE; + else + return FP_NAN; +} + +int signbit(real f) +{ + static if (Info.realFormat == RealFormat.SameAsDouble) { + return signbit(cast(double) f); + } else static if (Info.realFormat == RealFormat.DoubleDouble) { + Info.real_rec r = void; + r.f = f; + return signbit(r.hd); + } else static if (Info.realFormat == RealFormat.Intel80) { + Info.real_rec r = void; + r.f = f; + return r.hi & 0x00008000; + } +} + +int fpclassify(real f) +{ + static if (Info.realFormat == RealFormat.SameAsDouble) { + return fpclassify(cast(double) f); + } else static if (Info.realFormat == RealFormat.DoubleDouble) { + Info.real_rec r = void; + r.f = f; + return fpclassify(r.hd); + } else static if (Info.realFormat == RealFormat.Intel80) { + Info.real_rec r = void; + r.f = f; + uint i = r.hi & 0x00007fff; + uint li = r.li | (r.mi & 0x7fffffff) ; + if (! i && ! li) + return FP_ZERO; + else if (i < 0x00000001 && (r.mi & 0x80000000) == 0) + return FP_SUBNORMAL; + else if (i < 0x00007fff) + return FP_NORMAL; + else if (i == 0x00007fff && ! li) + return FP_INFINITE; + else + return FP_NAN; + } +} + +unittest +{ + static if (Info.realFormat == RealFormat.SameAsDouble) { + const real xrsn = 0x1p-1050; + } else static if (Info.realFormat == RealFormat.DoubleDouble) { + const real xrsn = 0x1p-1050; + } else static if (Info.realFormat == RealFormat.Intel80) { + const real xrsn = 0x1p-16390; + } + + static float[] xfi = [ float.nan, -float.nan, float.infinity, -float.infinity, + 0.0f, -0.0f, 0x1p-135f, -0x1p-135f, 4.2f, -4.2f ]; + static double[] xdi = [ double.nan, -double.nan, double.infinity, -double.infinity, + 0.0, -0.0, 0x1p-1050, -0x1p-1050, 4.2, -4.2 ]; + static real[] xri = [ real.nan, -real.nan, real.infinity, -real.infinity, + 0.0L, -0.0L, xrsn, -xrsn, 4.2L, -4.2L ]; + static int[] xo = [ FP_NAN, FP_NAN, FP_INFINITE, FP_INFINITE, + FP_ZERO, FP_ZERO, FP_SUBNORMAL, FP_SUBNORMAL, FP_NORMAL, FP_NORMAL]; + + foreach (int i, int cls; xo) { + assert( fpclassify(xfi[i]) == xo[i] ); + assert( fpclassify(xdi[i]) == xo[i] ); + assert( fpclassify(xri[i]) == xo[i] ); + assert( ( signbit(xfi[i]) ?1:0 ) == (i & 1) ); + assert( ( signbit(xdi[i]) ?1:0 ) == (i & 1) ); + assert( ( signbit(xri[i]) ?1:0 ) == (i & 1) ); + } +} diff -uNrp dmd-1.007/src/phobos/internal/gc/gcbits.d gdc-0.23/d/phobos/internal/gc/gcbits.d --- dmd-1.007/src/phobos/internal/gc/gcbits.d 2007-02-20 20:22:02.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gcbits.d 2006-06-03 04:57:25.000000000 +0200 @@ -4,13 +4,24 @@ // www.digitalmars.com // Written by Walter Bright +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + import std.c.string; import std.c.stdlib; import std.outofmemory; import std.intrinsic; //version = Asm86; -version = bitops; +version (GNU) { + // bitop intrinsics not implemented yet +} else { + version = bitops; +} + struct GCBits { diff -uNrp dmd-1.007/src/phobos/internal/gc/gc_c.h gdc-0.23/d/phobos/internal/gc/gc_c.h --- dmd-1.007/src/phobos/internal/gc/gc_c.h 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gc_c.h 2006-06-03 04:57:25.000000000 +0200 @@ -0,0 +1,9 @@ +enum DataSegmentTracking { + ExecutableOnly, + LoadTimeLibrariesOnly, + Dynamic +}; +extern void _D3std2gc8addRangeFPvPvZv(void *, void *); +extern void _D3std2gc11removeRangeFPvZv(void *); +#define GC_add_range(x,y) (_D3std2gc8addRangeFPvPvZv((x),(y))) +#define GC_remove_range(x) (_D3std2gc11removeRangeFPvZv(x)) diff -uNrp dmd-1.007/src/phobos/internal/gc/gc.d gdc-0.23/d/phobos/internal/gc/gc.d --- dmd-1.007/src/phobos/internal/gc/gc.d 2007-02-20 20:22:02.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gc.d 2007-03-04 15:45:25.000000000 +0100 @@ -24,6 +24,12 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, February 2007 +*/ + // Storage allocation @@ -215,38 +221,34 @@ void _d_delclass(Object *p) */ /* For when the array is initialized to 0 */ -ulong _d_newarrayT(TypeInfo ti, size_t length) +Array _d_newarrayT(TypeInfo ti, size_t length) { - void *p; - ulong result; + Array result; auto size = ti.next.tsize(); // array element size debug(PRINTF) printf("_d_newT(length = %d, size = %d)\n", length, size); - if (length == 0 || size == 0) - result = 0; - else + if (length && size) { + result.length = length; size *= length; - p = _gc.malloc(size + 1); - debug(PRINTF) printf(" p = %p\n", p); + result.data = cast(byte*) _gc.malloc(size + 1); if (!(ti.next.flags() & 1)) - _gc.hasNoPointers(p); - memset(p, 0, size); - result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); + _gc.hasNoPointers(result.data); + memset(result.data, 0, size); } return result; } /* For when the array has a non-zero initializer. */ -ulong _d_newarrayiT(TypeInfo ti, size_t length) +Array _d_newarrayiT(TypeInfo ti, size_t length) { - ulong result; + Array result; auto size = ti.next.tsize(); // array element size //debug(PRINTF) printf("_d_newarrayiT(length = %d, size = %d, isize = %d)\n", length, size, isize); if (length == 0 || size == 0) - result = 0; + { } else { auto initializer = ti.next.init(); @@ -275,23 +277,22 @@ ulong _d_newarrayiT(TypeInfo ti, size_t memcpy(p + u, q, isize); } } - va_end(q); - result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); + result.length = length; + result.data = cast(byte*) p ; } return result; } -ulong _d_newarraymT(TypeInfo ti, int ndims, ...) +void[] _d_newarraymTp(TypeInfo ti, int ndims, size_t* pdim) { - ulong result; + void[] result = void; //debug(PRINTF) //printf("_d_newarraymT(ndims = %d)\n", ndims); if (ndims == 0) - result = 0; + result = null; else - { va_list q; - va_start!(int)(q, ndims); + { void[] foo(TypeInfo ti, size_t* pdim, int ndims) { @@ -315,34 +316,30 @@ ulong _d_newarraymT(TypeInfo ti, int ndi return p; } - size_t* pdim = cast(size_t *)q; - result = cast(ulong)foo(ti, pdim, ndims); + result = foo(ti, pdim, ndims); //printf("result = %llx\n", result); version (none) { for (int i = 0; i < ndims; i++) { - printf("index %d: %d\n", i, va_arg!(int)(q)); + printf("index %d: %d\n", i, pdim[i]); } } - va_end(q); } return result; } -ulong _d_newarraymiT(TypeInfo ti, int ndims, ...) +void[] _d_newarraymiTp(TypeInfo ti, int ndims, size_t* pdim) { - ulong result; + void[] result = void; //debug(PRINTF) //printf("_d_newarraymi(size = %d, ndims = %d)\n", size, ndims); if (ndims == 0) - result = 0; + result = null; else { - va_list q; - va_start!(int)(q, ndims); void[] foo(TypeInfo ti, size_t* pdim, int ndims) { @@ -365,19 +362,17 @@ ulong _d_newarraymiT(TypeInfo ti, int nd return p; } - size_t* pdim = cast(size_t *)q; - result = cast(ulong)foo(ti, pdim, ndims); + result = foo(ti, pdim, ndims); //printf("result = %llx\n", result); version (none) { for (int i = 0; i < ndims; i++) { - printf("index %d: %d\n", i, va_arg!(int)(q)); - printf("init = %d\n", va_arg!(int)(q)); + printf("index %d: %d\n", i, pdim[i]); + printf("init = %d\n", *cast(int*)pinit); } } - va_end(q); } return result; } @@ -483,6 +478,14 @@ body if (newlength) { + version (GNU) + { + // required to output the label; + static char x = 0; + if (x) + goto Loverflow; + } + version (D_InlineAsm_X86) { size_t newsize = void; @@ -577,6 +580,14 @@ body if (newlength) { + version (GNU) + { + // required to output the label; + static char x = 0; + if (x) + goto Loverflow; + } + version (D_InlineAsm_X86) { size_t newsize = void; @@ -657,7 +668,7 @@ Loverflow: */ extern (C) -long _d_arrayappendT(TypeInfo ti, Array *px, byte[] y) +Array _d_arrayappendT(TypeInfo ti, Array *px, byte[] y) { auto size = ti.next.tsize(); // array element size size_t cap = _gc.capacity(px.data); @@ -674,7 +685,7 @@ long _d_arrayappendT(TypeInfo ti, Array } px.length = newlength; memcpy(px.data + length * size, y.ptr, y.length * size); - return *cast(long*)px; + return *px; } size_t newCapacity(size_t newlength, size_t size) @@ -745,7 +756,7 @@ size_t newCapacity(size_t newlength, siz } extern (C) -byte[] _d_arrayappendcT(TypeInfo ti, inout byte[] x, ...) +byte[] _d_arrayappendcTp(TypeInfo ti, inout byte[] x, void *argp) { auto size = ti.next.tsize(); // array element size size_t cap = _gc.capacity(x.ptr); @@ -768,10 +779,9 @@ byte[] _d_arrayappendcT(TypeInfo ti, ino memcpy(newdata, x.ptr, length * size); (cast(void **)(&x))[1] = newdata; } - byte *argp = cast(byte *)(&ti + 2); *cast(size_t *)&x = newlength; - (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; + (cast(byte *)x)[length * size .. newlength * size] = (cast(byte*)argp)[0 .. size]; assert((cast(size_t)x.ptr & 15) == 0); assert(_gc.capacity(x.ptr) > x.length * size); return x; @@ -836,13 +846,14 @@ byte[] _d_arraycatnT(TypeInfo ti, uint n byte[]* p; uint i; byte[] b; + va_list va; auto size = ti.next.tsize(); // array element size - p = cast(byte[]*)(&n + 1); + va_start!(typeof(n))(va, n); for (i = 0; i < n; i++) { - b = *p++; + b = va_arg!(typeof(b))(va); length += b.length; } if (!length) @@ -851,12 +862,12 @@ byte[] _d_arraycatnT(TypeInfo ti, uint n a = new byte[length * size]; if (!(ti.next.flags() & 1)) _gc.hasNoPointers(a.ptr); - p = cast(byte[]*)(&n + 1); + va_start!(typeof(n))(va, n); uint j = 0; for (i = 0; i < n; i++) { - b = *p++; + b = va_arg!(typeof(b))(va); if (b.length) { memcpy(&a[j], b.ptr, b.length * size); @@ -864,11 +875,12 @@ byte[] _d_arraycatnT(TypeInfo ti, uint n } } - *cast(int *)&a = length; // jam length + *cast(size_t *)&a = length; // jam length //a.length = length; return a; } +version (GNU) { } else extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...) { @@ -921,7 +933,7 @@ struct Array2 } extern (C) -long _adDupT(TypeInfo ti, Array2 a) +Array2 _adDupT(TypeInfo ti, Array2 a) out (result) { auto szelem = ti.next.tsize(); // array element size @@ -941,7 +953,7 @@ long _adDupT(TypeInfo ti, Array2 a) r.length = a.length; memcpy(r.ptr, a.ptr, size); } - return *cast(long*)(&r); + return r; } unittest diff -uNrp dmd-1.007/src/phobos/internal/gc/gc_dyld.c gdc-0.23/d/phobos/internal/gc/gc_dyld.c --- dmd-1.007/src/phobos/internal/gc/gc_dyld.c 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gc_dyld.c 2007-03-06 03:20:13.000000000 +0100 @@ -0,0 +1,109 @@ +// Could config test HAVE_PRIVATE_EXTERN, but this should be okay +#ifndef __private_extern__ +#define __private_extern__ extern +#include +#undef __private_extern__ +#else +#include +#endif + +#include +#include + +#include "gc_c.h" + +const static struct { + const char *seg; + const char *sect; +} GC_dyld_sections[] = { + { SEG_DATA, SECT_DATA }, + { SEG_DATA, SECT_BSS }, + { SEG_DATA, SECT_COMMON } +}; + +#ifdef __ppc__ +#define THIS_IS_64_BIT 0 +#elif defined(__i386__) +#define THIS_IS_64_BIT 0 +#elif defined(__ppc64__) +#define THIS_IS_64_BIT 1 +#elif defined(__x86_64__) +#define THIS_IS_64_BIT 1 +#else +#error This architecture is not supported +#endif + +/* This should never be called by a thread holding the lock */ +static void +on_dyld_add_image(const struct mach_header* hdr, intptr_t slide) { + unsigned i; + uintptr_t start, end; +#if THIS_IS_64_BIT + const struct section_64 *sec; +#else + const struct section *sec; +#endif + + for (i = 0; + i < sizeof(GC_dyld_sections) / sizeof(GC_dyld_sections[0]); + i++) { + +#if THIS_IS_64_BIT + sec = getsectbynamefromheader_64((const struct mach_header_64*) hdr, + GC_dyld_sections[i].seg, GC_dyld_sections[i].sect); +#else + sec = getsectbynamefromheader(hdr, GC_dyld_sections[i].seg, + GC_dyld_sections[i].sect); +#endif + if (sec == NULL || sec->size == 0) + continue; + start = slide + sec->addr; + end = start + sec->size; + + GC_add_range((void*) start, (void*) end); + } +} + +/* This should never be called by a thread holding the lock */ +static void +on_dyld_remove_image(const struct mach_header* hdr, intptr_t slide) { + unsigned i; + uintptr_t start, end; +#if THIS_IS_64_BIT + const struct section_64 *sec; +#else + const struct section *sec; +#endif + + for(i = 0; + i < sizeof(GC_dyld_sections) / sizeof(GC_dyld_sections[0]); + i++) { + +#if THIS_IS_64_BIT + sec = getsectbynamefromheader_64((const struct mach_header_64*) hdr, + GC_dyld_sections[i].seg, GC_dyld_sections[i].sect); +#else + sec = getsectbynamefromheader(hdr, GC_dyld_sections[i].seg, + GC_dyld_sections[i].sect); +#endif + if (sec == NULL || sec->size == 0) + continue; + start = slide + sec->addr; + end = start + sec->size; + + GC_remove_range((void*) start);//, (void*) end); + } +} + +void _d_gcc_dyld_start(enum DataSegmentTracking mode) +{ + static int started = 0; + + if (! started) { + started = 1; + _dyld_register_func_for_add_image(on_dyld_add_image); + _dyld_register_func_for_remove_image(on_dyld_remove_image); + } + + // (for LoadTimeLibrariesOnly:) Can't unregister callbacks +} diff -uNrp dmd-1.007/src/phobos/internal/gc/gc_freebsd.c gdc-0.23/d/phobos/internal/gc/gc_freebsd.c --- dmd-1.007/src/phobos/internal/gc/gc_freebsd.c 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gc_freebsd.c 2006-06-03 04:57:25.000000000 +0200 @@ -0,0 +1,12 @@ +#include +#include +#include + +int _d_gcc_gc_freebsd_stack(void ** out_origin) +{ + int nm[2] = {CTL_KERN, KERN_USRSTACK}; + size_t len = sizeof(void *); + int r = sysctl(nm, 2, out_origin, &len, NULL, 0); + + return ! r; +} diff -uNrp dmd-1.007/src/phobos/internal/gc/gcgcc.d gdc-0.23/d/phobos/internal/gc/gcgcc.d --- dmd-1.007/src/phobos/internal/gc/gcgcc.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gcgcc.d 2007-03-06 03:20:47.000000000 +0100 @@ -0,0 +1,293 @@ +private import gcgccextern; +private import std.gc; +private import std.c.stdlib; +private import std.string; // for memmove + +debug(ProcMaps) + private import std.c.stdio; + +/* ------- Memory allocation ------------- */ + +version (GC_Use_Alloc_MMap) +{ + private import std.c.unix.unix; + + void *os_mem_map(size_t nbytes) + { void *p; + p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + return (p == MAP_FAILED) ? null : p; + } + int os_mem_commit(void *base, size_t offset, size_t nbytes) + { + return 0; + } + + int os_mem_decommit(void *base, size_t offset, size_t nbytes) + { + return 0; + } + + int os_mem_unmap(void *base, size_t nbytes) + { + return munmap(base, nbytes); + } +} +else version (GC_Use_Alloc_Valloc) +{ + extern (C) void * valloc(size_t); + void *os_mem_map(size_t nbytes) { return valloc(nbytes); } + int os_mem_commit(void *base, size_t offset, size_t nbytes) { return 0; } + int os_mem_decommit(void *base, size_t offset, size_t nbytes) { return 0; } + int os_mem_unmap(void *base, size_t nbytes) { free(base); return 0; } +} +else version (GC_Use_Alloc_Malloc) +{ + /* Assumes malloc granularity is at least (void *).sizeof. If + (req_size + PAGESIZE) is allocated, and the pointer is rounded + up to PAGESIZE alignment, there will be space for a void* at the + end after PAGESIZE bytes used by the GC. */ + + private import gcx; // for PAGESIZE + + const uint PAGE_MASK = PAGESIZE - 1; + + void *os_mem_map(size_t nbytes) + { byte * p, q; + p = cast(byte *) malloc(nbytes + PAGESIZE); + q = p + ((PAGESIZE - ((cast(size_t) p & PAGE_MASK))) & PAGE_MASK); + * cast(void**)(q + nbytes) = p; + return q; + } + int os_mem_commit(void *base, size_t offset, size_t nbytes) + { + return 0; + } + + int os_mem_decommit(void *base, size_t offset, size_t nbytes) + { + return 0; + } + + int os_mem_unmap(void *base, size_t nbytes) + { + free( * cast(void**)( cast(byte*) base + nbytes ) ); + return 0; + } +} +else version (GC_Use_Alloc_Fixed_Heap) +{ + // TODO + static assert(0); +} +else +{ + static assert(0); +} + + +/* ------- Stack origin ------------- */ + +version (GC_Use_Stack_Guess) + private import gc_guess_stack; + +version (GC_Use_Stack_FreeBSD) + extern (C) int _d_gcc_gc_freebsd_stack(void **); + +void *os_query_stackBottom() +{ + version (GC_Use_Stack_GLibC) + { + return __libc_stack_end; + } + else version (GC_Use_Stack_Guess) + { + // dmainwhatever should be private too + // import main? + return stackOriginGuess; + } + else version (GC_Use_Stack_FreeBSD) + { + void * stack_origin; + if (_d_gcc_gc_freebsd_stack(& stack_origin)) + return stack_origin; + else + // No way to signal an error + return null; + } + else version (GC_Use_Stack_Scan) + { + static assert(0); + } + else version (GC_Use_Stack_Fixed) + { + version (darwin) + { + static if (size_t.sizeof == 4) + return cast(void*) 0xc0000000; + else static if (size_t.sizeof == 8) + return cast(void*) 0x7ffff_00000000UL; + else + static assert(0); + } + else + static assert(0); + } + else + { + static assert(0); + } +} + +// std.thread needs to know the stack origin +extern (C) void* _d_gcc_query_stack_origin() +{ + return os_query_stackBottom(); +} + + +/* ------- Data segments ------------- */ + +version (GC_Use_Data_Dyld) + extern (C) void _d_gcc_dyld_start(DataSegmentTracking mode); + +version (GC_Use_Data_Proc_Maps) +{ + private import std.c.unix.unix; + private import std.c.stdlib; +} + + +/* + It is assumed that this is called during GC initialization and + only once. +*/ + +void os_query_staticdataseg(void **base, size_t *nbytes) +{ + const size_t S = (void *).sizeof; + + // Can't assume the input addresses are word-aligned + static void * adjust_up(void * p) + { + return p + ((S - (cast(size_t)p & (S-1))) & (S-1)); // cast ok even if 64-bit + } + static void * adjust_down(void * p) + { + return p - (cast(size_t) p & (S-1)); + } + + void * main_data_start; + void * main_data_end; + + *base = null; + *nbytes = 0; + + version (GC_Use_Data_Dyld) + { + _d_gcc_dyld_start(DataSegmentTracking.Dynamic); + return; // no need for any other method + } + + version (GC_Use_Data_Fixed) + { + static if (FM.One) { + main_data_start = adjust_up ( & Data_Start ); + main_data_end = adjust_down( & Data_End ); + *base = main_data_start; + *nbytes = main_data_end - main_data_start; + } else static if (FM.Two) { + main_data_start = adjust_up ( & Data_Start ); + main_data_end = adjust_down( & Data_End ); + *base = main_data_start; + *nbytes = main_data_end - main_data_start; + addRange(adjust_up( & Data_Start_2 ), adjust_down( & Data_End_2 )); + } else static if (FM.MinMax) { + static void * min(void *a, void *b) { return a < b ? a : b; } + static void * max(void *a, void *b) { return a > b ? a : b; } + main_data_start = adjust_up ( & Data_Start < & Data_Start_2 ? & Data_Start : & Data_Start_2 ); + main_data_end = adjust_down( & Data_End > & Data_End_2 ? & Data_End : & Data_End_2 ); + *base = main_data_start; + *nbytes = main_data_end - main_data_start; + } + //goto have_main_data; + } + + //have_main_data: + + version (GC_Use_Data_Proc_Maps) + { + // TODO: Exclude zero-mapped regions... + + int fd = open("/proc/self/maps", O_RDONLY); + int count; // %% need to configure ret for read.. + char buf[2024]; + char * p; + char * e; + char * s; + void * start; + void * end; + + p = buf; + if (fd != -1) { + while ( (count = read(fd, p, buf.sizeof - (p - buf.ptr))) > 0 ) { + e = p + count; + p = buf; + while (1) { + s = p; + while (p < e && *p != '\n') + p++; + if (p < e) { + // parse the entry in [s, p) + static if (S == 4) { + enum Ofs { + Write_Prot = 19, + Start_Addr = 0, + End_Addr = 9, + Addr_Len = 8, + } + } else static if (S == 8) { + enum Ofs { + Write_Prot = 35, + Start_Addr = 0, + End_Addr = 9, + Addr_Len = 17, + } + } else { + static assert(0); + } + + // %% this is wrong for 64-bit: + // uint strtoul(char *,char **,int); + + if (s[Ofs.Write_Prot] == 'w') { + s[Ofs.Start_Addr + Ofs.Addr_Len] = '\0'; + s[Ofs.End_Addr + Ofs.Addr_Len] = '\0'; + start = cast(void *) strtoul(s + Ofs.Start_Addr, null, 16); + end = cast(void *) strtoul(s + Ofs.End_Addr, null, 16); + + // 1. Exclude anything overlapping [main_data_start,main_data_end) + // 2. Exclude stack + if ( (! main_data_end || + ! (main_data_start >= start && main_data_end <= end)) && + ! (& buf >= start && & buf < end)) { + // we already have static data from this region. anything else + // is heap (%% check) + debug (ProcMaps) + printf("Adding map range %p 0%p\n", start, end); + addRange(start, end); + } + } + + p++; + } else { + count = p - s; + memmove(buf, s, count); + p = buf.ptr + count; + break; + } + } + } + close(fd); + } + } +} diff -uNrp dmd-1.007/src/phobos/internal/gc/gcgccextern.d gdc-0.23/d/phobos/internal/gc/gcgccextern.d --- dmd-1.007/src/phobos/internal/gc/gcgccextern.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gcgccextern.d 2006-06-11 00:33:19.000000000 +0200 @@ -0,0 +1,68 @@ +module gcc.gccextern; + +version(GC_Use_Stack_GLibC) + extern (C) void * __libc_stack_end; + +version(GC_Use_Data_Fixed) +{ + extern (C) int _data; + extern (C) int __data_start; + extern (C) int _end; + extern (C) int _data_start__; + extern (C) int _data_end__; + extern (C) int _bss_start__; + extern (C) int _bss_end__; + extern (C) int __fini_array_end; + + /* %% Move all this to configure script to test if it actually works? + --enable-gc-data-fixed=Mode,s1,e1,s2,e2 + .. the Mode can be a version instead of enum trick + */ + + version (aix) + { + alias _data Data_Start; + alias _end Data_End; + enum FM { One = 1, MinMax = 0, Two = 0 } + } + else version (cygwin) + { + alias _data_start__ Data_Start; + alias _data_end__ Data_End; + alias _bss_start__ Data_Start_2; + alias _bss_end__ Data_End_2; + enum FM { MinMax = 1, One = 0, Two = 0 } + } + else version (freebsd) + { + // use '_etext' if '__fini_array_end' doesn't work + /* There is a bunch of read-only data after .data and before .bss, but + no linker symbols to find it. Would have to set up a fault handler + and scan... */ + alias __fini_array_end Data_Start; + alias _end Data_End; + enum FM { One = 1, MinMax = 0, Two = 0 } + } + else version (linux) + { + alias __data_start Data_Start; + alias _end Data_End; + /* possible better way: + [__data_start,_DYNAMIC) and [_edata/edata or __bss_start,_end/end) + This doesn't really save much.. a better linker script is needed. + */ + enum FM { One = 1, MinMax = 0, Two = 0 } + } + else version (skyos) + { + alias _data_start__ Data_Start; + alias _bss_end__ Data_End; + enum FM { One = 1, MinMax = 0, Two = 0 } + } +} + +enum DataSegmentTracking { + ExecutableOnly, + LoadTimeLibrariesOnly, + Dynamic +} diff -uNrp dmd-1.007/src/phobos/internal/gc/gc_guess_stack.d gdc-0.23/d/phobos/internal/gc/gc_guess_stack.d --- dmd-1.007/src/phobos/internal/gc/gc_guess_stack.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gc_guess_stack.d 2006-06-03 04:57:25.000000000 +0200 @@ -0,0 +1,3 @@ +module gcc.gc_guess_stack; +void * stackOriginGuess; + diff -uNrp dmd-1.007/src/phobos/internal/gc/gcold.d gdc-0.23/d/phobos/internal/gc/gcold.d --- dmd-1.007/src/phobos/internal/gc/gcold.d 2007-02-20 20:22:02.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gcold.d 2007-02-19 19:50:21.000000000 +0100 @@ -36,44 +36,39 @@ module std.gcold; import gc; extern (C) -ulong _d_newarrayi(size_t length, size_t size, ...) +Array _d_newarrayip(size_t length, size_t size, void * init) { - void *p; - ulong result; + Array result; - //debug(PRINTF) printf("_d_newarrayi(length = %d, size = %d)\n", length, size); - if (length == 0 || size == 0) - result = 0; - else + if (length && size) { - //void* q = cast(void*)(&size + 1); // pointer to initializer - va_list q; - va_start!(size_t)(q, size); // q is pointer to ... initializer - p = _gc.malloc(length * size + 1); - debug(PRINTF) printf(" p = %p\n", p); + result.length = length; + result.data = cast(byte*) _gc.malloc(length * size + 1); if (size == 1) - memset(p, *cast(ubyte*)q, length); + memset(result.data, * cast(ubyte*) init, length); else if (size == int.sizeof) { - int init = *cast(int*)q; + int init_val = *cast(int*)init; + void * p = result.data; for (uint u = 0; u < length; u++) { - (cast(int*)p)[u] = init; + (cast(int*)p)[u] = init_val; } } else { + void * p = result.data; for (uint u = 0; u < length; u++) { - memcpy(p + u * size, q, size); + memcpy(p, init, size); + p += size; } } - va_end(q); - result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); } return result; } +version (GNU) { } else extern (C) ulong _d_newarrayii(size_t length, size_t size, size_t isize ...) { @@ -115,17 +110,16 @@ ulong _d_newarrayii(size_t length, size_ } extern (C) -ulong _d_newm(size_t size, int ndims, ...) +void[] _d_newmp(size_t size, int ndims, size_t* pdim) { - ulong result; + void[] result = void; //debug(PRINTF) //printf("_d_newm(size = %d, ndims = %d)\n", size, ndims); if (size == 0 || ndims == 0) - result = 0; + result = null; else - { va_list q; - va_start!(int)(q, ndims); + { void[] foo(size_t* pdim, int ndims) { @@ -147,35 +141,31 @@ ulong _d_newm(size_t size, int ndims, .. return p; } - size_t* pdim = cast(size_t *)q; - result = cast(ulong)foo(pdim, ndims); + result = foo(pdim, ndims); //printf("result = %llx\n", result); version (none) { for (int i = 0; i < ndims; i++) { - printf("index %d: %d\n", i, va_arg!(int)(q)); + printf("index %d: %d\n", i, pdim[i]); } } - va_end(q); } return result; } extern (C) -ulong _d_newarraymi(size_t size, int ndims, ...) +void[] _d_newarraymip(size_t size, int ndims, size_t* pdim, size_t mult, void* pinit) { - ulong result; + void[] result = void; //debug(PRINTF) //printf("_d_newarraymi(size = %d, ndims = %d)\n", size, ndims); if (size == 0 || ndims == 0) - result = 0; + result = null; else - { void* pinit; // pointer to initializer - va_list q; - va_start!(int)(q, ndims); + { void[] foo(size_t* pdim, int ndims) { @@ -183,12 +173,13 @@ ulong _d_newarraymi(size_t size, int ndi void[] p; if (ndims == 1) - { p = _gc.malloc(dim * size + 1)[0 .. dim]; + { p = _gc.malloc(dim * mult * size + 1)[0 .. dim]; if (size == 1) memset(p.ptr, *cast(ubyte*)pinit, dim); else { - for (size_t u = 0; u < dim; u++) + size_t n = dim * mult; + for (size_t u = 0; u < n; u++) { memcpy(p.ptr + u * size, pinit, size); } @@ -205,20 +196,17 @@ ulong _d_newarraymi(size_t size, int ndi return p; } - size_t* pdim = cast(size_t *)q; - pinit = pdim + ndims; - result = cast(ulong)foo(pdim, ndims); + result = foo(pdim, ndims); //printf("result = %llx\n", result); version (none) { for (int i = 0; i < ndims; i++) { - printf("index %d: %d\n", i, va_arg!(int)(q)); - printf("init = %d\n", va_arg!(int)(q)); + printf("index %d: %d\n", i, pdim[i]); + printf("init = %d\n", *cast(int*)pinit); } } - va_end(q); } return result; } @@ -229,20 +217,25 @@ ulong _d_newarraymi(size_t size, int ndi */ extern (C) -ulong _d_new(size_t length, size_t size) +Array _d_new(size_t length, size_t size) { void *p; - ulong result; + Array result; debug(PRINTF) printf("_d_new(length = %d, size = %d)\n", length, size); + /* if (length == 0 || size == 0) result = 0; else + */ + if (length && size) { p = _gc.malloc(length * size + 1); debug(PRINTF) printf(" p = %p\n", p); memset(p, 0, length * size); - result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); + result.length = length; + result.data = cast(byte*)p; + return result; } return result; } @@ -267,6 +260,14 @@ body if (newlength) { + version (GNU) + { + // required to output the label; + static char x = 0; + if (x) + goto Loverflow; + } + version (D_InlineAsm_X86) { size_t newsize = void; @@ -327,7 +328,7 @@ Loverflow: * (obsolete, replaced by _d_arraysetlength3) */ extern (C) -byte[] _d_arraysetlength2(size_t newlength, size_t sizeelem, Array *p, ...) +byte[] _d_arraysetlength2p(size_t newlength, size_t sizeelem, Array *p, void * init) in { assert(sizeelem); @@ -346,6 +347,14 @@ body if (newlength) { + version (GNU) + { + // required to output the label; + static char x = 0; + if (x) + goto Loverflow; + } + version (D_InlineAsm_X86) { size_t newsize = void; @@ -387,21 +396,18 @@ body newdata = cast(byte *)_gc.malloc(newsize + 1); } - va_list q; - va_start!(Array *)(q, p); // q is pointer to initializer - if (newsize > size) { if (sizeelem == 1) { //printf("newdata = %p, size = %d, newsize = %d, *q = %d\n", newdata, size, newsize, *cast(byte*)q); - newdata[size .. newsize] = *(cast(byte*)q); + newdata[size .. newsize] = *(cast(byte*)init); } else { for (size_t u = size; u < newsize; u += sizeelem) { - memcpy(newdata + u, q, sizeelem); + memcpy(newdata + u, init, sizeelem); } } } @@ -554,8 +560,8 @@ bit[] _d_arrayappendcb(inout bit[] x, bi * ... initializer */ extern (C) -byte[] _d_arraysetlength3(size_t newlength, size_t sizeelem, Array *p, - size_t initsize, ...) +byte[] _d_arraysetlength3p(size_t newlength, size_t sizeelem, Array *p, + size_t initsize, void *init) in { assert(sizeelem); @@ -577,6 +583,14 @@ body if (newlength) { + version (GNU) + { + // required to output the label; + static char x = 0; + if (x) + goto Loverflow; + } + version (D_InlineAsm_X86) { size_t newsize = void; @@ -618,21 +632,18 @@ body newdata = cast(byte *)_gc.malloc(newsize + 1); } - va_list q; - va_start!(size_t)(q, initsize); // q is pointer to initializer - if (newsize > size) { if (initsize == 1) { //printf("newdata = %p, size = %d, newsize = %d, *q = %d\n", newdata, size, newsize, *cast(byte*)q); - newdata[size .. newsize] = *(cast(byte*)q); + newdata[size .. newsize] = *(cast(byte*)init); } else { for (size_t u = size; u < newsize; u += initsize) { - memcpy(newdata + u, q, initsize); + memcpy(newdata + u, init, initsize); } } } @@ -652,7 +663,7 @@ Loverflow: extern (C) -long _d_arrayappend(Array *px, byte[] y, size_t size) +Array _d_arrayappend(Array *px, byte[] y, size_t size) { size_t cap = _gc.capacity(px.data); @@ -667,12 +678,12 @@ long _d_arrayappend(Array *px, byte[] y, } px.length = newlength; memcpy(px.data + length * size, y.ptr, y.length * size); - return *cast(long*)px; + return *px; } extern (C) -byte[] _d_arrayappendc(inout byte[] x, in size_t size, ...) +byte[] _d_arrayappendcp(inout byte[] x, in size_t size, void *argp) { size_t cap = _gc.capacity(x.ptr); size_t length = x.length; @@ -692,10 +703,9 @@ byte[] _d_arrayappendc(inout byte[] x, i memcpy(newdata, x.ptr, length * size); (cast(void **)(&x))[1] = newdata; } - byte *argp = cast(byte *)(&size + 1); *cast(size_t *)&x = newlength; - (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; + (cast(byte *)x)[length * size .. newlength * size] = (cast(byte*)argp)[0 .. size]; assert((cast(size_t)x.ptr & 15) == 0); assert(_gc.capacity(x.ptr) > x.length * size); return x; @@ -749,30 +759,30 @@ body extern (C) -byte[] _d_arraycatn(uint size, uint n, ...) +byte[] _d_arraycatn(size_t size, uint n, ...) { byte[] a; uint length; - byte[]* p; uint i; byte[] b; + va_list va; - p = cast(byte[]*)(&n + 1); + va_start!(typeof(n))(va, n); for (i = 0; i < n; i++) { - b = *p++; + b = va_arg!(typeof(b))(va); length += b.length; } if (!length) return null; a = new byte[length * size]; - p = cast(byte[]*)(&n + 1); + va_start!(typeof(n))(va, n); uint j = 0; for (i = 0; i < n; i++) { - b = *p++; + b = va_arg!(typeof(b))(va); if (b.length) { memcpy(&a[j], b.ptr, b.length * size); @@ -780,7 +790,7 @@ byte[] _d_arraycatn(uint size, uint n, . } } - *cast(int *)&a = length; // jam length + *cast(size_t *)&a = length; // jam length //a.length = length; return a; } @@ -886,6 +896,8 @@ bit[] _d_arraysetbit2(bit[] ba, bit valu } } +version (GNU) { /* _d_arrayliteral not used; can't always be compiled */ } +else extern (C) void* _d_arrayliteral(size_t size, size_t length, ...) { @@ -926,20 +938,20 @@ void* _d_arrayliteral(size_t size, size_ * Support for array.dup property. */ -extern (C) long _adDup(Array2 a, int szelem) +extern (C) Array _adDup(Array a, int szelem) out (result) { - assert(memcmp((*cast(Array2*)&result).ptr, a.ptr, a.length * szelem) == 0); + assert(memcmp(result.ptr, a.ptr, a.length * szelem) == 0); } body { - Array2 r; + Array r; auto size = a.length * szelem; r.ptr = cast(void *) new byte[size]; r.length = a.length; memcpy(r.ptr, a.ptr, size); - return *cast(long*)(&r); + return r; } unittest @@ -964,10 +976,10 @@ unittest version (none) { -extern (C) long _adDupBit(Array a) +extern (C) Array _adDupBit(Array a) out (result) { - assert(memcmp((*cast(Array*)(&result)).ptr, a.ptr, (a.length + 7) / 8) == 0); + assert(memcmp(result.ptr, a.ptr, (a.length + 7) / 8) == 0); } body { @@ -977,7 +989,7 @@ extern (C) long _adDupBit(Array a) r.ptr = cast(void *) new uint[size]; r.length = a.length; memcpy(r.ptr, a.ptr, size * uint.sizeof); - return *cast(long*)(&r); + return r; } unittest diff -uNrp dmd-1.007/src/phobos/internal/gc/gcstub.d gdc-0.23/d/phobos/internal/gc/gcstub.d --- dmd-1.007/src/phobos/internal/gc/gcstub.d 2007-02-20 20:22:02.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gcstub.d 2007-02-15 23:05:33.000000000 +0100 @@ -129,7 +129,7 @@ class GC { void *pbot; void *ptop; - uint nbytes; + size_t nbytes; debug(PRINTF) printf("scanStaticData()\n"); //debug(PRINTF) printf("+GC.scanStaticData()\n"); @@ -142,7 +142,7 @@ class GC static void unscanStaticData(gc_t g) { void *pbot; - uint nbytes; + size_t nbytes; debug(PRINTF) printf("unscanStaticData()\n"); os_query_staticdataseg(&pbot, &nbytes); diff -uNrp dmd-1.007/src/phobos/internal/gc/gcx.d gdc-0.23/d/phobos/internal/gc/gcx.d --- dmd-1.007/src/phobos/internal/gc/gcx.d 2007-02-20 20:22:02.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/gcx.d 2007-03-04 15:45:52.000000000 +0100 @@ -1,10 +1,16 @@ // -// Copyright (C) 2001-2007 by Digital Mars +// Copyright (C) 2001-2006 by Digital Mars // All Rights Reserved // Written by Walter Bright // www.digitalmars.com -// D Programming Language Garbage Collector implementation +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, July 2006 +*/ + +// D Garbage Collector implementation /************** Debugging ***************************/ @@ -37,17 +43,29 @@ import std.outofmemory; import std.gc; import gcstats; +version (GNU) +{ + private import gcc.builtins; +} + version (Win32) { import win32; import std.c.windows.windows; } - -version (linux) +else version (GNU) +{ + private import gcgcc; +} +else version (linux) { import gclinux; } +/*version (BigEndian) + private import std.intrinsic;*/ + + version (MULTI_THREADED) { @@ -57,6 +75,8 @@ version (MULTI_THREADED) //alias GC* gc_t; alias GC gc_t; +version (X86) version (D_InlineAsm) { version = Asm86; } + /* ======================= Leak Detector =========================== */ debug (LOGGING) @@ -64,7 +84,7 @@ debug (LOGGING) struct Log { void *p; - uint size; + size_t size; uint line; char *file; void *parent; @@ -83,8 +103,8 @@ debug (LOGGING) struct LogArray { - uint dim; - uint allocdim; + size_t dim; + size_t allocdim; Log *data; void Dtor() @@ -94,7 +114,7 @@ debug (LOGGING) data = null; } - void reserve(uint nentries) + void reserve(size_t nentries) { assert(dim <= allocdim); if (allocdim - dim < nentries) @@ -124,15 +144,15 @@ debug (LOGGING) data[dim++] = log; } - void remove(uint i) + void remove(size_t i) { memmove(data + i, data + i + 1, (dim - i) * Log.sizeof); dim--; } - uint find(void *p) + size_t find(void *p) { - for (uint i = 0; i < dim; i++) + for (size_t i = 0; i < dim; i++) { if (data[i].p == p) return i; @@ -183,7 +203,11 @@ class GC { setStackBottom(win32.os_query_stackBottom()); } - version (linux) + else version (GNU) + { + setStackBottom(gcgcc.os_query_stackBottom()); + } + else version (linux) { setStackBottom(gclinux.os_query_stackBottom()); } @@ -291,9 +315,11 @@ class GC // Return next item from free list gcx.bucket[bin] = (cast(List *)p).next; - //memset(p + size, 0, binsize[bin] - size); - // 'inline' memset - Dave Fladebo. - foreach(inout byte b; cast(byte[])(p + size)[0..binsize[bin] - size]) { b = 0; } + version(GNU) + memset(p + size, 0, binsize[bin] - size); + else + // 'inline' memset - Dave Fladebo. + foreach(inout byte b; cast(byte[])(p + size)[0..binsize[bin] - size]) { b = 0; } //debug(PRINTF) printf("\tmalloc => %x\n", p); debug (MEMSTOMP) memset(p, 0xF0, size); } @@ -314,7 +340,7 @@ class GC void *calloc(size_t size, size_t n) { - uint len; + size_t len; void *p; len = size * n; @@ -341,7 +367,7 @@ class GC } else { void *p2; - uint psize; + size_t psize; //debug(PRINTF) printf("GC::realloc(p = %x, size = %u)\n", p, size); version (SENTINEL) @@ -451,7 +477,7 @@ class GC // This depends on: // 1) size is a power of 2 for less than PAGESIZE values // 2) base of memory pool is aligned on PAGESIZE boundary - if (cast(uint)p & (size - 1) & (PAGESIZE - 1)) + if (cast(size_t)p & (size - 1) & (PAGESIZE - 1)) size = 0; return size ? size - SENTINAL_EXTRA : 0; } @@ -466,7 +492,7 @@ class GC // This depends on: // 1) size is a power of 2 for less than PAGESIZE values // 2) base of memory pool is aligned on PAGESIZE boundary - if (cast(uint)p & (size - 1) & (PAGESIZE - 1)) + if (cast(size_t)p & (size - 1) & (PAGESIZE - 1)) size = 0; else { @@ -498,7 +524,7 @@ class GC Pool *pool; uint pagenum; Bins bin; - uint size; + size_t size; p = sentinel_sub(p); pool = gcx.findPool(p); @@ -507,7 +533,7 @@ class GC bin = cast(Bins)pool.pagetable[pagenum]; assert(bin <= B_PAGE); size = binsize[bin]; - assert((cast(uint)p & (size - 1)) == 0); + assert((cast(size_t)p & (size - 1)) == 0); debug (PTRCHECK2) { @@ -554,22 +580,34 @@ class GC { void *pbot; void *ptop; - uint nbytes; + size_t nbytes; //debug(PRINTF) printf("+GC.scanStaticData()\n"); os_query_staticdataseg(&pbot, &nbytes); ptop = pbot + nbytes; - g.addRange(pbot, ptop); + version (GNU) { + if (pbot) { + g.addRange(pbot, ptop); + } + } else { + g.addRange(pbot, ptop); + } //debug(PRINTF) printf("-GC.scanStaticData()\n"); } static void unscanStaticData(gc_t g) { void *pbot; - uint nbytes; + size_t nbytes; os_query_staticdataseg(&pbot, &nbytes); - g.removeRange(pbot); + version (GNU) { + if (pbot) { + g.removeRange(pbot); + } + } else { + g.removeRange(pbot); + } } @@ -703,12 +741,12 @@ class GC void getStats(out GCStats stats) { - uint psize = 0; - uint usize = 0; - uint flsize = 0; + size_t psize = 0; + size_t usize = 0; + size_t flsize = 0; - uint n; - uint bsize = 0; + size_t n; + size_t bsize = 0; //debug(PRINTF) printf("getStats()\n"); memset(&stats, 0, GCStats.sizeof); @@ -816,14 +854,14 @@ struct Gcx } void *p_cache; - uint size_cache; + size_t size_cache; - uint nroots; - uint rootdim; + size_t nroots; + size_t rootdim; void **roots; - uint nranges; - uint rangedim; + size_t nranges; + size_t rangedim; Range *ranges; uint conservative; // !=0 means conservative behavior @@ -942,7 +980,7 @@ struct Gcx { if (nroots == rootdim) { - uint newdim = rootdim * 2 + 16; + size_t newdim = rootdim * 2 + 16; void **newroots; newroots = cast(void **)std.c.stdlib.malloc(newdim * newroots[0].sizeof); @@ -961,7 +999,7 @@ struct Gcx void removeRoot(void *p) { - uint i; + size_t i; for (i = nroots; i--;) { if (roots[i] == p) @@ -979,11 +1017,11 @@ struct Gcx void addRange(void *pbot, void *ptop) { - debug(PRINTF) printf("Thread %x ", pthread_self()); + debug(THREADINVARIANT) { debug(PRINTF) printf("Thread %x ", pthread_self()); } debug(PRINTF) printf("%x.Gcx::addRange(%x, %x), nranges = %d\n", this, pbot, ptop, nranges); if (nranges == rangedim) { - uint newdim = rangedim * 2 + 16; + size_t newdim = rangedim * 2 + 16; Range *newranges; newranges = cast(Range *)std.c.stdlib.malloc(newdim * newranges[0].sizeof); @@ -1003,9 +1041,9 @@ struct Gcx void removeRange(void *pbot) { - debug(PRINTF) printf("Thread %x ", pthread_self()); + debug(THREADINVARIANT) { debug(PRINTF) printf("Thread %x ", pthread_self()); } debug(PRINTF) printf("%x.Gcx.removeRange(%x), nranges = %d\n", this, pbot, nranges); - for (uint i = nranges; i--;) + for (size_t i = nranges; i--;) { if (ranges[i].pbot == pbot) { @@ -1057,10 +1095,10 @@ struct Gcx * Returns 0 if not a gc'd pointer */ - uint findSize(void *p) + size_t findSize(void *p) { Pool *pool; - uint size = 0; + size_t size = 0; pool = findPool(p); if (pool) @@ -1093,7 +1131,7 @@ struct Gcx * Compute bin for size. */ - static Bins findBin(uint size) + static Bins findBin(size_t size) { Bins bin; if (size <= 256) @@ -1140,7 +1178,7 @@ struct Gcx * Return null if out of memory. */ - void *bigAlloc(uint size) + void *bigAlloc(size_t size) { Pool *pool; uint npages; @@ -1317,7 +1355,7 @@ struct Gcx pool.pagetable[pn] = cast(ubyte)bin; // Convert page to free list - uint size = binsize[bin]; + size_t size = binsize[bin]; List **b = &bucket[bin]; p = pool.baseAddr + pn * PAGESIZE; @@ -1353,7 +1391,7 @@ struct Gcx pool = findPool(p); if (pool) { - uint offset = cast(uint)(p - pool.baseAddr); + size_t offset = cast(uint)(p - pool.baseAddr); uint biti; uint pn = offset / PAGESIZE; Bins bin = cast(Bins)pool.pagetable[pn]; @@ -1400,27 +1438,42 @@ struct Gcx * Return number of full pages free'd. */ - uint fullcollectshell() + size_t fullcollectshell() { // The purpose of the 'shell' is to ensure all the registers // get put on the stack so they'll be scanned void *sp; - uint result; - asm + size_t result; + version (GNU) { - pushad ; - mov sp[EBP],ESP ; + __builtin_unwind_init(); + sp = & sp; + } + else + { + asm + { + pushad ; + mov sp[EBP],ESP ; + } } result = fullcollect(sp); - asm + version (GNU) { - popad ; + // nothing to do + } + else + { + asm + { + popad ; + } } return result; } - uint fullcollect(void *stackTop) + size_t fullcollect(void *stackTop) { uint n; Pool *pool; @@ -1484,7 +1537,18 @@ struct Gcx mark(cast(void *)context.Esp, t.stackBottom); mark(&context.Edi, &context.Eip); } - version (linux) + else version (GNU) + { + if (t.isSelf()) + t.stackTop = Thread.getESP(); + + //%%fry printf("top=%08x bot=%08x ext=%08x\n", t.stackTop, t.stackBottom, Thread.getESP());//%%try + version (STACKGROWSDOWN) + mark(t.stackTop, t.stackBottom); + else + mark(t.stackBottom, t.stackTop); + } + else version (linux) { // The registers are already stored in the stack //printf("Thread: ESP = x%x, stackBottom = x%x, isSelf = %d\n", Thread.getESP(), t.stackBottom, t.isSelf()); @@ -1555,6 +1619,9 @@ struct Gcx *b = 0; o = pool.baseAddr + (b - bbase) * 32 * 16; + /* version (BigEndian) + bitm = bswap(bitm); + */ if (!(bitm & 0xFFFF)) { bitm >>= 16; @@ -1590,8 +1657,8 @@ struct Gcx // Free up everything not marked debug(COLLECT_PRINTF) printf("\tfree'ing\n"); - uint freedpages = 0; - uint freed = 0; + size_t freedpages = 0; + size_t freed = 0; for (n = 0; n < npools; n++) { uint pn; uint ncommitted; @@ -1706,7 +1773,7 @@ struct Gcx // Free complete pages, rebuild free list debug(COLLECT_PRINTF) printf("\tfree complete pages\n"); - uint recoveredpages = 0; + size_t recoveredpages = 0; for (n = 0; n < npools; n++) { uint pn; uint ncommitted; @@ -1822,13 +1889,13 @@ struct Gcx //debug(PRINTF) printf("-log_init()\n"); } - void log_malloc(void *p, uint size) + void log_malloc(void *p, size_t size) { //debug(PRINTF) printf("+log_malloc(p = %x, size = %d)\n", p, size); Log log; log.p = p; - log.sizeof = size; + log.size = size; log.line = GC.line; log.file = GC.file; log.parent = null; @@ -1843,7 +1910,7 @@ struct Gcx void log_free(void *p) { //debug(PRINTF) printf("+log_free(%x)\n", p); - uint i; + size_t i; i = current.find(p); if (i == ~0u) @@ -1861,10 +1928,10 @@ struct Gcx // Print everything in current that is not in prev debug(PRINTF) printf("New pointers this cycle: --------------------------------\n"); - int used = 0; - for (uint i = 0; i < current.dim; i++) + size_t used = 0; + for (size_t i = 0; i < current.dim; i++) { - uint j; + size_t j; j = prev.find(current.data[i].p); if (j == ~0u) @@ -1874,10 +1941,10 @@ struct Gcx } debug(PRINTF) printf("All roots this cycle: --------------------------------\n"); - for (uint i = 0; i < current.dim; i++) + for (size_t i = 0; i < current.dim; i++) { void *p; - uint j; + size_t j; p = current.data[i].p; if (!findPool(current.data[i].parent)) @@ -1900,7 +1967,7 @@ struct Gcx void log_parent(void *p, void *parent) { //debug(PRINTF) printf("+log_parent()\n"); - uint i; + size_t i; i = current.find(p); if (i == ~0u) @@ -1909,8 +1976,8 @@ struct Gcx Pool *pool; pool = findPool(p); assert(pool); - uint offset = cast(uint)(p - pool.baseAddr); - uint biti; + size_t offset = cast(uint)(p - pool.baseAddr); + size_t biti; uint pn = offset / PAGESIZE; Bins bin = cast(Bins)pool.pagetable[pn]; biti = (offset & notbinsize[bin]); @@ -1927,7 +1994,7 @@ struct Gcx else { void log_init() { } - void log_malloc(void *p, uint size) { } + void log_malloc(void *p, size_t size) { } void log_free(void *p) { } void log_collect() { } void log_parent(void *p, void *parent) { } @@ -1952,7 +2019,7 @@ struct Pool void initialize(uint npages) { - uint poolsize; + size_t poolsize; //debug(PRINTF) printf("Pool::Pool(%u)\n", npages); poolsize = npages * PAGESIZE; @@ -2119,15 +2186,15 @@ struct Pool version (SENTINEL) { - const uint SENTINEL_PRE = 0xF4F4F4F4; // 32 bits + const size_t SENTINEL_PRE = cast(size_t) 0xF4F4F4F4F4F4F4F4UL; // 32 or 64 bits const ubyte SENTINEL_POST = 0xF5; // 8 bits - const uint SENTINEL_EXTRA = 2 * uint.sizeof + 1; + const uint SENTINEL_EXTRA = 2 * size_t.sizeof + 1; - uint* sentinel_size(void *p) { return &(cast(uint *)p)[-2]; } - uint* sentinel_pre(void *p) { return &(cast(uint *)p)[-1]; } + size_t* sentinel_size(void *p) { return &(cast(size_t *)p)[-2]; } + size_t* sentinel_pre(void *p) { return &(cast(size_t *)p)[-1]; } ubyte* sentinel_post(void *p) { return &(cast(ubyte *)p)[sentinel_size(p)]; } - void sentinel_init(void *p, uint size) + void sentinel_init(void *p, size_t size) { *sentinel_size(p) = size; *sentinel_pre(p) = SENTINEL_PRE; @@ -2142,19 +2209,19 @@ version (SENTINEL) void *sentinel_add(void *p) { - return p + 2 * uint.sizeof; + return p + 2 * size_t.sizeof; } void *sentinel_sub(void *p) { - return p - 2 * uint.sizeof; + return p - 2 * size_t.sizeof; } } else { const uint SENTINEL_EXTRA = 0; - void sentinel_init(void *p, uint size) + void sentinel_init(void *p, size_t size) { } diff -uNrp dmd-1.007/src/phobos/internal/gc/testgc.d gdc-0.23/d/phobos/internal/gc/testgc.d --- dmd-1.007/src/phobos/internal/gc/testgc.d 2007-02-20 20:22:02.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/testgc.d 2006-12-09 17:40:20.000000000 +0100 @@ -4,6 +4,12 @@ // Written by Walter Bright // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, July 2006 +*/ + // GC tester program import std.c.stdio; diff -uNrp dmd-1.007/src/phobos/internal/gc/win32.d gdc-0.23/d/phobos/internal/gc/win32.d --- dmd-1.007/src/phobos/internal/gc/win32.d 2007-02-20 20:22:02.000000000 +0100 +++ gdc-0.23/d/phobos/internal/gc/win32.d 2007-03-04 15:46:59.000000000 +0100 @@ -42,7 +42,7 @@ int os_mem_commit(void *base, uint offse int os_mem_decommit(void *base, uint offset, uint nbytes) { - return cast(int)(VirtualFree(base + offset, nbytes, MEM_DECOMMIT) == 0); + return cast(int)VirtualFree(base + offset, nbytes, MEM_DECOMMIT) == 0; } /*********************************** @@ -55,7 +55,7 @@ int os_mem_decommit(void *base, uint off int os_mem_unmap(void *base, uint nbytes) { - return cast(int)(VirtualFree(base, 0, MEM_RELEASE) == 0); + return cast(int)VirtualFree(base, 0, MEM_RELEASE) == 0; } @@ -86,6 +86,26 @@ void *os_query_stackBottom() * Determine base address and size of static data segment. */ +version (GNU) +{ +// This is MinGW specific +extern (C) +{ + // TODO: skip the .rdata between .data and .bss? + extern int _data_start__; + extern int _bss_end__; +} + +void os_query_staticdataseg(void **base, uint *nbytes) +{ + *base = cast(void *)&_data_start__; + *nbytes = cast(uint)(cast(char *)&_bss_end__ - cast(char *)&_data_start__); +} + +} +else +{ + extern (C) { extern int _xi_a; // &_xi_a just happens to be start of data segment @@ -99,6 +119,7 @@ void os_query_staticdataseg(void **base, *nbytes = cast(uint)(cast(char *)&_end - cast(char *)&_xi_a); } +} /++++ void os_query_staticdataseg(void **base, uint *nbytes) diff -uNrp dmd-1.007/src/phobos/internal/mars.h gdc-0.23/d/phobos/internal/mars.h --- dmd-1.007/src/phobos/internal/mars.h 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/mars.h 2007-02-27 03:13:03.000000000 +0100 @@ -6,6 +6,7 @@ */ #include +#include #if __cplusplus extern "C" { @@ -24,7 +25,7 @@ typedef struct Interface { struct ClassInfo *classinfo; struct Vtbl vtbl; - int offset; + ptrdiff_t offset; } Interface; typedef struct Object diff -uNrp dmd-1.007/src/phobos/internal/memset.d gdc-0.23/d/phobos/internal/memset.d --- dmd-1.007/src/phobos/internal/memset.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/memset.d 2007-02-23 18:08:49.000000000 +0100 @@ -21,16 +21,21 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ extern (C) { // Functions from the C library. - void *memcpy(void *, void *, uint); + void *memcpy(void *, void *, size_t); } extern (C): -short *_memset16(short *p, short value, int count) +short *_memset16(short *p, short value, size_t count) { short *pstart = p; short *ptop; @@ -40,9 +45,9 @@ short *_memset16(short *p, short value, return pstart; } -int *_memset32(int *p, int value, int count) +int *_memset32(int *p, int value, size_t count) { -version (X86) +version (Asm86) { asm { @@ -66,7 +71,7 @@ else } } -long *_memset64(long *p, long value, int count) +long *_memset64(long *p, long value, size_t count) { long *pstart = p; long *ptop; @@ -76,7 +81,7 @@ long *_memset64(long *p, long value, int return pstart; } -cdouble *_memset128(cdouble *p, cdouble value, int count) +cdouble *_memset128(cdouble *p, cdouble value, size_t count) { cdouble *pstart = p; cdouble *ptop; @@ -86,7 +91,7 @@ cdouble *_memset128(cdouble *p, cdouble return pstart; } -real *_memset80(real *p, real value, int count) +real *_memset80(real *p, real value, size_t count) { real *pstart = p; real *ptop; @@ -96,7 +101,7 @@ real *_memset80(real *p, real value, int return pstart; } -creal *_memset160(creal *p, creal value, int count) +creal *_memset160(creal *p, creal value, size_t count) { creal *pstart = p; creal *ptop; @@ -106,7 +111,7 @@ creal *_memset160(creal *p, creal value, return pstart; } -void *_memsetn(void *p, void *value, int count, int sizelem) +void *_memsetn(void *p, void *value, int count, size_t sizelem) { void *pstart = p; int i; diff -uNrp dmd-1.007/src/phobos/internal/monitor.c gdc-0.23/d/phobos/internal/monitor.c --- dmd-1.007/src/phobos/internal/monitor.c 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/monitor.c 2006-11-12 03:18:56.000000000 +0100 @@ -6,6 +6,14 @@ // This is written in C because nobody has written a pthreads interface // to D yet. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + +#include "config.h" + #include #include @@ -13,7 +21,7 @@ #if _WIN32 #elif linux -#define USE_PTHREADS 1 +#define PHOBOS_USE_PTHREADS 1 #else #endif @@ -21,7 +29,7 @@ #include #endif -#if USE_PTHREADS +#if PHOBOS_USE_PTHREADS #include #endif @@ -36,7 +44,7 @@ typedef struct Monitor CRITICAL_SECTION mon; #endif -#if USE_PTHREADS +#if PHOBOS_USE_PTHREADS pthread_mutex_t mon; #endif } Monitor; @@ -123,9 +131,12 @@ void _d_monitorrelease(Object *h) /* =============================== linux ============================ */ -#if USE_PTHREADS +// needs to be else.. +#if PHOBOS_USE_PTHREADS -// Includes attribute fixes from David Friedman's GDC port +#ifndef HAVE_PTHREAD_MUTEX_RECURSIVE +#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +#endif static pthread_mutex_t _monitor_critsec; static pthread_mutexattr_t _monitors_attr; @@ -133,10 +144,12 @@ static pthread_mutexattr_t _monitors_att void _STI_monitor_staticctor() { if (!inited) - { + { +#ifndef PTHREAD_MUTEX_ALREADY_RECURSIVE pthread_mutexattr_init(&_monitors_attr); - pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP); - pthread_mutex_init(&_monitor_critsec, 0); + pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE); +#endif + pthread_mutex_init(&_monitor_critsec, 0); // the global critical section doesn't need to be recursive inited = 1; } } @@ -145,8 +158,10 @@ void _STD_monitor_staticdtor() { if (inited) { inited = 0; +#ifndef PTHREAD_MUTEX_ALREADY_RECURSIVE pthread_mutex_destroy(&_monitor_critsec); pthread_mutexattr_destroy(&_monitors_attr); +#endif } } @@ -162,7 +177,11 @@ void _d_monitorenter(Object *h) if (!h->monitor) // if, in the meantime, another thread didn't set it { h->monitor = (void *)cs; +#ifndef PTHREAD_MUTEX_ALREADY_RECURSIVE pthread_mutex_init(&cs->mon, & _monitors_attr); +#else + pthread_mutex_init(&cs->mon, NULL); +#endif cs = NULL; } pthread_mutex_unlock(&_monitor_critsec); diff -uNrp dmd-1.007/src/phobos/internal/object.d gdc-0.23/d/phobos/internal/object.d --- dmd-1.007/src/phobos/internal/object.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/object.d 2007-03-04 15:48:12.000000000 +0100 @@ -32,11 +32,38 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, April 2005 +*/ + module object; import std.outofmemory; +/// Standard boolean type. +alias bool bit; + +/** + * An unsigned integral type large enough to span the memory space. Use for + * array indices and pointer offsets for maximal portability to + * architectures that have different memory address ranges. This is + * analogous to C's size_t. + */ +alias typeof(int.sizeof) size_t; + +/** + * A signed integral type large enough to span the memory space. Use for + * pointer differences and for size_t differences for maximal portability to + * architectures that have different memory address ranges. This is + * analogous to C's ptrdiff_t. + */ +alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; + +alias size_t hash_t; + extern (C) { /// C's printf function. int printf(char *, ...); @@ -48,36 +75,6 @@ extern (C) void free(void*); } -/// Standard boolean type. -alias bool bit; - -version (X86_64) -{ - /** - * An unsigned integral type large enough to span the memory space. Use for - * array indices and pointer offsets for maximal portability to - * architectures that have different memory address ranges. This is - * analogous to C's size_t. - */ - alias ulong size_t; - - /** - * A signed integral type large enough to span the memory space. Use for - * pointer differences and for size_t differences for maximal portability to - * architectures that have different memory address ranges. This is - * analogous to C's ptrdiff_t. - */ - alias long ptrdiff_t; - - alias ulong hash_t; -} -else -{ - alias uint size_t; - alias int ptrdiff_t; - alias uint hash_t; -} - /* ************************* * Internal struct pointed to by the hidden .monitor member. */ @@ -95,7 +92,8 @@ class Object { void print() { - printf("%.*s\n", toString()); + char[] s = toString(); + printf("%.*s\n", cast(int) s.length, s.ptr); } /** @@ -112,7 +110,7 @@ class Object hash_t toHash() { // BUG: this prevents a compacting GC from working, needs to be fixed - return cast(uint)cast(void *)this; + return cast(size_t)cast(void *)this; } /** @@ -240,7 +238,7 @@ struct Interface { ClassInfo classinfo; /// .classinfo for this interface (not for containing class) void *[] vtbl; - int offset; /// offset to Interface 'this' from Object 'this' + ptrdiff_t offset; /// offset to Interface 'this' from Object 'this' } /** @@ -318,7 +316,7 @@ class TypeInfo } /// Returns a hash of the instance of a type. - hash_t getHash(void *p) { return cast(uint)p; } + hash_t getHash(void *p) { return cast(size_t)p; } /// Compares two instances for equality. int equals(void *p1, void *p2) { return cast(int)(p1 == p2); } @@ -403,7 +401,7 @@ class TypeInfo_Pointer : TypeInfo hash_t getHash(void *p) { - return cast(uint)*cast(void* *)p; + return cast(size_t)*cast(void* *)p; } int equals(void *p1, void *p2) @@ -846,7 +844,13 @@ class TypeInfo_Struct : TypeInfo else if (!p1 || !p2) c = 0; else if (xopEquals) - c = (*xopEquals)(p1, p2); + { + version (GNU) + // GDC and DMD use different calling conventions + c = (*xopEquals)(p2, p1); + else + c = (*xopEquals)(p1, p2); + } else // BUG: relies on the GC not moving objects c = (memcmp(p1, p2, init.length) == 0); @@ -864,7 +868,13 @@ class TypeInfo_Struct : TypeInfo { if (!p2) c = 1; else if (xopCmp) - c = (*xopCmp)(p1, p2); + { + version (GNU) + // GDC and DMD use different calling conventions + c = (*xopCmp)(p2, p1); + else + c = (*xopCmp)(p1, p2); + } else // BUG: relies on the GC not moving objects c = memcmp(p1, p2, init.length); @@ -974,7 +984,8 @@ class Exception : Object void print() { - printf("%.*s\n", toString()); + char[] s = toString(); + printf("%.*s\n", cast(int) s.length, s.ptr); } char[] toString() { return msg; } diff -uNrp dmd-1.007/src/phobos/internal/qsort.d gdc-0.23/d/phobos/internal/qsort.d --- dmd-1.007/src/phobos/internal/qsort.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/qsort.d 1970-01-01 01:00:00.000000000 +0100 @@ -1,162 +0,0 @@ -/* - Portions of this file are: - Copyright Prototronics, 1987 - Totem Lake P.O. 8117 - Kirkland, Washington 98034 - (206) 820-1972 - Licensed to Digital Mars. - - June 11, 1987 from Ray Gardner's - Denver, Colorado) public domain version - - Use qsort2.d instead of this file if a redistributable version of - _adSort() is required. -*/ - - -/* -** Sorts an array starting at base, of length nbr_elements, each -** element of size width_bytes, ordered via compare_function; which -** is called as (*comp_fp)(ptr_to_element1, ptr_to_element2) -** and returns < 0 if element1 < element2, 0 if element1 = element2, -** > 0 if element1 > element2. Most of the refinements are due to -** R. Sedgewick. See "Implementing Quicksort Programs", Comm. ACM, -** Oct. 1978, and Corrigendum, Comm. ACM, June 1979. -*/ - -//debug=qsort; // uncomment to turn on debugging printf's - -import std.c.stdio; -import std.c.stdlib; -import std.string; -import std.outofmemory; - -struct Array -{ - int length; - void *ptr; -} - - -private const int _maxspan = 7; // subarrays of _maxspan or fewer elements - // will be sorted by a simple insertion sort - -/* Adjust _maxspan according to relative cost of a swap and a compare. Reduce -_maxspan (not less than 1) if a swap is very expensive such as when you have -an array of large structures to be sorted, rather than an array of pointers to -structures. The default value is optimized for a high cost for compares. */ - - -extern (C) long _adSort(Array a, TypeInfo ti) -{ - byte* base; - byte*[40] stack; // stack - byte** sp; // stack pointer - byte* i, j, limit; // scan and limit pointers - uint thresh; // size of _maxspan elements in bytes - uint width = ti.tsize(); - - base = cast(byte *)a.ptr; - thresh = _maxspan * width; // init threshold - sp = stack.ptr; // init stack pointer - limit = base + a.length * width; // pointer past end of array - while (1) // repeat until done then return - { - while (limit - base > thresh) // if more than _maxspan elements - { - //swap middle, base - ti.swap((cast(uint)(limit - base) >> 1) - - (((cast(uint)(limit - base) >> 1)) % width) + base, base); - - i = base + width; // i scans from left to right - j = limit - width; // j scans from right to left - - if (ti.compare(i, j) > 0) // Sedgewick's - ti.swap(i, j); // three-element sort - if (ti.compare(base, j) > 0) // sets things up - ti.swap(base, j); // so that - if (ti.compare(i, base) > 0) // *i <= *base <= *j - ti.swap(i, base); // *base is the pivot element - - while (1) - { - do // move i right until *i >= pivot - i += width; - while (ti.compare(i, base) < 0); - do // move j left until *j <= pivot - j -= width; - while (ti.compare(j, base) > 0); - if (i > j) // break loop if pointers crossed - break; - ti.swap(i, j); // else swap elements, keep scanning - } - ti.swap(base, j); // move pivot into correct place - if (j - base > limit - i) // if left subarray is larger... - { - sp[0] = base; // stack left subarray base - sp[1] = j; // and limit - base = i; // sort the right subarray - } - else // else right subarray is larger - { - sp[0] = i; // stack right subarray base - sp[1] = limit; // and limit - limit = j; // sort the left subarray - } - sp += 2; // increment stack pointer - assert(sp < cast(byte**)stack + stack.length); - } - - // Insertion sort on remaining subarray - i = base + width; - while (i < limit) - { - j = i; - while (j > base && ti.compare(j - width, j) > 0) - { - ti.swap(j - width, j); - j -= width; - } - i += width; - } - - if (sp > stack.ptr) // if any entries on stack... - { - sp -= 2; // pop the base and limit - base = sp[0]; - limit = sp[1]; - } - else // else stack empty, all done - return *cast(long*)(&a); - } - assert(0); -} - - -unittest -{ - debug(qsort) printf("array.sort.unittest()\n"); - - int a[] = new int[10]; - - a[0] = 23; - a[1] = 1; - a[2] = 64; - a[3] = 5; - a[4] = 6; - a[5] = 5; - a[6] = 17; - a[7] = 3; - a[8] = 0; - a[9] = -1; - - a.sort; - - for (int i = 0; i < a.length - 1; i++) - { - //printf("i = %d", i); - //printf(" %d %d\n", a[i], a[i + 1]); - assert(a[i] <= a[i + 1]); - } -} - diff -uNrp dmd-1.007/src/phobos/internal/qsortg.d gdc-0.23/d/phobos/internal/qsortg.d --- dmd-1.007/src/phobos/internal/qsortg.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/qsortg.d 2007-02-15 17:37:43.000000000 +0100 @@ -0,0 +1,115 @@ + +struct Array +{ + size_t length; + void * ptr; +} + +extern (C) Array _adSort(Array a, TypeInfo ti) +{ + static const uint Qsort_Threshold = 7; + + struct StackEntry { + byte *l; + byte *r; + } + + size_t elem_size = ti.tsize(); + size_t qsort_limit = elem_size * Qsort_Threshold; + + static assert(ubyte.sizeof == 1); + static assert(ubyte.max == 255); + + StackEntry[size_t.sizeof * 8] stack; // log2( size_t.max ) + StackEntry * sp = stack.ptr; + byte* lbound = cast(byte *) a.ptr; + byte* rbound = cast(byte *) a.ptr + a.length * elem_size; + byte* li = void; + byte* ri = void; + + while (1) + { + if (rbound - lbound > qsort_limit) + { + ti.swap(lbound, + lbound + ( + ((rbound - lbound) >>> 1) - + (((rbound - lbound) >>> 1) % elem_size) + )); + + li = lbound + elem_size; + ri = rbound - elem_size; + + if (ti.compare(li, ri) > 0) + ti.swap(li, ri); + if (ti.compare(lbound, ri) > 0) + ti.swap(lbound, ri); + if (ti.compare(li, lbound) > 0) + ti.swap(li, lbound); + + while (1) + { + do + li += elem_size; + while (ti.compare(li, lbound) < 0); + do + ri -= elem_size; + while (ti.compare(ri, lbound) > 0); + if (li > ri) + break; + ti.swap(li, ri); + } + ti.swap(lbound, ri); + if (ri - lbound > rbound - li) + { + sp.l = lbound; + sp.r = ri; + lbound = li; + } + else + { + sp.l = li; + sp.r = rbound; + rbound = ri; + } + ++sp; + } else { + // Use insertion sort + for (ri = lbound, li = lbound + elem_size; + li < rbound; + ri = li, li += elem_size) + { + for ( ; ti.compare(ri, ri + elem_size) > 0; + ri -= elem_size) + { + ti.swap(ri, ri + elem_size); + if (ri == lbound) + break; + } + } + if (sp != stack.ptr) + { + --sp; + lbound = sp.l; + rbound = sp.r; + } + else + return a; + } + } +} + +unittest +{ + static void check(int[] a) { + for (uint i = 1; i < a.length; i++) + assert(a[i-1] <= a[i]); + } + + static int[] t1 = [ 4, 3, 19, 7, 6, 20, 11, 1, 2, 5 ]; + int[] a; + + a = t1; + a.sort; + check(a); +} diff -uNrp dmd-1.007/src/phobos/internal/rundmain.d gdc-0.23/d/phobos/internal/rundmain.d --- dmd-1.007/src/phobos/internal/rundmain.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/internal/rundmain.d 2006-06-03 04:57:26.000000000 +0200 @@ -0,0 +1,6 @@ +private extern (C) int _d_run_main(int argc, char **argv, void * p); +int main(); +extern (C) int _d_run_Dmain(int argc, char **argv) +{ + return _d_run_main(argc, argv, & main); +} diff -uNrp dmd-1.007/src/phobos/Makefile.am gdc-0.23/d/phobos/Makefile.am --- dmd-1.007/src/phobos/Makefile.am 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/Makefile.am 2007-03-06 05:11:55.000000000 +0100 @@ -0,0 +1,284 @@ +# GDC -- D front-end for GCC +# Copyright (C) 2004 David Friedman +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# AUTOMAKE_OPTIONS = 1.9.6 foreign no-dependencies + +OUR_CFLAGS=@DEFS@ -I . -I $(srcdir)/gcc +D_EXTRA_DFLAGS=-nostdinc -pipe +ALL_DFLAGS = $(DFLAGS) $(D_GC_FLAGS) $(D_EXTRA_DFLAGS) $(MULTIFLAGS) + +toolexecdir = $(phobos_toolexecdir) +toolexeclibdir = $(phobos_toolexeclibdir) + +config_d_src=$(host_alias)/gcc/config.d +configunix_d_src=$(host_alias)/gcc/configunix.d + +# This is a hook to get Automake to build libgphobos.a +BUILT_SOURCES = minimal.c +noinst_PROGRAMS = minimal +minimal_SOURCES = minimal.c +minimal_DEPENDENCIES = libgphobos.a +minimal.c: + echo "int main() { return 0; }" > $@ + +all-local: libgphobos.a + +SUFFIXES = .d + +%.o : %.d $(D_PREREQ_SRCS) + $(GDC) -o $@ $(ALL_DFLAGS) \ + -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +# %.o : %.c +# Use .c.o to override Automake +.c.o: + $(CC) -o $@ $(OUR_CFLAGS) $(CFLAGS) -c $< + +# boxer is currently broken +std/boxer.t.o: std/boxer.o + cp $< $@ + +%.t.o : %.d $(D_PREREQ_SRCS) + $(GDC) -o $@ $(ALL_DFLAGS) -fno-release -funittest -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +internal/gc/gcx.t.o: $(D_PREREQ_SRCS) $(srcdir)/internal/gc/gcx.d + $(GDC) -o $@ $(ALL_DFLAGS) -funittest -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +%.t.o : %.o + cp $< $@ + +unittest: unittest.o libgphobos_t.a libgphobos.a + $(GDC) -o $@ $(CFLAGS) unittest.o -L./ -lgphobos_t $(LIBS) + +internal/gc/testgc.o: $(host_alias)/gcc/config.d $(srcdir)/internal/gc/testgc.d + $(GDC) -o $@ $(ALL_DFLAGS) -fno-release -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $(srcdir)/internal/gc/testgc.d + +testgc: internal/gc/testgc.o libgphobos_t.a libgphobos.a + $(GDC) -o $@ $(ALL_DFLAGS) internal/gc/testgc.o -L./ -lgphobos_t $(LIBS) + +TI=ti_AC.o ti_Ag.o ti_Aint.o ti_Along.o ti_Ashort.o \ + ti_C.o \ + ti_byte.o ti_cdouble.o ti_cfloat.o ti_char.o ti_creal.o \ + ti_dchar.o ti_delegate.o ti_double.o ti_float.o ti_idouble.o ti_ifloat.o \ + ti_int.o ti_ireal.o ti_long.o ti_ptr.o ti_real.o ti_short.o ti_ubyte.o \ + ti_uint.o ti_ulong.o ti_ushort.o ti_wchar.o \ + ti_Afloat.o ti_Adouble.o ti_Areal.o \ + ti_Acfloat.o ti_Acdouble.o ti_Acreal.o \ + ti_void.o + +MAIN_OBJS=std/asserterror.o internal/switch.o gcstats.o \ + internal/critical.o internal/object.o internal/monitor.o internal/arraycat.o internal/invariant.o \ + std/outofmemory.o internal/aaA.o internal/adi.o internal/aApply.o internal/aApplyR.o std/file.o \ + std/compiler.o std/system.o std/moduleinit.o std/md5.o std/base64.o \ + internal/cast.o std/path.o std/string.o internal/memset.o std/math.o std/mmfile.o \ + std/outbuffer.o std/ctype.o std/regexp.o std/random.o \ + std/stream.o std/cstream.o std/switcherr.o std/array.o std/gc.o \ + internal/qsortg.o std/thread.o internal/obj.o std/utf.o std/uri.o \ + crc32.o std/conv.o internal/arraycast.o errno.o \ + std/process.o std/syserror.o std/metastrings.o \ + std/socket.o std/socketstream.o std/c/stdarg.o std/stdio.o std/format.o \ + std/perf.o std/openrj.o std/uni.o std/demangle.o std/bitarray.o \ + $(subst ti_,std/typeinfo/ti_,$(TI)) \ + std/date.o std/dateparse.o std/math2.o etc/c/zlib.o std/zlib.o std/zip.o \ + internal/dgccmain2.o internal/rundmain.o std/stdarg.o \ + std/signals.o std/cpuid.o std/traits.o std/typetuple.o std/bind.o + +# This should not be linked into a shared library. +CMAIN_OBJS=internal/cmain.o + +ZLIB_OBJS= etc/c/zlib/adler32.o etc/c/zlib/compress.o \ + etc/c/zlib/crc32.o etc/c/zlib/gzio.o \ + etc/c/zlib/uncompr.o etc/c/zlib/deflate.o \ + etc/c/zlib/trees.o etc/c/zlib/zutil.o \ + etc/c/zlib/inflate.o etc/c/zlib/infback.o \ + etc/c/zlib/inftrees.o etc/c/zlib/inffast.o + +GC_OBJS= internal/gc/gc.o internal/gc/gcx.o \ + internal/gc/gcbits.o +GC_OBJS += @D_GC_MODULES@ + +GCC_OBJS = gcc/config.o gcc/unwind.o gcc/deh.o gcc/threadsem.o \ + std/c/dirent.o gcc/cbridge_time.o + +# std.c.linux.linux, std.loader, gcc.cbridge* +WINDOWS_OBJS=std/c/windows/windows.o std/c/windows/com.o std/c/windows/winsock.o \ + std/windows/iunknown.o std/windows/registry.o std/windows/syserror.o \ + std/windows/charset.o +# D_EXTRA_OBJS=@D_EXTRA_OBJS@ + +# needed until instrinsics are implemented +D_EXTRA_OBJS+=std/intrinsic.o + +# currently just add compatibility for a bug +D_EXTRA_OBJS+=gcc/support.o + +CONFIG_D_FRAGMENTS = config/config-head frag-ac frag-gen frag-math config/config-mid config/config-tail +CONFIG_UNIX_FRAGMENTS = config/unix-head frag-unix config/unix-mid + +gen_config1: config/gen_config1.o + $(CC) $(CFLAGS) -o $@ $^ + +$(config_d_src): $(CONFIG_D_FRAGMENTS) stamp-tgtdir + cat $^ > $@ + +gcc/config.o: $(config_d_src) + $(GDC) -o $@ $(ALL_DFLAGS) -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< +gcc/config.t.o: gcc/config.o + cp gcc/config.o gcc/config.t.o + + +gen_math: config/gen_math.o + $(CC) $(CFLAGS) -o $@ $^ + +config/gen_unix.o: config/gen_unix.c config/makestruct.h + +gen_unix: config/gen_unix.o + $(CC) $(CFLAGS) -o $@ $^ + + +# Plain 'make' would use: ifdef D_GENERATE_FRAGMENTS +if D_GENERATE_FRAGMENTS +frag-gen: gen_config1 + ./gen_config1 > $@ || rm -f $@ +frag-unix: gen_unix + ./gen_unix > $@ +frag-math: gen_math + ./gen_math > $@ || rm -f $@ +else +frag-gen: $(D_FRAGMENT_SRCDIR)/$@ + cp $(D_FRAGMENT_SRCDIR)/$@ $@ +frag-unix: $(D_FRAGMENT_SRCDIR)/$@ + cp $(D_FRAGMENT_SRCDIR)/$@ $@ +frag-math: $(D_FRAGMENT_SRCDIR)/$@ + cp $(D_FRAGMENT_SRCDIR)/$@ $@ +endif + +$(configunix_d_src): $(CONFIG_UNIX_FRAGMENTS) stamp-tgtdir + cat $^ > $@ + +gcc/configunix.o: $(configunix_d_src) $(config_d_src) + $(GDC) -o $@ $(ALL_DFLAGS) -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< +gcc/configunix.t.o: gcc/configunix.o + cp gcc/configunix.o gcc/configunix.t.o + +gcc/cbridge_math.o: gcc/cbridge_math.c + $(CC) -o $@ $(OUR_CFLAGS) $(CFLAGS) -fno-strict-aliasing -c $< + +std/stream.o: std/stream.d $(D_PREREQ_SRCS) + $(GDC) -o $@ $(ALL_DFLAGS) -fdeprecated -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< +std/stream.t.o: std/stream.d $(D_PREREQ_SRCS) + $(GDC) -o $@ $(ALL_DFLAGS) -fdeprecated -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +# GCC_OBJS (gcc/config.o) first so I don't have to write more deps +ALL_PHOBOS_OBJS = $(D_EXTRA_OBJS) $(GCC_OBJS) $(MAIN_OBJS) $(ZLIB_OBJS) $(GC_OBJS) $(WEAK_OBJS) + +libgphobos.a : $(ALL_PHOBOS_OBJS) $(CMAIN_OBJS) + $(AR) -r $@ $(ALL_PHOBOS_OBJS) $(CMAIN_OBJS) + $(RANLIB) $@ + +libgphobos_t.a : $(ALL_PHOBOS_OBJS:.o=.t.o) $(CMAIN_OBJS) + $(AR) -r $@ $(ALL_PHOBOS_OBJS:.o=.t.o) $(CMAIN_OBJS) + $(RANLIB) $@ + +# This has to be an empty file because it is included in the prerequisites of rules +# that use "cat $^" to generate their targets. +# Otherwise, need to specify $srcdir for known source files in CONFIG_xxx_FRAGMENTS.. +stamp-tgtdir: + mkdir -p $(host_alias)/gcc + touch $@ + +check-local: unittest testgc + ./unittest + ./testgc + +install-exec-local: $(D_PREREQ_SRCS) libgphobos.a + $(mkinstalldirs) $(DESTDIR)$(toolexeclibdir) + $(INSTALL) libgphobos.a $(DESTDIR)$(toolexeclibdir) + $(RANLIB) $(DESTDIR)$(toolexeclibdir)/libgphobos.a + +install-data-local: $(D_PREREQ_SRCS) libgphobos.a + for i in etc etc/c \ + etc/c/zlib \ + gcc std std/c \ + std/c/darwin std/c/linux std/c/mach std/c/skyos std/c/unix std/c/windows \ + std/typeinfo std/windows; do \ + $(mkinstalldirs) $(DESTDIR)$(gdc_include_dir)/$$i; \ + for f in $(srcdir)/$$i/*.[hd]; do $(INSTALL_HEADER) $$f $(DESTDIR)$(gdc_include_dir)/$$i; done; \ + done + for i in crc32.d gcstats.d object.d; do \ + $(INSTALL_HEADER) $(srcdir)/$$i $(DESTDIR)$(gdc_include_dir); done + $(mkinstalldirs) $(DESTDIR)$(gdc_include_dir)/$(host_alias)/$(MULTISUBDIR)/gcc + $(INSTALL_HEADER) $(config_d_src) $(DESTDIR)$(gdc_include_dir)/$(host_alias)/$(MULTISUBDIR)/gcc + if test -f $(configunix_d_src); then $(INSTALL_HEADER) $(host_alias)/gcc/configunix.d $(DESTDIR)$(gdc_include_dir)/$(host_alias)/$(MULTISUBDIR)/gcc; fi + $(INSTALL) phobos-ver-syms $(DESTDIR)$(gdc_include_dir)/$(host_alias)/$(MULTISUBDIR) + +clean-local: + rm -f $(ALL_PHOBOS_OBJS) $(CMAIN_OBJS) + rm -f $(ALL_PHOBOS_OBJS:.o=.t.o) + rm -f unittest.o internal/gc/testgc.o + rm -f unittest$(EXEEXT) testgc$(EXEEXT) + rm -f config/gen_config1.o config/gen_unix.o config/gen_math.o + rm -f gen_config1$(EXEEXT) gen_unix$(EXEEXT) gen_math$(EXEEXT) + rm -f frag-gen frag-math frag-unix + rm -f $(config_d_src) $(configunix_d_src) + rm -f libgphobos.a + rm -f libgphobos_t.a + + +# Work around what appears to be a GNU make bug handling MAKEFLAGS +# values defined in terms of make variables, as is the case for CC and +# friends when we are called from the top level Makefile. +AM_MAKEFLAGS = \ + "AR_FLAGS=$(AR_FLAGS)" \ + "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ + "CC_FOR_TARGET=$(CC_FOR_TARGET)" \ + "CFLAGS=$(CFLAGS)" \ + "CXXFLAGS=$(CXXFLAGS)" \ + "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ + "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ + "INSTALL=$(INSTALL)" \ + "INSTALL_DATA=$(INSTALL_DATA)" \ + "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ + "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ + "LDFLAGS=$(LDFLAGS)" \ + "LIBCFLAGS=$(LIBCFLAGS)" \ + "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ + "MAKE=$(MAKE)" \ + "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ + "PICFLAG=$(PICFLAG)" \ + "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ + "SHELL=$(SHELL)" \ + "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ + "exec_prefix=$(exec_prefix)" \ + "infodir=$(infodir)" \ + "libdir=$(libdir)" \ + "includedir=$(includedir)" \ + "prefix=$(prefix)" \ + "tooldir=$(tooldir)" \ + "gdc_include_dir=$(gdc_include_dir)" \ + "AR=$(AR)" \ + "AS=$(AS)" \ + "LD=$(LD)" \ + "RANLIB=$(RANLIB)" \ + "NM=$(NM)" \ + "NM_FOR_BUILD=$(NM_FOR_BUILD)" \ + "NM_FOR_TARGET=$(NM_FOR_TARGET)" \ + "DESTDIR=$(DESTDIR)" \ + "WERROR=$(WERROR)" + +# Subdir rules rely on $(FLAGS_TO_PASS) +FLAGS_TO_PASS = $(AM_MAKEFLAGS) diff -uNrp dmd-1.007/src/phobos/Makefile.in gdc-0.23/d/phobos/Makefile.in --- dmd-1.007/src/phobos/Makefile.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/Makefile.in 2007-03-06 05:12:30.000000000 +0100 @@ -0,0 +1,841 @@ +# Makefile.in generated by automake 1.9.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# GDC -- D front-end for GCC +# Copyright (C) 2004 David Friedman +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# AUTOMAKE_OPTIONS = 1.9.6 foreign no-dependencies + +SOURCES = $(minimal_SOURCES) + +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +noinst_PROGRAMS = minimal$(EXEEXT) +DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/frag-ac.in $(srcdir)/phobos-ver-syms.in \ + $(top_srcdir)/configure config.guess config.sub install-sh \ + missing +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = frag-ac phobos-ver-syms +PROGRAMS = $(noinst_PROGRAMS) +am_minimal_OBJECTS = minimal.$(OBJEXT) +minimal_OBJECTS = $(am_minimal_OBJECTS) +minimal_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I. +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(minimal_SOURCES) +DIST_SOURCES = $(minimal_SOURCES) +MULTISRCTOP = +MULTIBUILDTOP = +MULTIDIRS = +MULTISUBDIR = +MULTIDO = true +MULTICLEAN = true +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +srcdir = @srcdir@ +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DCFG_CBRIDGE_STDIO = @DCFG_CBRIDGE_STDIO@ +DCFG_EXECVPE = @DCFG_EXECVPE@ +DCFG_EXP2_LOG2 = @DCFG_EXP2_LOG2@ +DCFG_FWIDE = @DCFG_FWIDE@ +DCFG_GETPWNAM_R = @DCFG_GETPWNAM_R@ +DCFG_MMAP = @DCFG_MMAP@ +DCFG_NAN = @DCFG_NAN@ +DCFG_NEARBYINT = @DCFG_NEARBYINT@ +DCFG_PTHREAD_SUSPEND = @DCFG_PTHREAD_SUSPEND@ +DCFG_ROUND = @DCFG_ROUND@ +DCFG_SA_LEN = @DCFG_SA_LEN@ +DCFG_SEMAPHORE_IMPL = @DCFG_SEMAPHORE_IMPL@ +DCFG_SPAWNVP = @DCFG_SPAWNVP@ +DCFG_STRTOLD = @DCFG_STRTOLD@ +DCFG_TGAMMA = @DCFG_TGAMMA@ +DCFG_TRUNC = @DCFG_TRUNC@ +DCFG_UNIX = @DCFG_UNIX@ +DEFS = @DEFS@ +DFLAGS = @DFLAGS@ +# D_EXTRA_OBJS=@D_EXTRA_OBJS@ + +# needed until instrinsics are implemented + +# currently just add compatibility for a bug +D_EXTRA_OBJS = @D_EXTRA_OBJS@ std/intrinsic.o gcc/support.o +D_FRAGMENT_SRCDIR = @D_FRAGMENT_SRCDIR@ +D_GC_FLAGS = @D_GC_FLAGS@ +D_GC_MODULES = @D_GC_MODULES@ +D_GENERATE_FRAGMENTS_FALSE = @D_GENERATE_FRAGMENTS_FALSE@ +D_GENERATE_FRAGMENTS_TRUE = @D_GENERATE_FRAGMENTS_TRUE@ +D_PREREQ_SRCS = @D_PREREQ_SRCS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GDC = @GDC@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +gdc_include_dir = @gdc_include_dir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +oldincludedir = @oldincludedir@ +phobos_toolexecdir = @phobos_toolexecdir@ +phobos_toolexeclibdir = @phobos_toolexeclibdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +OUR_CFLAGS = @DEFS@ -I . -I $(srcdir)/gcc +D_EXTRA_DFLAGS = -nostdinc -pipe +ALL_DFLAGS = $(DFLAGS) $(D_GC_FLAGS) $(D_EXTRA_DFLAGS) $(MULTIFLAGS) +toolexecdir = $(phobos_toolexecdir) +toolexeclibdir = $(phobos_toolexeclibdir) +config_d_src = $(host_alias)/gcc/config.d +configunix_d_src = $(host_alias)/gcc/configunix.d + +# This is a hook to get Automake to build libgphobos.a +BUILT_SOURCES = minimal.c +minimal_SOURCES = minimal.c +minimal_DEPENDENCIES = libgphobos.a +SUFFIXES = .d +TI = ti_AC.o ti_Ag.o ti_Aint.o ti_Along.o ti_Ashort.o \ + ti_C.o \ + ti_byte.o ti_cdouble.o ti_cfloat.o ti_char.o ti_creal.o \ + ti_dchar.o ti_delegate.o ti_double.o ti_float.o ti_idouble.o ti_ifloat.o \ + ti_int.o ti_ireal.o ti_long.o ti_ptr.o ti_real.o ti_short.o ti_ubyte.o \ + ti_uint.o ti_ulong.o ti_ushort.o ti_wchar.o \ + ti_Afloat.o ti_Adouble.o ti_Areal.o \ + ti_Acfloat.o ti_Acdouble.o ti_Acreal.o \ + ti_void.o + +MAIN_OBJS = std/asserterror.o internal/switch.o gcstats.o \ + internal/critical.o internal/object.o internal/monitor.o internal/arraycat.o internal/invariant.o \ + std/outofmemory.o internal/aaA.o internal/adi.o internal/aApply.o internal/aApplyR.o std/file.o \ + std/compiler.o std/system.o std/moduleinit.o std/md5.o std/base64.o \ + internal/cast.o std/path.o std/string.o internal/memset.o std/math.o std/mmfile.o \ + std/outbuffer.o std/ctype.o std/regexp.o std/random.o \ + std/stream.o std/cstream.o std/switcherr.o std/array.o std/gc.o \ + internal/qsortg.o std/thread.o internal/obj.o std/utf.o std/uri.o \ + crc32.o std/conv.o internal/arraycast.o errno.o \ + std/process.o std/syserror.o std/metastrings.o \ + std/socket.o std/socketstream.o std/c/stdarg.o std/stdio.o std/format.o \ + std/perf.o std/openrj.o std/uni.o std/demangle.o std/bitarray.o \ + $(subst ti_,std/typeinfo/ti_,$(TI)) \ + std/date.o std/dateparse.o std/math2.o etc/c/zlib.o std/zlib.o std/zip.o \ + internal/dgccmain2.o internal/rundmain.o std/stdarg.o \ + std/signals.o std/cpuid.o std/traits.o std/typetuple.o std/bind.o + + +# This should not be linked into a shared library. +CMAIN_OBJS = internal/cmain.o +ZLIB_OBJS = etc/c/zlib/adler32.o etc/c/zlib/compress.o \ + etc/c/zlib/crc32.o etc/c/zlib/gzio.o \ + etc/c/zlib/uncompr.o etc/c/zlib/deflate.o \ + etc/c/zlib/trees.o etc/c/zlib/zutil.o \ + etc/c/zlib/inflate.o etc/c/zlib/infback.o \ + etc/c/zlib/inftrees.o etc/c/zlib/inffast.o + +GC_OBJS = internal/gc/gc.o internal/gc/gcx.o internal/gc/gcbits.o \ + @D_GC_MODULES@ $(am__empty) +GCC_OBJS = gcc/config.o gcc/unwind.o gcc/deh.o gcc/threadsem.o \ + std/c/dirent.o gcc/cbridge_time.o + + +# std.c.linux.linux, std.loader, gcc.cbridge* +WINDOWS_OBJS = std/c/windows/windows.o std/c/windows/com.o std/c/windows/winsock.o \ + std/windows/iunknown.o std/windows/registry.o std/windows/syserror.o \ + std/windows/charset.o + +CONFIG_D_FRAGMENTS = config/config-head frag-ac frag-gen frag-math config/config-mid config/config-tail +CONFIG_UNIX_FRAGMENTS = config/unix-head frag-unix config/unix-mid + +# GCC_OBJS (gcc/config.o) first so I don't have to write more deps +ALL_PHOBOS_OBJS = $(D_EXTRA_OBJS) $(GCC_OBJS) $(MAIN_OBJS) $(ZLIB_OBJS) $(GC_OBJS) $(WEAK_OBJS) + +# Work around what appears to be a GNU make bug handling MAKEFLAGS +# values defined in terms of make variables, as is the case for CC and +# friends when we are called from the top level Makefile. +AM_MAKEFLAGS = \ + "AR_FLAGS=$(AR_FLAGS)" \ + "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ + "CC_FOR_TARGET=$(CC_FOR_TARGET)" \ + "CFLAGS=$(CFLAGS)" \ + "CXXFLAGS=$(CXXFLAGS)" \ + "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ + "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ + "INSTALL=$(INSTALL)" \ + "INSTALL_DATA=$(INSTALL_DATA)" \ + "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ + "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ + "LDFLAGS=$(LDFLAGS)" \ + "LIBCFLAGS=$(LIBCFLAGS)" \ + "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ + "MAKE=$(MAKE)" \ + "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ + "PICFLAG=$(PICFLAG)" \ + "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ + "SHELL=$(SHELL)" \ + "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ + "exec_prefix=$(exec_prefix)" \ + "infodir=$(infodir)" \ + "libdir=$(libdir)" \ + "includedir=$(includedir)" \ + "prefix=$(prefix)" \ + "tooldir=$(tooldir)" \ + "gdc_include_dir=$(gdc_include_dir)" \ + "AR=$(AR)" \ + "AS=$(AS)" \ + "LD=$(LD)" \ + "RANLIB=$(RANLIB)" \ + "NM=$(NM)" \ + "NM_FOR_BUILD=$(NM_FOR_BUILD)" \ + "NM_FOR_TARGET=$(NM_FOR_TARGET)" \ + "DESTDIR=$(DESTDIR)" \ + "WERROR=$(WERROR)" + + +# Subdir rules rely on $(FLAGS_TO_PASS) +FLAGS_TO_PASS = $(AM_MAKEFLAGS) +all: $(BUILT_SOURCES) config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .d .c .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign --ignore-deps'; \ + cd $(srcdir) && $(AUTOMAKE) --foreign --ignore-deps \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign --ignore-deps Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +frag-ac: $(top_builddir)/config.status $(srcdir)/frag-ac.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +phobos-ver-syms: $(top_builddir)/config.status $(srcdir)/phobos-ver-syms.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +minimal$(EXEEXT): $(minimal_OBJECTS) $(minimal_DEPENDENCIES) + @rm -f minimal$(EXEEXT) + $(LINK) $(minimal_LDFLAGS) $(minimal_OBJECTS) $(minimal_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +# GNU Make needs to see an explicit $(MAKE) variable in the command it +# runs to enable its job server during parallel builds. Hence the +# comments below. +all-multi: + $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE) +install-multi: + $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE) + +mostlyclean-multi: + $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE) +clean-multi: + $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE) +distclean-multi: + $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE) +maintainer-clean-multi: + $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE) +uninstall-info-am: + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + $(mkdir_p) $(distdir)/. + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(PROGRAMS) all-multi config.h all-local +installdirs: +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am clean-multi + +clean-am: clean-generic clean-local clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am distclean-multi + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-data-local + +install-exec-am: install-exec-local install-multi + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am maintainer-clean-multi + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am mostlyclean-multi + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am all-local all-multi am--refresh check \ + check-am check-local clean clean-generic clean-local \ + clean-multi clean-noinstPROGRAMS ctags dist dist-all \ + dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip distcheck \ + distclean distclean-compile distclean-generic distclean-hdr \ + distclean-multi distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-local install-exec install-exec-am \ + install-exec-local install-info install-info-am install-man \ + install-multi install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + maintainer-clean-multi mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-multi pdf pdf-am ps ps-am tags \ + uninstall uninstall-am uninstall-info-am + +minimal.c: + echo "int main() { return 0; }" > $@ + +all-local: libgphobos.a + +%.o : %.d $(D_PREREQ_SRCS) + $(GDC) -o $@ $(ALL_DFLAGS) \ + -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +# %.o : %.c +# Use .c.o to override Automake +.c.o: + $(CC) -o $@ $(OUR_CFLAGS) $(CFLAGS) -c $< + +# boxer is currently broken +std/boxer.t.o: std/boxer.o + cp $< $@ + +%.t.o : %.d $(D_PREREQ_SRCS) + $(GDC) -o $@ $(ALL_DFLAGS) -fno-release -funittest -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +internal/gc/gcx.t.o: $(D_PREREQ_SRCS) $(srcdir)/internal/gc/gcx.d + $(GDC) -o $@ $(ALL_DFLAGS) -funittest -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +%.t.o : %.o + cp $< $@ + +unittest: unittest.o libgphobos_t.a libgphobos.a + $(GDC) -o $@ $(CFLAGS) unittest.o -L./ -lgphobos_t $(LIBS) + +internal/gc/testgc.o: $(host_alias)/gcc/config.d $(srcdir)/internal/gc/testgc.d + $(GDC) -o $@ $(ALL_DFLAGS) -fno-release -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $(srcdir)/internal/gc/testgc.d + +testgc: internal/gc/testgc.o libgphobos_t.a libgphobos.a + $(GDC) -o $@ $(ALL_DFLAGS) internal/gc/testgc.o -L./ -lgphobos_t $(LIBS) + +gen_config1: config/gen_config1.o + $(CC) $(CFLAGS) -o $@ $^ + +$(config_d_src): $(CONFIG_D_FRAGMENTS) stamp-tgtdir + cat $^ > $@ + +gcc/config.o: $(config_d_src) + $(GDC) -o $@ $(ALL_DFLAGS) -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< +gcc/config.t.o: gcc/config.o + cp gcc/config.o gcc/config.t.o + +gen_math: config/gen_math.o + $(CC) $(CFLAGS) -o $@ $^ + +config/gen_unix.o: config/gen_unix.c config/makestruct.h + +gen_unix: config/gen_unix.o + $(CC) $(CFLAGS) -o $@ $^ + +# Plain 'make' would use: ifdef D_GENERATE_FRAGMENTS +@D_GENERATE_FRAGMENTS_TRUE@frag-gen: gen_config1 +@D_GENERATE_FRAGMENTS_TRUE@ ./gen_config1 > $@ || rm -f $@ +@D_GENERATE_FRAGMENTS_TRUE@frag-unix: gen_unix +@D_GENERATE_FRAGMENTS_TRUE@ ./gen_unix > $@ +@D_GENERATE_FRAGMENTS_TRUE@frag-math: gen_math +@D_GENERATE_FRAGMENTS_TRUE@ ./gen_math > $@ || rm -f $@ +@D_GENERATE_FRAGMENTS_FALSE@frag-gen: $(D_FRAGMENT_SRCDIR)/$@ +@D_GENERATE_FRAGMENTS_FALSE@ cp $(D_FRAGMENT_SRCDIR)/$@ $@ +@D_GENERATE_FRAGMENTS_FALSE@frag-unix: $(D_FRAGMENT_SRCDIR)/$@ +@D_GENERATE_FRAGMENTS_FALSE@ cp $(D_FRAGMENT_SRCDIR)/$@ $@ +@D_GENERATE_FRAGMENTS_FALSE@frag-math: $(D_FRAGMENT_SRCDIR)/$@ +@D_GENERATE_FRAGMENTS_FALSE@ cp $(D_FRAGMENT_SRCDIR)/$@ $@ + +$(configunix_d_src): $(CONFIG_UNIX_FRAGMENTS) stamp-tgtdir + cat $^ > $@ + +gcc/configunix.o: $(configunix_d_src) $(config_d_src) + $(GDC) -o $@ $(ALL_DFLAGS) -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< +gcc/configunix.t.o: gcc/configunix.o + cp gcc/configunix.o gcc/configunix.t.o + +gcc/cbridge_math.o: gcc/cbridge_math.c + $(CC) -o $@ $(OUR_CFLAGS) $(CFLAGS) -fno-strict-aliasing -c $< + +std/stream.o: std/stream.d $(D_PREREQ_SRCS) + $(GDC) -o $@ $(ALL_DFLAGS) -fdeprecated -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< +std/stream.t.o: std/stream.d $(D_PREREQ_SRCS) + $(GDC) -o $@ $(ALL_DFLAGS) -fdeprecated -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +libgphobos.a : $(ALL_PHOBOS_OBJS) $(CMAIN_OBJS) + $(AR) -r $@ $(ALL_PHOBOS_OBJS) $(CMAIN_OBJS) + $(RANLIB) $@ + +libgphobos_t.a : $(ALL_PHOBOS_OBJS:.o=.t.o) $(CMAIN_OBJS) + $(AR) -r $@ $(ALL_PHOBOS_OBJS:.o=.t.o) $(CMAIN_OBJS) + $(RANLIB) $@ + +# This has to be an empty file because it is included in the prerequisites of rules +# that use "cat $^" to generate their targets. +# Otherwise, need to specify $srcdir for known source files in CONFIG_xxx_FRAGMENTS.. +stamp-tgtdir: + mkdir -p $(host_alias)/gcc + touch $@ + +check-local: unittest testgc + ./unittest + ./testgc + +install-exec-local: $(D_PREREQ_SRCS) libgphobos.a + $(mkinstalldirs) $(DESTDIR)$(toolexeclibdir) + $(INSTALL) libgphobos.a $(DESTDIR)$(toolexeclibdir) + $(RANLIB) $(DESTDIR)$(toolexeclibdir)/libgphobos.a + +install-data-local: $(D_PREREQ_SRCS) libgphobos.a + for i in etc etc/c \ + etc/c/zlib \ + gcc std std/c \ + std/c/darwin std/c/linux std/c/mach std/c/skyos std/c/unix std/c/windows \ + std/typeinfo std/windows; do \ + $(mkinstalldirs) $(DESTDIR)$(gdc_include_dir)/$$i; \ + for f in $(srcdir)/$$i/*.[hd]; do $(INSTALL_HEADER) $$f $(DESTDIR)$(gdc_include_dir)/$$i; done; \ + done + for i in crc32.d gcstats.d object.d; do \ + $(INSTALL_HEADER) $(srcdir)/$$i $(DESTDIR)$(gdc_include_dir); done + $(mkinstalldirs) $(DESTDIR)$(gdc_include_dir)/$(host_alias)/$(MULTISUBDIR)/gcc + $(INSTALL_HEADER) $(config_d_src) $(DESTDIR)$(gdc_include_dir)/$(host_alias)/$(MULTISUBDIR)/gcc + if test -f $(configunix_d_src); then $(INSTALL_HEADER) $(host_alias)/gcc/configunix.d $(DESTDIR)$(gdc_include_dir)/$(host_alias)/$(MULTISUBDIR)/gcc; fi + $(INSTALL) phobos-ver-syms $(DESTDIR)$(gdc_include_dir)/$(host_alias)/$(MULTISUBDIR) + +clean-local: + rm -f $(ALL_PHOBOS_OBJS) $(CMAIN_OBJS) + rm -f $(ALL_PHOBOS_OBJS:.o=.t.o) + rm -f unittest.o internal/gc/testgc.o + rm -f unittest$(EXEEXT) testgc$(EXEEXT) + rm -f config/gen_config1.o config/gen_unix.o config/gen_math.o + rm -f gen_config1$(EXEEXT) gen_unix$(EXEEXT) gen_math$(EXEEXT) + rm -f frag-gen frag-math frag-unix + rm -f $(config_d_src) $(configunix_d_src) + rm -f libgphobos.a + rm -f libgphobos_t.a +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -uNrp dmd-1.007/src/phobos/object.d gdc-0.23/d/phobos/object.d --- dmd-1.007/src/phobos/object.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/object.d 2007-02-13 14:37:13.000000000 +0100 @@ -30,7 +30,7 @@ struct Interface { ClassInfo classinfo; void *[] vtbl; - int offset; // offset to Interface 'this' from Object 'this' + ptrdiff_t offset; // offset to Interface 'this' from Object 'this' } class ClassInfo : Object diff -uNrp dmd-1.007/src/phobos/phobos-ver-syms.in gdc-0.23/d/phobos/phobos-ver-syms.in --- dmd-1.007/src/phobos/phobos-ver-syms.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/phobos-ver-syms.in 2006-06-03 04:57:27.000000000 +0200 @@ -0,0 +1,17 @@ +@DCFG_UNIX@ +@DCFG_PTHREAD_SUSPEND@ +@DCFG_SEMAPHORE_IMPL@ +@DCFG_TRUNC@ +@DCFG_NEARBYINT@ +@DCFG_ROUND@ +@DCFG_TGAMMA@ +@DCFG_NAN@ +@DCFG_EXP2_LOG2@ +@DCFG_EXECVPE@ +@DCFG_SPAWNVP@ +@DCFG_FWIDE@ +@DCFG_STRTOLD@ +@DCFG_SA_LEN@ +@DCFG_CBRIDGE_STDIO@ +@DCFG_MMAP@ +@DCFG_GETPWNAM_R@ diff -uNrp dmd-1.007/src/phobos/std/array.d gdc-0.23/d/phobos/std/array.d --- dmd-1.007/src/phobos/std/array.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/array.d 2007-02-25 23:06:51.000000000 +0100 @@ -18,7 +18,8 @@ class ArrayBoundsError : Error char[] buffer = new char[19 + filename.length + linnum.sizeof * 3 + 1]; int len; - len = sprintf(buffer.ptr, "ArrayBoundsError %.*s(%u)", filename, linnum); + len = sprintf(buffer.ptr, "ArrayBoundsError %.*s(%u)", + cast(int) filename.length, filename.ptr, linnum); super(buffer[0..len]); } } diff -uNrp dmd-1.007/src/phobos/std/asserterror.d gdc-0.23/d/phobos/std/asserterror.d --- dmd-1.007/src/phobos/std/asserterror.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/asserterror.d 2007-02-25 23:07:33.000000000 +0100 @@ -36,7 +36,7 @@ class AssertError : Error { version (Win32) alias _snprintf snprintf; count = snprintf(buffer, len, "AssertError Failure %.*s(%u) %.*s", - filename, linnum, msg); + cast(int) filename.length, filename.ptr, linnum, msg); if (count >= len || count == -1) { super("AssertError internal failure"); std.c.stdlib.free(buffer); diff -uNrp dmd-1.007/src/phobos/std/base64.d gdc-0.23/d/phobos/std/base64.d --- dmd-1.007/src/phobos/std/base64.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/base64.d 2007-03-04 15:48:29.000000000 +0100 @@ -66,7 +66,7 @@ const char[] array = "ABCDEFGHIJKLMNOPQR * Returns the number of bytes needed to encode a string of length slen. */ -uint encodeLength(uint slen) +size_t encodeLength(size_t slen) { uint result; result = slen / 3; @@ -94,9 +94,9 @@ body if(!str.length) return buf[0 .. 0]; - uint stri; - uint strmax = str.length / 3; - uint strleft = str.length % 3; + size_t stri; + size_t strmax = str.length / 3; + size_t strleft = str.length % 3; uint x; char* sp, bp; @@ -166,7 +166,7 @@ unittest * Returns the number of bytes needed to decode an encoded string of this * length. */ -uint decodeLength(uint elen) +size_t decodeLength(size_t elen) { return elen / 4 * 3; } @@ -224,8 +224,8 @@ body if(estr.length % 4) throw new Base64Exception("Invalid encoded base64 string"); - uint estri; - uint estrmax = estr.length / 4; + size_t estri; + size_t estrmax = estr.length / 4; uint x; char* sp, bp; char ch; diff -uNrp dmd-1.007/src/phobos/std/bitarray.d gdc-0.23/d/phobos/std/bitarray.d --- dmd-1.007/src/phobos/std/bitarray.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/bitarray.d 2007-02-28 02:20:15.000000000 +0100 @@ -287,23 +287,23 @@ struct BitArray */ int opEquals(BitArray a2) - { int i; + { size_t i; if (this.length != a2.length) return 0; // not equal - byte *p1 = cast(byte*)this.ptr; - byte *p2 = cast(byte*)a2.ptr; - uint n = this.length / 8; + uint *p1 = cast(uint*)this.ptr; + uint *p2 = cast(uint*)a2.ptr; + size_t n = this.length / (8 * uint.sizeof); for (i = 0; i < n; i++) { if (p1[i] != p2[i]) return 0; // not equal } - ubyte mask; + uint mask; - n = this.length & 7; - mask = cast(ubyte)((1 << n) - 1); + n = this.length & ((8 * uint.sizeof) - 1); + mask = (1 << n) - 1; //printf("i = %d, n = %d, mask = %x, %x, %x\n", i, n, mask, p1[i], p2[i]); return (mask == 0) || (p1[i] & mask) == (p2[i] & mask); } @@ -336,20 +336,21 @@ struct BitArray int opCmp(BitArray a2) { - uint len; - uint i; + size_t len; + size_t i; len = this.length; if (a2.length < len) len = a2.length; - ubyte* p1 = cast(ubyte*)this.ptr; - ubyte* p2 = cast(ubyte*)a2.ptr; - uint n = len / 8; + uint* p1 = cast(uint*)this.ptr; + uint* p2 = cast(uint*)a2.ptr; + size_t n = len / (8 * uint.sizeof); for (i = 0; i < n; i++) { if (p1[i] != p2[i]) break; // not equal } + /* for (uint j = i * 8; j < len; j++) { ubyte mask = cast(ubyte)(1 << j); int c; @@ -358,7 +359,22 @@ struct BitArray if (c) return c; } - return cast(int)this.len - cast(int)a2.length; + */ + uint mask = 1; + for (size_t j = i * (8 * uint.sizeof); j < len; j++) + { int c; + + c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask); + if (c) + return c; + mask <<= 1; + } + ptrdiff_t c = cast(ptrdiff_t)this.len - cast(ptrdiff_t)a2.length; + if (c < 0) + return -1; + else if (c > 0) + return 1; + return 0; } unittest diff -uNrp dmd-1.007/src/phobos/std/boxer.d gdc-0.23/d/phobos/std/boxer.d --- dmd-1.007/src/phobos/std/boxer.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/boxer.d 2006-12-09 17:52:48.000000000 +0100 @@ -57,11 +57,21 @@ a = boxArray(arg_types, arg_data); * WIKI=Phobos/StdBoxer */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, May 2005 + + This module make not work on all GCC targets due to assumptions + about the type of va_list. +*/ module std.boxer; private import std.format; private import std.string; private import std.utf; +version (GNU) + private import std.stdarg; /* These functions and types allow packing objects into generic containers * and recovering them later. This comes into play in a wide spectrum of @@ -133,6 +143,11 @@ private enum TypeClass Other, /**< Any other type, such as delegates, function pointers, struct, void... */ } +version (DigitalMars) + version = DigitalMars_TypeInfo; +else version (GNU) + version = DigitalMars_TypeInfo; + /** * Box is a generic container for objects (both value and heap), allowing the * user to box them in a generic form and recover them later. @@ -150,7 +165,7 @@ struct Box void* p_longData; /**< An array of the contained object. */ void[8] p_shortData; /**< Data used when the object is small. */ } - + private static TypeClass findTypeClass(TypeInfo type) { if (cast(TypeInfo_Class) type) @@ -160,7 +175,7 @@ struct Box if (isArrayTypeInfo(type)) return TypeClass.Array; - version (DigitalMars) + version (DigitalMars_TypeInfo) { /* Depend upon the name of the base type classes. */ if (type.classinfo.name.length != "TypeInfo_?".length) @@ -276,7 +291,13 @@ struct Box args[0..(char[]).sizeof] = (cast(void*) &format)[0..(char[]).sizeof]; args[(char[]).sizeof..length] = data; - std.format.doFormat(&putc, arguments, args.ptr); + version (GNU) + { + va_list dummy = void; + std.format.doFormat(&putc, arguments, dummy, args.ptr); + } + else + std.format.doFormat(&putc, arguments, args.ptr); delete args; return string; @@ -400,7 +421,7 @@ in } body { - return box(_arguments[0], _argptr); + return box(_arguments[0], cast(void*) _argptr); } /** @@ -449,17 +470,17 @@ Box[] boxArray(TypeInfo[] types, void* d return array; } -/** - * Box each argument passed to the function, returning an array of boxes. - */ + /** + * Box each argument passed to the function, returning an array of boxes. + */ Box[] boxArray(...) { - return boxArray(_arguments, _argptr); + return boxArray(_arguments, cast(void *) _argptr); } -/** - * Convert an array of boxes into an array of arguments. - */ + /** + * Convert an array of boxes into an array of arguments. + */ void boxArrayToArguments(Box[] arguments, out TypeInfo[] types, out void* data) { size_t dataLength; @@ -706,7 +727,7 @@ template unbox(T : void*) return *cast(void**) value.data; if (isArrayTypeInfo(value.type)) return (*cast(void[]*) value.data).ptr; - if (typeid(Object) == value.type) + if (cast(TypeInfo_Class) value.type) return *cast(Object*) value.data; throw new UnboxException(value, typeid(T)); diff -uNrp dmd-1.007/src/phobos/std/c/darwin/ldblcompat.d gdc-0.23/d/phobos/std/c/darwin/ldblcompat.d --- dmd-1.007/src/phobos/std/c/darwin/ldblcompat.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/darwin/ldblcompat.d 2006-06-03 04:57:06.000000000 +0200 @@ -0,0 +1,39 @@ +/* In C, the stdio/stdlib function to use are determined by a test in cdefs.h. + There is another test for math functions in architecture/ppc/math.h which + is reproduced, in spirit, here. This one test controls both stdio/stdlib and + math functions for D. */ + +module std.c.darwin.ldblcompat; + +version (PPC) +{ + version (GNU_WantLongDoubleFormat128) + version = GNU_UseLongDoubleFormat128; + else version (GNU_WantLongDoubleFormat64) + { } + else + { + version (GNU_LongDouble128) + version = GNU_UseLongDoubleFormat128; + } +} + +version (GNU_UseLongDoubleFormat128) +{ + // Currently, the following test from cdefs.h is not supported: + //# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 < 1040 + version (all) + const char[] __DARWIN_LDBL_COMPAT = "$LDBL128"; + else + const char[] __DARWIN_LDBL_COMPAT = "$LDBLStub"; + const char[] __DARWIN_LDBL_COMPAT2 = "$LDBL128"; + + const char[] __LIBMLDBL_COMPAT = "$LDBL128"; +} +else +{ + const char[] __DARWIN_LDBL_COMPAT = ""; + const char[] __DARWIN_LDBL_COMPAT2 = ""; + + const char[] __LIBMLDBL_COMPAT = ""; +} diff -uNrp dmd-1.007/src/phobos/std/c/dirent.d gdc-0.23/d/phobos/std/c/dirent.d --- dmd-1.007/src/phobos/std/c/dirent.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/dirent.d 2006-12-09 20:39:21.000000000 +0100 @@ -0,0 +1,53 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.dirent; + +private import gcc.config; +private import std.string; +private import gcc.config; + +extern(C) { + +struct dirent { + byte[gcc.config.dirent_d_name_offset] opaque1; + char[gcc.config.dirent_d_name_size] d_name; + byte[gcc.config.dirent_remaining_size] opaque2; +} + +struct DIR { + byte[gcc.config.DIR_struct_size] opaque; +} + +DIR * opendir(char *); +dirent * readdir(DIR *); +void rewinddir(DIR *); +int closedir(DIR *); +Coff_t telldir(DIR* dir); +void seekdir(DIR* dir, Coff_t offset); + +} + +char[] readdirD(DIR * dir) +{ + dirent* ent = readdir(dir); + if (ent) + return toString(ent.d_name.ptr); + else + return null; +} diff -uNrp dmd-1.007/src/phobos/std/c/fenv.d gdc-0.23/d/phobos/std/c/fenv.d --- dmd-1.007/src/phobos/std/c/fenv.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/fenv.d 2007-02-23 19:45:32.000000000 +0100 @@ -36,6 +36,8 @@ struct fenv_t uint __data_offset; ushort __data_selector; ushort __unused5; + static if (size_t.sizeof == 8) + uint __mxcsr; } else { diff -uNrp dmd-1.007/src/phobos/std/c/linux/ldblcompat.d gdc-0.23/d/phobos/std/c/linux/ldblcompat.d --- dmd-1.007/src/phobos/std/c/linux/ldblcompat.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/linux/ldblcompat.d 2006-06-03 04:57:08.000000000 +0200 @@ -0,0 +1,25 @@ +/* In C, the stdio/stdlib function to use are determined by a test in cdefs.h. + Not exactly sure how math funcs are handled. */ + +module std.c.linux.ldblcompat; + +version (GNU_WantLongDoubleFormat128) + version = GNU_UseLongDoubleFormat128; +else version (GNU_WantLongDoubleFormat64) + { } +else +{ + version (GNU_LongDouble128) + version = GNU_UseLongDoubleFormat128; +} + +version (GNU_UseLongDoubleFormat128) +{ + static const bool __No_Long_Double_Math = false; + const char[] __LDBL_COMPAT_PFX = ""; +} +else +{ + static const bool __No_Long_Double_Math = true; + const char[] __LDBL_COMPAT_PFX = "__nldbl_"; +} diff -uNrp dmd-1.007/src/phobos/std/c/linux/linux.d gdc-0.23/d/phobos/std/c/linux/linux.d --- dmd-1.007/src/phobos/std/c/linux/linux.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/linux/linux.d 2006-12-26 22:27:18.000000000 +0100 @@ -1,397 +1,10 @@ - -/* Written by Walter Bright, Christopher E. Miller, and many others. - * www.digitalmars.com - * Placed into public domain. - * Linux(R) is the registered trademark of Linus Torvalds in the U.S. and other - * countries. - */ +// This is a backwards compatibility module for the DMD std.c.linux.linux module std.c.linux.linux; +public import std.c.unix.unix; +public import std.c.dirent; public import std.c.linux.linuxextern; -public import std.c.linux.pthread; - -private import std.c.stdio; - -alias int pid_t; -alias int off_t; -alias uint mode_t; - -alias uint uid_t; -alias uint gid_t; - -enum : int -{ - SIGHUP = 1, - SIGINT = 2, - SIGQUIT = 3, - SIGILL = 4, - SIGTRAP = 5, - SIGABRT = 6, - SIGIOT = 6, - SIGBUS = 7, - SIGFPE = 8, - SIGKILL = 9, - SIGUSR1 = 10, - SIGSEGV = 11, - SIGUSR2 = 12, - SIGPIPE = 13, - SIGALRM = 14, - SIGTERM = 15, - SIGSTKFLT = 16, - SIGCHLD = 17, - SIGCONT = 18, - SIGSTOP = 19, - SIGTSTP = 20, - SIGTTIN = 21, - SIGTTOU = 22, - SIGURG = 23, - SIGXCPU = 24, - SIGXFSZ = 25, - SIGVTALRM = 26, - SIGPROF = 27, - SIGWINCH = 28, - SIGPOLL = 29, - SIGIO = 29, - SIGPWR = 30, - SIGSYS = 31, - SIGUNUSED = 31, -} - -enum -{ - O_RDONLY = 0, - O_WRONLY = 1, - O_RDWR = 2, - O_CREAT = 0100, - O_EXCL = 0200, - O_TRUNC = 01000, - O_APPEND = 02000, -} - -struct struct_stat // distinguish it from the stat() function -{ - ulong st_dev; /// device - ushort __pad1; - uint st_ino; /// file serial number - uint st_mode; /// file mode - uint st_nlink; /// link count - uint st_uid; /// user ID of file's owner - uint st_gid; /// user ID of group's owner - ulong st_rdev; /// if device then device number - ushort __pad2; - int st_size; /// file size in bytes - int st_blksize; /// optimal I/O block size - int st_blocks; /// number of allocated 512 byte blocks - int st_atime; - uint st_atimensec; - int st_mtime; - uint st_mtimensec; - int st_ctime; - uint st_ctimensec; - - uint __unused4; - uint __unused5; -} - -unittest -{ - assert(struct_stat.sizeof == 88); -} - -enum : int -{ - S_IFIFO = 0010000, - S_IFCHR = 0020000, - S_IFDIR = 0040000, - S_IFBLK = 0060000, - S_IFREG = 0100000, - S_IFLNK = 0120000, - S_IFSOCK = 0140000, - - S_IFMT = 0170000, - - S_IREAD = 0000400, - S_IWRITE = 0000200, - S_IEXEC = 0000100, -} - -extern (C) -{ - int access(char*, int); - int open(char*, int, ...); - int read(int, void*, int); - int write(int, void*, int); - int close(int); - int lseek(int, int, int); - int fstat(int, struct_stat*); - int lstat(char*, struct_stat*); - int stat(char*, struct_stat*); - int chdir(char*); - int mkdir(char*, int); - int rmdir(char*); - char* getcwd(char*, int); - int chmod(char*, mode_t); - int fork(); - int dup(int); - int dup2(int, int); - int pipe(int[2]); - pid_t wait(int*); - int waitpid(pid_t, int*, int); - - uint alarm(uint); - char* basename(char*); - //wint_t btowc(int); - int chown(char*, uid_t, gid_t); - int chroot(char*); - size_t confstr(int, char*, size_t); - int creat(char*, mode_t); - char* ctermid(char*); - int dirfd(DIR*); - char* dirname(char*); - int fattach(int, char*); - int fchmod(int, mode_t); - int fdatasync(int); - int ffs(int); - int fmtmsg(int, char*, int, char*, char*, char*); - int fpathconf(int, int); - int fseeko(FILE*, off_t, int); - off_t ftello(FILE*); - - extern char** environ; -} - -struct timeval -{ - int tv_sec; - int tv_usec; -} - -struct struct_timezone -{ - int tz_minuteswest; - int tz_dstime; -} - -struct tm -{ - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - int tm_gmtoff; - int tm_zone; -} - -extern (C) -{ - int gettimeofday(timeval*, struct_timezone*); - __time_t time(__time_t*); - char* asctime(tm*); - char* ctime(__time_t*); - tm* gmtime(__time_t*); - tm* localtime(__time_t*); - __time_t mktime(tm*); - char* asctime_r(tm* t, char* buf); - char* ctime_r(__time_t* timep, char* buf); - tm* gmtime_r(__time_t* timep, tm* result); - tm* localtime_r(__time_t* timep, tm* result); -} - -/**************************************************************/ -// Memory mapping from and - -enum -{ - PROT_NONE = 0, - PROT_READ = 1, - PROT_WRITE = 2, - PROT_EXEC = 4, -} - -// Memory mapping sharing types - -enum -{ MAP_SHARED = 1, - MAP_PRIVATE = 2, - MAP_TYPE = 0x0F, - MAP_FIXED = 0x10, - MAP_FILE = 0, - MAP_ANONYMOUS = 0x20, - MAP_ANON = 0x20, - MAP_GROWSDOWN = 0x100, - MAP_DENYWRITE = 0x800, - MAP_EXECUTABLE = 0x1000, - MAP_LOCKED = 0x2000, - MAP_NORESERVE = 0x4000, - MAP_POPULATE = 0x8000, - MAP_NONBLOCK = 0x10000, -} - -// Values for msync() - -enum -{ MS_ASYNC = 1, - MS_INVALIDATE = 2, - MS_SYNC = 4, -} - -// Values for mlockall() - -enum -{ - MCL_CURRENT = 1, - MCL_FUTURE = 2, -} - -// Values for mremap() - -enum -{ - MREMAP_MAYMOVE = 1, -} - -// Values for madvise - -enum -{ MADV_NORMAL = 0, - MADV_RANDOM = 1, - MADV_SEQUENTIAL = 2, - MADV_WILLNEED = 3, - MADV_DONTNEED = 4, -} - -extern (C) -{ -void* mmap(void*, size_t, int, int, int, off_t); -const void* MAP_FAILED = cast(void*)-1; - -int munmap(void*, size_t); -int mprotect(void*, size_t, int); -int msync(void*, size_t, int); -int madvise(void*, size_t, int); -int mlock(void*, size_t); -int munlock(void*, size_t); -int mlockall(int); -int munlockall(); -void* mremap(void*, size_t, size_t, int); -int mincore(void*, size_t, ubyte*); -int remap_file_pages(void*, size_t, int, size_t, int); -int shm_open(char*, int, int); -int shm_unlink(char*); -} - -extern(C) -{ - - enum - { - DT_UNKNOWN = 0, - DT_FIFO = 1, - DT_CHR = 2, - DT_DIR = 4, - DT_BLK = 6, - DT_REG = 8, - DT_LNK = 10, - DT_SOCK = 12, - DT_WHT = 14, - } - - struct dirent - { - int d_ino; - off_t d_off; - ushort d_reclen; - ubyte d_type; - char[256] d_name; - } - - struct DIR - { - // Managed by OS. - } - - DIR* opendir(char* name); - int closedir(DIR* dir); - dirent* readdir(DIR* dir); - void rewinddir(DIR* dir); - off_t telldir(DIR* dir); - void seekdir(DIR* dir, off_t offset); -} - - -extern(C) -{ - private import std.intrinsic; - - - int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout); - int fcntl(int s, int f, ...); - - - enum - { - EINTR = 4, - EINPROGRESS = 115, - } - - - const uint FD_SETSIZE = 1024; - //const uint NFDBITS = 8 * int.sizeof; // DMD 0.110: 8 * (int).sizeof is not an expression - const int NFDBITS = 32; - - - struct fd_set - { - int[FD_SETSIZE / NFDBITS] fds_bits; - alias fds_bits __fds_bits; - } - - - int FDELT(int d) - { - return d / NFDBITS; - } - - - int FDMASK(int d) - { - return 1 << (d % NFDBITS); - } - - - // Removes. - void FD_CLR(int fd, fd_set* set) - { - btr(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS)); - } - - - // Tests. - int FD_ISSET(int fd, fd_set* set) - { - return bt(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS)); - } - - - // Adds. - void FD_SET(int fd, fd_set* set) - { - bts(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS)); - } - - - // Resets to zero. - void FD_ZERO(fd_set* set) - { - set.fds_bits[] = 0; - } -} extern (C) { @@ -406,71 +19,3 @@ extern (C) void* dlsym(void* handle, char* name); 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; - } - - const size_t _SIGSET_NWORDS = 1024 / (8 * uint.sizeof); - struct sigset_t - { - uint[_SIGSET_NWORDS] __val; - } - - int getpwnam_r(char*, passwd*, void*, size_t, passwd**); - passwd* getpwnam(char*); - passwd* getpwuid(uid_t); - int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); - int kill(pid_t, int); - int sem_close(sem_t*); - int sigemptyset(sigset_t*); - int sigfillset(sigset_t*); - int sigismember(sigset_t*, int); - int sigsuspend(sigset_t*); -} - -extern (C) -{ - /* from semaphore.h - */ - - struct sem_t - { - _pthread_fastlock __sem_lock; - int __sem_value; - void* __sem_waiting; - } - - int sem_init(sem_t*, int, uint); - int sem_wait(sem_t*); - int sem_trywait(sem_t*); - int sem_post(sem_t*); - int sem_getvalue(sem_t*, int*); - int sem_destroy(sem_t*); -} - -extern (C) -{ - /* from utime.h - */ - - struct utimbuf - { - __time_t actime; - __time_t modtime; - } - - int utime(char* filename, utimbuf* buf); -} diff -uNrp dmd-1.007/src/phobos/std/c/linux/linux.d.orig-dmd gdc-0.23/d/phobos/std/c/linux/linux.d.orig-dmd --- dmd-1.007/src/phobos/std/c/linux/linux.d.orig-dmd 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/linux/linux.d.orig-dmd 2007-02-02 19:33:16.000000000 +0100 @@ -0,0 +1,476 @@ + +/* Written by Walter Bright, Christopher E. Miller, and many others. + * www.digitalmars.com + * Placed into public domain. + * Linux(R) is the registered trademark of Linus Torvalds in the U.S. and other + * countries. + */ + +module std.c.linux.linux; + +public import std.c.linux.linuxextern; +public import std.c.linux.pthread; + +private import std.c.stdio; + +alias int pid_t; +alias int off_t; +alias uint mode_t; + +alias uint uid_t; +alias uint gid_t; + +enum : int +{ + SIGHUP = 1, + SIGINT = 2, + SIGQUIT = 3, + SIGILL = 4, + SIGTRAP = 5, + SIGABRT = 6, + SIGIOT = 6, + SIGBUS = 7, + SIGFPE = 8, + SIGKILL = 9, + SIGUSR1 = 10, + SIGSEGV = 11, + SIGUSR2 = 12, + SIGPIPE = 13, + SIGALRM = 14, + SIGTERM = 15, + SIGSTKFLT = 16, + SIGCHLD = 17, + SIGCONT = 18, + SIGSTOP = 19, + SIGTSTP = 20, + SIGTTIN = 21, + SIGTTOU = 22, + SIGURG = 23, + SIGXCPU = 24, + SIGXFSZ = 25, + SIGVTALRM = 26, + SIGPROF = 27, + SIGWINCH = 28, + SIGPOLL = 29, + SIGIO = 29, + SIGPWR = 30, + SIGSYS = 31, + SIGUNUSED = 31, +} + +enum +{ + O_RDONLY = 0, + O_WRONLY = 1, + O_RDWR = 2, + O_CREAT = 0100, + O_EXCL = 0200, + O_TRUNC = 01000, + O_APPEND = 02000, +} + +struct struct_stat // distinguish it from the stat() function +{ + ulong st_dev; /// device + ushort __pad1; + uint st_ino; /// file serial number + uint st_mode; /// file mode + uint st_nlink; /// link count + uint st_uid; /// user ID of file's owner + uint st_gid; /// user ID of group's owner + ulong st_rdev; /// if device then device number + ushort __pad2; + int st_size; /// file size in bytes + int st_blksize; /// optimal I/O block size + int st_blocks; /// number of allocated 512 byte blocks + int st_atime; + uint st_atimensec; + int st_mtime; + uint st_mtimensec; + int st_ctime; + uint st_ctimensec; + + uint __unused4; + uint __unused5; +} + +unittest +{ + assert(struct_stat.sizeof == 88); +} + +enum : int +{ + S_IFIFO = 0010000, + S_IFCHR = 0020000, + S_IFDIR = 0040000, + S_IFBLK = 0060000, + S_IFREG = 0100000, + S_IFLNK = 0120000, + S_IFSOCK = 0140000, + + S_IFMT = 0170000, + + S_IREAD = 0000400, + S_IWRITE = 0000200, + S_IEXEC = 0000100, +} + +extern (C) +{ + int access(char*, int); + int open(char*, int, ...); + int read(int, void*, int); + int write(int, void*, int); + int close(int); + int lseek(int, int, int); + int fstat(int, struct_stat*); + int lstat(char*, struct_stat*); + int stat(char*, struct_stat*); + int chdir(char*); + int mkdir(char*, int); + int rmdir(char*); + char* getcwd(char*, int); + int chmod(char*, mode_t); + int fork(); + int dup(int); + int dup2(int, int); + int pipe(int[2]); + pid_t wait(int*); + int waitpid(pid_t, int*, int); + + uint alarm(uint); + char* basename(char*); + //wint_t btowc(int); + int chown(char*, uid_t, gid_t); + int chroot(char*); + size_t confstr(int, char*, size_t); + int creat(char*, mode_t); + char* ctermid(char*); + int dirfd(DIR*); + char* dirname(char*); + int fattach(int, char*); + int fchmod(int, mode_t); + int fdatasync(int); + int ffs(int); + int fmtmsg(int, char*, int, char*, char*, char*); + int fpathconf(int, int); + int fseeko(FILE*, off_t, int); + off_t ftello(FILE*); + + extern char** environ; +} + +struct timeval +{ + int tv_sec; + int tv_usec; +} + +struct struct_timezone +{ + int tz_minuteswest; + int tz_dstime; +} + +struct tm +{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + int tm_gmtoff; + int tm_zone; +} + +extern (C) +{ + int gettimeofday(timeval*, struct_timezone*); + __time_t time(__time_t*); + char* asctime(tm*); + char* ctime(__time_t*); + tm* gmtime(__time_t*); + tm* localtime(__time_t*); + __time_t mktime(tm*); + char* asctime_r(tm* t, char* buf); + char* ctime_r(__time_t* timep, char* buf); + tm* gmtime_r(__time_t* timep, tm* result); + tm* localtime_r(__time_t* timep, tm* result); +} + +/**************************************************************/ +// Memory mapping from and + +enum +{ + PROT_NONE = 0, + PROT_READ = 1, + PROT_WRITE = 2, + PROT_EXEC = 4, +} + +// Memory mapping sharing types + +enum +{ MAP_SHARED = 1, + MAP_PRIVATE = 2, + MAP_TYPE = 0x0F, + MAP_FIXED = 0x10, + MAP_FILE = 0, + MAP_ANONYMOUS = 0x20, + MAP_ANON = 0x20, + MAP_GROWSDOWN = 0x100, + MAP_DENYWRITE = 0x800, + MAP_EXECUTABLE = 0x1000, + MAP_LOCKED = 0x2000, + MAP_NORESERVE = 0x4000, + MAP_POPULATE = 0x8000, + MAP_NONBLOCK = 0x10000, +} + +// Values for msync() + +enum +{ MS_ASYNC = 1, + MS_INVALIDATE = 2, + MS_SYNC = 4, +} + +// Values for mlockall() + +enum +{ + MCL_CURRENT = 1, + MCL_FUTURE = 2, +} + +// Values for mremap() + +enum +{ + MREMAP_MAYMOVE = 1, +} + +// Values for madvise + +enum +{ MADV_NORMAL = 0, + MADV_RANDOM = 1, + MADV_SEQUENTIAL = 2, + MADV_WILLNEED = 3, + MADV_DONTNEED = 4, +} + +extern (C) +{ +void* mmap(void*, size_t, int, int, int, off_t); +const void* MAP_FAILED = cast(void*)-1; + +int munmap(void*, size_t); +int mprotect(void*, size_t, int); +int msync(void*, size_t, int); +int madvise(void*, size_t, int); +int mlock(void*, size_t); +int munlock(void*, size_t); +int mlockall(int); +int munlockall(); +void* mremap(void*, size_t, size_t, int); +int mincore(void*, size_t, ubyte*); +int remap_file_pages(void*, size_t, int, size_t, int); +int shm_open(char*, int, int); +int shm_unlink(char*); +} + +extern(C) +{ + + enum + { + DT_UNKNOWN = 0, + DT_FIFO = 1, + DT_CHR = 2, + DT_DIR = 4, + DT_BLK = 6, + DT_REG = 8, + DT_LNK = 10, + DT_SOCK = 12, + DT_WHT = 14, + } + + struct dirent + { + int d_ino; + off_t d_off; + ushort d_reclen; + ubyte d_type; + char[256] d_name; + } + + struct DIR + { + // Managed by OS. + } + + DIR* opendir(char* name); + int closedir(DIR* dir); + dirent* readdir(DIR* dir); + void rewinddir(DIR* dir); + off_t telldir(DIR* dir); + void seekdir(DIR* dir, off_t offset); +} + + +extern(C) +{ + private import std.intrinsic; + + + int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout); + int fcntl(int s, int f, ...); + + + enum + { + EINTR = 4, + EINPROGRESS = 115, + } + + + const uint FD_SETSIZE = 1024; + //const uint NFDBITS = 8 * int.sizeof; // DMD 0.110: 8 * (int).sizeof is not an expression + const int NFDBITS = 32; + + + struct fd_set + { + int[FD_SETSIZE / NFDBITS] fds_bits; + alias fds_bits __fds_bits; + } + + + int FDELT(int d) + { + return d / NFDBITS; + } + + + int FDMASK(int d) + { + return 1 << (d % NFDBITS); + } + + + // Removes. + void FD_CLR(int fd, fd_set* set) + { + btr(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS)); + } + + + // Tests. + int FD_ISSET(int fd, fd_set* set) + { + return bt(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS)); + } + + + // Adds. + void FD_SET(int fd, fd_set* set) + { + bts(cast(uint*)&set.fds_bits.ptr[FDELT(fd)], cast(uint)(fd % NFDBITS)); + } + + + // Resets to zero. + void FD_ZERO(fd_set* set) + { + set.fds_bits[] = 0; + } +} + +extern (C) +{ + /* From + * See http://www.opengroup.org/onlinepubs/007908799/xsh/dlsym.html + */ + + const int RTLD_NOW = 0x00002; // Correct for Red Hat 8 + + void* dlopen(char* file, int mode); + int dlclose(void* handle); + void* dlsym(void* handle, char* name); + 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; + } + + const size_t _SIGSET_NWORDS = 1024 / (8 * uint.sizeof); + struct sigset_t + { + uint[_SIGSET_NWORDS] __val; + } + + int getpwnam_r(char*, passwd*, void*, size_t, passwd**); + passwd* getpwnam(char*); + passwd* getpwuid(uid_t); + int getpwuid_r(uid_t, passwd*, char*, size_t, passwd**); + int kill(pid_t, int); + int sem_close(sem_t*); + int sigemptyset(sigset_t*); + int sigfillset(sigset_t*); + int sigismember(sigset_t*, int); + int sigsuspend(sigset_t*); +} + +extern (C) +{ + /* from semaphore.h + */ + + struct sem_t + { + _pthread_fastlock __sem_lock; + int __sem_value; + void* __sem_waiting; + } + + int sem_init(sem_t*, int, uint); + int sem_wait(sem_t*); + int sem_trywait(sem_t*); + int sem_post(sem_t*); + int sem_getvalue(sem_t*, int*); + int sem_destroy(sem_t*); +} + +extern (C) +{ + /* from utime.h + */ + + struct utimbuf + { + __time_t actime; + __time_t modtime; + } + + int utime(char* filename, utimbuf* buf); +} diff -uNrp dmd-1.007/src/phobos/std/c/linux/linuxextern.d gdc-0.23/d/phobos/std/c/linux/linuxextern.d --- dmd-1.007/src/phobos/std/c/linux/linuxextern.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/linux/linuxextern.d 2007-02-23 20:00:05.000000000 +0100 @@ -11,13 +11,14 @@ */ module std.c.linux.linuxextern; +private import std.stdint; extern (C) { void* __libc_stack_end; int __data_start; int _end; - int timezone; + Clong_t timezone; void *_deh_beg; void *_deh_end; diff -uNrp dmd-1.007/src/phobos/std/c/linux/pthread.d gdc-0.23/d/phobos/std/c/linux/pthread.d --- dmd-1.007/src/phobos/std/c/linux/pthread.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/linux/pthread.d 1970-01-01 01:00:00.000000000 +0100 @@ -1,257 +0,0 @@ -/* Written by Walter Bright, Christopher E. Miller, and many others. - * www.digitalmars.com - * Placed into public domain. - */ - -module std.c.linux.pthread; - -extern (C) -{ - /* pthread declarations taken from pthread headers and - http://svn.dsource.org/projects/bindings/trunk/pthreads.d - */ - - /* from bits/types.h - */ - - typedef int __time_t; - - /* from time.h - */ - - struct timespec - { - __time_t tv_sec; /* seconds */ - int tv_nsec; /* nanosecs. */ - } - - /* from bits/pthreadtypes.h - */ - - alias uint pthread_t; - alias uint pthread_key_t; - alias int pthread_once_t; - alias int clockid_t; - alias int pthread_spinlock_t; // volatile - - struct _pthread_descr_struct - { - /* Not defined in the headers ??? - Just needed here to typedef - the _pthread_descr pointer - */ - } - - typedef _pthread_descr_struct* _pthread_descr; - - struct _pthread_fastlock - { - int __status; - int __spinlock; - } - - typedef long __pthread_cond_align_t; - - struct pthread_cond_t - { - _pthread_fastlock __c_lock; - _pthread_descr __c_waiting; - char[48 - - _pthread_fastlock.sizeof - - _pthread_descr.sizeof - - __pthread_cond_align_t.sizeof - ] __padding; - __pthread_cond_align_t __align; - } - - struct pthread_condattr_t - { - int __dummy; - } - - struct pthread_mutex_t - { - int __m_reserved; - int __m_count; - _pthread_descr __m_owner; - int __m_kind; - _pthread_fastlock __m_lock; - } - - struct pthread_mutexattr_t - { - int __mutexkind; - } - - /* from pthread.h - */ - - struct _pthread_cleanup_buffer - { - void function(void*) __routine; - void* __arg; - int __canceltype; - _pthread_cleanup_buffer* __prev; - } - - struct __sched_param // bits/sched.h - { - int __sched_priority; - } - - struct pthread_attr_t - { - int __detachstate; - int __schedpolicy; - __sched_param schedparam; - int __inheritshed; - int __scope; - size_t __guardsize; - int __stackaddr_set; - void* __stackaddr; - size_t __stacksize; - } - - struct pthread_barrier_t - { - _pthread_fastlock __ba_lock; - int __ba_required; - int __ba_present; - _pthread_descr __ba_waiting; - } - - struct pthread_barrierattr_t - { - int __pshared; - } - - struct pthread_rwlockattr_t - { - int __lockkind; - int __pshared; - } - - struct pthread_rwlock_t - { - _pthread_fastlock __rw_lock; - int __rw_readers; - _pthread_descr __rw_writer; - _pthread_descr __rw_read_waiting; - _pthread_descr __rw_write_waiting; - int __rw_kind; - int __rw_pshared; - } - - int pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*); - int pthread_mutex_destroy(pthread_mutex_t*); - int pthread_mutex_trylock(pthread_mutex_t*); - int pthread_mutex_lock(pthread_mutex_t*); - int pthread_mutex_unlock(pthread_mutex_t*); - - int pthread_mutexattr_init(pthread_mutexattr_t*); - int pthread_mutexattr_destroy(pthread_mutexattr_t*); - - int pthread_cond_init(pthread_cond_t*, pthread_condattr_t*); - int pthread_cond_destroy(pthread_cond_t*); - int pthread_cond_signal(pthread_cond_t*); - int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*); - int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, timespec*); - - int pthread_attr_init(pthread_attr_t*); - int pthread_attr_destroy(pthread_attr_t*); - int pthread_attr_setdetachstate(pthread_attr_t*, int); - int pthread_attr_getdetachstate(pthread_attr_t*, int*); - int pthread_attr_setinheritsched(pthread_attr_t*, int); - int pthread_attr_getinheritsched(pthread_attr_t*, int*); - int pthread_attr_setschedparam(pthread_attr_t*, __sched_param*); - int pthread_attr_getschedparam(pthread_attr_t*, __sched_param*); - int pthread_attr_setschedpolicy(pthread_attr_t*, int); - int pthread_attr_getschedpolicy(pthread_attr_t*, int*); - int pthread_attr_setscope(pthread_attr_t*, int); - int pthread_attr_getscope(pthread_attr_t*, int*); - int pthread_attr_setguardsize(pthread_attr_t*, size_t); - int pthread_attr_getguardsize(pthread_attr_t*, size_t*); - int pthread_attr_setstack(pthread_attr_t*, void*, size_t); - int pthread_attr_getstack(pthread_attr_t*, void**, size_t*); - int pthread_attr_setstackaddr(pthread_attr_t*, void*); - int pthread_attr_getstackaddr(pthread_attr_t*, void**); - int pthread_attr_setstacksize(pthread_attr_t*, size_t); - int pthread_attr_getstacksize(pthread_attr_t*, size_t*); - - int pthread_barrierattr_init(pthread_barrierattr_t*); - int pthread_barrierattr_getpshared(pthread_barrierattr_t*, int*); - int pthread_barrierattr_destroy(pthread_barrierattr_t*); - int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); - - int pthread_barrier_init(pthread_barrier_t*, pthread_barrierattr_t*, uint); - int pthread_barrier_destroy(pthread_barrier_t*); - int pthread_barrier_wait(pthread_barrier_t*); - - int pthread_condattr_init(pthread_condattr_t*); - int pthread_condattr_destroy(pthread_condattr_t*); - int pthread_condattr_getpshared(pthread_condattr_t*, int*); - int pthread_condattr_setpshared(pthread_condattr_t*, int); - - int pthread_detach(pthread_t); - void pthread_exit(void*); - int pthread_getattr_np(pthread_t, pthread_attr_t*); - int pthread_getconcurrency(); - int pthread_getcpuclockid(pthread_t, clockid_t*); - - int pthread_mutexattr_getpshared(pthread_mutexattr_t*, int*); - int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); - int pthread_mutexattr_settype(pthread_mutexattr_t*, int); - int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*); - int pthread_mutex_timedlock(pthread_mutex_t*, timespec*); - int pthread_yield(); - - int pthread_rwlock_init(pthread_rwlock_t*, pthread_rwlockattr_t*); - int pthread_rwlock_destroy(pthread_rwlock_t*); - int pthread_rwlock_rdlock(pthread_rwlock_t*); - int pthread_rwlock_tryrdlock(pthread_rwlock_t*); - int pthread_rwlock_timedrdlock(pthread_rwlock_t*, timespec*); - int pthread_rwlock_wrlock(pthread_rwlock_t*); - int pthread_rwlock_trywrlock(pthread_rwlock_t*); - int pthread_rwlock_timedwrlock(pthread_rwlock_t*, timespec*); - int pthread_rwlock_unlock(pthread_rwlock_t*); - - int pthread_rwlockattr_init(pthread_rwlockattr_t*); - int pthread_rwlockattr_destroy(pthread_rwlockattr_t*); - int pthread_rwlockattr_getpshared(pthread_rwlockattr_t*, int*); - int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); - int pthread_rwlockattr_getkind_np(pthread_rwlockattr_t*, int*); - int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t*, int); - - int pthread_spin_init(pthread_spinlock_t*, int); - int pthread_spin_destroy(pthread_spinlock_t*); - int pthread_spin_lock(pthread_spinlock_t*); - int pthread_spin_trylock(pthread_spinlock_t*); - int pthread_spin_unlock(pthread_spinlock_t*); - - int pthread_cancel(pthread_t); - void pthread_testcancel(); - int pthread_once(pthread_once_t*, void function()); - - int pthread_join(pthread_t, void**); - int pthread_create(pthread_t*, pthread_attr_t*, void*function(void*), void*); - pthread_t pthread_self(); - int pthread_equal(pthread_t, pthread_t); - int pthread_atfork(void function(), void function(), void function()); - void pthread_kill_other_threads_np(); - int pthread_setschedparam(pthread_t, int, __sched_param*); - int pthread_getschedparam(pthread_t, int*, __sched_param*); - int pthread_cond_broadcast(pthread_cond_t*); - int pthread_key_create(pthread_key_t*, void function(void*)); - int pthread_key_delete(pthread_key_t); - int pthread_setconcurrency(int); - int pthread_setspecific(pthread_key_t, void*); - void* pthread_getspecific(pthread_key_t); - int pthread_setcanceltype(int, int*); - int pthread_setcancelstate(int, int*); - - void _pthread_cleanup_push(_pthread_cleanup_buffer*, void function(void*), void*); - void _pthread_cleanup_push_defer(_pthread_cleanup_buffer*, void function(void*), void*); - void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int); - void _pthread_cleanup_pop_restore(_pthread_cleanup_buffer*, int); -} - diff -uNrp dmd-1.007/src/phobos/std/c/linux/pthread.d.orig-dmd gdc-0.23/d/phobos/std/c/linux/pthread.d.orig-dmd --- dmd-1.007/src/phobos/std/c/linux/pthread.d.orig-dmd 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/linux/pthread.d.orig-dmd 2007-01-03 06:51:22.000000000 +0100 @@ -0,0 +1,257 @@ +/* Written by Walter Bright, Christopher E. Miller, and many others. + * www.digitalmars.com + * Placed into public domain. + */ + +module std.c.linux.pthread; + +extern (C) +{ + /* pthread declarations taken from pthread headers and + http://svn.dsource.org/projects/bindings/trunk/pthreads.d + */ + + /* from bits/types.h + */ + + typedef int __time_t; + + /* from time.h + */ + + struct timespec + { + __time_t tv_sec; /* seconds */ + int tv_nsec; /* nanosecs. */ + } + + /* from bits/pthreadtypes.h + */ + + alias uint pthread_t; + alias uint pthread_key_t; + alias int pthread_once_t; + alias int clockid_t; + alias int pthread_spinlock_t; // volatile + + struct _pthread_descr_struct + { + /* Not defined in the headers ??? + Just needed here to typedef + the _pthread_descr pointer + */ + } + + typedef _pthread_descr_struct* _pthread_descr; + + struct _pthread_fastlock + { + int __status; + int __spinlock; + } + + typedef long __pthread_cond_align_t; + + struct pthread_cond_t + { + _pthread_fastlock __c_lock; + _pthread_descr __c_waiting; + char[48 + - _pthread_fastlock.sizeof + - _pthread_descr.sizeof + - __pthread_cond_align_t.sizeof + ] __padding; + __pthread_cond_align_t __align; + } + + struct pthread_condattr_t + { + int __dummy; + } + + struct pthread_mutex_t + { + int __m_reserved; + int __m_count; + _pthread_descr __m_owner; + int __m_kind; + _pthread_fastlock __m_lock; + } + + struct pthread_mutexattr_t + { + int __mutexkind; + } + + /* from pthread.h + */ + + struct _pthread_cleanup_buffer + { + void function(void*) __routine; + void* __arg; + int __canceltype; + _pthread_cleanup_buffer* __prev; + } + + struct __sched_param // bits/sched.h + { + int __sched_priority; + } + + struct pthread_attr_t + { + int __detachstate; + int __schedpolicy; + __sched_param schedparam; + int __inheritshed; + int __scope; + size_t __guardsize; + int __stackaddr_set; + void* __stackaddr; + size_t __stacksize; + } + + struct pthread_barrier_t + { + _pthread_fastlock __ba_lock; + int __ba_required; + int __ba_present; + _pthread_descr __ba_waiting; + } + + struct pthread_barrierattr_t + { + int __pshared; + } + + struct pthread_rwlockattr_t + { + int __lockkind; + int __pshared; + } + + struct pthread_rwlock_t + { + _pthread_fastlock __rw_lock; + int __rw_readers; + _pthread_descr __rw_writer; + _pthread_descr __rw_read_waiting; + _pthread_descr __rw_write_waiting; + int __rw_kind; + int __rw_pshared; + } + + int pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*); + int pthread_mutex_destroy(pthread_mutex_t*); + int pthread_mutex_trylock(pthread_mutex_t*); + int pthread_mutex_lock(pthread_mutex_t*); + int pthread_mutex_unlock(pthread_mutex_t*); + + int pthread_mutexattr_init(pthread_mutexattr_t*); + int pthread_mutexattr_destroy(pthread_mutexattr_t*); + + int pthread_cond_init(pthread_cond_t*, pthread_condattr_t*); + int pthread_cond_destroy(pthread_cond_t*); + int pthread_cond_signal(pthread_cond_t*); + int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*); + int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, timespec*); + + int pthread_attr_init(pthread_attr_t*); + int pthread_attr_destroy(pthread_attr_t*); + int pthread_attr_setdetachstate(pthread_attr_t*, int); + int pthread_attr_getdetachstate(pthread_attr_t*, int*); + int pthread_attr_setinheritsched(pthread_attr_t*, int); + int pthread_attr_getinheritsched(pthread_attr_t*, int*); + int pthread_attr_setschedparam(pthread_attr_t*, __sched_param*); + int pthread_attr_getschedparam(pthread_attr_t*, __sched_param*); + int pthread_attr_setschedpolicy(pthread_attr_t*, int); + int pthread_attr_getschedpolicy(pthread_attr_t*, int*); + int pthread_attr_setscope(pthread_attr_t*, int); + int pthread_attr_getscope(pthread_attr_t*, int*); + int pthread_attr_setguardsize(pthread_attr_t*, size_t); + int pthread_attr_getguardsize(pthread_attr_t*, size_t*); + int pthread_attr_setstack(pthread_attr_t*, void*, size_t); + int pthread_attr_getstack(pthread_attr_t*, void**, size_t*); + int pthread_attr_setstackaddr(pthread_attr_t*, void*); + int pthread_attr_getstackaddr(pthread_attr_t*, void**); + int pthread_attr_setstacksize(pthread_attr_t*, size_t); + int pthread_attr_getstacksize(pthread_attr_t*, size_t*); + + int pthread_barrierattr_init(pthread_barrierattr_t*); + int pthread_barrierattr_getpshared(pthread_barrierattr_t*, int*); + int pthread_barrierattr_destroy(pthread_barrierattr_t*); + int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); + + int pthread_barrier_init(pthread_barrier_t*, pthread_barrierattr_t*, uint); + int pthread_barrier_destroy(pthread_barrier_t*); + int pthread_barrier_wait(pthread_barrier_t*); + + int pthread_condattr_init(pthread_condattr_t*); + int pthread_condattr_destroy(pthread_condattr_t*); + int pthread_condattr_getpshared(pthread_condattr_t*, int*); + int pthread_condattr_setpshared(pthread_condattr_t*, int); + + int pthread_detach(pthread_t); + void pthread_exit(void*); + int pthread_getattr_np(pthread_t, pthread_attr_t*); + int pthread_getconcurrency(); + int pthread_getcpuclockid(pthread_t, clockid_t*); + + int pthread_mutexattr_getpshared(pthread_mutexattr_t*, int*); + int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int); + int pthread_mutexattr_settype(pthread_mutexattr_t*, int); + int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*); + int pthread_mutex_timedlock(pthread_mutex_t*, timespec*); + int pthread_yield(); + + int pthread_rwlock_init(pthread_rwlock_t*, pthread_rwlockattr_t*); + int pthread_rwlock_destroy(pthread_rwlock_t*); + int pthread_rwlock_rdlock(pthread_rwlock_t*); + int pthread_rwlock_tryrdlock(pthread_rwlock_t*); + int pthread_rwlock_timedrdlock(pthread_rwlock_t*, timespec*); + int pthread_rwlock_wrlock(pthread_rwlock_t*); + int pthread_rwlock_trywrlock(pthread_rwlock_t*); + int pthread_rwlock_timedwrlock(pthread_rwlock_t*, timespec*); + int pthread_rwlock_unlock(pthread_rwlock_t*); + + int pthread_rwlockattr_init(pthread_rwlockattr_t*); + int pthread_rwlockattr_destroy(pthread_rwlockattr_t*); + int pthread_rwlockattr_getpshared(pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int); + int pthread_rwlockattr_getkind_np(pthread_rwlockattr_t*, int*); + int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t*, int); + + int pthread_spin_init(pthread_spinlock_t*, int); + int pthread_spin_destroy(pthread_spinlock_t*); + int pthread_spin_lock(pthread_spinlock_t*); + int pthread_spin_trylock(pthread_spinlock_t*); + int pthread_spin_unlock(pthread_spinlock_t*); + + int pthread_cancel(pthread_t); + void pthread_testcancel(); + int pthread_once(pthread_once_t*, void function()); + + int pthread_join(pthread_t, void**); + int pthread_create(pthread_t*, pthread_attr_t*, void*function(void*), void*); + pthread_t pthread_self(); + int pthread_equal(pthread_t, pthread_t); + int pthread_atfork(void function(), void function(), void function()); + void pthread_kill_other_threads_np(); + int pthread_setschedparam(pthread_t, int, __sched_param*); + int pthread_getschedparam(pthread_t, int*, __sched_param*); + int pthread_cond_broadcast(pthread_cond_t*); + int pthread_key_create(pthread_key_t*, void function(void*)); + int pthread_key_delete(pthread_key_t); + int pthread_setconcurrency(int); + int pthread_setspecific(pthread_key_t, void*); + void* pthread_getspecific(pthread_key_t); + int pthread_setcanceltype(int, int*); + int pthread_setcancelstate(int, int*); + + void _pthread_cleanup_push(_pthread_cleanup_buffer*, void function(void*), void*); + void _pthread_cleanup_push_defer(_pthread_cleanup_buffer*, void function(void*), void*); + void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int); + void _pthread_cleanup_pop_restore(_pthread_cleanup_buffer*, int); +} + diff -uNrp dmd-1.007/src/phobos/std/c/linux/socket.d gdc-0.23/d/phobos/std/c/linux/socket.d --- dmd-1.007/src/phobos/std/c/linux/socket.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/linux/socket.d 2006-12-04 03:12:28.000000000 +0100 @@ -35,20 +35,19 @@ int setsockopt(int s, int level, int opt uint inet_addr(char* cp); char* inet_ntoa(in_addr ina); hostent* gethostbyname(char* name); -int gethostbyname_r(char* name, hostent* ret, void* buf, size_t buflen, hostent** result, int* h_errnop); -int gethostbyname2_r(char* name, int af, hostent* ret, void* buf, size_t buflen, hostent** result, int* h_errnop); hostent* gethostbyaddr(void* addr, int len, int type); protoent* getprotobyname(char* name); protoent* getprotobynumber(int number); servent* getservbyname(char* name, char* proto); servent* getservbyport(int port, char* proto); int gethostname(char* name, int namelen); +int gethostbyname_r(char* name, hostent* ret, void* buf, size_t buflen, hostent** result, int* h_errnop); +int gethostbyname2_r(char* name, int af, hostent* ret, void* buf, size_t buflen, hostent** result, int* h_errnop); int getaddrinfo(char* nodename, char* servname, addrinfo* hints, addrinfo** res); void freeaddrinfo(addrinfo* ai); int getnameinfo(sockaddr* sa, socklen_t salen, char* node, socklen_t nodelen, char* service, socklen_t servicelen, int flags); - enum: int { AF_UNSPEC = 0, diff -uNrp dmd-1.007/src/phobos/std/c/mach/mach.d gdc-0.23/d/phobos/std/c/mach/mach.d --- dmd-1.007/src/phobos/std/c/mach/mach.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/mach/mach.d 2007-02-15 15:05:04.000000000 +0100 @@ -0,0 +1,61 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.mach.mach; + +private import gcc.builtins; + +private alias uint natural_t; // uint on both 32- and 64-bit + +private import std.c.mach.mach_extern; + +extern(C): + +enum { + SYNC_POLICY_FIFO = 0x0, + SYNC_POLICY_FIXED_PRIORITY = 0x1, + SYNC_POLICY_REVERSED = 0x2, + SYNC_POLICY_ORDER_MASK = 0x3, + SYNC_POLICY_LIFO = (SYNC_POLICY_FIFO|SYNC_POLICY_REVERSED) +} + +enum { + KERN_SUCCESS = 0 +} + +alias natural_t semaphore_t; // TODO: natural_t +alias natural_t task_t; // TODO: natural_t +alias natural_t mach_port_t; // TODO: natural_t +alias int kern_return_t; +kern_return_t semaphore_create +( + task_t task, + semaphore_t *semaphore, + int policy, + int value +); +kern_return_t semaphore_destroy +( + task_t task, + semaphore_t semaphore +); +kern_return_t semaphore_signal (semaphore_t semaphore); +kern_return_t semaphore_wait (semaphore_t semaphore); + +// just in case this actually gets defined.. +extern(D) mach_port_t current_task() { return mach_task_self_; } diff -uNrp dmd-1.007/src/phobos/std/c/mach/mach_extern.d gdc-0.23/d/phobos/std/c/mach/mach_extern.d --- dmd-1.007/src/phobos/std/c/mach/mach_extern.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/mach/mach_extern.d 2006-06-03 04:57:08.000000000 +0200 @@ -0,0 +1,24 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.mach.mach_extern; + +private import std.c.mach.mach; + +// This probably isn't stable +extern (C) mach_port_t mach_task_self_; diff -uNrp dmd-1.007/src/phobos/std/c/math.d gdc-0.23/d/phobos/std/c/math.d --- dmd-1.007/src/phobos/std/c/math.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/math.d 2007-02-18 18:26:23.000000000 +0100 @@ -7,8 +7,16 @@ * WIKI=Phobos/StdCMath */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, February 2007 +*/ + module std.c.math; +private import std.stdint; + extern (C): alias float float_t; /// @@ -48,6 +56,241 @@ const int MATH_ERRNO = 1; /// const int MATH_ERREXCEPT = 2; /// const int math_errhandling = MATH_ERRNO | MATH_ERREXCEPT; /// +version (GNU) +{ + private import gcc.builtins; + + double acos(double x); + float acosf(float x); + + double asin(double x); + float asinf(float x); + + double atan(double x); + float atanf(float x); + + double atan2(double y, double x); + float atan2f(float y, float x); + + double cos(double x); + float cosf(float x); + + double sin(double x); + float sinf(float x); + + double tan(double x); + float tanf(float x); + + double acosh(double x); + float acoshf(float x); + + double asinh(double x); + float asinhf(float x); + + double atanh(double x); + float atanhf(float x); + + double cosh(double x); + float coshf(float x); + + double sinh(double x); + float sinhf(float x); + + double tanh(double x); + float tanhf(float x); + + double exp(double x); + float expf(float x); + + double exp2(double x); + float exp2f(float x); + + double expm1(double x); + float expm1f(float x); + + double frexp(double value, int *exp); + float frexpf(float value, int *exp); + + int ilogb(double x); + int ilogbf(float x); + + double ldexp(double x, int exp); + float ldexpf(float x, int exp); + + double log(double x); + float logf(float x); + + double log10(double x); + float log10f(float x); + + double log1p(double x); + float log1pf(float x); + + double log2(double x); + float log2f(float x); + + double logb(double x); + float logbf(float x); + + double modf(double value, double *iptr); + float modff(float value, float *iptr); + + double scalbn(double x, int n); + float scalbnf(float x, int n); + + double scalbln(double x, int n); + float scalblnf(float x, int n); + + double cbrt(double x); + float cbrtf(float x); + + double fabs(double x); + float fabsf(float x); + + double hypot(double x, double y); + float hypotf(float x, float y); + + double pow(double x, double y); + float powf(float x, float y); + + double sqrt(double x); + float sqrtf(float x); + + double erf(double x); + float erff(float x); + + double erfc(double x); + float erfcf(float x); + + double lgamma(double x); + float lgammaf(float x); + + double tgamma(double x); + float tgammaf(float x); + + double ceil(double x); + float ceilf(float x); + + double floor(double x); + float floorf(float x); + + double nearbyint(double x); + float nearbyintf(float x); + + double rint(double x); + float rintf(float x); + + Clong_t lrint(double x); + Clong_t lrintf(float x); + + long llrint(double x); + long llrintf(float x); + + double round(double x); + float roundf(float x); + + Clong_t lround(double x); + Clong_t lroundf(float x); + + long llround(double x); + long llroundf(float x); + + double trunc(double x); + float truncf(float x); + + double fmod(double x, double y); + float fmodf(float x, float y); + + double remainder(double x, double y); + float remainderf(float x, float y); + + double remquo(double x, double y, int *quo); + float remquof(float x, float y, int *quo); + + double copysign(double x, double y); + float copysignf(float x, float y); + + double nan(char *tagp); + float nanf(char *tagp); + + double nextafter(double x, double y); + float nextafterf(float x, float y); + + double nexttoward(double x, real y); + float nexttowardf(float x, real y); + + double fdim(double x, double y); + float fdimf(float x, float y); + + double fmax(double x, double y); + float fmaxf(float x, float y); + + double fmin(double x, double y); + float fminf(float x, float y); + + double fma(double x, double y, double z); + float fmaf(float x, float y, float z); + + private import gcc.config; + // unfortunately, these do not always exist in a library + alias gcc.config.acosl acosl; + alias gcc.config.asinl asinl; + alias gcc.config.atanl atanl; + alias gcc.config.atan2l atan2l; + alias gcc.config.cosl cosl; + alias gcc.config.sinl sinl; + alias gcc.config.tanl tanl; + alias gcc.config.acoshl acoshl; + alias gcc.config.asinhl asinhl; + alias gcc.config.atanhl atanhl; + alias gcc.config.coshl coshl; + alias gcc.config.sinhl sinhl; + alias gcc.config.tanhl tanhl; + alias gcc.config.expl expl; + alias gcc.config.exp2l exp2l; + alias gcc.config.expm1l expm1l; + alias gcc.config.frexpl frexpl; + alias gcc.config.ilogbl ilogbl; + alias gcc.config.ldexpl ldexpl; + alias gcc.config.logl logl; + alias gcc.config.log10l log10l; + alias gcc.config.log1pl log1pl; + alias gcc.config.log2l log2l; + alias gcc.config.logbl logbl; + alias gcc.config.modfl modfl; + alias gcc.config.scalbnl scalbnl; + alias gcc.config.scalblnl scalblnl; + alias gcc.config.cbrtl cbrtl; + alias gcc.config.fabsl fabsl; + alias gcc.config.hypotl hypotl; + alias gcc.config.powl powl; + alias gcc.config.sqrtl sqrtl; + alias gcc.config.erfl erfl; + alias gcc.config.erfcl erfcl; + alias gcc.config.lgammal lgammal; + alias gcc.config.tgammal tgammal; + alias gcc.config.ceill ceill; + alias gcc.config.floorl floorl; + alias gcc.config.nearbyintl nearbyintl; + alias gcc.config.rintl rintl; + alias gcc.config.lrintl lrintl; + alias gcc.config.llrintl llrintl; + alias gcc.config.roundl roundl; + alias gcc.config.lroundl lroundl; + alias gcc.config.llroundl llroundl; + alias gcc.config.truncl truncl; + alias gcc.config.fmodl fmodl; + alias gcc.config.remainderl remainderl; + alias gcc.config.remquol remquol; + alias gcc.config.copysignl copysignl; + alias gcc.config.nanl nanl;//doesn't work... + alias gcc.config.nextafterl nextafterl; + alias gcc.config.nexttowardl nexttowardl; + alias gcc.config.fdiml fdiml; + alias gcc.config.fmaxl fmaxl; + alias gcc.config.fminl fminl; + alias gcc.config.fmal fmal; +} else { double acos(double x); /// float acosf(float x); /// ditto real acosl(real x); /// ditto @@ -208,9 +451,9 @@ double rint(double x); /// float rintf(float x); /// ditto real rintl(real x); /// ditto -int lrint(double x); /// -int lrintf(float x); /// ditto -int lrintl(real x); /// ditto +Clong_t lrint(double x); /// +Clong_t lrintf(float x); /// ditto +Clong_t lrintl(real x); /// ditto long llrint(double x); /// long llrintf(float x); /// ditto @@ -220,9 +463,9 @@ double round(double x); /// float roundf(float x); /// ditto real roundl(real x); /// ditto -int lround(double x); /// -int lroundf(float x); /// ditto -int lroundl(real x); /// ditto +Clong_t lround(double x); /// +Clong_t lroundf(float x); /// ditto +Clong_t lroundl(real x); /// ditto long llround(double x); /// long llroundf(float x); /// ditto @@ -275,6 +518,7 @@ real fminl(real x, real y); /// ditto double fma(double x, double y, double z); /// float fmaf(float x, float y, float z); /// ditto real fmal(real x, real y, real z); /// ditto +} /// int isgreater(real x, real y) { return !(x !> y); } diff -uNrp dmd-1.007/src/phobos/std/c/skyos/compat.d gdc-0.23/d/phobos/std/c/skyos/compat.d --- dmd-1.007/src/phobos/std/c/skyos/compat.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/skyos/compat.d 2006-06-03 04:57:08.000000000 +0200 @@ -0,0 +1,39 @@ +module std.c.skyos.compat; +private import std.c.unix.unix; +private import std.c.skyos.skyos; + +enum { + TASK_CREATE_FLAG_WANT_WAIT_FOR = 0x00002000 +} + +// libpthread pthread_create has problems? +int pthread_create(pthread_t * pth, pthread_attr_t * attr, void* fn, void * arg) +{ + int tid = ThreadCreate("thread", TASK_CREATE_FLAG_WANT_WAIT_FOR, + cast(void *) fn, cast(uint) arg, 0, 0, 0, 0, 0, 0, 0, 0, 0); + if (tid) { + *pth = tid; + return 0; + } else { + return EAGAIN; + } +} +int pthread_join(pthread_t thread, void ** result) +{ + int v; + int r = ThreadWait(thread, & v); + if (r == thread) { + if (result) + *result = null; + return 0; + } else + return -1; +} + +pthread_t pthread_self() { return cast(pthread_t) ThreadGetPid(); } +int pthread_equal(pthread_t a, pthread_t b) { return a == b; } +int pthread_kill(pthread_t pth, int sig) { return kill(cast(pid_t) pth, sig); } +alias ThreadYield sched_yield; + +int pthread_suspend_np(pthread_t p) { return ThreadSuspend(p) == 0 ? 0 : -1; } +int pthread_continue_np(pthread_t p) { return ThreadResume(p) == 0 ? 0 : -1; } diff -uNrp dmd-1.007/src/phobos/std/c/skyos/skyos.d gdc-0.23/d/phobos/std/c/skyos/skyos.d --- dmd-1.007/src/phobos/std/c/skyos/skyos.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/skyos/skyos.d 2006-06-03 04:57:08.000000000 +0200 @@ -0,0 +1,11 @@ +module std.c.skyos.skyos; + +extern(C): + +int ThreadCreate (char *ucName, uint uiFlags, void *fpFunction, uint arg1, uint arg2, uint arg3, uint arg4, uint arg5, uint arg6, uint arg7, uint arg8, uint arg9, uint arg10); +int ThreadWait (int iPid, int *iStatus); +int ThreadGetPid (); +int ThreadSuspend (int iPid); +int ThreadResume (int iPid); +void ThreadYield (); +int ThreadSleep (uint uiMilliseconds); diff -uNrp dmd-1.007/src/phobos/std/c/stdarg.d gdc-0.23/d/phobos/std/c/stdarg.d --- dmd-1.007/src/phobos/std/c/stdarg.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/stdarg.d 2006-06-03 04:57:08.000000000 +0200 @@ -9,15 +9,49 @@ /* This is for use with extern(C) variable argument lists. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.c.stdarg; +version (GNU) { + private import gcc.builtins; + alias __builtin_va_list va_list; + alias __builtin_va_end va_end; + alias __builtin_va_copy va_copy; + + // The va_start and va_arg template functions are magically + // handled by the compiler. +} else { + alias void* va_list; +void va_end(va_list ap) +{ + +} + +void va_copy(out va_list dest, va_list src) +{ + static if ( is( dest T == T[1]) ) { + dest[0] = src[0]; + } else { + dest = src; + } +} + +} + template va_start(T) { void va_start(out va_list ap, inout T parmn) { + /* ap = cast(va_list)(cast(void*)&parmn + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1))); + */ } } @@ -25,18 +59,13 @@ template va_arg(T) { T va_arg(inout va_list ap) { + /* T arg = *cast(T*)ap; ap = cast(va_list)(cast(void*)ap + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1))); return arg; + */ + T t; + return t; } } -void va_end(va_list ap) -{ - -} - -void va_copy(out va_list dest, va_list src) -{ - dest = src; -} diff -uNrp dmd-1.007/src/phobos/std/c/stddef.d gdc-0.23/d/phobos/std/c/stddef.d --- dmd-1.007/src/phobos/std/c/stddef.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/stddef.d 2006-06-03 04:57:08.000000000 +0200 @@ -1,10 +1,10 @@ /** - * C's <stddef.h> - * Authors: Walter Bright, Digital Mars, www.digitalmars.com + * C's <stdarg.h> + * Authors: Hauke Duden and Walter Bright, Digital Mars, www.digitalmars.com * License: Public Domain * Macros: - * WIKI=Phobos/StdCStddef + * WIKI=Phobos/StdCStdarg */ module std.c.stddef; @@ -17,6 +17,10 @@ else version (linux) { alias dchar wchar_t; } +else version (Unix) +{ + alias dchar wchar_t; +} else { static assert(0); diff -uNrp dmd-1.007/src/phobos/std/c/stdio.d gdc-0.23/d/phobos/std/c/stdio.d --- dmd-1.007/src/phobos/std/c/stdio.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/stdio.d 2007-02-26 15:01:16.000000000 +0100 @@ -7,16 +7,34 @@ * WIKI=Phobos/StdCStdio */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.c.stdio; +private import std.stdint; import std.c.stddef; private import std.c.stdarg; extern (C): -version (Win32) +version (GNU) +{ + private import gcc.builtins; + private import gcc.config; + alias gcc.config.EOF EOF; + alias gcc.config.FOPEN_MAX FOPEN_MAX; + alias gcc.config.FILENAME_MAX FILENAME_MAX; + alias gcc.config.PATH_MAX PATH_MAX; + alias gcc.config.TMP_MAX TMP_MAX; + alias gcc.config.L_tmpnam L_tmpnam; +} +else version (Win32) { const int _NFILE = 60; /// const int BUFSIZ = 0x4000; /// @@ -28,8 +46,7 @@ version (Win32) const int SYS_OPEN = _SYS_OPEN; /// const wchar WEOF = 0xFFFF; /// } - -version (linux) +else version (linux) { const int EOF = -1; const int FOPEN_MAX = 16; @@ -54,7 +71,7 @@ struct _iobuf int _bufsiz; int __tmpnum; } - version (linux) + else version (linux) { char* _read_ptr; char* _read_end; @@ -77,6 +94,10 @@ struct _iobuf char[1] _shortbuf; void* _lock; } + else version (GNU) { + byte[gcc.config.FILE_struct_size] opaque; + } + } alias _iobuf FILE; /// @@ -98,8 +119,13 @@ enum version (Win32) { - extern FILE _iob[_NFILE]; - extern void function() _fcloseallp; + version (GNU) { + // _NFILE is not defined anywhere + extern export FILE _iob[5]; + } else { + extern FILE _iob[_NFILE]; + extern void function() _fcloseallp; + } } version (Win32) @@ -131,16 +157,59 @@ version (linux) } } -version (Win32) + +version (GNU_CBridge_Stdio) { + extern FILE * _d_gnu_cbridge_stdin; + extern FILE * _d_gnu_cbridge_stdout; + extern FILE * _d_gnu_cbridge_stderr; + + /* Call from dgccmain2. Can't use a static constructor here + because std.c.stdio is not compiled. */ + extern void _d_gnu_cbridge_init_stdio(); + + alias _d_gnu_cbridge_stdin stdin; + alias _d_gnu_cbridge_stdout stdout; + alias _d_gnu_cbridge_stderr stderr; +} +else version (Win32) +{ + // This works for DMD/DMC and MinGW/msvcrt const FILE *stdin = &_iob[0]; /// const FILE *stdout = &_iob[1]; /// const FILE *stderr = &_iob[2]; /// const FILE *stdaux = &_iob[3]; /// const FILE *stdprn = &_iob[4]; /// } - -version (linux) +else version (aix) +{ + // 32- and 64-bit + extern FILE _iob[16]; + const FILE *stdin = &_iob[0]; + const FILE *stdout = &_iob[1]; + const FILE *stderr = &_iob[2]; +} +else version (darwin) +{ + static if (size_t.sizeof == 4) + { + static assert(gcc.config.FILE_struct_size != 0); + extern FILE __sF[3]; + const FILE * stdin = &__sF[0]; + const FILE * stdout = &__sF[1]; + const FILE * stderr = &__sF[2]; + } + else static if (size_t.sizeof == 8) + { + extern FILE *__stdinp; + extern FILE *__stdoutp; + extern FILE *__stderrp; + alias __stdinp stdin; + alias __stdoutp stdout; + alias __stderrp stderr; + } +} +else version (linux) { extern FILE *stdin; extern FILE *stdout; @@ -151,7 +220,11 @@ version (Win32) { const char[] _P_tmpdir = "\\"; const wchar[] _wP_tmpdir = "\\"; - const int L_tmpnam = _P_tmpdir.length + 12; + version (GNU) { } + else + { + const int L_tmpnam = _P_tmpdir.length + 12; + } } alias int fpos_t; /// @@ -160,8 +233,8 @@ char * tmpnam(char *); /// FILE * fopen(char *,char *); /// FILE * _fsopen(char *,char *,int ); /// FILE * freopen(char *,char *,FILE *); /// -int fseek(FILE *,int,int); /// -int ftell(FILE *); /// +int fseek(FILE *,Clong_t,int); /// +Clong_t ftell(FILE *); /// char * fgets(char *,int,FILE *); /// int fgetc(FILE *); /// int _fgetchar(); /// @@ -208,6 +281,10 @@ int getc(FILE *fp) { return fgetc(fp); /// int putc(int c,FILE *fp) { return fputc(c,fp); } +version(PPC) + version(Linux) + version=PPCLinux; + version (Win32) { /// @@ -224,8 +301,74 @@ version (Win32) int _snprintf(char *,size_t,char *,...); int _vsnprintf(char *,size_t,char *,va_list); } - -version (linux) +else version (darwin) +{ + private import std.c.darwin.ldblcompat; + + alias gcc.config.ferror ferror; + alias gcc.config.feof feof; + alias gcc.config.clearerr clearerr; + alias gcc.config.rewind rewind; + alias gcc.config._bufsize _bufsize; + alias gcc.config.fileno fileno; + + int snprintf(char *, size_t, char *, ...); + int vsnprintf(char *, size_t, char *, va_list); + + // printf is declared in object, but it won't be fixed unless std.c.stdio is imported... + pragma(GNU_asm,printf,"printf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,fprintf,"fprintf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,vfprintf,"vfprintf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,vprintf,"vprintf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,sprintf,"sprintf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,vsprintf,"vsprintf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,scanf,"scanf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,fscanf,"fscanf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,sscanf,"sscanf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,snprintf,"snprintf" ~ __DARWIN_LDBL_COMPAT); + pragma(GNU_asm,vsnprintf,"vsnprintf" ~ __DARWIN_LDBL_COMPAT); +} +else version (PPCLinux) +{ + private import std.c.linux.ldblcompat; + + alias gcc.config.ferror ferror; + alias gcc.config.feof feof; + alias gcc.config.clearerr clearerr; + alias gcc.config.rewind rewind; + alias gcc.config._bufsize _bufsize; + alias gcc.config.fileno fileno; + + int snprintf(char *, size_t, char *, ...); + int vsnprintf(char *, size_t, char *, va_list); + + // printf is declared in object, but it won't be fixed unless std.c.stdio is imported... + pragma(GNU_asm,printf,__LDBL_COMPAT_PFX ~ "printf"); + pragma(GNU_asm,fprintf,__LDBL_COMPAT_PFX ~ "fprintf"); + pragma(GNU_asm,vfprintf,__LDBL_COMPAT_PFX ~ "vfprintf"); + pragma(GNU_asm,vprintf,__LDBL_COMPAT_PFX ~ "vprintf"); + pragma(GNU_asm,sprintf,__LDBL_COMPAT_PFX ~ "sprintf"); + pragma(GNU_asm,vsprintf,__LDBL_COMPAT_PFX ~ "vsprintf"); + pragma(GNU_asm,scanf,__LDBL_COMPAT_PFX ~ "scanf"); + pragma(GNU_asm,fscanf,__LDBL_COMPAT_PFX ~ "fscanf"); + pragma(GNU_asm,sscanf,__LDBL_COMPAT_PFX ~ "sscanf"); + pragma(GNU_asm,snprintf,__LDBL_COMPAT_PFX ~ "snprintf"); + pragma(GNU_asm,vsnprintf,__LDBL_COMPAT_PFX ~ "vsnprintf"); +} +else version (GNU) +{ + alias gcc.config.ferror ferror; + alias gcc.config.feof feof; + alias gcc.config.clearerr clearerr; + alias gcc.config.rewind rewind; + alias gcc.config._bufsize _bufsize; + alias gcc.config.fileno fileno; + alias gcc.config.Csnprintf snprintf; + alias gcc.config.Cvsnprintf vsnprintf; + alias gcc.config.Csnprintf _snprintf; + alias gcc.config.Cvsnprintf _vsnprintf; +} +else version (linux) { int ferror(FILE *fp); int feof(FILE *fp); diff -uNrp dmd-1.007/src/phobos/std/c/stdlib.d gdc-0.23/d/phobos/std/c/stdlib.d --- dmd-1.007/src/phobos/std/c/stdlib.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/stdlib.d 2007-02-18 18:26:00.000000000 +0100 @@ -7,9 +7,16 @@ */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, February 2007 +*/ + module std.c.stdlib; private import std.c.stddef; +private import std.stdint; extern (C): @@ -25,12 +32,12 @@ enum /// struct div_t { int quot,rem; } /// -struct ldiv_t { int quot,rem; } +struct ldiv_t { Clong_t quot,rem; } /// struct lldiv_t { long quot,rem; } div_t div(int,int); /// - ldiv_t ldiv(int,int); /// ditto + ldiv_t ldiv(Clong_t, Clong_t); /// ditto lldiv_t lldiv(long, long); /// ditto const int EXIT_SUCCESS = 0; /// @@ -42,7 +49,13 @@ struct lldiv_t { long quot,rem; } int system(char *); - void *alloca(uint); /// + version (GNU) + { + private import gcc.builtins; + alias gcc.builtins.__builtin_alloca alloca; /// + } else { + void *alloca(size_t); /// + } void *calloc(size_t, size_t); /// void *malloc(size_t); /// ditto @@ -58,9 +71,15 @@ struct lldiv_t { long quot,rem; } int setenv(char*, char*, int); /// extension to ISO C standard, not available on all platforms void unsetenv(char*); /// extension to ISO C standard, not available on all platforms + version (GNU) + { + private import gcc.config; + alias gcc.config.RAND_MAX RAND_MAX; + } + int rand(); /// void srand(uint); /// ditto - int random(int num); /// ditto + Clong_t random(int num); /// ditto void randomize(); /// ditto int getErrno(); /// ditto @@ -70,18 +89,45 @@ const int ERANGE = 34; // on both Window double atof(char *); /// int atoi(char *); /// ditto -int atol(char *); /// ditto +Clong_t atol(char *); /// ditto float strtof(char *,char **); /// ditto double strtod(char *,char **); /// ditto -real strtold(char *,char **); /// ditto -long strtol(char *,char **,int); /// ditto -uint strtoul(char *,char **,int); /// ditto -long atoll(char *); /// ditto -long strtoll(char *,char **,int); /// ditto -ulong strtoull(char *,char **,int); /// ditto -char* itoa(int, char*, int); /// -char* ultoa(uint, char*, int); /// ditto +//real strtold(char *,char **); +version (darwin) + version (GNU_Have_strtold) + version = darwin_strtold; +version(PPC) + version(Linux) + version=PPCLinux; +version (darwin_strtold) +{ + private import std.c.darwin.ldblcompat; + real strtold(char *, char **); /// ditto + pragma(GNU_asm,strtold,"strtold"~__DARWIN_LDBL_COMPAT); +} +else version (PPCLinux) +{ + private import std.c.linux.ldblcompat; + static if (std.c.linux.ldblcompat.__No_Long_Double_Math) + alias strtod strtold; /// ditto + else + alias gcc.config.cstrtold strtold; /// ditto +} +else +{ + private import gcc.config; + alias gcc.config.cstrtold strtold; /// ditto +} + +Clong_t strtol(char *,char **,int); /// ditto +Culong_t strtoul(char *,char **,int); /// ditto +long atoll(char *); /// ditto +long strtoll(char *,char **,int); /// ditto +ulong strtoull(char *,char **,int); /// ditto + +char* itoa(int, char*, int); +char* ultoa(Culong_t, char*, int); int mblen(char *s, size_t n); /// int mbtowc(wchar_t *pwc, char *s, size_t n); /// ditto diff -uNrp dmd-1.007/src/phobos/std/c/string.d gdc-0.23/d/phobos/std/c/string.d --- dmd-1.007/src/phobos/std/c/string.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/string.d 2007-03-04 15:48:59.000000000 +0100 @@ -7,32 +7,62 @@ * WIKI=Phobos/StdCString */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, May 2006 +*/ + + module std.c.string; extern (C): +version (GNU) +{ + private import gcc.builtins; + alias __builtin_memcpy memcpy; /// + alias __builtin_strcpy strcpy; /// + alias __builtin_strncpy strncpy; /// + alias __builtin_strncat strncat; /// + alias __builtin_strncmp strncmp; /// + alias __builtin_strchr strchr; /// + alias __builtin_strcspn strcspn; /// + alias __builtin_strpbrk strpbrk; /// + alias __builtin_strrchr strrchr; /// + alias __builtin_strspn strspn; /// + alias __builtin_strstr strstr; /// + alias __builtin_memset memset; /// + alias __builtin_strlen strlen; /// + alias __builtin_strcmp strcmp; /// + alias __builtin_strcat strcat; /// + alias __builtin_memcmp memcmp; /// +} +else +{ void* memcpy(void* s1, void* s2, size_t n); /// -void* memmove(void* s1, void* s2, size_t n); /// char* strcpy(char* s1, char* s2); /// char* strncpy(char* s1, char* s2, size_t n); /// char* strncat(char* s1, char* s2, size_t n); /// -int strcoll(char* s1, char* s2); /// int strncmp(char* s1, char* s2, size_t n); /// -size_t strxfrm(char* s1, char* s2, size_t n); /// -void* memchr(void* s, int c, size_t n); /// char* strchr(char* s, int c); /// size_t strcspn(char* s1, char* s2); /// char* strpbrk(char* s1, char* s2); /// char* strrchr(char* s, int c); /// size_t strspn(char* s1, char* s2); /// char* strstr(char* s1, char* s2); /// -char* strtok(char* s1, char* s2); /// void* memset(void* s, int c, size_t n); /// -char* strerror(int errnum); /// size_t strlen(char* s); /// int strcmp(char* s1, char* s2); /// char* strcat(char* s1, char* s2); /// int memcmp(void* s1, void* s2, size_t n); /// +} +void* memmove(void* s1, void* s2, size_t n); /// +size_t strxfrm(char* s1, char* s2, size_t n); /// +int strcoll(char* s1, char* s2); /// +void* memchr(void* s, int c, size_t n); /// +char* strtok(char* s1, char* s2); /// +char* strerror(int errnum); /// version (Windows) { diff -uNrp dmd-1.007/src/phobos/std/c/time.d gdc-0.23/d/phobos/std/c/time.d --- dmd-1.007/src/phobos/std/c/time.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/time.d 2007-03-04 15:49:43.000000000 +0100 @@ -10,10 +10,31 @@ module std.c.time; private import std.c.stddef; +private import std.stdint; extern (C): -alias int clock_t; +version (GNU) +{ + private import gcc.config; + alias gcc.config.CLOCKS_PER_SEC CLOCKS_PER_SEC; + alias gcc.config.Cclock_t clock_t; + alias gcc.config.Ctime_t time_t; + alias gcc.config.tm tm; + extern int daylight; + extern int timezone; + extern int altzone; + extern char *tzname[2]; + version (Windows) + { + const clock_t CLK_TCK = 1000; + } + // Else: not implemented yet. Could be be a constant or + // a sysconf() call depending on the OS. +} +else +{ +alias Clong_t clock_t; version (Windows) { const clock_t CLOCKS_PER_SEC = 1000; @@ -50,7 +71,7 @@ else const uint TIMEOFFSET = 315558000; -alias int time_t; +alias Clong_t time_t; extern int daylight; extern int timezone; @@ -68,6 +89,7 @@ struct tm tm_yday, tm_isdst; } +} clock_t clock(); time_t time(time_t *); diff -uNrp dmd-1.007/src/phobos/std/c/unix/unix.d gdc-0.23/d/phobos/std/c/unix/unix.d --- dmd-1.007/src/phobos/std/c/unix/unix.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/c/unix/unix.d 2006-07-22 16:36:37.000000000 +0200 @@ -0,0 +1,28 @@ +/* GDC -- D front-end for GCC + Copyright (C) 2004 David Friedman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +module std.c.unix.unix; + +/* This module imports the unix module for the currect + target system. Currently, all targets can be + handled with the autoconf'd version. */ + +public import gcc.configunix; + +// DMD linux.d has dirent.h declarations +public import std.c.dirent; diff -uNrp dmd-1.007/src/phobos/std/conv.d gdc-0.23/d/phobos/std/conv.d --- dmd-1.007/src/phobos/std/conv.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/conv.d 2007-02-08 19:07:06.000000000 +0100 @@ -105,7 +105,7 @@ int toInt(char[] s) goto Lerr; int sign = 0; - int v = 0; + uint v = 0; for (int i = 0; i < length; i++) { @@ -133,13 +133,13 @@ int toInt(char[] s) } if (sign == -1) { - if (cast(uint)v > 0x80000000) + if (v > 0x80000000) goto Loverflow; v = -v; } else { - if (cast(uint)v > 0x7FFFFFFF) + if (v > 0x7FFFFFFF) goto Loverflow; } return v; @@ -325,7 +325,7 @@ long toLong(char[] s) goto Lerr; int sign = 0; - long v = 0; + ulong v = 0; for (int i = 0; i < length; i++) { @@ -353,13 +353,13 @@ long toLong(char[] s) } if (sign == -1) { - if (cast(ulong)v > 0x8000000000000000) + if (v > 0x8000000000000000) goto Loverflow; v = -v; } else { - if (cast(ulong)v > 0x7FFFFFFFFFFFFFFF) + if (v > 0x7FFFFFFFFFFFFFFF) goto Loverflow; } return v; @@ -872,6 +872,18 @@ unittest * ditto */ +version (skyos) +{ + float strtof(char * s, char ** ep) { + return strtod(s, ep); + } +} + +static if (real.sizeof > double.sizeof) + private alias strtold _conv_strtold; +else + private alias strtod _conv_strtold; + float toFloat(in char[] s) { float f; @@ -879,6 +891,8 @@ float toFloat(in char[] s) char* sz; //writefln("toFloat('%s')", s); + version (aix) + s = toupper(s); sz = toStringz(s); if (std.ctype.isspace(*sz)) goto Lerr; @@ -889,7 +903,7 @@ float toFloat(in char[] s) f = strtof(sz, &endptr); if (getErrno() == ERANGE) goto Lerr; - if (endptr && (endptr == s.ptr || *endptr != 0)) + if (endptr && (endptr == sz || *endptr != 0)) goto Lerr; return f; @@ -943,6 +957,8 @@ double toDouble(in char[] s) char* sz; //writefln("toDouble('%s')", s); + version (aix) + s = toupper(s); sz = toStringz(s); if (std.ctype.isspace(*sz)) goto Lerr; @@ -953,7 +969,7 @@ double toDouble(in char[] s) f = strtod(sz, &endptr); if (getErrno() == ERANGE) goto Lerr; - if (endptr && (endptr == s.ptr || *endptr != 0)) + if (endptr && (endptr == sz || *endptr != 0)) goto Lerr; return f; @@ -1009,6 +1025,8 @@ real toReal(in char[] s) char* sz; //writefln("toReal('%s')", s); + version (aix) + s = toupper(s); sz = toStringz(s); if (std.ctype.isspace(*sz)) goto Lerr; @@ -1016,10 +1034,10 @@ real toReal(in char[] s) // BUG: should set __locale_decpoint to "." for DMC setErrno(0); - f = strtold(sz, &endptr); + f = _conv_strtold(sz, &endptr); if (getErrno() == ERANGE) goto Lerr; - if (endptr && (endptr == s.ptr || *endptr != 0)) + if (endptr && (endptr == sz || *endptr != 0)) goto Lerr; return f; @@ -1219,11 +1237,11 @@ cfloat toCfloat(in char[] s) // atof(s1); endptr = &s1[s1.length - 1]; - r1 = strtold(s1, &endptr); + r1 = _conv_strtold(s1, &endptr); // atof(s2); endptr = &s2[s2.length - 1]; - r2 = strtold(s2, &endptr); + r2 = _conv_strtold(s2, &endptr); cf = cast(cfloat)(r1 + (r2 * 1.0i)); @@ -1298,11 +1316,11 @@ cdouble toCdouble(in char[] s) // atof(s1); endptr = &s1[s1.length - 1]; - r1 = strtold(s1, &endptr); + r1 = _conv_strtold(s1, &endptr); // atof(s2); endptr = &s2[s2.length - 1]; - r2 = strtold(s2, &endptr); //atof(s2); + r2 = _conv_strtold(s2, &endptr); //atof(s2); cd = cast(cdouble)(r1 + (r2 * 1.0i)); @@ -1373,11 +1391,11 @@ creal toCreal(in char[] s) // atof(s1); endptr = &s1[s1.length - 1]; - r1 = strtold(s1, &endptr); + r1 = _conv_strtold(s1, &endptr); // atof(s2); endptr = &s2[s2.length - 1]; - r2 = strtold(s2, &endptr); //atof(s2); + r2 = _conv_strtold(s2, &endptr); //atof(s2); //writefln("toCreal() r1=%g, r2=%g, s1=\"%s\", s2=\"%s\", nan=%g", // r1, r2, s1, s2, creal.nan); diff -uNrp dmd-1.007/src/phobos/std/cpuid.d gdc-0.23/d/phobos/std/cpuid.d --- dmd-1.007/src/phobos/std/cpuid.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/cpuid.d 2006-12-09 17:56:59.000000000 +0100 @@ -34,6 +34,12 @@ COPYRIGHT: Public Domain * COPYRIGHT = Public Domain */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, November 2006 +*/ + module std.cpuid; import std.string; @@ -118,9 +124,9 @@ version(D_InlineAsm_X86) static this() { - getVendorString(); - getProcessorString(); - getFeatureFlags(); + getVendorString(vendorStr.ptr); + processorStr = getProcessorString(); + getFeatureFlags(& flags, & misc, & exflags, & apic, & signature); // stepping / family / model _stepping = signature&0xF; @@ -218,28 +224,30 @@ private: /* ** * fetches the cpu vendor string */ - private void getVendorString() + private void getVendorString(char* dst) { - char* dst = vendorStr.ptr; // puts the vendor string into dst asm { + push EBX ; mov EAX, 0 ; cpuid ; mov EAX, dst ; mov [EAX], EBX ; mov [EAX+4], EDX ; mov [EAX+8], ECX ; + db 0x5b /* pop EBX */ ; } } - private void getProcessorString() + private char[] getProcessorString() { char[48] buffer; char* dst = buffer.ptr; // puts the processor string into dst asm { + push EBX ; mov EAX, 0x8000_0000 ; cpuid ; cmp EAX, 0x8000_0004 ; @@ -266,20 +274,23 @@ private: mov [EDI+44], EDX ; pop EDI ; PSLabel: ; + db 0x5b /* pop EBX */ ; } if (buffer[0] == char.init) // no support - return; + return ""; // seems many intel processors prepend whitespace - processorStr = std.string.strip(std.string.toString(dst)).dup; + return std.string.strip(std.string.toString(dst)).dup; } - private void getFeatureFlags() + private void getFeatureFlags(uint *flags, uint *misc, uint *exflags, + uint *apic, uint *signature) { uint f,m,e,a,s; asm { + push EBX ; mov EAX, 0 ; cpuid ; cmp EAX, 1 ; @@ -301,13 +312,14 @@ private: mov e, EDX ; FeatLabel2: + db 0x5b /* pop EBX */ ; ; } - flags = f; - misc = m; - exflags = e; - apic = a; - signature = s; + *flags = f; + *misc = m; + *exflags = e; + *apic = a; + *signature = s; } private void getThreadingIntel() @@ -316,6 +328,7 @@ private: ubyte b = 0; asm { + push EBX ; mov EAX, 0 ; cpuid ; cmp EAX, 4 ; @@ -326,6 +339,7 @@ private: mov n, EAX ; mov b, 1 ; IntelSingle: ; + db 0x5b /* pop EBX */ ; } if (b != 0) { @@ -344,6 +358,7 @@ private: ubyte b = 0; asm { + push EBX ; mov EAX, 0x8000_0000 ; cpuid ; cmp EAX, 0x8000_0008 ; @@ -353,6 +368,7 @@ private: mov n, CL ; mov b, 1 ; AMDSingle: ; + db 0x5b /* pop EBX */ ; } if (b != 0) { diff -uNrp dmd-1.007/src/phobos/std/date.d gdc-0.23/d/phobos/std/date.d --- dmd-1.007/src/phobos/std/date.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/date.d 2007-03-02 18:17:02.000000000 +0100 @@ -17,6 +17,12 @@ // written by Walter Bright // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, May 2005 +*/ + module std.date; private import std.stdio; @@ -513,7 +519,7 @@ char[] toString(d_time time) DateFromTime(t), HourFromTime(t), MinFromTime(t), SecFromTime(t), sign, hr, mn, - cast(long)YearFromTime(t)); + /*cast(long)*/YearFromTime(t)); // Ensure no buggy buffer overflows //printf("len = %d, buffer.length = %d\n", len, buffer.length); @@ -577,7 +583,7 @@ char[] toDateString(d_time time) &daystr[WeekDay(t) * 3], &monstr[MonthFromTime(t) * 3], DateFromTime(t), - cast(long)YearFromTime(t)); + /*cast(long)*/YearFromTime(t)); // Ensure no buggy buffer overflows assert(len < buffer.length); @@ -822,7 +828,84 @@ version (Win32) } } -version (linux) +else version (GNU) +{ + // for now, just copy linux + private import std.c.unix.unix; + + d_time getUTCtime() + { timeval tv; + + if (gettimeofday(&tv, null)) + { // Some error happened - try time() instead + return time(null) * TicksPerSecond; + } + + return tv.tv_sec * cast(d_time)TicksPerSecond + + (tv.tv_usec / (1000000 / cast(d_time)TicksPerSecond)); + } + + private extern (C) time_t _d_gnu_cbridge_tza(); + + d_time getLocalTZA() + { + return _d_gnu_cbridge_tza() * TicksPerSecond; + } + + /* + * Get daylight savings time adjust for time dt. + */ + + int DaylightSavingTA(d_time dt) + { + tm *tmp; + time_t t; + int dst = 0; + + if (dt != d_time_nan) + { + d_time seconds = dt / TicksPerSecond; + t = cast(time_t) 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(cast(int)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; + } +} +else version (linux) { private import std.c.linux.linux; @@ -842,7 +925,7 @@ version (linux) d_time getLocalTZA() { - __time_t t; + int t; time(&t); localtime(&t); // this will set timezone @@ -856,13 +939,13 @@ version (linux) int DaylightSavingTA(d_time dt) { tm *tmp; - std.c.linux.linux.__time_t t; + int t; int dst = 0; if (dt != d_time_nan) { d_time seconds = dt / TicksPerSecond; - t = cast(__time_t) seconds; + t = cast(int) seconds; if (t == seconds) // if in range { tmp = localtime(&t); @@ -876,7 +959,7 @@ version (linux) dt -= LocalTZA; int year = YearFromTime(dt); - int leap = LeapYear(cast(int)dt); + int leap = LeapYear(dt); //writefln("year = %s, leap = %s, month = %s", year, leap, MonthFromTime(dt)); d_time start = TimeFromYear(year); // Jan 1 diff -uNrp dmd-1.007/src/phobos/std/dateparse.d gdc-0.23/d/phobos/std/dateparse.d --- dmd-1.007/src/phobos/std/dateparse.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/dateparse.d 2007-03-04 15:50:21.000000000 +0100 @@ -52,7 +52,8 @@ struct DateParse //else //buffer = new char[s.length]; - debug(dateparse) printf("DateParse.parse('%.*s')\n", s); + debug(dateparse) printf("DateParse.parse('%.*s')\n", + cast(int) s.length, s.ptr); if (!parseString(s)) { goto Lerror; diff -uNrp dmd-1.007/src/phobos/std/demangle.d gdc-0.23/d/phobos/std/demangle.d --- dmd-1.007/src/phobos/std/demangle.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/demangle.d 2007-03-04 15:50:25.000000000 +0100 @@ -5,6 +5,11 @@ * Placed into the Public Domain. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, November 2005 +*/ /**** * Demangle D mangled names. * Macros: @@ -347,9 +352,9 @@ char[] demangle(char[] name) { real r; ubyte *p = cast(ubyte *)&r; - if (ni + 10 * 2 > name.length) + if (ni + real.sizeof * 2 > name.length) error(); - for (i = 0; i < 10; i++) + for (i = 0; i < real.sizeof; i++) { ubyte b; b = cast(ubyte) @@ -496,8 +501,12 @@ unittest [ "_D8demangle4testFLAiXi", "int demangle.test(lazy int[] ...)"] ]; - foreach (char[][2] name; table) + foreach (uint i, char[][2] name; table) { + static if (real.sizeof != 10) { + if (i == 7 || i == 8) + continue; + } char[] r = demangle(name[0]); //writefln("[ \"%s\", \"%s\" ],", name[0], r); assert(r == name[1]); diff -uNrp dmd-1.007/src/phobos/std/file.d gdc-0.23/d/phobos/std/file.d --- dmd-1.007/src/phobos/std/file.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/file.d 2007-03-04 15:51:03.000000000 +0100 @@ -27,10 +27,17 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, March 2006 +*/ + module std.file; private import std.c.stdio; private import std.c.stdlib; +private import std.c.string; private import std.path; private import std.string; private import std.regexp; @@ -840,11 +847,13 @@ void copy(char[] from, char[] to) /* =========================== linux ======================= */ -version (linux) +else version (Unix) { +private import std.c.unix.unix; private import std.date; -private import std.c.linux.linux; + +alias std.c.unix.unix unix; extern (C) char* strerror(int); @@ -886,7 +895,7 @@ void[] read(char[] name) auto namez = toStringz(name); //printf("file.read('%s')\n",namez); - auto fd = std.c.linux.linux.open(namez, O_RDONLY); + auto fd = unix.open(namez, O_RDONLY); if (fd == -1) { //printf("\topen error, errno = %d\n",getErrno()); @@ -894,24 +903,27 @@ void[] read(char[] name) } //printf("\tfile opened\n"); - if (std.c.linux.linux.fstat(fd, &statbuf)) + if (unix.fstat(fd, &statbuf)) { //printf("\tfstat error, errno = %d\n",getErrno()); goto err2; } auto size = statbuf.st_size; + if (size > size_t.max) + goto err2; + auto buf = new void[size]; if (buf.ptr) std.gc.hasNoPointers(buf.ptr); - numread = std.c.linux.linux.read(fd, cast(char*)buf, size); + numread = unix.read(fd, cast(char*)buf, size); if (numread != size) { //printf("\tread error, errno = %d\n",getErrno()); goto err2; } - if (std.c.linux.linux.close(fd) == -1) + if (unix.close(fd) == -1) { //printf("\tclose error, errno = %d\n",getErrno()); goto err; @@ -920,7 +932,7 @@ void[] read(char[] name) return buf; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: delete buf; @@ -937,25 +949,24 @@ err1: void write(char[] name, void[] buffer) { int fd; - int numwritten; char *namez; namez = toStringz(name); - fd = std.c.linux.linux.open(namez, O_CREAT | O_WRONLY | O_TRUNC, 0660); + fd = unix.open(namez, O_CREAT | O_WRONLY | O_TRUNC, 0660); if (fd == -1) goto err; - numwritten = std.c.linux.linux.write(fd, buffer.ptr, buffer.length); + auto numwritten = unix.write(fd, buffer.ptr, buffer.length); if (buffer.length != numwritten) goto err2; - if (std.c.linux.linux.close(fd) == -1) + if (unix.close(fd) == -1) goto err; return; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: throw new FileException(name, getErrno()); } @@ -968,25 +979,24 @@ err: void append(char[] name, void[] buffer) { int fd; - int numwritten; char *namez; namez = toStringz(name); - fd = std.c.linux.linux.open(namez, O_APPEND | O_WRONLY | O_CREAT, 0660); + fd = unix.open(namez, O_APPEND | O_WRONLY | O_CREAT, 0660); if (fd == -1) goto err; - numwritten = std.c.linux.linux.write(fd, buffer.ptr, buffer.length); + auto numwritten = unix.write(fd, buffer.ptr, buffer.length); if (buffer.length != numwritten) goto err2; - if (std.c.linux.linux.close(fd) == -1) + if (unix.close(fd) == -1) goto err; return; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: throw new FileException(name, getErrno()); } @@ -1030,7 +1040,7 @@ ulong getSize(char[] name) namez = toStringz(name); //printf("file.getSize('%s')\n",namez); - fd = std.c.linux.linux.open(namez, O_RDONLY); + fd = unix.open(namez, O_RDONLY); if (fd == -1) { //printf("\topen error, errno = %d\n",getErrno()); @@ -1038,14 +1048,14 @@ ulong getSize(char[] name) } //printf("\tfile opened\n"); - if (std.c.linux.linux.fstat(fd, &statbuf)) + if (unix.fstat(fd, &statbuf)) { //printf("\tfstat error, errno = %d\n",getErrno()); goto err2; } size = statbuf.st_size; - if (std.c.linux.linux.close(fd) == -1) + if (unix.close(fd) == -1) { //printf("\tclose error, errno = %d\n",getErrno()); goto err; @@ -1054,7 +1064,7 @@ ulong getSize(char[] name) return size; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: err1: throw new FileException(name, getErrno()); @@ -1071,7 +1081,7 @@ uint getAttributes(char[] name) char *namez; namez = toStringz(name); - if (std.c.linux.linux.stat(namez, &statbuf)) + if (unix.stat(namez, &statbuf)) { throw new FileException(name, getErrno()); } @@ -1090,7 +1100,7 @@ void getTimes(char[] name, out d_time ft char *namez; namez = toStringz(name); - if (std.c.linux.linux.stat(namez, &statbuf)) + if (std.c.unix.unix.stat(namez, &statbuf)) { throw new FileException(name, getErrno()); } @@ -1114,7 +1124,7 @@ int exists(char[] name) char *namez; namez = toStringz(name); - if (std.c.linux.linux.stat(namez, &statbuf)) + if (unix.stat(namez, &statbuf)) { return 0; } @@ -1151,7 +1161,7 @@ int isdir(char[] name) void chdir(char[] pathname) { - if (std.c.linux.linux.chdir(toStringz(pathname))) + if (unix.chdir(toStringz(pathname))) { throw new FileException(pathname, getErrno()); } @@ -1163,7 +1173,7 @@ void chdir(char[] pathname) void mkdir(char[] pathname) { - if (std.c.linux.linux.mkdir(toStringz(pathname), 0777)) + if (unix.mkdir(toStringz(pathname), 0777)) { throw new FileException(pathname, getErrno()); } @@ -1175,7 +1185,7 @@ void mkdir(char[] pathname) void rmdir(char[] pathname) { - if (std.c.linux.linux.rmdir(toStringz(pathname))) + if (unix.rmdir(toStringz(pathname))) { throw new FileException(pathname, getErrno()); } @@ -1187,17 +1197,32 @@ void rmdir(char[] pathname) char[] getcwd() { - auto p = std.c.linux.linux.getcwd(null, 0); + version(all) + { + char buf[PATH_MAX]; + if (! unix.getcwd(buf.ptr, buf.length)) + { + throw new FileException("cannot get cwd", getErrno()); + } + size_t len = strlen(buf.ptr); + char[] result = new char[len]; + result[] = buf[0..len]; + return result; + } + else + { + auto p = unix.getcwd(null, 0); if (!p) { throw new FileException("cannot get cwd", getErrno()); } - auto len = std.string.strlen(p); auto buf = new char[len]; buf[] = p[0 .. len]; std.c.stdlib.free(p); return buf; + } + } /*************************************************** @@ -1211,24 +1236,44 @@ struct DirEntry d_time _creationTime = d_time_nan; // time of file creation d_time _lastAccessTime = d_time_nan; // time file was last accessed d_time _lastWriteTime = d_time_nan; // time file was last written to - ubyte d_type; + version (GNU) + typeof(struct_stat.st_mode) _st_mode; + else + ubyte d_type; ubyte didstat; // done lazy evaluation of stat() void init(char[] path, dirent *fd) { size_t len = std.string.strlen(fd.d_name.ptr); name = std.path.join(path, fd.d_name[0 .. len]); - d_type = fd.d_type; + version(GNU) + { } + else + d_type = fd.d_type; didstat = 0; } int isdir() { - return d_type & DT_DIR; + version(GNU) + { + if (!didstat) + doStat(); + return (_st_mode & S_IFMT) == S_IFDIR; + } + else + return d_type & DT_DIR; } int isfile() { - return d_type & DT_REG; + version(GNU) + { + if (!didstat) + doStat(); + return (_st_mode & S_IFMT) == S_IFREG; + } + else + return d_type & DT_REG; } ulong size() @@ -1270,7 +1315,7 @@ struct DirEntry char* namez; namez = toStringz(name); - if (std.c.linux.linux.stat(namez, &statbuf)) + if (std.c.unix.unix.stat(namez, &statbuf)) { //printf("\tstat error, errno = %d\n",getErrno()); return; @@ -1279,7 +1324,7 @@ struct DirEntry _creationTime = cast(d_time)statbuf.st_ctime * std.date.TicksPerSecond; _lastAccessTime = cast(d_time)statbuf.st_atime * std.date.TicksPerSecond; _lastWriteTime = cast(d_time)statbuf.st_mtime * std.date.TicksPerSecond; - + _st_mode = statbuf.st_mode; didstat = 1; } } @@ -1398,7 +1443,7 @@ void copy(char[] from, char[] to) char* toz = toStringz(to); //printf("file.copy(from='%s', to='%s')\n", fromz, toz); - int fd = std.c.linux.linux.open(fromz, O_RDONLY); + int fd = std.c.unix.unix.open(fromz, O_RDONLY); if (fd == -1) { //printf("\topen error, errno = %d\n",getErrno()); @@ -1406,13 +1451,13 @@ void copy(char[] from, char[] to) } //printf("\tfile opened\n"); - if (std.c.linux.linux.fstat(fd, &statbuf)) + if (std.c.unix.unix.fstat(fd, &statbuf)) { //printf("\tfstat error, errno = %d\n",getErrno()); goto err2; } - int fdw = std.c.linux.linux.open(toz, O_CREAT | O_WRONLY | O_TRUNC, 0660); + int fdw = std.c.unix.unix.open(toz, O_CREAT | O_WRONLY | O_TRUNC, 0660); if (fdw == -1) { //printf("\topen error, errno = %d\n",getErrno()); @@ -1431,16 +1476,16 @@ void copy(char[] from, char[] to) goto err4; } - for (size_t size = statbuf.st_size; size; ) + for (auto size = statbuf.st_size; size; ) { size_t toread = (size > BUFSIZ) ? BUFSIZ : size; - auto n = std.c.linux.linux.read(fd, buf, toread); + auto n = std.c.unix.unix.read(fd, buf, toread); if (n != toread) { //printf("\tread error, errno = %d\n",getErrno()); goto err5; } - n = std.c.linux.linux.write(fdw, buf, toread); + n = std.c.unix.unix.write(fdw, buf, toread); if (n != toread) { //printf("\twrite error, errno = %d\n",getErrno()); @@ -1451,22 +1496,22 @@ void copy(char[] from, char[] to) std.c.stdlib.free(buf); - if (std.c.linux.linux.close(fdw) == -1) + if (std.c.unix.unix.close(fdw) == -1) { //printf("\tclose error, errno = %d\n",getErrno()); goto err2; } utimbuf utim; - utim.actime = cast(__time_t)statbuf.st_atime; - utim.modtime = cast(__time_t)statbuf.st_mtime; + utim.actime = cast(typeof(utim.actime))statbuf.st_atime; + utim.modtime = cast(typeof(utim.modtime))statbuf.st_mtime; if (utime(toz, &utim) == -1) { //printf("\tutime error, errno = %d\n",getErrno()); goto err3; } - if (std.c.linux.linux.close(fd) == -1) + if (std.c.unix.unix.close(fd) == -1) { //printf("\tclose error, errno = %d\n",getErrno()); goto err1; @@ -1477,11 +1522,11 @@ void copy(char[] from, char[] to) err5: std.c.stdlib.free(buf); err4: - std.c.linux.linux.close(fdw); + std.c.unix.unix.close(fdw); err3: std.c.stdio.remove(toz); err2: - std.c.linux.linux.close(fd); + std.c.unix.unix.close(fd); err1: throw new FileException(from, getErrno()); } diff -uNrp dmd-1.007/src/phobos/std/format.d gdc-0.23/d/phobos/std/format.d --- dmd-1.007/src/phobos/std/format.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/format.d 2007-03-04 15:51:34.000000000 +0100 @@ -45,6 +45,10 @@ version (Windows) { version = DigitalMarsC; } + version (GNU) + { + version = GNU_MinGW_MSVCRT; + } } version (DigitalMarsC) @@ -442,7 +446,8 @@ formattedPrint("The answer is %s:", x, 6 ------------------------ */ -void doFormat(void delegate(dchar) putc, TypeInfo[] arguments, va_list argptr) +void doFormat(void delegate(dchar) putc, TypeInfo[] arguments, va_list argptr, + void * p_args = null) { int j; TypeInfo ti; Mangle m; @@ -571,16 +576,24 @@ void doFormat(void delegate(dchar) putc, format[i + 0] = '*'; format[i + 1] = '.'; format[i + 2] = '*'; - format[i + 3] = 'L'; - format[i + 4] = fc; - format[i + 5] = 0; + i += 3; + version (GNU_MinGW_MSVCRT) + { /* nothing: no support for long double */ } + else + static if (real.sizeof > double.sizeof) + format[i++] = 'L'; + format[i++] = fc; + format[i] = 0; if (!(flags & FLprecision)) precision = -1; while (1) { int n; sl = fbuf.length; - n = snprintf(fbuf.ptr, sl, format.ptr, field_width, precision, v); + version (GNU_MinGW_MSVCRT) + n = snprintf(fbuf.ptr, sl, format.ptr, field_width, precision, cast(double) v); + else + n = snprintf(fbuf.ptr, sl, format.ptr, field_width, precision, v); //printf("format = '%s', n = %d\n", cast(char*)format, n); if (n >= 0 && n < sl) { sl = n; @@ -601,29 +614,36 @@ void doFormat(void delegate(dchar) putc, { putc('['); size_t tsize = valti.tsize(); - auto argptrSave = argptr; + auto argptrSave = p_args; auto tiSave = ti; ti = valti; m = cast(Mangle)valti.classinfo.name[9]; while (len--) { //doFormat(putc, (&valti)[0 .. 1], p); - argptr = p; + p_args = p; formatArg('s'); p += tsize; if (len > 0) putc(','); } ti = tiSave; - argptr = argptrSave; + p_args = argptrSave; putc(']'); } void putAArray(ubyte[long] vaa, TypeInfo valti, TypeInfo keyti) { + // Copied from aaA.d + size_t aligntsize(size_t tsize) + { + // Is pointer alignment on the x64 4 bytes or 8? + return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1); + } + putc('['); bool comma=false; - auto argptrSave = argptr; + auto argptrSave = p_args; auto tiSave = ti; foreach(inout fakevalue; vaa) { @@ -633,25 +653,26 @@ void doFormat(void delegate(dchar) putc, ubyte* key = &fakevalue - long.sizeof; //doFormat(putc, (&keyti)[0..1], key); - argptr = key; + p_args = key; ti = keyti; m = cast(Mangle)keyti.classinfo.name[9]; formatArg('s'); putc(':'); - ubyte* value = key + keyti.tsize; + ubyte* value = key + aligntsize(keyti.tsize); //doFormat(putc, (&valti)[0..1], value); - argptr = value; + p_args = value; ti = valti; m = cast(Mangle)valti.classinfo.name[9]; formatArg('s'); } ti = tiSave; - argptr = argptrSave; + p_args = argptrSave; putc(']'); } //printf("formatArg(fc = '%c', m = '%c')\n", fc, m); + if (! p_args) switch (m) { case Mangle.Tbit: @@ -746,7 +767,7 @@ void doFormat(void delegate(dchar) putc, goto Lputstr; case Mangle.Tpointer: - vnumber = cast(ulong)va_arg!(void*)(argptr); + vnumber = cast(size_t)va_arg!(void*)(argptr); uc = 1; flags |= FL0pad; if (!(flags & FLprecision)) @@ -760,14 +781,22 @@ void doFormat(void delegate(dchar) putc, case Mangle.Tfloat: case Mangle.Tifloat: if (fc == 'x' || fc == 'X') - goto Luint; + { + float f = va_arg!(float)(argptr); + vnumber = *cast(uint*)&f; + goto Lnumber; + } vreal = va_arg!(float)(argptr); goto Lreal; case Mangle.Tdouble: case Mangle.Tidouble: if (fc == 'x' || fc == 'X') - goto Lulong; + { + double f = va_arg!(double)(argptr); + vnumber = *cast(ulong*)&f; + goto Lnumber; + } vreal = va_arg!(double)(argptr); goto Lreal; @@ -853,14 +882,247 @@ void doFormat(void delegate(dchar) putc, case Mangle.Tstruct: { TypeInfo_Struct tis = cast(TypeInfo_Struct)ti; - s = tis.xtoString(argptr); - argptr += (tis.tsize() + 3) & ~3; + static if + ( + is( typeof(argptr): void[] ) || + is( typeof(argptr) == struct )) + { + version(PPC) + { + // Structs are pass-by-reference in V4 ABI + s = tis.xtoString(va_arg!(void*)(argptr)); + } + else version(X86_64) + { + throw new FormatError("cannot portably format a struct on this target"); + } + else + { + static assert(0, "unimplemented"); + } + } + else + { + s = tis.xtoString(argptr); + argptr += (tis.tsize() + 3) & ~3; + } goto Lputstr; } default: goto Lerror; } + else + { + switch (m) + { + case Mangle.Tbit: + case Mangle.Tbool: + vbit = *cast(bool*)(p_args); p_args += bool.sizeof; // int.sizeof, etc.? + if (fc != 's') + { vnumber = vbit; + goto Lnumber; + } + putstr(vbit ? "true" : "false"); + return; + + + case Mangle.Tchar: + vchar = *cast(char*)(p_args); p_args += char.sizeof; + if (fc != 's') + { vnumber = vchar; + goto Lnumber; + } + PL2: // there is goto L2 outside of thise switch; it's okay to do that + putstr((&vchar)[0 .. 1]); + return; + + case Mangle.Twchar: + vdchar = *cast(wchar*)(p_args); p_args += wchar.sizeof; + goto PL1; + + case Mangle.Tdchar: + vdchar = *cast(dchar*)(p_args); p_args += dchar.sizeof; + PL1: + if (fc != 's') + { vnumber = vdchar; + goto Lnumber; + } + if (vdchar <= 0x7F) + { vchar = cast(char)vdchar; + goto PL2; + } + else + { if (!isValidDchar(vdchar)) + throw new UtfException("invalid dchar in format", 0); + char[4] vbuf; + putstr(toUTF8(vbuf, vdchar)); + } + return; + + + case Mangle.Tbyte: + signed = 1; + vnumber = *cast(byte*)p_args; p_args += byte.sizeof; + goto Lnumber; + + case Mangle.Tubyte: + vnumber = *cast(ubyte*)p_args; p_args += ubyte.sizeof; + goto Lnumber; + + case Mangle.Tshort: + signed = 1; + vnumber = *cast(short*)p_args; p_args += short.sizeof; + goto Lnumber; + + case Mangle.Tushort: + vnumber = *cast(ushort*)p_args; p_args += ushort.sizeof; + goto Lnumber; + + case Mangle.Tint: + signed = 1; + vnumber = *cast(int*)p_args; p_args += int.sizeof; + goto Lnumber; + + case Mangle.Tuint: + PLuint: + vnumber = *cast(uint*)p_args; p_args += uint.sizeof; + goto Lnumber; + + case Mangle.Tlong: + signed = 1; + vnumber = cast(ulong)*cast(long*)p_args; p_args += long.sizeof; + goto Lnumber; + + case Mangle.Tulong: + PLulong: + vnumber = *cast(ulong*)p_args; p_args += ulong.sizeof; + goto Lnumber; + + case Mangle.Tclass: + vobject = *cast(Object*)p_args; p_args += Object.sizeof; + s = vobject.toString(); + goto Lputstr; + + case Mangle.Tpointer: + alias void * void_ponter_t; + vnumber = cast(size_t)*cast(void**)p_args; p_args += void_ponter_t.sizeof; + uc = 1; + flags |= FL0pad; + if (!(flags & FLprecision)) + { flags |= FLprecision; + precision = (void*).sizeof; + } + base = 16; + goto Lnumber; + + + case Mangle.Tfloat: + case Mangle.Tifloat: + if (fc == 'x' || fc == 'X') + goto PLuint; + vreal = *cast(float*)p_args; p_args += float.sizeof; + goto Lreal; + + case Mangle.Tdouble: + case Mangle.Tidouble: + if (fc == 'x' || fc == 'X') + goto PLulong; + vreal = *cast(double*)p_args; p_args += double.sizeof; + goto Lreal; + + case Mangle.Treal: + case Mangle.Tireal: + vreal = *cast(real*)p_args; p_args += real.sizeof; + goto Lreal; + + + case Mangle.Tcfloat: + vcreal = *cast(cfloat*)p_args; p_args += cfloat.sizeof; + goto Lcomplex; + + case Mangle.Tcdouble: + vcreal = *cast(cdouble*)p_args; p_args += cdouble.sizeof; + goto Lcomplex; + + case Mangle.Tcreal: + vcreal = *cast(creal*)p_args; p_args += creal.sizeof; + goto Lcomplex; + + case Mangle.Tarray: + alias void[] array_t; + if (ti.classinfo.name.length == 14 && + ti.classinfo.name[9..14] == "Array") + { // array of non-primitive types + void[] va = *cast(void[]*)p_args; p_args += array_t.sizeof; + putArray(va.ptr, va.length, (cast(TypeInfo_Array)ti).next); + return; + } + if (ti.classinfo.name.length == 25 && + ti.classinfo.name[9..25] == "AssociativeArray") + { // associative array + ubyte[long] vaa = *cast(ubyte[long]*)p_args; p_args += vaa.sizeof; + putAArray(vaa, + (cast(TypeInfo_AssociativeArray)ti).next, + (cast(TypeInfo_AssociativeArray)ti).key); + return; + } + + m2 = cast(Mangle)ti.classinfo.name[10]; + switch (m2) + { + case Mangle.Tchar: + s = *cast(char[]*)p_args; p_args += array_t.sizeof; + goto PLputstr; + + case Mangle.Twchar: + wchar[] sw = *cast(wchar[]*)p_args; p_args += array_t.sizeof; + s = toUTF8(sw); + goto PLputstr; + + case Mangle.Tdchar: + dchar[] sd = *cast(dchar[]*)p_args; p_args += array_t.sizeof; + s = toUTF8(sd); + PLputstr: + if (fc != 's') + throw new FormatError("string"); + if (flags & FLprecision && precision < s.length) + s = s[0 .. precision]; + putstr(s); + break; + + default: + TypeInfo ti2 = primitiveTypeInfo(m2); + if (!ti2) + goto Lerror; + void[] va = *cast(void[]*)p_args; p_args += array_t.sizeof; + putArray(va.ptr, va.length, ti2); + } + return; + + case Mangle.Ttypedef: + ti = (cast(TypeInfo_Typedef)ti).base; + m = cast(Mangle)ti.classinfo.name[9]; + formatArg(fc); + return; + + case Mangle.Tenum: + ti = (cast(TypeInfo_Enum)ti).base; + m = cast(Mangle)ti.classinfo.name[9]; + formatArg(fc); + return; + + case Mangle.Tstruct: + { TypeInfo_Struct tis = cast(TypeInfo_Struct)ti; + s = tis.xtoString(p_args); + p_args += tis.tsize(); + goto Lputstr; + } + + default: + goto Lerror; + } + } Lnumber: switch (fc) @@ -1010,6 +1272,7 @@ void doFormat(void delegate(dchar) putc, * to deal with UTF in a couple of isolated spots. */ + if (! p_args) switch (m2) { case Mangle.Tchar: @@ -1030,6 +1293,30 @@ void doFormat(void delegate(dchar) putc, formatArg('s'); continue; } + else + { + alias void[] array_t; + switch (m2) + { + case Mangle.Tchar: + fmt = *cast(char[]*)p_args; p_args += array_t.sizeof; + break; + + case Mangle.Twchar: + wfmt = *cast(wchar[]*)p_args; p_args += array_t.sizeof; + fmt = toUTF8(wfmt); + break; + + case Mangle.Tdchar: + dfmt = *cast(dchar[]*)p_args; p_args += array_t.sizeof; + fmt = toUTF8(dfmt); + break; + + default: + formatArg('s'); + continue; + } + } for (size_t i = 0; i < fmt.length; ) { dchar c = fmt[i++]; @@ -1066,7 +1353,13 @@ void doFormat(void delegate(dchar) putc, m = cast(Mangle)ti.classinfo.name[9]; if (m != Mangle.Tint) throw new FormatError("int argument expected"); + if (! p_args) return va_arg!(int)(argptr); + else + { + int result = *cast(int*)(p_args); p_args += int.sizeof; + return result; + } } if (c != '%') @@ -1168,6 +1461,9 @@ Lerror: /* ======================== Unit Tests ====================================== */ +version (skyos) + version = no_hexfloat; + unittest { int i; @@ -1183,10 +1479,16 @@ unittest * C99 doesn't specify what the hex digit before the decimal point * is for %A. */ - version (linux) - assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan"); + /* + printf("%.*s\n", s); + printf("d: %A\n", -1.28); + printf("r: %LA\n", -1.28L); + */ + version (no_hexfloat) + { /*nothing*/ } else - assert(s == "1.67 -0X1.47AE147AE147BP+0 nan"); + assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan" || + s == "1.67 -0X1.47AE147AE147BP+0 nan"); s = std.string.format("%x %X", 0x1234AF, 0xAFAFAFAF); assert(s == "1234af AFAFAFAF"); diff -uNrp dmd-1.007/src/phobos/std/intrinsic.d gdc-0.23/d/phobos/std/intrinsic.d --- dmd-1.007/src/phobos/std/intrinsic.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/intrinsic.d 2006-06-03 04:57:13.000000000 +0200 @@ -4,6 +4,12 @@ // www.digitalmars.com // Placed into the public domain +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, May 2006 +*/ + /** These functions are built-in intrinsics to the compiler. * Intrinsic functions are functions built in to the compiler, @@ -26,7 +32,19 @@ module std.intrinsic; * The bit number of the first bit set. * The return value is undefined if v is zero. */ -int bsf(uint v); +version (GNU) + int bsf(uint v) + { + uint m = 1; + uint i; + for (i = 0; i < 32; i++,m<<=1) { + if (v&m) + return i; + } + return i; // supposed to be undefined + } +else + int bsf(uint v); /** * Scans the bits in v from the most significant bit @@ -56,22 +74,60 @@ int bsf(uint v); * bsf(x21) = 0
* bsr(x21) = 5 */ -int bsr(uint v); +version (GNU) +int bsr(uint v) +{ + uint m = 0x80000000; + uint i; + for (i = 32; i ; i--,m>>>=1) { + if (v&m) + return i-1; + } + return i; // supposed to be undefined +} +else + int bsr(uint v); /** * Tests the bit. */ -int bt(uint *p, uint bitnum); +version (GNU) +int bt(uint *p, uint bitnum) +{ + return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ; +} +else + int bt(uint *p, uint bitnum); /** * Tests and complements the bit. */ +version (GNU) +int btc(uint *p, uint bitnum) +{ + uint * q = p + (bitnum / (uint.sizeof*8)); + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1)); + int result = *q & mask; + *q ^= mask; + return result ? -1 : 0; +} +else int btc(uint *p, uint bitnum); /** * Tests and resets (sets to 0) the bit. */ -int btr(uint *p, uint bitnum); +version (GNU) +int btr(uint *p, uint bitnum) +{ + uint * q = p + (bitnum / (uint.sizeof*8)); + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1)); + int result = *q & mask; + *q &= ~mask; + return result ? -1 : 0; +} +else + int btr(uint *p, uint bitnum); /** * Tests and sets the bit. @@ -129,7 +185,17 @@ bt(array, 1) = -1 array = [0]:x2, [1]:x100 */ -int bts(uint *p, uint bitnum); +version (GNU) +int bts(uint *p, uint bitnum) +{ + uint * q = p + (bitnum / (uint.sizeof*8)); + uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1)); + int result = *q & mask; + *q |= mask; + return result ? -1 : 0; +} +else + int bts(uint *p, uint bitnum); /** @@ -137,38 +203,62 @@ int bts(uint *p, uint bitnum); byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3 becomes byte 0. */ -uint bswap(uint v); +version (GNU) +uint bswap(uint v) +{ + return ((v&0xFF)<<24)|((v&0xFF00)<<8)|((v&0xFF0000)>>>8)|((v&0xFF000000)>>>24); +} +else + uint bswap(uint v); /** * Reads I/O port at port_address. */ -ubyte inp(uint port_address); +version (GNU) + ubyte inp(uint p) { return 0; } +else + ubyte inp(uint port_address); /** * ditto */ -ushort inpw(uint port_address); +version (GNU) + ushort inpw(uint p) { return 0; } +else + ushort inpw(uint port_address); /** * ditto */ -uint inpl(uint port_address); +version (GNU) + uint inpl(uint p) { return 0; } +else + uint inpl(uint port_address); /** * Writes and returns value to I/O port at port_address. */ -ubyte outp(uint port_address, ubyte value); +version (GNU) + ubyte outp(uint p, ubyte v) { return v; } +else + ubyte outp(uint port_address, ubyte value); /** * ditto */ -ushort outpw(uint port_address, ushort value); +version (GNU) + ushort outpw(uint p, ushort v) { return v; } +else + ushort outpw(uint port_address, ushort value); /** * ditto */ -uint outpl(uint port_address, uint value); +version (GNU) + uint outpl(uint p, uint v) { return v; } +else + uint outpl(uint port_address, uint value); diff -uNrp dmd-1.007/src/phobos/std/loader.d gdc-0.23/d/phobos/std/loader.d --- dmd-1.007/src/phobos/std/loader.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/loader.d 2007-02-28 19:41:31.000000000 +0100 @@ -8,7 +8,7 @@ * * Author: Matthew Wilson * - * License: (Licensed under the Synesis Software Standard Source License) + * License: * * Copyright (C) 2002-2004, Synesis Software Pty Ltd. * @@ -20,25 +20,19 @@ * email: submissions@synsoft.org for submissions * admin@synsoft.org for other enquiries * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * (i) Redistributions of source code must retain the above - * copyright notice and contact information, this list of - * conditions and the following disclaimer. - * - * (ii) Any derived versions of this software (howsoever modified) - * remain the sole property of Synesis Software. - * - * (iii) Any derived versions of this software (howsoever modified) - * remain subject to all these conditions. - * - * (iv) Neither the name of Synesis Software nor the names of any - * subdivisions, employees or agents of Synesis Software, nor the - * names of any other contributors to this software may be used to - * endorse or promote products derived from this software without - * specific prior written permission. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, in both source and binary form, subject to the following + * restrictions: + * + * - The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * - Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * - This notice may not be removed or altered from any source + * distribution. * * This source code is provided by Synesis Software "as is" and any * warranties, whether expressed or implied, including, but not @@ -56,6 +50,36 @@ * * ////////////////////////////////////////////////////////////////////////// */ +/* + Copyright for Darwin specific code + + Copyright (c) 2002 Peter O'Gorman + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, June 2006 (applied patches from Anders F Björklund.) +*/ /** \file D/std/loader.d This file contains the \c D standard library @@ -84,6 +108,11 @@ public alias int bool * External function declarations */ +version(linux) + version = dlopen; +else version (freebsd) + version = dlopen; + version(Windows) { private import std.c.windows.windows; @@ -94,7 +123,7 @@ version(Windows) alias HMODULE HModule_; } } -else version(linux) +else version(dlopen) { extern(C) { @@ -110,6 +139,106 @@ else version(linux) char* strerror(int); } } +else version(darwin) +{ + extern(C) + { + // #include + + struct mach_header + { + uint magic; /* mach magic number identifier */ + uint cputype; /* cpu specifier */ + uint cpusubtype; /* machine specifier */ + uint filetype; /* type of file */ + uint ncmds; /* number of load commands */ + uint sizeofcmds; /* the size of all the load commands */ + uint flags; /* flags */ + } + + /* Constant for the magic field of the mach_header */ + const uint MH_MAGIC = 0xfeedface; // the mach magic number + const uint MH_CIGAM = 0xcefaedfe; // x86 variant + const uint MH_MAGIC_64 = 0xfeedfacf; // the 64-bit mach magic number + const uint MH_CIGAM_64 = 0xcffaedfe; // NXSwapInt(MH_MAGIC_64) + + // #include + + typedef void *NSObjectFileImage; + + typedef void *NSModule; + + typedef void *NSSymbol; + + enum // DYLD_BOOL: uint + { + FALSE, + TRUE + } + alias uint DYLD_BOOL; + + enum // NSObjectFileImageReturnCode: uint + { + NSObjectFileImageFailure, /* for this a message is printed on stderr */ + NSObjectFileImageSuccess, + NSObjectFileImageInappropriateFile, + NSObjectFileImageArch, + NSObjectFileImageFormat, /* for this a message is printed on stderr */ + NSObjectFileImageAccess + } + alias uint NSObjectFileImageReturnCode; + + enum // NSLinkEditErrors: uint + { + NSLinkEditFileAccessError, + NSLinkEditFileFormatError, + NSLinkEditMachResourceError, + NSLinkEditUnixResourceError, + NSLinkEditOtherError, + NSLinkEditWarningError, + NSLinkEditMultiplyDefinedError, + NSLinkEditUndefinedError + } + alias uint NSLinkEditErrors; + + + alias NSModule HModule_; + + NSObjectFileImageReturnCode NSCreateObjectFileImageFromFile(char *pathName, NSObjectFileImage* objectFileImage); + DYLD_BOOL NSDestroyObjectFileImage(NSObjectFileImage objectFileImage); + + mach_header * NSAddImage(char *image_name, uint options); + const uint NSADDIMAGE_OPTION_NONE = 0x0; + const uint NSADDIMAGE_OPTION_RETURN_ON_ERROR = 0x1; + const uint NSADDIMAGE_OPTION_WITH_SEARCHING = 0x2; + const uint NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED = 0x4; + const uint NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME = 0x8; + + NSModule NSLinkModule(NSObjectFileImage objectFileImage, char* moduleName, uint options); + const uint NSLINKMODULE_OPTION_NONE = 0x0; + const uint NSLINKMODULE_OPTION_BINDNOW = 0x01; + const uint NSLINKMODULE_OPTION_PRIVATE = 0x02; + const uint NSLINKMODULE_OPTION_RETURN_ON_ERROR = 0x04; + const uint NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES = 0x08; + const uint NSLINKMODULE_OPTION_TRAILING_PHYS_NAME = 0x10; + DYLD_BOOL NSUnLinkModule(NSModule module_, uint options); + + void NSLinkEditError(NSLinkEditErrors *c, int *errorNumber, char **fileName, char **errorString); + + DYLD_BOOL NSIsSymbolNameDefined(char *symbolName); + DYLD_BOOL NSIsSymbolNameDefinedInImage(mach_header *image, char *symbolName); + NSSymbol NSLookupAndBindSymbol(char *symbolName); + NSSymbol NSLookupSymbolInModule(NSModule module_, char* symbolName); + NSSymbol NSLookupSymbolInImage(mach_header *image, char *symbolName, uint options); + const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND = 0x0; + const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW = 0x1; + const uint NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY = 0x2; + const uint NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR = 0x4; + + void* NSAddressOfSymbol(NSSymbol symbol); + char* NSNameOfSymbol(NSSymbol symbol); + } +} else { const int platform_not_discriminated = 0; @@ -285,7 +414,7 @@ version(Windows) return szFileName[0 .. cch].dup; } } -else version(linux) +else version(dlopen) { private class ExeModuleInfo { @@ -326,7 +455,7 @@ else version(linux) private void ExeModule_Uninit_() { if(0 == --s_init) - { + { } } @@ -337,11 +466,11 @@ else version(linux) } body { - ExeModuleInfo mi = s_modules[moduleName]; + ExeModuleInfo *p_mi = moduleName in s_modules; - if(null !is mi) + if(p_mi != null) { - return (++mi.m_cRefs, cast(HXModule)mi); + return (++(*p_mi).m_cRefs, cast(HXModule)*p_mi); } else { @@ -416,7 +545,7 @@ else version(linux) { record_error_(); } - delete s_modules[name]; + s_modules.remove(name); delete mi; } @@ -474,6 +603,261 @@ else version(linux) return mi.m_name; } } +else version(darwin) +{ + private class ExeModuleInfo + { + public: + int m_cRefs; + HModule_ m_hmod; + char[] m_name; + + this(HModule_ hmod, char[] name) + { + m_cRefs = 1; + m_hmod = hmod; + m_name = name; + } + }; + + private void record_error_() + { + NSLinkEditErrors error; + int errno; + char *fileName; + char *err = null; + + NSLinkEditError(&error, &errno, &fileName, &err); + printf("NSLinkEditError: %d %d - %s %s\n", cast(uint) error, errno, fileName, err); + + s_lastError = (err == null) ? "" : err[0 .. std.string.strlen(err)]; + } + + private int s_init; + private ExeModuleInfo [char[]] s_modules; + private char[] s_lastError; // This is NOT thread-specific + + private int ExeModule_Init_() + { + if(1 == ++s_init) + { + return 0; + } + + return 1; + } + + private void ExeModule_Uninit_() + { + if(0 == --s_init) + { + } + } + + private HXModule ExeModule_Load_(in char[] moduleName) + in + { + assert(null !is moduleName); + } + body + { + ExeModuleInfo *p_mi = moduleName in s_modules; + + if(p_mi != null) + { + return (++(*p_mi).m_cRefs, cast(HXModule)*p_mi); + } + else + { + NSModule handle = null; + NSObjectFileImage fileImage = null; + char * filename = toStringz(moduleName); + // printf("DEBUG Trying to load: %s\n", filename); + + NSObjectFileImageReturnCode returnCode = + NSCreateObjectFileImageFromFile(filename, &fileImage); + if(returnCode == NSObjectFileImageSuccess) + { + handle = NSLinkModule(fileImage,filename, + NSLINKMODULE_OPTION_RETURN_ON_ERROR | + NSLINKMODULE_OPTION_PRIVATE | + NSLINKMODULE_OPTION_BINDNOW); + NSDestroyObjectFileImage(fileImage); + } + else if(returnCode == NSObjectFileImageInappropriateFile) + { + NSDestroyObjectFileImage(fileImage); + /* Could be dynamic library rather than a bundle */ + handle = cast(NSModule) NSAddImage(filename, + NSADDIMAGE_OPTION_RETURN_ON_ERROR); + } + else + { + // printf("Failed: %d\n", returnCode); + s_lastError = "NSCreateObjectFileImageFromFile failed"; + return null; + } + + if (handle == null) + { + record_error_(); + + return null; + } + else + { + ExeModuleInfo mi = new ExeModuleInfo(handle, moduleName); + + s_modules[moduleName] = mi; + + return cast(HXModule)mi; + } + } + } + + private HXModule ExeModule_AddRef_(in HXModule hModule) + in + { + assert(null !is hModule); + + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + assert(0 < mi.m_cRefs); + assert(null !is mi.m_hmod); + assert(null !is mi.m_name); + assert(null !is s_modules[mi.m_name]); + assert(mi is s_modules[mi.m_name]); + } + body + { + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + if(null !is mi) + { + return (++mi.m_cRefs, hModule); + } + else + { + return null; + } + } + + private void ExeModule_Release_(inout HXModule hModule) + in + { + assert(null !is hModule); + + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + assert(0 < mi.m_cRefs); + assert(null !is mi.m_hmod); + assert(null !is mi.m_name); + assert(null !is s_modules[mi.m_name]); + assert(mi is s_modules[mi.m_name]); + } + body + { + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + if(0 == --mi.m_cRefs) + { + char[] name = mi.m_name; + uint magic; + + magic = (* cast(mach_header *) mi.m_hmod).magic; + if ( magic == MH_MAGIC || magic == MH_CIGAM || + magic == MH_MAGIC_64 || magic == MH_CIGAM_64) + { + // Can not unlink dynamic libraries on Darwin + } + else if (NSUnLinkModule(mi.m_hmod, 0) == FALSE) + { + // printf("DEBUG: Could not unlink module %.*s\n", name); + } + s_modules.remove(name); + delete mi; + } + + hModule = null; + } + + private void *ExeModule_GetSymbol_(inout HXModule hModule, in char[] symbolName) + in + { + assert(null !is hModule); + + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + assert(0 < mi.m_cRefs); + assert(null !is mi.m_hmod); + assert(null !is mi.m_name); + assert(null !is s_modules[mi.m_name]); + assert(mi is s_modules[mi.m_name]); + } + body + { + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + NSModule handle = mi.m_hmod; + uint magic = (* cast(mach_header *) handle).magic; + char *name = ("_" ~ symbolName ~ "\0").ptr; + NSSymbol symbol = null; + + if ( (handle == cast(NSModule) -1) && + NSIsSymbolNameDefined(name)) + /* Global context, use NSLookupAndBindSymbol */ + symbol = NSLookupAndBindSymbol(name); + else if ( ( magic == MH_MAGIC || magic == MH_CIGAM || + magic == MH_MAGIC_64 || magic == MH_CIGAM_64 + ) && + NSIsSymbolNameDefinedInImage(cast(mach_header *) handle, name)) + symbol = NSLookupSymbolInImage(cast(mach_header *) handle, name, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + else + symbol = NSLookupSymbolInModule(handle, name); + + if (symbol == null) + { + // printf("DEBUG: Symbol not found: %s\n", name); + return null; + } + + void *address = NSAddressOfSymbol(symbol); + + if(address == null) + { + record_error_(); + } + + return address; + } + + private char[] ExeModule_Error_() + { + return s_lastError; + } + + private char[] ExeModule_GetPath_(HXModule hModule) + in + { + assert(null !is hModule); + + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + assert(0 < mi.m_cRefs); + assert(null !is mi.m_hmod); + assert(null !is mi.m_name); + assert(null !is s_modules[mi.m_name]); + assert(mi is s_modules[mi.m_name]); + } + body + { + ExeModuleInfo mi = cast(ExeModuleInfo)hModule; + + return mi.m_name; + } +} else { const int platform_not_discriminated = 0; @@ -527,10 +911,14 @@ public: if (m_hModule == null) throw new ExeModuleException(GetLastError()); } - else version (linux) + else version (dlopen) { m_hModule = ExeModule_AddRef(hModule); } + else version (darwin) + { + m_hModule = ExeModule_AddRef(hModule); + } else static assert(0); } @@ -549,12 +937,18 @@ public: if (null is m_hModule) throw new ExeModuleException(GetLastError()); } - else version (linux) + else version (dlopen) { m_hModule = ExeModule_Load(moduleName); if (null is m_hModule) throw new ExeModuleException(ExeModule_Error()); } + else version (darwin) + { + m_hModule = ExeModule_Load(moduleName); + if (null is m_hModule) + throw new ExeModuleException(ExeModule_Error()); + } else { static assert(0); // unsupported system @@ -582,10 +976,14 @@ public: if(!FreeLibrary(cast(HModule_)m_hModule)) throw new ExeModuleException(GetLastError()); } - else version (linux) + else version (dlopen) { ExeModule_Release(m_hModule); } + else version (darwin) + { + ExeModule_Release(m_hModule); + } else static assert(0); } @@ -610,7 +1008,7 @@ public: throw new ExeModuleException(GetLastError()); } } - else version (linux) + else version (dlopen) { void *symbol = ExeModule_GetSymbol(m_hModule, symbolName); @@ -619,6 +1017,15 @@ public: throw new ExeModuleException(ExeModule_Error()); } } + else version (darwin) + { + void *symbol = ExeModule_GetSymbol(m_hModule, symbolName); + + if(null is symbol) + { + throw new ExeModuleException(ExeModule_Error()); + } + } else { static assert(0); @@ -666,10 +1073,14 @@ public: return szFileName[0 .. cch].dup; } - else version (linux) + else version (dlopen) { return ExeModule_GetPath_(m_hModule); } + else version (darwin) + { + return ExeModule_GetPath_(m_hModule); + } else static assert(0); } @@ -698,7 +1109,8 @@ version(TestMain) { auto ExeModule xmod = new ExeModule(moduleName); - printf("\"%.*s\" is loaded\n", moduleName); + printf("\"%.*s\" is loaded\n", cast(int) moduleName.length, + moduleName.ptr); void *symbol = xmod.getSymbol(symbolName); diff -uNrp dmd-1.007/src/phobos/std/math2.d gdc-0.23/d/phobos/std/math2.d --- dmd-1.007/src/phobos/std/math2.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/math2.d 2007-02-24 02:40:20.000000000 +0100 @@ -10,9 +10,19 @@ * the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. */ + +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ module std.math2; private import std.math, std.string, std.c.stdlib, std.c.stdio; +version(GNU) +{ + private import gcc.config; +} //debug=math2; @@ -80,17 +90,30 @@ private ushort fp_cw_chop = 7999; * Integer part */ -real trunc(real n) +version (GNU) { - ushort cw; - asm - { - fstcw cw; - fldcw fp_cw_chop; - fld n; - frndint; - fldcw cw; - } + version (GNU_Need_trunc) { + real trunc(real n) { + return n >= 0 ? std.math.floor(n) : std.math.ceil(n); + } + } else { + alias gcc.config.truncl trunc; + } +} +else +{ + real trunc(real n) + { + ushort cw; + asm + { + fstcw cw; + fldcw fp_cw_chop; + fld n; + frndint; + fldcw cw; + } + } } unittest @@ -241,7 +264,7 @@ unittest real avg(real[] n) { real result = 0; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) result += n[i]; return result / n.length; } @@ -273,7 +296,7 @@ unittest long sum(long[] n) { long result = 0; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) result += n[i]; return result; } @@ -287,7 +310,7 @@ unittest real sum(real[] n) { real result = 0; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) result += n[i]; return result; } @@ -305,7 +328,7 @@ unittest int min(int[] n) { int result = int.max; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) if (n[i] < result) result = n[i]; return result; @@ -320,7 +343,7 @@ unittest long min(long[] n) { long result = long.max; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) if (n[i] < result) result = n[i]; return result; @@ -335,7 +358,7 @@ unittest real min(real[] n) { real result = real.max; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) { if (n[i] < result) result = n[i]; @@ -386,7 +409,7 @@ unittest int max(int[] n) { int result = int.min; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) if (n[i] > result) result = n[i]; return result; @@ -401,7 +424,7 @@ unittest long max(long[] n) { long result = long.min; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) if (n[i] > result) result = n[i]; return result; @@ -416,7 +439,7 @@ unittest real max(real[] n) { real result = real.min; - for (uint i = 0; i < n.length; i++) + for (size_t i = 0; i < n.length; i++) if (n[i] > result) result = n[i]; return result; @@ -464,7 +487,7 @@ unittest real acot(real x) { - return tan(1.0 / x); + return std.math.tan(1.0 / x); } unittest @@ -519,6 +542,10 @@ unittest real cot(real x) { + version(GNU) { + // %% is the asm below missing fld1? + return 1/gcc.config.tanl(x); + } else { asm { fld x; @@ -526,6 +553,7 @@ real cot(real x) fdivrp; fwait; } + } } unittest @@ -539,6 +567,9 @@ unittest real sec(real x) { + version(GNU) { + return 1/gcc.config.cosl(x); + } else { asm { fld x; @@ -547,6 +578,7 @@ real sec(real x) fdivrp; fwait; } + } } @@ -556,6 +588,10 @@ real sec(real x) real cosec(real x) { + version(GNU) { + // %% is the asm below missing fld1? + return 1/gcc.config.sinl(x); + } else { asm { fld x; @@ -564,6 +600,7 @@ real cosec(real x) fdivrp; fwait; } + } } /********************************************* @@ -573,6 +610,9 @@ real cosec(real x) /+ real frexp(real x, out int exponent) { + version (GNU) { + return gcc.config.frexpl(x, & exponent); + } else { asm { fld x; @@ -595,13 +635,14 @@ real frexp(real x, out int exponent) done: fwait; } + } } unittest { int exponent; real mantissa = frexp(123.456, exponent); - assert(feq(mantissa * pow(2.0L, cast(real)exponent), 123.456)); + assert(feq(mantissa * std.math.pow(2.0L, cast(real)exponent), 123.456)); } +/ @@ -611,12 +652,19 @@ unittest real coth(real x) { - return 1 / tanh(x); + return 1 / std.math.tanh(x); } unittest { - assert(feq(coth(1), cosh(1) / sinh(1))); + real r1 = coth(1); + real r2 = std.math.sinh(1); + real r3 = std.math.tanh(1); + real r4 = coth(1); + printf("%0.5Lg %0.5Lg %0.5Lg %0.5Lg\n", r1, r2, r3, r4); + printf("%0.5g %0.5g %0.5g %0.5g\n", + coth(1), std.math.sinh(1), std.math.tanh(1), coth(1)); + assert(feq(coth(1), std.math.cosh(1) / std.math.sinh(1))); } /************************************* @@ -625,7 +673,7 @@ unittest real sech(real x) { - return 1 / cosh(x); + return 1 / std.math.cosh(x); } /************************************* @@ -634,7 +682,7 @@ real sech(real x) real cosech(real x) { - return 1 / sinh(x); + return 1 / std.math.sinh(x); } /************************************* @@ -655,7 +703,7 @@ real acosh(real x) unittest { assert(acosh(0.5) == 0); - assert(feq(acosh(cosh(3)), 3)); + assert(feq(acosh(std.math.cosh(3)), 3)); } +/ @@ -676,15 +724,15 @@ real asinh(real x) { real z = x * x; return x > 0 ? - log1p(x + z / (1.0 + std.math.sqrt(1.0 + z))) : - -log1p(-x + z / (1.0 + std.math.sqrt(1.0 + z))); + std.math.log1p(x + z / (1.0 + std.math.sqrt(1.0 + z))) : + -std.math.log1p(-x + z / (1.0 + std.math.sqrt(1.0 + z))); } } unittest { assert(asinh(0) == 0); - assert(feq(asinh(sinh(3)), 3)); + assert(feq(asinh(std.math.sinh(3)), 3)); } +/ @@ -704,15 +752,15 @@ real atanh(real x) return -real.max; else return x > 0 ? - 0.5 * log1p((2.0 * x) / (1.0 - x)) : - -0.5 * log1p((-2.0 * x) / (1.0 + x)); + 0.5 * std.math.log1p((2.0 * x) / (1.0 - x)) : + -0.5 * std.math.log1p((-2.0 * x) / (1.0 + x)); } } unittest { assert(atanh(0) == 0); - assert(feq(atanh(tanh(0.5)), 0.5)); + assert(feq(atanh(std.math.tanh(0.5)), 0.5)); } +/ @@ -757,7 +805,7 @@ real atof(char[] s) if (!s.length) return real.nan; real result = 0; - uint i = 0; + size_t i = 0; while (s[i] == '\t' || s[i] == ' ') if (++i >= s.length) return real.nan; @@ -881,7 +929,7 @@ real atof(char[] s) } if (eneg) e = -e; - result *= pow(hex ? 2.0L : 10.0L, cast(real)e); + result *= std.math.pow(hex ? 2.0L : 10.0L, cast(real)e); done: return neg ? -result : result; } diff -uNrp dmd-1.007/src/phobos/std/math.d gdc-0.23/d/phobos/std/math.d --- dmd-1.007/src/phobos/std/math.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/math.d 2007-02-24 02:34:01.000000000 +0100 @@ -51,6 +51,12 @@ * */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2005 +*/ + module std.math; @@ -61,6 +67,15 @@ private import std.c.stdio; private import std.string; private import std.c.math; +version (GNU) +{ + private import gcc.config; + + // Some functions are missing from msvcrt... + version (Windows) + version = GNU_msvcrt_math; +} + class NotImplemented : Error { this(char[] msg) @@ -145,7 +160,7 @@ unittest assert(abs(71.6Li) == 71.6L); assert(abs(-56) == 56); assert(abs(2321312L) == 2321312L); - assert(abs(-1+1i) == sqrt(2.0)); + assert(mfeq(abs(-1+1i), sqrt(2.0), .0000001)); } /*********************************** @@ -186,6 +201,7 @@ unittest * Results are undefined if |x| >= $(POWER 2,64). */ +version(GNU) alias gcc.config.cosl cos; else real cos(real x); /* intrinsic */ /*********************************** @@ -201,6 +217,7 @@ real cos(real x); /* intrinsic */ * Results are undefined if |x| >= $(POWER 2,64). */ +version(GNU) alias gcc.config.sinl sin; else real sin(real x); /* intrinsic */ @@ -215,6 +232,7 @@ real sin(real x); /* intrinsic */ * ) */ +version(GNU) alias gcc.config.tanl tan; else real tan(real x) { asm @@ -290,6 +308,12 @@ unittest for (i = 0; i < vals.length; i++) { + /* Library tanl does not have the same limit as the fptan + instruction. */ + version (GNU) + if (i == vals.length - 1) + continue; + real x = vals[i][0]; real r = vals[i][1]; real t = tan(x); @@ -490,7 +514,7 @@ unittest real atanh(real x) { // log( (1+x)/(1-x) ) == log ( 1 + (2*x)/(1-x) ) - return 0.5 * log1p( 2 * x / (1 - x) ); + return copysign(0.5 * log1p( 2 * x / (1 - x) ), x); } unittest @@ -529,8 +553,11 @@ extern (C) real rndtonl(real x); * ) */ +version(GNU) float sqrt(float x) { return gcc.config.sqrtf(x); } else float sqrt(float x); /* intrinsic */ +version(GNU) double sqrt(double x) { return gcc.config.sqrt(x); } else /// ditto double sqrt(double x); /* intrinsic */ /// ditto +version(GNU) real sqrt(real x) { return gcc.config.sqrtl(x); } else /// ditto real sqrt(real x); /* intrinsic */ /// ditto creal sqrt(creal z) @@ -593,6 +620,7 @@ real exp(real x) { return std.c.math.ex * -∞ +0.0 * ) */ +version (GNU_Need_exp2_log2) real exp2(real x) { return std.c.math.powl(2, x); } else real exp2(real x) { return std.c.math.exp2l(x); } /****************************************** @@ -610,6 +638,7 @@ real exp2(real x) { return std.c.math.e * ) */ +version (GNU_msvcrt_math) { /* nothing */ } else real expm1(real x) { return std.c.math.expm1l(x); } @@ -634,6 +663,8 @@ real expm1(real x) { return std.c.math. real frexp(real value, out int exp) { + version (X86) { + ushort* vu = cast(ushort*)&value; long* vl = cast(long*)&value; uint ex; @@ -681,6 +712,23 @@ real frexp(real value, out int exp) vu[4] = cast(ushort)((0x8000 & vu[4]) | 0x3FFE); } return value; + + } + else version(GNU) + { + switch (gcc.config.fpclassify(value)) { + case gcc.config.FP_NORMAL: + case gcc.config.FP_ZERO: + case gcc.config.FP_SUBNORMAL: // I can only hope the library frexp normalizes the value... + return gcc.config.frexpl(value, & exp); + case gcc.config.FP_INFINITE: + exp = gcc.config.signbit(value) ? int.min : int.max; + return value; + case gcc.config.FP_NAN: + exp = int.min; + return value; + } + } } @@ -711,6 +759,8 @@ unittest for (i = 0; i < vals.length; i++) { + if (i >= 6 && i <= 8 && real.min_exp > -16381) + continue; real x = vals[i][0]; real e = vals[i][1]; int exp = cast(int)vals[i][2]; @@ -748,6 +798,7 @@ alias std.c.math.FP_ILOGBNAN FP_ILOGBNAN * References: frexp */ +version(GNU) alias gcc.config.ldexpl ldexp; else real ldexp(real n, int exp); /* intrinsic */ /************************************** @@ -804,6 +855,7 @@ real log1p(real x) { return std.c.math. * +∞ +∞ no no * ) */ +version (GNU_Need_exp2_log2) real log2(real x) { return std.c.math.logl(x) / LOG2; } else real log2(real x) { return std.c.math.log2l(x); } /***************************************** @@ -882,6 +934,7 @@ real cbrt(real x) { return std.c.math.c * ±∞ +∞ * ) */ +version (GNU) alias gcc.config.fabsl fabs; else real fabs(real x); /* intrinsic */ @@ -993,6 +1046,9 @@ unittest for (i = 0; i < vals.length; i++) { + if (i == 5 && real.max_exp < 16383) + continue; + real x = vals[i][0]; real y = vals[i][1]; real z = vals[i][2]; @@ -1010,6 +1066,7 @@ unittest * * error function */ +version (GNU_msvcrt_math) { /* nothing */ } else real erf(real x) { return std.c.math.erfl(x); } /********************************** @@ -1017,6 +1074,7 @@ real erf(real x) { return std.c.math.er * * complementary error function */ +version (GNU_msvcrt_math) { /* nothing */ } else real erfc(real x) { return std.c.math.erfcl(x); } /*********************************** @@ -1067,6 +1125,12 @@ real lgamma(real x) * $(LINK http://www.netlib.org/cephes/ldoubdoc.html#gamma) */ /* Documentation prepared by Don Clugston */ +version (GNU_Need_tgamma) +{ + private import etc.gamma; + alias etc.gamma.tgamma tgamma; +} +else real tgamma(real x) { return std.c.math.tgammal(x); @@ -1093,6 +1157,11 @@ real floor(real x) { return std.c.math. * Unlike the rint functions, nearbyint does not raise the * FE_INEXACT exception. */ +version (GNU_Need_nearbyint) +{ + // not implemented yet +} +else real nearbyint(real x) { return std.c.math.nearbyintl(x); } /********************************** @@ -1103,6 +1172,7 @@ real nearbyint(real x) { return std.c.ma * nearbyint performs * the same operation, but does not set the FE_INEXACT exception. */ +version(GNU) alias gcc.config.rintl rint; else real rint(real x); /* intrinsic */ /*************************************** @@ -1122,6 +1192,38 @@ long lrint(real x) * If the fractional part of x is exactly 0.5, the return value is rounded to * the even integer. */ +version (GNU_Need_round) +{ + real round(real x) + { + real y = floor(x); + real r = x - y; + if (r > 0.5) + return y + 1; + else if (r == 0.5) + { + r = y - 2.0 * floor(0.5 * y); + if (r == 1.0) + return y + 1; + } + return y; + } + unittest { + real r; + assert(isnan(round(real.nan))); + r = round(real.infinity); + assert(isinf(r) && r > 0); + r = round(-real.infinity); + assert(isinf(r) && r < 0); + assert(round(3.4) == 3); + assert(round(3.5) == 4); + assert(round(3.6) == 4); + assert(round(-3.4) == -3); + assert(round(-3.5) == -4); + assert(round(-3.6) == -4); + } +} +else real round(real x) { return std.c.math.roundl(x); } /********************************************** @@ -1143,6 +1245,24 @@ long lround(real x) * * This is also known as "chop" rounding. */ +version (GNU_Need_trunc) +{ + real trunc(real n) { return n >= 0 ? std.math.floor(n) : std.math.ceil(n); } + unittest + { + real r; + r = trunc(real.infinity); + assert(isinf(r) && r > 0); + r = trunc(-real.infinity); + assert(isinf(r) && r < 0); + assert(isnan(trunc(real.nan))); + assert(trunc(3.3) == 3); + assert(trunc(3.6) == 3); + assert(trunc(-3.3) == -3); + assert(trunc(-3.6) == -3); + } +} +else real trunc(real x) { return std.c.math.truncl(x); } /**************************************************** @@ -1179,6 +1299,7 @@ real remquo(real x, real y, out int n) / * Returns !=0 if e is a NaN. */ +version (X86) int isnan(real e) { ushort* pe = cast(ushort *)&e; @@ -1187,6 +1308,8 @@ int isnan(real e) return (pe[4] & 0x7FFF) == 0x7FFF && *ps & 0x7FFFFFFFFFFFFFFF; } +else version(GNU) + alias gcc.config.isnan isnan; unittest { @@ -1202,12 +1325,15 @@ unittest * Returns !=0 if e is finite. */ +version (X86) int isfinite(real e) { ushort* pe = cast(ushort *)&e; return (pe[4] & 0x7FFF) != 0x7FFF; } +else version(GNU) + alias gcc.config.isfinite isfinite; unittest { @@ -1225,6 +1351,7 @@ unittest * be converted to normal reals. */ +version (X86) int isnormal(float x) { uint *p = cast(uint *)&x; @@ -1234,9 +1361,12 @@ int isnormal(float x) //printf("e = x%x, *p = x%x\n", e, *p); return e && e != 0x7F800000; } +else version(GNU) + alias gcc.config.isnormal isnormal; /// ditto +version (X86) int isnormal(double d) { uint *p = cast(uint *)&d; @@ -1245,9 +1375,11 @@ int isnormal(double d) e = p[1] & 0x7FF00000; return e && e != 0x7FF00000; } +else version(GNU) { /* nothing, handled above */ } /// ditto +version (X86) int isnormal(real e) { ushort* pe = cast(ushort *)&e; @@ -1255,6 +1387,7 @@ int isnormal(real e) return (pe[4] & 0x7FFF) != 0x7FFF && *ps < 0; } +else version(GNU) { /* nothing, handled above */ } unittest { @@ -1276,6 +1409,7 @@ unittest * be converted to normal reals. */ +version (X86) int issubnormal(float f) { uint *p = cast(uint *)&f; @@ -1283,6 +1417,8 @@ int issubnormal(float f) //printf("*p = x%x\n", *p); return (*p & 0x7F800000) == 0 && *p & 0x007FFFFF; } +else version(GNU) + alias gcc.config.issubnormal issubnormal; unittest { @@ -1294,12 +1430,14 @@ unittest /// ditto +version (X86) int issubnormal(double d) { uint *p = cast(uint *)&d; return (p[1] & 0x7FF00000) == 0 && (p[0] || p[1] & 0x000FFFFF); } +else version(GNU) { /* nothing, handled above */ } unittest { @@ -1311,6 +1449,7 @@ unittest /// ditto +version (X86) int issubnormal(real e) { ushort* pe = cast(ushort *)&e; @@ -1318,6 +1457,7 @@ int issubnormal(real e) return (pe[4] & 0x7FFF) == 0 && *ps > 0; } +else version(GNU) { /* nothing, handled above */ } unittest { @@ -1331,6 +1471,7 @@ unittest * Return !=0 if e is ±∞. */ +version (X86) int isinf(real e) { ushort* pe = cast(ushort *)&e; @@ -1339,7 +1480,9 @@ int isinf(real e) return (pe[4] & 0x7FFF) == 0x7FFF && *ps == 0x8000000000000000; } - +else version (GNU) + alias gcc.config.isinf isinf; + unittest { assert(isinf(float.infinity)); @@ -1354,6 +1497,7 @@ unittest * Return 1 if sign bit of e is set, 0 if not. */ +version (X86) int signbit(real e) { ubyte* pe = cast(ubyte *)&e; @@ -1361,6 +1505,8 @@ int signbit(real e) //printf("e = %Lg\n", e); return (pe[9] & 0x80) != 0; } +else version (GNU) + alias gcc.config.signbit signbit; unittest { @@ -1377,6 +1523,7 @@ unittest * Return a value composed of to with from's sign bit. */ +version (X86) real copysign(real to, real from) { ubyte* pto = cast(ubyte *)&to; @@ -1387,6 +1534,8 @@ real copysign(real to, real from) return to; } +else version (GNU) + alias gcc.config.copysignl copysign; unittest { @@ -1411,6 +1560,9 @@ unittest /****************************************** * Creates a quiet NAN with the information from tagp[] embedded in it. */ +version (GNU_Need_nan) +real nan(char[] tagp) { return real.nan; } // could implement with strtod, but need test if THAT works first +else real nan(char[] tagp) { return std.c.math.nanl(toStringz(tagp)); } /****************************************** @@ -1554,7 +1706,8 @@ real pow(real x, int n) real pow(real x, real y) { - version (linux) // C pow() often does not handle special values correctly + //version (linux) // C pow() often does not handle special values correctly + version (GNU) // ...assume the same for all GCC targets { if (isnan(y)) return y; @@ -1689,6 +1842,10 @@ bool isNegZero(real x) return (x == 0) && signbit(x); } +version (X86) +{ +// These routines assume Intel 80-bit floating point format + /************************************** * To what precision is x equal to y? * @@ -1788,7 +1945,22 @@ unittest assert(feqrel(real.max,-real.max)==0); } +} // version(X86) +else +{ + // not implemented +} + + +// The space allocated for real varies across targets. +version (D_InlineAsm_X86) +{ + static if (real.sizeof == 10) + { version = poly_10; } + else static if (real.sizeof == 12) + { version = poly_12; } +} /*********************************** * Evaluate polynomial A(x) = a0 + a1x + a2x² + a3x³ ... * @@ -1803,68 +1975,65 @@ in } body { - version (D_InlineAsm_X86) + version (poly_10) { - version (Windows) + asm // assembler by W. Bright { - asm // assembler by W. Bright - { - // EDX = (A.length - 1) * real.sizeof - mov ECX,A[EBP] ; // ECX = A.length - dec ECX ; - lea EDX,[ECX][ECX*8] ; - add EDX,ECX ; - add EDX,A+4[EBP] ; - fld real ptr [EDX] ; // ST0 = coeff[ECX] - jecxz return_ST ; - fld x[EBP] ; // ST0 = x - fxch ST(1) ; // ST1 = x, ST0 = r - align 4 ; - L2: fmul ST,ST(1) ; // r *= x - fld real ptr -10[EDX] ; - sub EDX,10 ; // deg-- - faddp ST(1),ST ; - dec ECX ; - jne L2 ; - fxch ST(1) ; // ST1 = r, ST0 = x - fstp ST(0) ; // dump x - align 4 ; - return_ST: ; - ; - } + // EDX = (A.length - 1) * real.sizeof + mov ECX,A[EBP] ; // ECX = A.length + dec ECX ; + lea EDX,[ECX][ECX*8] ; + add EDX,ECX ; + add EDX,A+4[EBP] ; + fld real ptr [EDX] ; // ST0 = coeff[ECX] + jecxz return_ST ; + fld x[EBP] ; // ST0 = x + fxch ST(1) ; // ST1 = x, ST0 = r + align 4 ; + L2: fmul ST,ST(1) ; // r *= x + fld real ptr -10[EDX] ; + sub EDX,10 ; // deg-- + faddp ST(1),ST ; + dec ECX ; + jne L2 ; + fxch ST(1) ; // ST1 = r, ST0 = x + fstp ST(0) ; // dump x + align 4 ; + return_ST: ; + ; } - else + } + else version (poly_12) + { + asm // above code with modifications for GCC { - asm // assembler by W. Bright - { - // EDX = (A.length - 1) * real.sizeof - mov ECX,A[EBP] ; // ECX = A.length - dec ECX ; - lea EDX,[ECX*8] ; - lea EDX,[EDX][ECX*4] ; - add EDX,A+4[EBP] ; - fld real ptr [EDX] ; // ST0 = coeff[ECX] - jecxz return_ST ; - fld x[EBP] ; // ST0 = x - fxch ST(1) ; // ST1 = x, ST0 = r - align 4 ; - L2: fmul ST,ST(1) ; // r *= x - fld real ptr -12[EDX] ; - sub EDX,12 ; // deg-- - faddp ST(1),ST ; - dec ECX ; - jne L2 ; - fxch ST(1) ; // ST1 = r, ST0 = x - fstp ST(0) ; // dump x - align 4 ; - return_ST: ; - ; - } + // EDX = (A.length - 1) * real.sizeof + mov ECX,A[EBP] ; // ECX = A.length + dec ECX ; + lea EDX,[ECX][ECX*2] ; + lea EDX,[EDX*4] ; + add EDX,A+4[EBP] ; + fld real ptr [EDX] ; // ST0 = coeff[ECX] + jecxz return_ST ; + fld x ; // ST0 = x + fxch ST(1) ; // ST1 = x, ST0 = r + align 4 ; + L2: fmul ST,ST(1) ; // r *= x + fld real ptr -12[EDX] ; + sub EDX,12 ; // deg-- + faddp ST(1),ST ; + dec ECX ; + jne L2 ; + fxch ST(1) ; // ST1 = r, ST0 = x + fstp ST(0) ; // dump x + align 4 ; + return_ST: ; + ; } } else { - int i = A.length - 1; + ptrdiff_t i = A.length - 1; real r = A[i]; while (--i >= 0) { diff -uNrp dmd-1.007/src/phobos/std/md5.d gdc-0.23/d/phobos/std/md5.d --- dmd-1.007/src/phobos/std/md5.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/md5.d 2007-02-24 03:38:20.000000000 +0100 @@ -89,12 +89,22 @@ These notices must be retained in any co documentation and/or software. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.md5; //debug=md5; // uncomment to turn on debugging printf's import std.string; +version(D_InlineAsm) + version(X86) + version = Asm86; + /*************************************** * Computes MD5 digest of array of data. */ @@ -170,14 +180,28 @@ struct MD5_CTX */ static uint ROTATE_LEFT(uint x, uint n) { - version (X86) + version (Asm86) { - asm - { naked ; - mov ECX,EAX ; - mov EAX,4[ESP] ; - rol EAX,CL ; - ret 4 ; + version (GNU) + { + asm + { + naked ; + mov ECX, n ; + mov EAX, x ; + rol EAX, CL ; + ret ; + } + } + else + { + asm + { naked ; + mov ECX,EAX ; + mov EAX,4[ESP] ; + rol EAX,CL ; + ret 4 ; + } } } else @@ -231,8 +255,9 @@ struct MD5_CTX */ void update(void[] input) { - uint i, index, partLen; - uint inputLen = input.length; + uint index, partLen; + size_t i; + size_t inputLen = input.length; /* Compute number of bytes mod 64 */ index = (cast(uint)count >> 3) & (64 - 1); diff -uNrp dmd-1.007/src/phobos/std/mmfile.d gdc-0.23/d/phobos/std/mmfile.d --- dmd-1.007/src/phobos/std/mmfile.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/mmfile.d 2006-12-09 17:40:24.000000000 +0100 @@ -10,6 +10,12 @@ * WIKI=Phobos/StdMmfile */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.mmfile; private import std.file; @@ -31,14 +37,30 @@ version (Win32) { // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getversion.asp dwVersion = GetVersion(); } + + private const bool Have_MMFile = true; // private for now... } -else version (linux) +else version (Unix) { - private import std.c.linux.linux; + version (GNU_Unix_Have_MMap) + { + private import std.c.unix.unix; + alias std.c.unix.unix unix; + + version = unix_mm; + private const bool Have_MMFile = true; + } + else + { + private const bool Have_MMFile = false; + } + } else { - static assert(0); + private const bool Have_MMFile = false; + // Can't simply fail because std.stream imports this module. + //static assert(0); } /** @@ -208,7 +230,7 @@ class MmFile errNo(); } - else version (linux) + else version (unix_mm) { char* namez = toStringz(filename); void* p; @@ -254,26 +276,26 @@ class MmFile { struct_stat statbuf; - fd = std.c.linux.linux.open(namez, oflag, fmode); + fd = unix.open(namez, oflag, fmode); if (fd == -1) { // printf("\topen error, errno = %d\n",getErrno()); errNo(); } - if (std.c.linux.linux.fstat(fd, &statbuf)) + if (unix.fstat(fd, &statbuf)) { //printf("\tfstat error, errno = %d\n",getErrno()); - std.c.linux.linux.close(fd); + unix.close(fd); errNo(); } if (prot & PROT_WRITE && size > statbuf.st_size) { // Need to make the file size bytes big - std.c.linux.linux.lseek(fd, cast(int)(size - 1), SEEK_SET); + unix.lseek(fd, cast(off_t)(size - 1), SEEK_SET); char c = 0; - std.c.linux.linux.write(fd, &c, 1); + unix.write(fd, &c, 1); } else if (prot & PROT_READ && size == 0) size = statbuf.st_size; @@ -288,12 +310,16 @@ class MmFile p = mmap(address, initial_map, prot, flags, fd, 0); if (p == MAP_FAILED) { if (fd != -1) - std.c.linux.linux.close(fd); + unix.close(fd); errNo(); } data = p[0 .. initial_map]; } + else static if (! Have_MMFile) + { + throw new FileException("This system does support memory mapped files"); + } else { static assert(0); @@ -317,12 +343,15 @@ class MmFile errNo(); hFile = INVALID_HANDLE_VALUE; } - else version (linux) + else version (unix_mm) { - if (fd != -1 && std.c.linux.linux.close(fd) == -1) + if (fd != -1 && unix.close(fd) == -1) errNo(); fd = -1; } + else static if (! Have_MMFile) + { + } else { static assert(0); @@ -339,7 +368,7 @@ class MmFile { FlushViewOfFile(data.ptr, data.length); } - else version (linux) + else version (unix_mm) { int i; @@ -347,6 +376,9 @@ class MmFile if (i != 0) errNo(); } + else static if (! Have_MMFile) + { + } else { static assert(0); @@ -434,7 +466,7 @@ class MmFile if (data && UnmapViewOfFile(data.ptr) == FALSE && (dwVersion & 0x80000000) == 0) errNo(); - } else { + } else version (unix_mm) { if (data && munmap(cast(void*)data, data.length) != 0) errNo(); } @@ -452,8 +484,8 @@ class MmFile uint hi = cast(uint)(start>>32); p = MapViewOfFileEx(hFileMap, dwDesiredAccess, hi, cast(uint)start, len, address); if (!p) errNo(); - } else { - p = mmap(address, len, prot, flags, fd, cast(int)start); + } else version (unix_mm) { + p = mmap(address, len, prot, flags, fd, cast(off_t)start); if (p == MAP_FAILED) errNo(); } data = p[0 .. len]; @@ -513,13 +545,16 @@ class MmFile HANDLE hFileMap = null; uint dwDesiredAccess; } - else version (linux) + else version (unix_mm) { int fd; int prot; int flags; int fmode; } + else static if (! Have_MMFile) + { + } else { static assert(0); @@ -532,10 +567,14 @@ class MmFile { throw new FileException(filename, GetLastError()); } - else version (linux) + else version (Unix) { throw new FileException(filename, getErrno()); } + else static if (! Have_MMFile) + { + throw new FileException(filename, "MMFile unsupported"); + } else { static assert(0); @@ -544,6 +583,8 @@ class MmFile } unittest { + static if (Have_MMFile) + { const size_t K = 1024; size_t win = 64*K; // assume the page size is 64K version(Win32) { @@ -552,7 +593,7 @@ unittest { GetSystemInfo(&sysinfo); win = sysinfo.dwAllocationGranularity; +/ - } else version (linux) { + } else version (Unix) { // getpagesize() is not defined in the unix D headers so use the guess } MmFile mf = new MmFile("testing.txt",MmFile.Mode.ReadWriteNew,100*K,null,win); @@ -572,4 +613,5 @@ unittest { assert( data2[length-1] == 'b' ); delete mf; std.file.remove("testing.txt"); + } } diff -uNrp dmd-1.007/src/phobos/std/moduleinit.d gdc-0.23/d/phobos/std/moduleinit.d --- dmd-1.007/src/phobos/std/moduleinit.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/moduleinit.d 2007-02-25 23:10:47.000000000 +0100 @@ -1,4 +1,10 @@ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.moduleinit; //debug = 1; @@ -44,8 +50,16 @@ class ModuleCtorError : Exception // linux: this gets initialized in _moduleCtor() extern (C) ModuleInfo[] _moduleinfo_array; +version (GNU) +{ + version = ModRefStyle; +} version (linux) { + version = ModRefStyle; +} +version (ModRefStyle) +{ // This linked list is created by a compiler generated function inserted // into the .ctor list by the compiler. struct ModuleReference @@ -70,9 +84,9 @@ extern (C) int _fatexit(void *); extern (C) void _moduleCtor() { debug printf("_moduleCtor()\n"); - version (linux) + version (ModRefStyle) { - int len = 0; + size_t len = 0; ModuleReference *mr; for (mr = _Dmodule_ref; mr; mr = mr.next) @@ -106,10 +120,12 @@ void _moduleCtor2(ModuleInfo[] mi, int s debug printf("\tmodule[%d] = '%p'\n", i, m); if (!m) continue; - debug printf("\tmodule[%d] = '%.*s'\n", i, m.name); + debug printf("\tmodule[%d] = '%.*s'\n", i, cast(int) m.name.length, + m.name.ptr); if (m.flags & MIctordone) continue; - debug printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m); + debug printf("\tmodule[%d] = '%.*s', m = x%x\n", i, + cast(int) m.name.length, m.name.ptr, m); if (m.ctor || m.dtor) { @@ -154,7 +170,8 @@ extern (C) void _moduleDtor() { ModuleInfo m = _moduleinfo_dtors[i]; - debug printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m); + debug printf("\tmodule[%d] = '%.*s', x%x\n", i, + cast(int) m.name.length, m.name.ptr, m); if (m.dtor) { (*m.dtor)(); @@ -177,7 +194,8 @@ extern (C) void _moduleUnitTests() if (!m) continue; - debug printf("\tmodule[%d] = '%.*s'\n", i, m.name); + debug printf("\tmodule[%d] = '%.*s'\n", i, + cast(int) m.name.length, m.name.ptr); if (m.unitTest) { (*m.unitTest)(); diff -uNrp dmd-1.007/src/phobos/std/openrj.d gdc-0.23/d/phobos/std/openrj.d --- dmd-1.007/src/phobos/std/openrj.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/openrj.d 2007-02-28 02:32:55.000000000 +0100 @@ -1067,7 +1067,8 @@ version(MainTest) try { printf( "std.openrj test:\n\tmodule: \t%.*s\n\tdescription: \t%.*s\n\tversion: \t%d.%d.%d.%d\n" - , std.openrj.VERSION.name + , cast(int) std.openrj.VERSION.name.length + , std.openrj.VERSION.name.ptr , std.openrj.VERSION.description , std.openrj.VERSION.major , std.openrj.VERSION.minor @@ -1112,14 +1113,18 @@ version(MainTest) printf(" Record\n"); foreach(Field field; record.fields) { - printf(" Field: %.*s=%.*s\n", field.name, field.value); + printf(" Field: %.*s=%.*s\n", + cast(int) field.name.length, field.name.ptr, + cast(int) field.value.length, field.value.ptr); } } printf("Fields (%u)\n", database.numFields); foreach(Field field; database) { - printf(" Field: %.*s=%.*s\n", field.name, field.value); + printf(" Field: %.*s=%.*s\n", + cast(int) field.name.length, field.name.ptr, + cast(int) field.value.length, field.value.ptr); } Record[] records = database.getRecordsContainingField("Name"); @@ -1129,13 +1134,16 @@ version(MainTest) printf(" Record\n"); foreach(Field field; record.fields) { - printf(" Field: %.*s=%.*s\n", field.name, field.value); + printf(" Field: %.*s=%.*s\n", + cast(int) field.name.length, field.name.ptr, + cast(int) field.value.length, field.value.ptr); } } } catch(Exception x) { - printf("Exception: %.*s\n", x.toString()); + char[] s = x.toString(); + printf("Exception: %.*s\n", cast(int) s.length, s.ptr); } } diff -uNrp dmd-1.007/src/phobos/std/outbuffer.d gdc-0.23/d/phobos/std/outbuffer.d --- dmd-1.007/src/phobos/std/outbuffer.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/outbuffer.d 2007-02-24 14:21:13.000000000 +0100 @@ -14,6 +14,12 @@ // Written by Walter Bright +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.outbuffer; private @@ -37,7 +43,7 @@ private class OutBuffer { ubyte data[]; - uint offset; + size_t offset; invariant { @@ -65,7 +71,7 @@ class OutBuffer */ - void reserve(uint nbytes) + void reserve(size_t nbytes) in { assert(offset + nbytes >= offset); @@ -185,7 +191,7 @@ class OutBuffer * 0-fill to align on power of 2 boundary. */ - void alignSize(uint alignsize) + void alignSize(size_t alignsize) in { assert(alignsize && (alignsize & (alignsize - 1)) == 0); @@ -195,7 +201,7 @@ class OutBuffer assert((offset & (alignsize - 1)) == 0); } body - { uint nbytes; + { size_t nbytes; nbytes = offset & (alignsize - 1); if (nbytes) @@ -219,7 +225,7 @@ class OutBuffer void align4() { if (offset & 3) - { uint nbytes = (4 - offset) & 3; + { size_t nbytes = (4 - offset) & 3; fill0(nbytes); } } @@ -245,23 +251,35 @@ class OutBuffer char* f; uint psize; int count; + va_list args_copy; f = toStringz(format); p = buffer.ptr; psize = buffer.length; for (;;) { + va_copy(args_copy, args); version(Win32) { - count = _vsnprintf(p,psize,f,args); + count = _vsnprintf(p,psize,f,args_copy); if (count != -1) break; psize *= 2; p = cast(char *) alloca(psize); // buffer too small, try again with larger size } - version(linux) + else version(GNU) { + count = vsnprintf(p,psize,f,args_copy); + if (count == -1) + psize *= 2; + else if (count >= psize) + psize = count + 1; + else + break; + p = cast(char *) alloca(psize); // buffer too small, try again with larger size + } + else version(linux) { - count = vsnprintf(p,psize,f,args); + count = vsnprintf(p,psize,f,args_copy); if (count == -1) psize *= 2; else if (count >= psize) @@ -292,10 +310,17 @@ class OutBuffer void printf(char[] format, ...) { - va_list ap; - ap = cast(va_list)&format; - ap += format.sizeof; - vprintf(format, ap); + version (GNU) + { + vprintf(format, _argptr); + } + else + { + va_list ap; + ap = cast(va_list)&format; + ap += format.sizeof; + vprintf(format, ap); + } } /***************************************** @@ -303,7 +328,7 @@ class OutBuffer * all data past index. */ - void spread(uint index, uint nbytes) + void spread(size_t index, size_t nbytes) in { assert(index <= offset); @@ -313,7 +338,7 @@ class OutBuffer reserve(nbytes); // This is an overlapping copy - should use memmove() - for (uint i = offset; i > index; ) + for (size_t i = offset; i > index; ) { --i; data[i + nbytes] = data[i]; diff -uNrp dmd-1.007/src/phobos/std/path.d gdc-0.23/d/phobos/std/path.d --- dmd-1.007/src/phobos/std/path.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/path.d 2007-02-24 15:19:05.000000000 +0100 @@ -16,6 +16,12 @@ * use the std.file module first (i.e. std.file.isDir()). */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, March 2006 +*/ + module std.path; //debug=path; // uncomment to turn on debugging printf's @@ -23,10 +29,10 @@ module std.path; private import std.string; -version(linux) +version(Unix) { private import std.c.stdlib; - private import std.c.linux.linux; + private import std.c.unix.unix; private import std.outofmemory; } @@ -48,7 +54,7 @@ version(Windows) const char[1] curdir = "."; /// String representing the current directory. const char[2] pardir = ".."; /// String representing the parent directory. } -version(linux) +else version(Unix) { /** String used to separate directory names in a path. Under * Windows this is a backslash, under Linux a slash. */ @@ -65,6 +71,10 @@ version(linux) const char[1] curdir = "."; /// String representing the current directory. const char[2] pardir = ".."; /// String representing the parent directory. } +else +{ + static assert(0); +} /***************************** * Compare file names. @@ -78,7 +88,7 @@ version(linux) version (Windows) alias std.string.cmp fcmp; -version (linux) alias std.string.icmp fcmp; +version (Unix) alias std.string.icmp fcmp; /************************** * Extracts the extension from a filename or path. @@ -112,7 +122,7 @@ version (linux) alias std.string.icmp fc char[] getExt(char[] fullname) { - uint i; + size_t i; i = fullname.length; while (i > 0) @@ -125,7 +135,7 @@ char[] getExt(char[] fullname) if (fullname[i] == ':' || fullname[i] == '\\') break; } - version(linux) + else version(Unix) { if (fullname[i] == '/') break; @@ -142,28 +152,28 @@ unittest version (Win32) result = getExt("d:\\path\\foo.bat"); - version (linux) + version (Unix) result = getExt("/path/foo.bat"); i = cmp(result, "bat"); assert(i == 0); version (Win32) result = getExt("d:\\path\\foo."); - version (linux) + version (Unix) result = getExt("d/path/foo."); i = cmp(result, ""); assert(i == 0); version (Win32) result = getExt("d:\\path\\foo"); - version (linux) + version (Unix) result = getExt("d/path/foo"); i = cmp(result, ""); assert(i == 0); version (Win32) result = getExt("d:\\path.bar\\foo"); - version (linux) + version (Unix) result = getExt("/path.bar/foo"); i = cmp(result, ""); @@ -206,7 +216,7 @@ unittest char[] getName(char[] fullname) { - uint i; + size_t i; i = fullname.length; while (i > 0) @@ -219,7 +229,7 @@ char[] getName(char[] fullname) if (fullname[i] == ':' || fullname[i] == '\\') break; } - version(linux) + version(Unix) { if (fullname[i] == '/') break; @@ -279,7 +289,7 @@ char[] getBaseName(char[] fullname) } body { - uint i; + size_t i; for (i = fullname.length; i > 0; i--) { @@ -288,7 +298,7 @@ char[] getBaseName(char[] fullname) if (fullname[i - 1] == ':' || fullname[i - 1] == '\\') break; } - version(linux) + else version(Unix) { if (fullname[i - 1] == '/') break; @@ -305,7 +315,7 @@ unittest version (Windows) result = getBaseName("d:\\path\\foo.bat"); - version (linux) + version (Unix) result = getBaseName("/path/foo.bat"); //printf("result = '%.*s'\n", result); i = cmp(result, "foo.bat"); @@ -313,7 +323,7 @@ unittest version (Windows) result = getBaseName("a\\b"); - version (linux) + version (Unix) result = getBaseName("a/b"); i = cmp(result, "b"); assert(i == 0); @@ -358,7 +368,7 @@ char[] getDirName(char[] fullname) } body { - uint i; + size_t i; for (i = fullname.length; i > 0; i--) { @@ -371,7 +381,7 @@ char[] getDirName(char[] fullname) break; } } - version(linux) + else version(Unix) { if (fullname[i - 1] == '/') { i--; @@ -410,7 +420,7 @@ char[] getDrive(char[] fullname) { version(Win32) { - int i; + size_t i; for (i = 0; i < fullname.length; i++) { @@ -419,7 +429,7 @@ char[] getDrive(char[] fullname) } return null; } - version(linux) + else version(Unix) { return null; } @@ -629,7 +639,7 @@ char[] join(char[] p1, char[] p2) } } } - version(linux) + else version(Unix) { if (p2[0] == sep[0]) { @@ -657,7 +667,7 @@ unittest p = join("foo", "bar"); version (Win32) i = cmp(p, "foo\\bar"); - version (linux) + version (Unix) i = cmp(p, "foo/bar"); assert(i == 0); @@ -665,7 +675,7 @@ unittest { p = join("foo\\", "bar"); i = cmp(p, "foo\\bar"); } - version (linux) + version (Unix) { p = join("foo/", "bar"); i = cmp(p, "foo/bar"); } @@ -675,7 +685,7 @@ unittest { p = join("foo", "\\bar"); i = cmp(p, "\\bar"); } - version (linux) + version (Unix) { p = join("foo", "/bar"); i = cmp(p, "/bar"); } @@ -685,7 +695,7 @@ unittest { p = join("foo\\", "\\bar"); i = cmp(p, "\\bar"); } - version (linux) + version (Unix) { p = join("foo/", "/bar"); i = cmp(p, "/bar"); } @@ -767,10 +777,17 @@ int fncharmatch(dchar c1, dchar c2) } return true; } - version (linux) + else version (Unix) { return c1 == c2; } + /* this is filesystem-dependent, figure out the filesystem? + else version (GNU) + { + // %% figure out filesystem? + return c1 == c2; + } + */ } /************************************ @@ -824,7 +841,7 @@ int fnmatch(char[] filename, char[] patt in { // Verify that pattern[] is valid - int i; + size_t i; int inbracket = false; for (i = 0; i < pattern.length; i++) @@ -848,11 +865,11 @@ int fnmatch(char[] filename, char[] patt } body { - int pi; - int ni; + size_t pi; + size_t ni; char pc; char nc; - int j; + size_t j; int not; int anymatch; @@ -929,7 +946,7 @@ unittest version (Win32) assert(fnmatch("foo", "Foo")); - version (linux) + version (Unix) assert(!fnmatch("foo", "Foo")); assert(fnmatch("foo", "*")); assert(fnmatch("foo.bar", "*")); @@ -1011,7 +1028,7 @@ unittest char[] expandTilde(char[] inputPath) { - version(linux) + version(Unix) { static assert(sep.length == 1); @@ -1040,7 +1057,7 @@ unittest { debug(path) printf("path.expandTilde.unittest\n"); - version (linux) + version (Unix) { // Retrieve the current home variable. char* c_home = getenv("HOME"); @@ -1069,13 +1086,15 @@ unittest 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) +version (Unix) { /** @@ -1136,7 +1155,7 @@ private char[] expandFromDatabase(char[] // Extract username, searching for path separator. char[] username; - int last_char = find(path, sep[0]); + ptrdiff_t last_char = find(path, sep[0]); if (last_char == -1) { @@ -1149,6 +1168,9 @@ private char[] expandFromDatabase(char[] } assert(last_char > 1); + version (GNU_Unix_Have_getpwnam_r) + { + // Reserve C memory for the getpwnam_r() function. passwd result; int extra_memory_size = 5 * 1024; @@ -1163,7 +1185,7 @@ private char[] expandFromDatabase(char[] // Obtain info from database. passwd *verify; std.c.stdlib.setErrno(0); - if (getpwnam_r(username.ptr, &result, extra_memory, extra_memory_size, + if (getpwnam_r(username.ptr, &result, cast(char*) extra_memory, extra_memory_size, &verify) == 0) { // Failure if verify doesn't point at result. @@ -1173,8 +1195,19 @@ private char[] expandFromDatabase(char[] break; } - if (std.c.stdlib.getErrno() != ERANGE) + switch (std.c.stdlib.getErrno()) { + case 0: + case ENOENT: + case ESRCH: + case EBADF: + case EPERM: + goto Lnotfound; + case ERANGE: + break; + default: + // not just out of memory: EMFILE, ENFILE too goto Lerror; + } // extra_memory isn't large enough std.c.stdlib.free(extra_memory); @@ -1193,6 +1226,22 @@ Lerror: std.c.stdlib.free(extra_memory); _d_OutOfMemory(); return null; + + } + else + { + passwd * result; + + /* This does not guarantee another thread will not + use getpwnam at the same time */ + synchronized { + result = getpwnam(username); + } + + if (result) + path = combineCPathWithDPath(result.pw_dir, path, last_char); + return path; + } } } diff -uNrp dmd-1.007/src/phobos/std/perf.d gdc-0.23/d/phobos/std/perf.d --- dmd-1.007/src/phobos/std/perf.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/perf.d 2006-06-03 04:57:13.000000000 +0200 @@ -21,6 +21,12 @@ * * ////////////////////////////////////////////////////////////////////////// */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /** \file std/perf.d This file contains platform-independent performance classes */ @@ -84,22 +90,27 @@ auto class PerformanceCounterScope(T) this(PerformanceCounterScope rhs); } -version(linux) +version(Unix) { - extern (C) - { - private struct timeval + version (GNU) { + private import std.c.unix.unix; + } + else version (linux) { + extern (C) { - int tv_sec; /*!< The number of seconds, since Jan. 1, 1970, in the time value. */ - int tv_usec; /*!< The number of microseconds in the time value. */ - }; - private struct timezone - { - int tz_minuteswest; /*!< minutes west of Greenwich. */ - int tz_dsttime; /*!< type of dst corrections to apply. */ - }; - private void gettimeofday(timeval *tv, timezone *tz); + private struct timeval + { + int tv_sec; /*!< The number of seconds, since Jan. 1, 1970, in the time value. */ + int tv_usec; /*!< The number of microseconds in the time value. */ + }; + private struct timezone + { + int tz_minuteswest; /*!< minutes west of Greenwich. */ + int tz_dsttime; /*!< type of dst corrections to apply. */ + }; + private void gettimeofday(timeval *tv, timezone *tz); + } } /* ////////////////////////////////////////////////////////////////////////// */ diff -uNrp dmd-1.007/src/phobos/std/process.d gdc-0.23/d/phobos/std/process.d --- dmd-1.007/src/phobos/std/process.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/process.d 2006-06-03 04:57:13.000000000 +0200 @@ -24,12 +24,18 @@ * o This notice may not be removed or altered from any source * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, October 2004 +*/ /** * Macros: * WIKI=Phobos/StdProcess */ + module std.process; private import std.c.stdlib; @@ -83,7 +89,7 @@ int spawnvp(int mode, char[] pathname, c toAStringz(argv, argv_); - version(linux) + version(Unix) { return _spawnvp(mode, toStringz(pathname), argv_); } @@ -93,9 +99,9 @@ int spawnvp(int mode, char[] pathname, c } } -version(linux) +version(Unix) { -private import std.c.linux.linux; +private import std.c.unix.unix; int _spawnvp(int mode, char *pathname, char **argv) { int retval = 0; @@ -195,7 +201,7 @@ int execvp(char[] pathname, char[][] arg /** ditto */ int execvpe(char[] pathname, char[][] argv, char[][] envp) { -version(linux) +version (GNU_Need_execvpe) { // Is pathname rooted? if(pathname[0] == '/') diff -uNrp dmd-1.007/src/phobos/std/random.d gdc-0.23/d/phobos/std/random.d --- dmd-1.007/src/phobos/std/random.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/random.d 2007-02-02 19:45:05.000000000 +0100 @@ -6,6 +6,12 @@ // random.d // www.digitalmars.com +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.random; // Segments of the code in this file Copyright (c) 1997 by Rick Booth @@ -16,7 +22,11 @@ version (Win32) extern(Windows) int QueryPerformanceCounter(ulong *count); } -version (linux) +else version (GNU) +{ + private import std.c.unix.unix; +} +else version (linux) { private import std.c.linux.linux; } @@ -98,7 +108,7 @@ static this() { QueryPerformanceCounter(&s); } - version(linux) + else version(Unix) { // time.h // sys/time.h diff -uNrp dmd-1.007/src/phobos/std/regexp.d gdc-0.23/d/phobos/std/regexp.d --- dmd-1.007/src/phobos/std/regexp.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/regexp.d 2007-03-04 15:51:39.000000000 +0100 @@ -23,6 +23,12 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /********************************************** * $(LINK2 http://www.digitalmars.com/ctg/regular.html, Regular expressions) * are a powerful method of string pattern matching. @@ -141,6 +147,7 @@ private import std.outbuffer; import std.bitarray; import std.utf; + import std.intrinsic; } /** Regular expression to extract an _email address */ @@ -260,7 +267,10 @@ char[] sub(char[] string, char[] pattern pattern == slice) // simple pattern (exact match, no special characters) { debug(regexp) - printf("pattern: %.*s, slice: %.*s, replacement: %.*s\n",pattern,result[offset + so .. offset + eo],replacement); + printf("pattern: %.*s, slice: %.*s, replacement: %.*s\n", + cast(int) pattern.length, pattern.ptr, + cast(int) (eo-so), result.ptr + offset, + cast(int) replacement.length, replacement.ptr); result = std.string.replace(result,slice,replacement); break; } @@ -1048,7 +1058,11 @@ public rchar[] replace(rchar[] string, r format == replacement) // simple format, not $ formats { debug(regexp) - printf("pattern: %.*s, slice: %.*s, format: %.*s, replacement: %.*s\n",pattern,result[offset + so .. offset + eo],format,replacement); + printf("pattern: %.*s, slice: %.*s, format: %.*s, replacement: %.*s\n", + cast(int) pattern.length, pattern.ptr, + cast(int) (eo-so), result.ptr + offset, + cast(int) format.length, format.ptr, + cast(int) replacement.length, replacement.ptr); result = std.string.replace(result,slice,replacement); break; } @@ -1099,7 +1113,8 @@ unittest public rchar[][] exec(rchar[] string) { - debug(regexp) printf("regexp.exec(string = '%.*s')\n", string); + debug(regexp) printf("regexp.exec(string = '%.*s')\n", + cast(int) string.length, string.ptr); input = string; pmatch[0].rm_so = 0; pmatch[0].rm_eo = 0; @@ -1161,7 +1176,8 @@ public int test(char[] string, int start uint si; input = string; - debug (regexp) printf("RegExp.test(input[] = '%.*s', startindex = %d)\n", input, startindex); + debug (regexp) printf("RegExp.test(input[] = '%.*s', startindex = %d)\n", + cast(int) input.length, input.ptr, startindex); pmatch[0].rm_so = 0; pmatch[0].rm_eo = 0; if (startindex < 0 || startindex > input.length) @@ -1245,6 +1261,7 @@ void printProgram(ubyte[] prog) uint m; ushort *pu; uint *puint; + ubyte[] s; printf("printProgram()\n"); for (pc = 0; pc < prog.length; ) @@ -1281,15 +1298,17 @@ void printProgram(ubyte[] prog) case REstring: len = *cast(uint *)&prog[pc + 1]; + s = (&prog[pc + 1 + uint.sizeof])[0 .. len]; printf("\tREstring x%x, '%.*s'\n", len, - (&prog[pc + 1 + uint.sizeof])[0 .. len]); + cast(int) s.length, s.ptr); pc += 1 + uint.sizeof + len * rchar.sizeof; break; case REistring: len = *cast(uint *)&prog[pc + 1]; + s = (&prog[pc + 1 + uint.sizeof])[0 .. len]; printf("\tREistring x%x, '%.*s'\n", len, - (&prog[pc + 1 + uint.sizeof])[0 .. len]); + cast(int) s.length, s.ptr); pc += 1 + uint.sizeof + len * rchar.sizeof; break; @@ -1365,8 +1384,8 @@ void printProgram(ubyte[] prog) len = puint[0]; n = puint[1]; m = puint[2]; - printf("\tREnm%.*s len=%d, n=%u, m=%u, pc=>%d\n", - (prog[pc] == REnmq) ? "q" : " ", + printf("\tREnm%s len=%d, n=%u, m=%u, pc=>%d\n", + (prog[pc] == REnmq) ? cast(char*)"q" : cast(char*)" ", len, n, m, pc + 1 + uint.sizeof * 3 + len); pc += 1 + uint.sizeof * 3; break; @@ -1459,8 +1478,11 @@ int trymatch(int pc, int pcend) uint* puint; debug(regexp) + { + char[] s = input[src .. input.length]; printf("RegExp.trymatch(pc = %d, src = '%.*s', pcend = %d)\n", - pc, input[src .. input.length], pcend); + pc, cast(int) s.length, s.ptr, pcend); + } srcsave = src; psave = null; for (;;) @@ -1544,8 +1566,12 @@ int trymatch(int pc, int pcend) case REstring: len = *cast(uint *)&program[pc + 1]; - debug(regexp) printf("\tREstring x%x, '%.*s'\n", len, - (&program[pc + 1 + uint.sizeof])[0 .. len]); + debug(regexp) + { + char[] s = (&program[pc + 1 + uint.sizeof])[0 .. len]; + printf("\tREstring x%x, '%.*s'\n", len, + cast(int) s.length, s.ptr); + } if (src + len > input.length) goto Lnomatch; if (memcmp(&program[pc + 1 + uint.sizeof], &input[src], len * rchar.sizeof)) @@ -1556,8 +1582,12 @@ int trymatch(int pc, int pcend) case REistring: len = *cast(uint *)&program[pc + 1]; - debug(regexp) printf("\tREistring x%x, '%.*s'\n", len, - (&program[pc + 1 + uint.sizeof])[0 .. len]); + debug(regexp) + { + char[] s = (&program[pc + 1 + uint.sizeof])[0 .. len]; + printf("\tREistring x%x, '%.*s'\n", len, + cast(int) s.length, s.ptr); + } if (src + len > input.length) goto Lnomatch; version (Win32) @@ -1585,7 +1615,7 @@ int trymatch(int pc, int pcend) c1 = input[src]; //printf("[x%02x]=x%02x, x%02x\n", c1 >> 3, ((&program[pc + 1 + 4])[c1 >> 3] ), (1 << (c1 & 7))); if (c1 <= pu[0] && - !((&(program[pc + 1 + 4]))[c1 >> 3] & (1 << (c1 & 7)))) + !bt(cast(uint*)&(program[pc + 1 + 4]), c1)) // assumes BitArray implementation goto Lnomatch; pc += 1 + 2 * ushort.sizeof + len; break; @@ -1600,7 +1630,7 @@ int trymatch(int pc, int pcend) c1 = input[src]; if (c1 > pu[0]) goto Lnomatch; - if (!((&program[pc + 1 + 4])[c1 >> 3] & (1 << (c1 & 7)))) + if (!bt(cast(uint*)&(program[pc + 1 + 4]), c1)) // assumes BitArray implementation goto Lnomatch; src++; pc += 1 + 2 * ushort.sizeof + len; @@ -1615,7 +1645,7 @@ int trymatch(int pc, int pcend) len = pu[1]; c1 = input[src]; if (c1 <= pu[0] && - ((&program[pc + 1 + 4])[c1 >> 3] & (1 << (c1 & 7)))) + bt(cast(uint*)&(program[pc + 1 + 4]), c1)) // assumes BitArray implementation goto Lnomatch; src++; pc += 1 + 2 * ushort.sizeof + len; @@ -2349,12 +2379,20 @@ class Range { uint u2; u2 = base ? base - &buf.data[0] : 0; - buf.fill0(b - maxb + 1); + ++b; + version (BigEndian) + { + while (b & (uint.sizeof-1)) + ++b; + } + + buf.fill0(b - maxb); base = &buf.data[u2]; - maxb = b + 1; - //bits = (cast(bit*)this.base)[0 .. maxc + 1]; + maxb = b; + // %% moved array recreate out of this condition bits.ptr = cast(uint*)this.base; - } + } + //bits = (cast(bit*)this.base)[0 .. maxc + 1]; bits.len = maxc + 1; } } @@ -2564,7 +2602,7 @@ Lerr: void error(char[] msg) { errors++; - debug(regexp) printf("error: %.*s\n", msg); + debug(regexp) printf("error: %.*s\n", cast(int) msg.length, msg.ptr); //assert(0); //*(char*)0=0; throw new RegExpException(msg); diff -uNrp dmd-1.007/src/phobos/std/socket.d gdc-0.23/d/phobos/std/socket.d --- dmd-1.007/src/phobos/std/socket.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/socket.d 2007-02-26 15:14:18.000000000 +0100 @@ -24,6 +24,12 @@ Thanks to Benjamin Herr for his assistance. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, April 2005 +*/ + /** * Notes: For Win32 systems, link with ws2_32.lib. * Example: See /dmd/samples/d/listener.d. @@ -37,11 +43,19 @@ module std.socket; private import std.string, std.stdint, std.c.string, std.c.stdlib; -version(linux) +version(Unix) { version = BsdSockets; } +version (skyos) { /* nothging */ } +else +{ + version = have_getservbyport; + version = have_getprotobynumber; +} + + version(Win32) { private import std.c.windows.windows, std.c.windows.winsock; @@ -58,10 +72,10 @@ version(Win32) } else version(BsdSockets) { - version(linux) + version (Unix) { - private import std.c.linux.linux, std.c.linux.socket; - private alias std.c.linux.linux.timeval _ctimeval; + private import std.c.unix.unix; + private alias std.c.unix.unix.timeval _ctimeval; } typedef int32_t socket_t = -1; @@ -88,7 +102,7 @@ class SocketException: Exception { errorCode = err; - version(linux) + version(Unix) { if(errorCode > 0) { @@ -231,12 +245,17 @@ class Protocol // Same as getprotobynumber(). bool getProtocolByType(ProtocolType type) { + version (have_getprotobynumber) + { protoent* proto; proto = getprotobynumber(type); if(!proto) return false; populate(proto); return true; + } + else + return false; } } @@ -245,10 +264,11 @@ unittest { Protocol proto = new Protocol; assert(proto.getProtocolByType(ProtocolType.TCP)); - printf("About protocol TCP:\n\tName: %.*s\n", proto.name); + printf("About protocol TCP:\n\tName: %.*s\n", + cast(int) proto.name.length, proto.name.ptr); foreach(char[] s; proto.aliases) { - printf("\tAlias: %.*s\n", s); + printf("\tAlias: %.*s\n", cast(int) s.length, s.ptr); } } @@ -323,12 +343,17 @@ class Service /// ditto bool getServiceByPort(ushort port, char[] protocolName) { + version (have_getservbyport) + { servent* serv; serv = getservbyport(port, toStringz(protocolName)); if(!serv) return false; populate(serv); return true; + } + else + return false; } @@ -336,12 +361,17 @@ class Service /// ditto bool getServiceByPort(ushort port) { + version (have_getservbyport) + { servent* serv; serv = getservbyport(port, null); if(!serv) return false; populate(serv); return true; + } + else + return false; } } @@ -352,10 +382,11 @@ unittest if(serv.getServiceByName("epmap", "tcp")) { printf("About service epmap:\n\tService: %.*s\n\tPort: %d\n\tProtocol: %.*s\n", - serv.name, serv.port, serv.protocolName); + cast(int) serv.name.length, serv.name.ptr, serv.port, + cast(int) serv.protocolName.length, serv.protocolName.ptr); foreach(char[] s; serv.aliases) { - printf("\tAlias: %.*s\n", s); + printf("\tAlias: %.*s\n", cast(int) s.length, s.ptr); } } else @@ -500,19 +531,21 @@ unittest printf("addrList.length = %d\n", ih.addrList.length); assert(ih.addrList.length); InternetAddress ia = new InternetAddress(ih.addrList[0], InternetAddress.PORT_ANY); - printf("IP address = %.*s\nname = %.*s\n", ia.toAddrString(), ih.name); + char[] sia = ia.toAddrString(); + printf("IPaddress = %.*s\nname = %.*s\n", cast(int) sia.length, sia.ptr, + cast(int) ih.name.length, ih.name.ptr); foreach(int i, char[] s; ih.aliases) { - printf("aliases[%d] = %.*s\n", i, s); + printf("aliases[%d] = %.*s\n", i, cast(int) s.length, s.ptr); } printf("---\n"); assert(ih.getHostByAddr(ih.addrList[0])); - printf("name = %.*s\n", ih.name); + printf("name = %.*s\n", cast(int) ih.name.length, ih.name.ptr); foreach(int i, char[] s; ih.aliases) { - printf("aliases[%d] = %.*s\n", i, s); + printf("aliases[%d] = %.*s\n", i, cast(int) s.length, s.ptr); } } @@ -829,7 +862,14 @@ class SocketSet else version(BsdSockets) { maxfd = -1; - buf[0 .. nbytes] = 0; + version(GNU) + { + FD_ZERO(_fd_set); + } + else + { + buf[0 .. nbytes] = 0; + } } } @@ -844,7 +884,15 @@ class SocketSet } else version(BsdSockets) { - assert(FDELT(s) < nbytes / socket_t.sizeof); + version(GNU) + { + // Tries to account for little and big endian..er needs work + // assert((s/NFDBITS+1)*NFDBITS/8 <= nbytes); + } + else + { + assert(FDELT(s) < nbytes / socket_t.sizeof); + } } } body @@ -942,9 +990,16 @@ enum SocketOptionLevel: int IPV6 = ProtocolType.IPV6, /// internet protocol version 6 level } + /// Linger information for use with SocketOption.LINGER. extern(C) struct linger { + version (BsdSockets) + version (GNU) + { + private alias std.c.unix.unix.linger __unix_linger; + static assert(linger.sizeof == __unix_linger.sizeof); + } // D interface version(Win32) { @@ -953,8 +1008,18 @@ extern(C) struct linger } else version(BsdSockets) { - int32_t on; - int32_t time; + version (GNU) + { + + typeof(__unix_linger.l_onoff) on; + typeof(__unix_linger.l_linger) time; + + } + else + { + int32_t on; + int32_t time; + } } // C interface @@ -1145,7 +1210,7 @@ class Socket if(WSAEWOULDBLOCK == err) return; } - else version(linux) + else version(Unix) { if(EINPROGRESS == err) return; @@ -1483,12 +1548,12 @@ class Socket //make sure none of the SocketSet's are the same object if(checkRead) { - assert(checkRead !is checkWrite); - assert(checkRead !is checkError); + assert(checkRead !is checkWrite); + assert(checkRead !is checkError); } if(checkWrite) { - assert(checkWrite !is checkError); + assert(checkWrite !is checkError); } } body @@ -1549,7 +1614,7 @@ class Socket if(_SOCKET_ERROR == result && WSAGetLastError() == WSAEINTR) return -1; } - else version(linux) + else version(Unix) { if(_SOCKET_ERROR == result && getErrno() == EINTR) return -1; diff -uNrp dmd-1.007/src/phobos/std/stdarg.d gdc-0.23/d/phobos/std/stdarg.d --- dmd-1.007/src/phobos/std/stdarg.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/stdarg.d 2006-06-03 04:57:13.000000000 +0200 @@ -6,17 +6,38 @@ /* This is for use with variable argument lists with extern(D) linkage. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.stdarg; -alias void* va_list; +version (GNU) { + // va_list might be a pointer, but assuming so is not portable. + private import gcc.builtins; + alias __builtin_va_list va_list; + + // va_arg is handled magically by the compiler +} else { + alias void* va_list; +} template va_arg(T) { T va_arg(inout va_list _argptr) { + /* T arg = *cast(T*)_argptr; _argptr = _argptr + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1)); return arg; + */ + T t; return t; } } +private import std.c.stdarg; +/* The existence of std.stdarg.va_copy isn't standard. Prevent + conflicts by using '__'. */ +alias std.c.stdarg.va_copy __va_copy; diff -uNrp dmd-1.007/src/phobos/std/stdint.d gdc-0.23/d/phobos/std/stdint.d --- dmd-1.007/src/phobos/std/stdint.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/stdint.d 2007-02-22 02:22:30.000000000 +0100 @@ -117,8 +117,17 @@ * WIKI=Phobos/StdStdint */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, February 2007 +*/ + module std.stdint; +version(GNU) + import gcc.builtins; + /* Exact sizes */ alias byte int8_t; @@ -154,11 +163,41 @@ alias ulong uint_fast64_t; /* Integer pointer holders */ -alias int intptr_t; -alias uint uintptr_t; +version(GNU) +{ + alias __builtin_pointer_int intptr_t; + alias __builtin_pointer_uint uintptr_t; +} +else version(X86_64) +{ + alias long intptr_t; + alias ulong uintptr_t; +} +else +{ + alias int intptr_t; + alias uint uintptr_t; +} /* Greatest width integer types */ alias long intmax_t; alias ulong uintmax_t; +/* C long types */ + +version(GNU) +{ + alias __builtin_Clong Clong_t; + alias __builtin_Culong Culong_t; +} +else version(X86_64) +{ + alias long Clong_t; + alias ulong Culong_t; +} +else +{ + alias int Clong_t; + alias uint Culong_t; +} diff -uNrp dmd-1.007/src/phobos/std/stdio.d gdc-0.23/d/phobos/std/stdio.d --- dmd-1.007/src/phobos/std/stdio.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/stdio.d 2007-03-04 15:51:46.000000000 +0100 @@ -6,6 +6,12 @@ * Placed in the Public Domain. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, July 2006 +*/ + /******************************** * Standard I/O functions that extend $(B std.c.stdio). * $(B std.c.stdio) is automatically imported when importing @@ -20,6 +26,7 @@ public import std.c.stdio; import std.format; import std.utf; +import std.stdarg; version (DigitalMars) { @@ -51,10 +58,11 @@ else void __fp_unlock(FILE* fp) { } } -void writefx(FILE* fp, TypeInfo[] arguments, void* argptr, int newline=false) +void writefx(FILE* fp, TypeInfo[] arguments, va_list argptr, int newline=false) { int orientation; - orientation = fwide(fp, 0); + version(GNU_Have_fwide) + orientation = fwide(fp, 0); try { /* Do the file stream locking at the outermost level @@ -86,6 +94,9 @@ void writefx(FILE* fp, TypeInfo[] argume } else if (orientation > 0) // wide orientation { + version (GNU_Have_fwide) + { + version (Windows) { void putcw(dchar c) @@ -105,7 +116,7 @@ void writefx(FILE* fp, TypeInfo[] argume } } } - else version (linux) + else version (Unix) { void putcw(dchar c) { @@ -120,6 +131,8 @@ void writefx(FILE* fp, TypeInfo[] argume std.format.doFormat(&putcw, arguments, argptr); if (newline) FPUTWC('\n', fp); + + } } } finally diff -uNrp dmd-1.007/src/phobos/std/stream.d gdc-0.23/d/phobos/std/stream.d --- dmd-1.007/src/phobos/std/stream.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/stream.d 2007-03-04 15:51:50.000000000 +0100 @@ -20,6 +20,12 @@ * "as is" without express or implied warranty. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, April 2005 +*/ + module std.stream; /* Class structure: @@ -183,7 +189,6 @@ interface InputStream { wchar[] readStringW(size_t length); - /*** * Read and return the next character in the stream. * @@ -192,6 +197,8 @@ interface InputStream { * If EOF is reached then getc returns char.init and getcw returns wchar.init. */ + // pushes back character c into the stream; only has + // effect on further calls to getc() and getcw() char getc(); wchar getcw(); /// ditto @@ -224,7 +231,7 @@ interface InputStream { * file.readf("%d hello %f", &x, &y, "%s", &s); * -------------------------- */ - int vreadf(TypeInfo[] arguments, void* args); + int vreadf(TypeInfo[] arguments, va_list args); int readf(...); /// ditto /// Retrieve the number of bytes available for immediate reading. @@ -343,14 +350,13 @@ interface OutputStream { */ OutputStream writef(...); OutputStream writefln(...); /// ditto - OutputStream writefx(TypeInfo[] arguments, void* argptr, int newline = false); /// ditto + OutputStream writefx(TypeInfo[] arguments, va_list argptr, int newline = false); /// ditto void flush(); /// Flush pending output if appropriate. void close(); /// Close the stream, flushing output if appropriate. bool isOpen(); /// Return true if the stream is currently open. } - /*** * Stream is the base abstract class from which the other stream classes derive. * @@ -679,7 +685,7 @@ class Stream : InputStream, OutputStream return c; } - int vreadf(TypeInfo[] arguments, void* args) { + int vreadf(TypeInfo[] arguments, va_list args) { char[] fmt; int j = 0; int count = 0, i = 0; @@ -1125,15 +1131,17 @@ class Stream : InputStream, OutputStream char* f = toStringz(format); size_t psize = buffer.length; size_t count; + va_list args_copy; while (true) { + __va_copy(args_copy, args); version (Win32) { - count = _vsnprintf(p, psize, f, args); + count = _vsnprintf(p, psize, f, args_copy); if (count != -1) break; psize *= 2; p = cast(char*) alloca(psize); - } else version (linux) { - count = vsnprintf(p, psize, f, args); + } else version (Unix) { + count = vsnprintf(p, psize, f, args_copy); if (count == -1) psize *= 2; else if (count >= psize) @@ -1151,10 +1159,14 @@ class Stream : InputStream, OutputStream // writes data to stream using printf() syntax, // returns number of bytes written size_t printf(char[] format, ...) { - va_list ap; - ap = cast(va_list) &format; - ap += format.sizeof; - return vprintf(format, ap); + version (GNU) + return vprintf(format, _argptr); + else { + va_list ap; + ap = cast(va_list) &format; + ap += format.sizeof; + return vprintf(format, ap); + } } private void doFormatCallback(dchar c) { @@ -1175,7 +1187,7 @@ class Stream : InputStream, OutputStream } // writes data with optional trailing newline - OutputStream writefx(TypeInfo[] arguments, void* argptr, int newline=false) { + OutputStream writefx(TypeInfo[] arguments, va_list argptr, int newline=false) { doFormat(&doFormatCallback,arguments,argptr); if (newline) writeLine(""); @@ -1774,8 +1786,8 @@ version (Win32) { DWORD GetFileType(HANDLE hFile); } } -version (linux) { - private import std.c.linux.linux; +version (Unix) { + private import std.c.unix.unix; alias int HANDLE; } @@ -1785,7 +1797,7 @@ class File: Stream { version (Win32) { private HANDLE hFile; } - version (linux) { + version (Unix) { private HANDLE hFile = -1; } @@ -1794,7 +1806,7 @@ class File: Stream { version (Win32) { hFile = null; } - version (linux) { + version (Unix) { hFile = -1; } isopen = false; @@ -1851,8 +1863,8 @@ class File: Stream { } isopen = hFile != INVALID_HANDLE_VALUE; } - version (linux) { - hFile = std.c.linux.linux.open(toStringz(filename), access | createMode, share); + version (Unix) { + hFile = std.c.unix.unix.open(toStringz(filename), access | createMode, share); isopen = hFile != -1; } if (!isopen) @@ -1879,7 +1891,7 @@ class File: Stream { createMode = CREATE_ALWAYS; // resets file } } - version (linux) { + version (Unix) { if (mode & FileMode.In) { access = O_RDONLY; share = 0660; @@ -1917,8 +1929,8 @@ class File: Stream { version (Win32) { CloseHandle(hFile); hFile = null; - } else version (linux) { - std.c.linux.linux.close(hFile); + } else version (Unix) { + std.c.unix.unix.close(hFile); hFile = -1; } } @@ -1942,8 +1954,8 @@ class File: Stream { assertReadable(); version (Win32) { ReadFile(hFile, buffer, size, &size, null); - } else version (linux) { - size = std.c.linux.linux.read(hFile, buffer, size); + } else version (Unix) { + size = std.c.unix.unix.read(hFile, buffer, size); if (size == -1) size = 0; } @@ -1955,8 +1967,8 @@ class File: Stream { assertWriteable(); version (Win32) { WriteFile(hFile, buffer, size, &size, null); - } else version (linux) { - size = std.c.linux.linux.write(hFile, buffer, size); + } else version (Unix) { + size = std.c.unix.unix.write(hFile, buffer, size); if (size == -1) size = 0; } @@ -1971,8 +1983,8 @@ class File: Stream { if ((low == INVALID_SET_FILE_POINTER) && (GetLastError() != 0)) throw new SeekException("unable to move file pointer"); ulong result = (cast(ulong)hi << 32) + low; - } else version (linux) { - ulong result = lseek(hFile, cast(int)offset, rel); + } else version (Unix) { + ulong result = lseek(hFile, cast(off_t)offset, rel); if (result == 0xFFFFFFFF) throw new SeekException("unable to move file pointer"); } @@ -2011,7 +2023,7 @@ class File: Stream { // string#1 + string#2 + int should give exacly that version (Win32) assert(file.position() == 19 + 13 + 4); - version (linux) + version (Unix) assert(file.position() == 18 + 13 + 4); // we must be at the end of file assert(file.eof()); @@ -2031,7 +2043,7 @@ class File: Stream { file.seek(7, SeekPos.Current); version (Win32) assert(file.position() == 19 + 7); - version (linux) + version (Unix) assert(file.position() == 18 + 7); assert(!std.string.cmp(file.readString(6), "world!")); i = 0; file.read(i); @@ -2039,7 +2051,7 @@ class File: Stream { // string#1 + string#2 + int should give exacly that version (Win32) assert(file.position() == 19 + 13 + 4); - version (linux) + version (Unix) assert(file.position() == 18 + 13 + 4); // we must be at the end of file assert(file.eof()); @@ -2128,7 +2140,7 @@ class BufferedFile: BufferedStream { // string#1 + string#2 + int should give exacly that version (Win32) assert(file.position() == 19 + 13 + 4); - version (linux) + version (Unix) assert(file.position() == 18 + 13 + 4); // we must be at the end of file assert(file.eof()); @@ -2148,7 +2160,7 @@ class BufferedFile: BufferedStream { file.seek(7, SeekPos.Current); version (Win32) assert(file.position() == 19 + 7); - version (linux) + version (Unix) assert(file.position() == 18 + 7); assert(!std.string.cmp(file.readString(6), "world!")); i = 0; file.read(i); @@ -2156,7 +2168,7 @@ class BufferedFile: BufferedStream { // string#1 + string#2 + int should give exacly that version (Win32) assert(file.position() == 19 + 13 + 4); - version (linux) + version (Unix) assert(file.position() == 18 + 13 + 4); // we must be at the end of file assert(file.eof()); @@ -2617,7 +2629,7 @@ class MemoryStream: TArrayStream!(ubyte[ /// Ensure the stream can hold count bytes. void reserve(size_t count) { if (cur + count > buf.length) - buf.length = cast(uint)((cur + count) * 2); + buf.length = cast(size_t)((cur + count) * 2); } override size_t writeBlock(void* buffer, size_t size) { diff -uNrp dmd-1.007/src/phobos/std/string.d gdc-0.23/d/phobos/std/string.d --- dmd-1.007/src/phobos/std/string.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/string.d 2007-03-04 15:53:28.000000000 +0100 @@ -25,6 +25,12 @@ // The code is not optimized for speed, that will have to wait // until the design is solidified. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + module std.string; //debug=string; // uncomment to turn on debugging printf's @@ -42,7 +48,6 @@ private import std.stdarg; extern (C) { - size_t wcslen(wchar *); int wcscmp(wchar *, wchar *); } @@ -75,7 +80,7 @@ const dchar PS = '\u2029'; /// UTF parag /// Newline sequence for this system version (Windows) const char[2] newline = "\r\n"; -else version (linux) +else version (Unix) const char[1] newline = "\n"; /********************************** @@ -148,7 +153,7 @@ int icmp(char[] s1, char[] s2) { result = memicmp(s1.ptr, s2.ptr, len); } - version (linux) + version (Unix) { for (size_t i = 0; i < len; i++) { @@ -271,7 +276,7 @@ unittest * Index in s where c is found, -1 if not found. */ -int find(char[] s, dchar c) +ptrdiff_t find(char[] s, dchar c) { if (c <= 0x7F) { // Plain old ASCII @@ -283,7 +288,7 @@ int find(char[] s, dchar c) } // c is a universal character - foreach (int i, dchar c2; s) + foreach (ptrdiff_t i, dchar c2; s) { if (c == c2) return i; @@ -312,7 +317,7 @@ unittest * ditto */ -int ifind(char[] s, dchar c) +ptrdiff_t ifind(char[] s, dchar c) { char* p; @@ -320,7 +325,7 @@ int ifind(char[] s, dchar c) { // Plain old ASCII char c1 = cast(char) std.ctype.tolower(c); - foreach (int i, char c2; s) + foreach (ptrdiff_t i, char c2; s) { c2 = cast(char)std.ctype.tolower(c2); if (c1 == c2) @@ -331,7 +336,7 @@ int ifind(char[] s, dchar c) { // c is a universal character dchar c1 = std.uni.toUniLower(c); - foreach (int i, dchar c2; s) + foreach (ptrdiff_t i, dchar c2; s) { c2 = std.uni.toUniLower(c2); if (c1 == c2) @@ -372,7 +377,7 @@ unittest * ditto */ -int rfind(char[] s, dchar c) +ptrdiff_t rfind(char[] s, dchar c) { size_t i; @@ -413,7 +418,7 @@ unittest * ditto */ -int irfind(char[] s, dchar c) +ptrdiff_t irfind(char[] s, dchar c) { size_t i; @@ -487,7 +492,7 @@ unittest * Index in s where c is found, -1 if not found. */ -int find(char[] s, char[] sub) +ptrdiff_t find(char[] s, char[] sub) out (result) { if (result == -1) @@ -562,7 +567,7 @@ unittest * ditto */ -int ifind(char[] s, char[] sub) +ptrdiff_t ifind(char[] s, char[] sub) out (result) { if (result == -1) @@ -577,7 +582,7 @@ int ifind(char[] s, char[] sub) body { auto sublength = sub.length; - int i; + ptrdiff_t i; if (sublength == 0) return 0; @@ -668,7 +673,7 @@ unittest * ditto */ -int rfind(char[] s, char[] sub) +ptrdiff_t rfind(char[] s, char[] sub) out (result) { if (result == -1) @@ -689,7 +694,7 @@ int rfind(char[] s, char[] sub) c = sub[0]; if (sub.length == 1) return rfind(s, c); - for (int i = s.length - sub.length; i >= 0; i--) + for (ptrdiff_t i = s.length - sub.length; i >= 0; i--) { if (s[i] == c) { @@ -722,7 +727,7 @@ unittest * ditto */ -int irfind(char[] s, char[] sub) +ptrdiff_t irfind(char[] s, char[] sub) out (result) { if (result == -1) @@ -746,7 +751,7 @@ int irfind(char[] s, char[] sub) if (c <= 0x7F) { c = std.ctype.tolower(c); - for (int i = s.length - sub.length; i >= 0; i--) + for (ptrdiff_t i = s.length - sub.length; i >= 0; i--) { if (std.ctype.tolower(s[i]) == c) { @@ -757,7 +762,7 @@ int irfind(char[] s, char[] sub) } else { - for (int i = s.length - sub.length; i >= 0; i--) + for (ptrdiff_t i = s.length - sub.length; i >= 0; i--) { if (icmp(s[i .. i + sub.length], sub) == 0) return i; @@ -950,7 +955,6 @@ unittest char[] capitalize(char[] s) { int changed; - int i; char[] r = s; changed = 0; @@ -1139,7 +1143,7 @@ char[] join(char[][] words, char[] sep) i = 0; while (true) { - uint wlen = words[i].length; + size_t wlen = words[i].length; result[j .. j + wlen] = words[i]; j += wlen; @@ -1274,7 +1278,7 @@ char[][] split(char[] s, char[] delim) } words.length = nwords; - int wordi = 0; + size_t wordi = 0; i = 0; while (true) { @@ -1314,7 +1318,7 @@ char[][] split(char[] s, char[] delim) } words.length = nwords; - int wordi = 0; + size_t wordi = 0; i = 0; while (true) { @@ -1406,14 +1410,13 @@ unittest /************************************** * Split s[] into an array of lines, * using CR, LF, or CR-LF as the delimiter. - * The delimiter is not included in the line. */ char[][] splitlines(char[] s) { - uint i; - uint istart; - uint nlines; + size_t i; + size_t istart; + size_t nlines; char[][] lines; nlines = 0; @@ -1499,7 +1502,7 @@ unittest char[] stripl(char[] s) { - uint i; + size_t i; for (i = 0; i < s.length; i++) { @@ -1511,7 +1514,7 @@ char[] stripl(char[] s) char[] stripr(char[] s) /// ditto { - uint i; + size_t i; for (i = s.length; i > 0; i--) { @@ -1654,7 +1657,7 @@ unittest * in field width chars wide. */ -char[] ljustify(char[] s, int width) +char[] ljustify(char[] s, ptrdiff_t width) { if (s.length >= width) return s; @@ -1665,7 +1668,7 @@ char[] ljustify(char[] s, int width) } /// ditto -char[] rjustify(char[] s, int width) +char[] rjustify(char[] s, ptrdiff_t width) { if (s.length >= width) return s; @@ -1676,12 +1679,12 @@ char[] rjustify(char[] s, int width) } /// ditto -char[] center(char[] s, int width) +char[] center(char[] s, ptrdiff_t width) { if (s.length >= width) return s; char[] r = new char[width]; - int left = (width - s.length) / 2; + ptrdiff_t left = (width - s.length) / 2; r[0 .. left] = cast(char)' '; r[left .. left + s.length] = s; r[left + s.length .. width] = cast(char)' '; @@ -1718,7 +1721,7 @@ unittest * Same as rjustify(), but fill with '0's. */ -char[] zfill(char[] s, int width) +char[] zfill(char[] s, ptrdiff_t width) { if (s.length >= width) return s; @@ -1735,7 +1738,7 @@ char[] zfill(char[] s, int width) char[] replace(char[] s, char[] from, char[] to) { char[] p; - int i; + ptrdiff_t i; size_t istart; //printf("replace('%.*s','%.*s','%.*s')\n", s, from, to); @@ -1784,7 +1787,7 @@ char[] replaceSlice(char[] string, char[ in { // Verify that slice[] really is a slice of string[] - int so = cast(char*)slice - cast(char*)string; + ptrdiff_t so = cast(char*)slice - cast(char*)string; assert(so >= 0); //printf("string.length = %d, so = %d, slice.length = %d\n", string.length, so, slice.length); assert(string.length >= so + slice.length); @@ -1792,7 +1795,7 @@ in body { char[] result; - int so = cast(char*)slice - cast(char*)string; + ptrdiff_t so = cast(char*)slice - cast(char*)string; result.length = string.length - slice.length + replacement.length; @@ -1833,7 +1836,7 @@ body if (s.length == 0) return sub; - int newlength = s.length + sub.length; + ptrdiff_t newlength = s.length + sub.length; char[] result = new char[newlength]; result[0 .. index] = s[0 .. index]; @@ -1877,7 +1880,7 @@ unittest size_t count(char[] s, char[] sub) { size_t i; - int j; + ptrdiff_t j; int count = 0; for (i = 0; i < s.length; i += j + sub.length) @@ -1908,12 +1911,12 @@ unittest * tabsize is the distance between tab stops. */ -char[] expandtabs(char[] string, int tabsize = 8) +char[] expandtabs(char[] string, ptrdiff_t tabsize = 8) { bool changes = false; char[] result = string; - int column; - int nspaces; + ptrdiff_t column; + ptrdiff_t nspaces; foreach (size_t i, dchar c; string) { @@ -1931,7 +1934,7 @@ char[] expandtabs(char[] string, int tab result[i .. i + nspaces] = ' '; } else - { int j = result.length; + { ptrdiff_t j = result.length; result.length = j + nspaces; result[j .. j + nspaces] = ' '; } @@ -1997,14 +2000,14 @@ unittest * tabsize = Tab columns are tabsize spaces apart. tabsize defaults to 8. */ -char[] entab(char[] string, int tabsize = 8) +char[] entab(char[] string, ptrdiff_t tabsize = 8) { bool changes = false; char[] result = string; - int nspaces = 0; - int nwhite = 0; - int column = 0; // column number + ptrdiff_t nspaces = 0; + ptrdiff_t nwhite = 0; + ptrdiff_t column = 0; // column number foreach (size_t i, dchar c; string) { @@ -2027,8 +2030,8 @@ char[] entab(char[] string, int tabsize if (!changes) change(); - int j = result.length - nspaces; - int ntabs = (((column - nspaces) % tabsize) + nspaces) / tabsize; + ptrdiff_t j = result.length - nspaces; + ptrdiff_t ntabs = (((column - nspaces) % tabsize) + nspaces) / tabsize; result.length = j + ntabs; result[j .. j + ntabs] = '\t'; nwhite += ntabs - nspaces; @@ -2056,8 +2059,8 @@ char[] entab(char[] string, int tabsize if (!changes) change(); - int j = result.length - nspaces; - int ntabs = (nspaces + tabsize - 1) / tabsize; + ptrdiff_t j = result.length - nspaces; + ptrdiff_t ntabs = (nspaces + tabsize - 1) / tabsize; result.length = j + ntabs; result[j .. j + ntabs] = '\t'; nwhite += ntabs - nspaces; @@ -2157,7 +2160,7 @@ char[] maketrans(char[] from, char[] to) body { char[] t = new char[256]; - int i; + ptrdiff_t i; for (i = 0; i < t.length; i++) t[i] = cast(char)i; @@ -2182,7 +2185,7 @@ char[] translate(char[] s, char[] transt body { char[] r; - int count; + ptrdiff_t count; bool[256] deltab; deltab[] = false; @@ -2480,11 +2483,16 @@ char[] toString(double d) } /// ditto +static if (real.sizeof != double.sizeof) + private static const char[] _longDoubleFormat = "L"; +else + private static const char[] _longDoubleFormat = ""; + char[] toString(real r) { char[20] buffer; - int len = sprintf(buffer.ptr, "%Lg", r); + int len = sprintf(buffer.ptr, ("%"~_longDoubleFormat~"g").ptr, r); return buffer[0 .. len].dup; } @@ -2505,7 +2513,7 @@ char[] toString(ireal r) { char[21] buffer; - int len = sprintf(buffer.ptr, "%Lgi", r); + int len = sprintf(buffer.ptr, ("%"~_longDoubleFormat~"gi").ptr, r); return buffer[0 .. len].dup; } @@ -2526,11 +2534,10 @@ char[] toString(creal r) { char[20 + 1 + 20 + 1] buffer; - int len = sprintf(buffer.ptr, "%Lg+%Lgi", r.re, r.im); + int len = sprintf(buffer.ptr, ("%"~_longDoubleFormat~"g+%"~_longDoubleFormat~"gi").ptr, r.re, r.im); return buffer[0 .. len].dup; } - /****************************************** * Convert value to string in _radix radix. * @@ -2559,7 +2566,7 @@ in body { char[value.sizeof * 8] buffer; - uint i = buffer.length; + size_t i = buffer.length; if (value < radix && value < hexdigits.length) return hexdigits[cast(size_t)value .. cast(size_t)value + 1]; @@ -3111,7 +3118,7 @@ char[] tr(char[] str, char[] from, char[ { dchar lastf; dchar lastt; dchar newc; - int n = 0; + ptrdiff_t n = 0; for (size_t i = 0; i < from.length; ) { @@ -3284,7 +3291,7 @@ unittest final bool isNumeric(in char[] s, in bool bAllowSep = false) { - int iLen = s.length; + ptrdiff_t iLen = s.length; bool bDecimalPoint = false; bool bExponent = false; bool bComplex = false; @@ -3309,7 +3316,7 @@ final bool isNumeric(in char[] s, in boo if (sx[0] == '-' || sx[0] == '+') j++; - for (int i = j; i < iLen; i++) + for (ptrdiff_t i = j; i < iLen; i++) { c = sx[i]; @@ -3815,7 +3822,7 @@ unittest * leftmost column, which is numbered starting from 0. */ -size_t column(char[] string, int tabsize = 8) +size_t column(char[] string, ptrdiff_t tabsize = 8) { size_t column; @@ -3871,12 +3878,12 @@ unittest * The resulting paragraph. */ -char[] wrap(char[] s, int columns = 80, char[] firstindent = null, - char[] indent = null, int tabsize = 8) +char[] wrap(char[] s, ptrdiff_t columns = 80, char[] firstindent = null, + char[] indent = null, ptrdiff_t tabsize = 8) { char[] result; - int col; - int spaces; + ptrdiff_t col; + ptrdiff_t spaces; bool inword; bool first = true; size_t wordstart; diff -uNrp dmd-1.007/src/phobos/std/switcherr.d gdc-0.23/d/phobos/std/switcherr.d --- dmd-1.007/src/phobos/std/switcherr.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/switcherr.d 2007-02-26 00:33:16.000000000 +0100 @@ -16,7 +16,8 @@ class SwitchError : Error this.filename = filename; char[] buffer = new char[17 + filename.length + linnum.sizeof * 3 + 1]; - int len = sprintf(buffer.ptr, "Switch Default %.*s(%u)", filename, linnum); + int len = sprintf(buffer.ptr, "Switch Default %.*s(%u)", + cast(int) filename.length, filename.ptr, linnum); super(buffer[0..len]); } diff -uNrp dmd-1.007/src/phobos/std/system.d gdc-0.23/d/phobos/std/system.d --- dmd-1.007/src/phobos/std/system.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/system.d 2006-11-12 19:58:05.000000000 +0100 @@ -7,6 +7,13 @@ * WIKI = Phobos/StdSystem */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + +// Information about the target operating system, environment, and CPU module std.system; @@ -18,6 +25,7 @@ const { Win32 = 1, // Microsoft 32 bit Windows systems linux, // all linux systems + Unix, // all other } version (Win32) @@ -28,6 +36,10 @@ const { Family family = Family.linux; } + else version (Unix) + { + Family family = Family.Unix; + } else { static assert(0); diff -uNrp dmd-1.007/src/phobos/std/thread.d gdc-0.23/d/phobos/std/thread.d --- dmd-1.007/src/phobos/std/thread.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/thread.d 2007-03-06 03:21:28.000000000 +0100 @@ -20,6 +20,12 @@ * distribution. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, July 2006 +*/ + /************************** * The thread module defines the class $(B Thread). * @@ -179,9 +185,8 @@ class Thread } } - /****************************** - * Wait for this thread to terminate or until milliseconds time has - * elapsed, whichever occurs first. + /***************************** + * Wait for this thread to terminate. * Simply returns if thread has already terminated. * Throws: $(B ThreadError) if the thread hasn't begun yet or * is called on itself. @@ -447,6 +452,7 @@ class Thread { if (allThreadsDim) { + version (GNU) { /* unresolved issue: this CloseHandle call causes crashes later... */ } else CloseHandle(allThreads[0].hdl); allThreads[0].hdl = GetCurrentThread(); } @@ -496,83 +502,37 @@ void *os_query_stackBottom() } -/* ================================ linux ================================= */ +/* ================================ GCC ================================= */ -version (linux) +else version (GNU) { -private import std.c.linux.linux; -private import std.c.linux.linuxextern; +private import std.c.unix.unix; +private import gcc.builtins; -alias uint pthread_t; -extern (C) alias void (*__sighandler_t)(int); - -struct sigset_t +version (skyos) { - uint __val[1024 / (8 * uint.sizeof)]; + private import std.c.skyos.skyos; + private import std.c.skyos.compat; + alias std.c.skyos.compat.pthread_create pthread_create; + alias std.c.skyos.compat.pthread_join pthread_join; + alias std.c.skyos.compat.pthread_self pthread_self; + alias std.c.skyos.compat.pthread_kill pthread_kill; + alias std.c.skyos.compat.pthread_equal pthread_equal; + alias std.c.skyos.compat.sched_yield sched_yield; } -struct sigaction_t +version (GNU_pthread_suspend) { - __sighandler_t sa_handler; - sigset_t sa_mask; - int sa_flags; - void (*sa_restorer)(); + // nothing } - -struct pthread_attr_t +else { - int __detachstate; - int __schedpolicy; - struct __schedparam - { - int __sched_priority; - } - int __inheritsched; - int __scope; - size_t __guardsize; - int __stackaddr_set; - void *__stackaddr; - size_t __stacksize; + private import gcc.threadsem; } -unittest -{ - assert(sigset_t.sizeof == 128); - assert(sigaction_t.sizeof == 140); - assert(sem_t.sizeof == 16); -} +private extern (C) void* _d_gcc_query_stack_origin(); -extern (C) -{ - int pthread_create(pthread_t*, void*, void* (*)(void*), void*); - int pthread_join(pthread_t, void**); - int pthread_kill(pthread_t, int); - pthread_t pthread_self(); - int pthread_equal(pthread_t, pthread_t); - int pthread_attr_init(pthread_attr_t*); - int pthread_attr_setstacksize(pthread_attr_t *, size_t); - int pthread_cancel(pthread_t); - int pthread_setcancelstate(int, int*); - int pthread_setcanceltype(int, int*); - int sched_yield(); - int sigfillset(sigset_t*); - int sigdelset(sigset_t*, int); - int sigaction(int, sigaction_t*, sigaction_t*); - int sigsuspend(sigset_t*); - - enum - { - PTHREAD_CANCEL_ENABLE, - PTHREAD_CANCEL_DISABLE - } - - enum - { - PTHREAD_CANCEL_DEFERRED, - PTHREAD_CANCEL_ASYNCHRONOUS - } -} class ThreadError : Error { @@ -634,20 +594,20 @@ class Thread } } nthreads++; - } - state = TS.RUNNING; - int result; - //printf("creating thread x%x\n", this); - //result = pthread_create(&id, null, &threadstart, this); - // Create with thread attributes to allow non-default stack size - Dave Fladebo - result = pthread_create(&id, &threadAttrs, &threadstart, cast(void*)this); - if (result) - { state = TS.TERMINATED; - allThreads[idx] = null; - idx = -1; - error("failed to start"); // BUG: should report errno - } + state = TS.RUNNING; + int result; + //printf("creating thread x%x\n", this); + //result = pthread_create(&id, null, &threadstart, this); + // Create with thread attributes to allow non-default stack size - Dave Fladebo + result = pthread_create(&id, &threadAttrs, &threadstart, cast(void*)this); + if (result) + { state = TS.TERMINATED; + allThreads[idx] = null; + idx = -1; + error("failed to start"); // BUG: should report errno + } + } // %% changed end of sync region //printf("t = x%x, id = %d\n", this, id); } @@ -696,6 +656,8 @@ class Thread timespec ts; timeval tv; + alias typeof(tv.tv_sec) __time_t; + pthread_mutex_lock(&waitMtx); gettimeofday(&tv, null); ts.tv_sec = cast(__time_t)tv.tv_sec + cast(__time_t)(milliseconds / 1_000); @@ -793,7 +755,7 @@ class Thread Thread result; //printf("getThis(), allThreadsDim = %d\n", allThreadsDim); - synchronized (threadLock) + //synchronized (threadLock) { id = pthread_self(); //printf("id = %d\n", id); @@ -820,13 +782,21 @@ class Thread void pause() { if (state == TS.RUNNING) - { int result; - - result = pthread_kill(id, SIGUSR1); - if (result) - error("cannot pause"); + { + version (GNU_pthread_suspend) + { + if (pthread_suspend_np(id) != 0) + error("cannot pause"); + } else - sem_wait(&flagSuspend); // wait for acknowledgement + { int result; + + result = pthread_kill(id, SIGUSR1); + if (result) + error("cannot pause"); + else + flagSuspend.wait(); // wait for acknowledgement + } } else error("cannot pause"); @@ -835,11 +805,19 @@ class Thread void resume() { if (state == TS.RUNNING) - { int result; + { + version (GNU_pthread_suspend) + { + if (pthread_continue_np(id) != 0) + error("cannot pause"); + } + else + { int result; - result = pthread_kill(id, SIGUSR2); - if (result) - error("cannot resume"); + result = pthread_kill(id, SIGUSR2); + if (result) + error("cannot resume"); + } } else error("cannot resume"); @@ -847,11 +825,37 @@ class Thread static void pauseAll() { + version (GNU_pthread_suspend) + { + if (nthreads > 1) + { + Thread tthis = getThis(); + + synchronized (threadLock) + { + + for (int i = 0; i < allThreadsDim; i++) + { Thread t; + + t = allThreads[i]; + if (t && t !is tthis && t.state == TS.RUNNING) + t.pause(); + } + + } + } + } + else + { + if (nthreads > 1) { Thread tthis = getThis(); int npause = 0; + synchronized (threadLock) + { + for (int i = 0; i < allThreadsDim; i++) { Thread t; @@ -867,12 +871,16 @@ class Thread } } + } + // Wait for each paused thread to acknowledge while (npause--) { - sem_wait(&flagSuspend); + flagSuspend.wait(); } } + + } } static void resumeAll() @@ -902,13 +910,20 @@ class Thread static uint allThreadsDim; static Object threadLock; - + // Set max to Windows equivalent for compatibility. // pthread_create will fail gracefully if stack limit // is reached prior to allThreads max. static Thread[0x400] allThreads; - - static sem_t flagSuspend; + + version (GNU_pthread_suspend) + { + // nothing + } + else + { + static Semaphore flagSuspend; + } TS state; int idx = -1; // index into allThreads[] @@ -962,6 +977,9 @@ class Thread // before pthread_create() sets it. t.id = pthread_self(); + version(skyos) + installSignalHandlers(); + t.stackBottom = getESP(); try { @@ -977,10 +995,13 @@ class Thread } debug (thread) printf("Ending thread %d\n", t.idx); - t.state = TS.TERMINATED; - allThreads[t.idx] = null; - t.idx = -1; - nthreads--; + synchronized (threadLock) + { + t.state = TS.TERMINATED; + allThreads[t.idx] = null; + t.idx = -1; + nthreads--; + } return cast(void*)result; } @@ -997,118 +1018,118 @@ class Thread t.state = TS.RUNNING; t.id = pthread_self(); - - version (none) - { - // See discussion: http://autopackage.org/forums/viewtopic.php?t=22 - static void** libc_stack_end; - - if (libc_stack_end == libc_stack_end.init) - { - void* handle = dlopen(null, RTLD_NOW); - libc_stack_end = cast(void **)dlsym(handle, "__libc_stack_end"); - dlclose(handle); - } - t.stackBottom = *libc_stack_end; - } - else - { - t.stackBottom = cast(void*)__libc_stack_end; - } + t.stackBottom = cast(void*) _d_gcc_query_stack_origin(); assert(!allThreads[0]); allThreads[0] = t; allThreadsDim = 1; t.idx = 0; - /* Install signal handlers so we can suspend/resume threads - */ - - int result; - sigaction_t sigact; - result = sigfillset(&sigact.sa_mask); - if (result) - goto Lfail; - sigact.sa_handler = &pauseHandler; - result = sigaction(SIGUSR1, &sigact, null); - if (result) - goto Lfail; - sigact.sa_handler = &resumeHandler; - result = sigaction(SIGUSR2, &sigact, null); - if (result) - goto Lfail; - - result = sem_init(&flagSuspend, 0, 0); - if (result) - goto Lfail; + version (GNU_pthread_suspend) + { + // nothing + } + else + { + /* Install signal handlers so we can suspend/resume threads + */ + installSignalHandlers(); + } return; - Lfail: - getThis().error("cannot initialize threads"); } - /********************************** - * This gets called when a thread gets SIGUSR1. - */ + version (GNU_pthread_suspend) + { + // nothing + } + else + { + + private static void installSignalHandlers() + { + int result; + sigaction_t sigact; + result = sigfillset(&sigact.sa_mask); + if (result) + goto Lfail; + sigact.sa_handler = &pauseHandler; + result = sigaction(SIGUSR1, &sigact, null); + if (result) + goto Lfail; + sigact.sa_handler = &resumeHandler; + result = sigaction(SIGUSR2, &sigact, null); + if (result) + goto Lfail; - extern (C) static void pauseHandler(int sig) - { int result; + if (! flagSuspend.create()) + goto Lfail; - // Save all registers on the stack so they'll be scanned by the GC - asm - { - pusha ; + return; + Lfail: + getThis().error("cannot initialize threads"); } - assert(sig == SIGUSR1); + + /********************************** + * This gets called when a thread gets SIGUSR1. + */ - sigset_t sigmask; - result = sigfillset(&sigmask); - assert(result == 0); - result = sigdelset(&sigmask, SIGUSR2); - assert(result == 0); + extern (C) static void pauseHandler(int sig) + { int result; - Thread t = getThis(); - t.stackTop = getESP(); - t.flags &= ~1; - // Release the semaphore _after_ stackTop is set - sem_post(&flagSuspend); - while (1) - { - sigsuspend(&sigmask); // suspend until SIGUSR2 - if (t.flags & 1) // ensure it was resumeHandler() - break; - } + // Save all registers on the stack so they'll be scanned by the GC + __builtin_unwind_init(); - // Restore all registers - asm - { - popa ; + + assert(sig == SIGUSR1); + + sigset_t sigmask; + result = sigfillset(&sigmask); + assert(result == 0); + result = sigdelset(&sigmask, SIGUSR2); + assert(result == 0); + + Thread t = getThis(); + t.stackTop = getESP(); + t.flags &= ~1; + flagSuspend.signal(); + while (1) + { + sigsuspend(&sigmask); // suspend until SIGUSR2 + if (t.flags & 1) // ensure it was resumeHandler() + break; + } } - } - /********************************** - * This gets called when a thread gets SIGUSR2. - */ + /********************************** + * This gets called when a thread gets SIGUSR2. + */ - extern (C) static void resumeHandler(int sig) - { - Thread t = getThis(); + extern (C) static void resumeHandler(int sig) + { + Thread t = getThis(); - t.flags |= 1; + t.flags |= 1; + } } public static void* getESP() { - asm - { naked ; - mov EAX,ESP ; - ret ; - } + // TODO add builtin for using stack_pointer_rtx + int dummy; + void * p = & dummy + 1; // +1 doesn't help much; also assume stack grows down + p = cast(void*)( (cast(size_t) p) & ~(size_t.sizeof - 1)); + return p; } } } + +else +{ + static assert(0); +} diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Abit.d gdc-0.23/d/phobos/std/typeinfo/ti_Abit.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Abit.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Abit.d 2006-06-03 04:57:04.000000000 +0200 @@ -0,0 +1,97 @@ + +module std.typeinfo.ti_Abit; + +private import std.string; + +// bit[] + +class TypeInfo_Ab : TypeInfo +{ + char[] toString() { return "bit[]"; } + + uint getHash(void *p) + { ubyte[] s = *cast(ubyte[]*)p; + size_t len = (s.length + 7) / 8; + ubyte *str = s; + uint hash = 0; + + while (1) + { + switch (len) + { + case 0: + return hash; + + case 1: + hash *= 9; + hash += *cast(ubyte *)str; + return hash; + + case 2: + hash *= 9; + hash += *cast(ushort *)str; + return hash; + + case 3: + hash *= 9; + hash += (*cast(ushort *)str << 8) + + (cast(ubyte *)str)[2]; + return hash; + + default: + hash *= 9; + hash += *cast(uint *)str; + str += 4; + len -= 4; + break; + } + } + + return hash; + } + + int equals(void *p1, void *p2) + { + bit[] s1 = *cast(bit[]*)p1; + bit[] s2 = *cast(bit[]*)p2; + + size_t len = s1.length; + + if (s2.length != len) + return 0;; + + // Woefully inefficient bit-by-bit comparison + for (size_t u = 0; u < len; u++) + { + if (s1[u] != s2[u]) + return 0; + } + return 1; + } + + int compare(void *p1, void *p2) + { + bit[] s1 = *cast(bit[]*)p1; + bit[] s2 = *cast(bit[]*)p2; + + size_t len = s1.length; + + if (s2.length < len) + len = s2.length; + + // Woefully inefficient bit-by-bit comparison + for (size_t u = 0; u < len; u++) + { + int result = s1[u] - s2[u]; + if (result) + return result; + } + return cast(int)s1.length - cast(int)s2.length; + } + + size_t tsize() + { + return (bit[]).sizeof; + } +} + diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_AC.d gdc-0.23/d/phobos/std/typeinfo/ti_AC.d --- dmd-1.007/src/phobos/std/typeinfo/ti_AC.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_AC.d 2007-02-26 15:11:47.000000000 +0100 @@ -42,9 +42,9 @@ class TypeInfo_AC : TypeInfo { Object[] s1 = *cast(Object[]*)p1; Object[] s2 = *cast(Object[]*)p2; - int c; + ptrdiff_t c; - c = cast(int)s1.length - cast(int)s2.length; + c = cast(ptrdiff_t)s1.length - cast(ptrdiff_t)s2.length; if (c == 0) { for (size_t u = 0; u < s1.length; u++) @@ -71,6 +71,10 @@ class TypeInfo_AC : TypeInfo } } } + if (c < 0) + c = -1; + else if (c > 0) + c = 1; return c; } diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Acdouble.d gdc-0.23/d/phobos/std/typeinfo/ti_Acdouble.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Acdouble.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Acdouble.d 2007-02-26 15:04:14.000000000 +0100 @@ -82,7 +82,11 @@ class TypeInfo_Ar : TypeInfo if (c) return c; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Acfloat.d gdc-0.23/d/phobos/std/typeinfo/ti_Acfloat.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Acfloat.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Acfloat.d 2007-02-26 15:04:33.000000000 +0100 @@ -80,7 +80,11 @@ class TypeInfo_Aq : TypeInfo if (c) return c; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Acreal.d gdc-0.23/d/phobos/std/typeinfo/ti_Acreal.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Acreal.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Acreal.d 2007-02-26 15:05:04.000000000 +0100 @@ -83,7 +83,11 @@ class TypeInfo_Ac : TypeInfo if (c) return c; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Adouble.d gdc-0.23/d/phobos/std/typeinfo/ti_Adouble.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Adouble.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Adouble.d 2007-02-26 15:04:52.000000000 +0100 @@ -80,7 +80,11 @@ class TypeInfo_Ad : TypeInfo if (c) return c; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Afloat.d gdc-0.23/d/phobos/std/typeinfo/ti_Afloat.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Afloat.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Afloat.d 2007-02-26 15:39:29.000000000 +0100 @@ -79,7 +79,11 @@ class TypeInfo_Af : TypeInfo if (c) return c; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Ag.d gdc-0.23/d/phobos/std/typeinfo/ti_Ag.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Ag.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Ag.d 2007-02-26 15:03:56.000000000 +0100 @@ -74,7 +74,11 @@ class TypeInfo_Ag : TypeInfo if (result) return result; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Aint.d gdc-0.23/d/phobos/std/typeinfo/ti_Aint.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Aint.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Aint.d 2007-02-26 15:05:20.000000000 +0100 @@ -49,7 +49,11 @@ class TypeInfo_Ai : TypeInfo if (result) return result; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() @@ -88,7 +92,11 @@ class TypeInfo_Ak : TypeInfo_Ai if (result) return result; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } TypeInfo next() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Along.d gdc-0.23/d/phobos/std/typeinfo/ti_Along.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Along.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Along.d 2007-02-26 15:05:33.000000000 +0100 @@ -50,7 +50,11 @@ class TypeInfo_Al : TypeInfo else if (s1[u] > s2[u]) return 1; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() @@ -91,7 +95,11 @@ class TypeInfo_Am : TypeInfo_Al else if (s1[u] > s2[u]) return 1; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } TypeInfo next() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Areal.d gdc-0.23/d/phobos/std/typeinfo/ti_Areal.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Areal.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Areal.d 2007-02-26 15:05:42.000000000 +0100 @@ -81,7 +81,11 @@ class TypeInfo_Ae : TypeInfo if (c) return c; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_Ashort.d gdc-0.23/d/phobos/std/typeinfo/ti_Ashort.d --- dmd-1.007/src/phobos/std/typeinfo/ti_Ashort.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_Ashort.d 2007-02-26 15:05:56.000000000 +0100 @@ -62,7 +62,11 @@ class TypeInfo_As : TypeInfo if (result) return result; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } size_t tsize() @@ -102,7 +106,11 @@ class TypeInfo_At : TypeInfo_As if (result) return result; } - return cast(int)s1.length - cast(int)s2.length; + if (s1.length < s2.length) + return -1; + else if (s1.length > s2.length) + return 1; + return 0; } TypeInfo next() diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_bit.d gdc-0.23/d/phobos/std/typeinfo/ti_bit.d --- dmd-1.007/src/phobos/std/typeinfo/ti_bit.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_bit.d 2006-06-03 04:57:04.000000000 +0200 @@ -0,0 +1,43 @@ + +// bit + +module std.typeinfo.ti_bit; + +class TypeInfo_b : TypeInfo +{ + char[] toString() { return "bit"; } + + uint getHash(void *p) + { + return *cast(bit *)p; + } + + int equals(void *p1, void *p2) + { + return *cast(bit *)p1 == *cast(bit *)p2; + } + + int compare(void *p1, void *p2) + { + if (*cast(bit*) p1 < *cast(bit*) p2) + return -1; + else if (*cast(bit*) p1 > *cast(bit*) p2) + return 1; + return 0; + } + + size_t tsize() + { + return bit.sizeof; + } + + void swap(void *p1, void *p2) + { + bit t; + + t = *cast(bit *)p1; + *cast(bit *)p1 = *cast(bit *)p2; + *cast(bit *)p2 = t; + } +} + diff -uNrp dmd-1.007/src/phobos/std/typeinfo/ti_ptr.d gdc-0.23/d/phobos/std/typeinfo/ti_ptr.d --- dmd-1.007/src/phobos/std/typeinfo/ti_ptr.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/typeinfo/ti_ptr.d 2007-02-26 15:49:25.000000000 +0100 @@ -17,7 +17,12 @@ class TypeInfo_P : TypeInfo int compare(void *p1, void *p2) { - return *cast(void* *)p1 - *cast(void* *)p2; + auto c = *cast(void* *)p1 - *cast(void* *)p2; + if (c < 0) + return -1; + else if (c > 0) + return 1; + return 0; } size_t tsize() diff -uNrp dmd-1.007/src/phobos/std/uri.d gdc-0.23/d/phobos/std/uri.d --- dmd-1.007/src/phobos/std/uri.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/uri.d 2007-02-26 00:33:36.000000000 +0100 @@ -73,10 +73,9 @@ static this() // Initialize uri_flags[] static void helper(char[] p, uint flags) - { int i; - - for (i = 0; i < p.length; i++) - uri_flags[p[i]] |= flags; + { + foreach (c; p) + uri_flags[c] |= flags; } uri_flags['#'] |= URI_Hash; @@ -92,17 +91,17 @@ static this() private char[] URI_Encode(dchar[] string, uint unescapedSet) -{ uint len; - uint j; - uint k; +{ size_t len; + size_t j; + size_t k; dchar V; dchar C; // result buffer char[50] buffer = void; char* R; - uint Rlen; - uint Rsize; // alloc'd size + size_t Rlen; + size_t Rsize; // alloc'd size len = string.length; @@ -233,9 +232,9 @@ uint ascii2hex(dchar c) } private dchar[] URI_Decode(char[] string, uint reservedSet) -{ uint len; +{ size_t len; uint j; - uint k; + size_t k; uint V; dchar C; char* s; @@ -244,8 +243,8 @@ private dchar[] URI_Decode(char[] string // Result array, allocated on stack dchar* R; - uint Rlen; - uint Rsize; // alloc'd size + size_t Rlen; + size_t Rsize; // alloc'd size len = string.length; s = string.ptr; @@ -263,7 +262,7 @@ private dchar[] URI_Decode(char[] string for (k = 0; k != len; k++) { char B; - uint start; + size_t start; C = s[k]; if (C != '%') @@ -407,10 +406,10 @@ unittest char[] r; r = encode(s); - debug(uri) printf("r = '%.*s'\n", r); + debug(uri) printf("r = '%.*s'\n", cast(int) r.length, r.ptr); assert(r == t); r = decode(t); - debug(uri) printf("r = '%.*s'\n", r); + debug(uri) printf("r = '%.*s'\n", cast(int) r.length, r.ptr); assert(r == s); r = encode( decode("%E3%81%82%E3%81%82") ); @@ -420,7 +419,8 @@ unittest //printf("r = '%.*s'\n", r); assert(r == "c%2B%2B"); - char[] str = new char[10_000_000]; + // char[] str = new char[10_000_000]; // Belongs in testgc.d? 8-\ + char[] str = new char[10_000]; str[] = 'A'; r = encodeComponent(str); foreach (char c; r) diff -uNrp dmd-1.007/src/phobos/std/windows/registry.d gdc-0.23/d/phobos/std/windows/registry.d --- dmd-1.007/src/phobos/std/windows/registry.d 2007-02-20 20:22:00.000000000 +0100 +++ gdc-0.23/d/phobos/std/windows/registry.d 2007-02-26 00:37:57.000000000 +0100 @@ -8,7 +8,7 @@ * * Author: Matthew Wilson * - * License: (Licensed under the Synesis Software Standard Source License) + * License: * * Copyright (C) 2002-2004, Synesis Software Pty Ltd. * @@ -20,25 +20,19 @@ * email: submissions@synsoft.org for submissions * admin@synsoft.org for other enquiries * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * (i) Redistributions of source code must retain the above - * copyright notice and contact information, this list of - * conditions and the following disclaimer. - * - * (ii) Any derived versions of this software (howsoever modified) - * remain the sole property of Synesis Software. - * - * (iii) Any derived versions of this software (howsoever modified) - * remain subject to all these conditions. - * - * (iv) Neither the name of Synesis Software nor the names of any - * subdivisions, employees or agents of Synesis Software, nor the - * names of any other contributors to this software may be used to - * endorse or promote products derived from this software without - * specific prior written permission. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, in both source and binary form, subject to the following + * restrictions: + * + * - The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * - Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * - This notice may not be removed or altered from any source + * distribution. * * This source code is provided by Synesis Software "as is" and any * warranties, whether expressed or implied, including, but not diff -uNrp dmd-1.007/src/phobos/std/zip.d gdc-0.23/d/phobos/std/zip.d --- dmd-1.007/src/phobos/std/zip.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/zip.d 2007-02-26 00:35:06.000000000 +0100 @@ -68,8 +68,8 @@ class ArchiveMember { void print() { - printf("name = '%.*s'\n", name); - printf("\tcomment = '%.*s'\n", comment); + printf("name = '%.*s'\n", cast(int) name.length, name.ptr); + printf("\tcomment = '%.*s'\n", cast(int) comment.length, comment.ptr); printf("\tmadeVersion = x%04x\n", madeVersion); printf("\textractVersion = x%04x\n", extractVersion); printf("\tflags = x%04x\n", flags); @@ -121,7 +121,7 @@ class ZipArchive printf("\tdiskStartDir = %u\n", diskStartDir); printf("\tnumEntries = %u\n", numEntries); printf("\ttotalEntries = %u\n", totalEntries); - printf("\tcomment = '%.*s'\n", comment); + printf("\tcomment = '%.*s'\n", cast(int) comment.length, comment.ptr); } } diff -uNrp dmd-1.007/src/phobos/std/zlib.d gdc-0.23/d/phobos/std/zlib.d --- dmd-1.007/src/phobos/std/zlib.d 2007-02-20 20:21:58.000000000 +0100 +++ gdc-0.23/d/phobos/std/zlib.d 2007-02-17 20:35:03.000000000 +0100 @@ -10,12 +10,17 @@ * WIKI = Phobos/StdZlib */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, February 2007 +*/ module std.zlib; //debug=zlib; // uncomment to turn on debugging printf's -private import etc.c.zlib, std.gc; +private import etc.c.zlib, std.stdint, std.gc; // Values for 'mode' @@ -113,7 +118,7 @@ body { int err; void[] destbuf; - uint destlen; + Culong_t destlen; destlen = srcbuf.length + ((srcbuf.length + 1023) / 1024) + 12; destbuf = new void[destlen]; @@ -145,7 +150,7 @@ void[] compress(void[] buf) * Returns: the decompressed data. */ -void[] uncompress(void[] srcbuf, uint destlen = 0u, int winbits = 15) +void[] uncompress(void[] srcbuf, size_t destlen = 0u, int winbits = 15) { int err; void[] destbuf;