diff -uNrp dmd-0.140/src/dmd/aggregate.h gdc-0.17/d/dmd/aggregate.h --- dmd-0.140/src/dmd/aggregate.h 2005-09-24 00:40:04.000000000 +0200 +++ gdc-0.17/d/dmd/aggregate.h 2005-10-13 03:06:51.000000000 +0200 @@ -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, October 2004 +*/ + #ifndef DMD_AGGREGATE_H #define DMD_AGGREGATE_H @@ -54,6 +60,10 @@ struct AggregateDeclaration : ScopeDsymb InvariantDeclaration *inv; // invariant NewDeclaration *aggNew; // allocator DeleteDeclaration *aggDelete; // deallocator +#ifdef IN_GCC + + Array methods; // flat list of all methods for debug information +#endif AggregateDeclaration(Loc loc, Identifier *id); diff -uNrp dmd-0.140/src/dmd/array.c gdc-0.17/d/dmd/array.c --- dmd-0.140/src/dmd/array.c 2004-03-26 23:11:52.000000000 +0100 +++ gdc-0.17/d/dmd/array.c 2005-05-29 23:09:19.000000000 +0200 @@ -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 @@ -17,11 +23,13 @@ #include #endif +#include "gdc_alloca.h" + #if _WIN32 #include #endif -#if linux +#ifndef _WIN32 #include #include #include diff -uNrp dmd-0.140/src/dmd/attrib.c gdc-0.17/d/dmd/attrib.c --- dmd-0.140/src/dmd/attrib.c 2005-11-16 15:11:30.000000000 +0100 +++ gdc-0.17/d/dmd/attrib.c 2005-11-28 05:17:52.000000000 +0100 @@ -7,11 +7,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, May 2005 +*/ + #include #include #include -#if _WIN32 +#if _WIN32 || IN_GCC #include "mem.h" #elif linux #include "../root/mem.h" @@ -652,12 +658,12 @@ void PragmaDeclaration::semantic(Scope * if (e->op == TOKstring) { StringExp *se = (StringExp *)e; - printf("%.*s", se->len, se->string); + fprintf(stderr, "%.*s", se->len, se->string); } else error("string expected for message, not '%s'", e->toChars()); } - printf("\n"); + fprintf(stderr, "\n"); } } else if (ident == Id::lib) @@ -674,6 +680,39 @@ void PragmaDeclaration::semantic(Scope * error("string expected for library name, not '%s'", e->toChars()); } } + else if (ident == Id::GNU_asm) + { + if (! args || args->dim != 2) + error("identifier and string expected for asm name"); + else + { + Expression *e; + Declaration *d = NULL; + StringExp *s = NULL; + + e = (Expression *)args->data[0]; + e = e->semantic(sc); + if (e->op == TOKvar) + { + d = ((VarExp *)e)->var; + if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) + d = NULL; + } + if (!d) + error("first argument of GNU_asm must be a function or variable declaration"); + + e = (Expression *)args->data[1]; + e = e->semantic(sc); + e = e->optimize(WANTvalue); + if (e->op == TOKstring && ((StringExp *)e)->sz == 1) + s = ((StringExp *)e); + else + error("second argument of GNU_asm must be a char string"); + + if (d && s) + d->c_ident = Lexer::idPool((char*) s->string); + } + } else error("unrecognized pragma(%s)", ident->toChars()); diff -uNrp dmd-0.140/src/dmd/cast.c gdc-0.17/d/dmd/cast.c --- dmd-0.140/src/dmd/cast.c 2005-11-24 01:04:34.000000000 +0100 +++ gdc-0.17/d/dmd/cast.c 2005-11-28 05:17:52.000000000 +0100 @@ -7,12 +7,18 @@ // 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 -#if _WIN32 +#if _WIN32 || IN_GCC #include "mem.h" -#elif linux +#else #include "../root/mem.h" #endif @@ -43,7 +49,7 @@ Expression *Expression::implicitCastTo(T if (e->op == TOKint64) return e->implicitCastTo(t); - printf("warning - "); + fprintf(stderr, "warning - "); error("implicit conversion of expression (%s) of type %s to %s can cause loss of data", toChars(), type->toChars(), t->toChars()); } diff -uNrp dmd-0.140/src/dmd/class.c gdc-0.17/d/dmd/class.c --- dmd-0.140/src/dmd/class.c 2005-09-24 00:45:10.000000000 +0200 +++ gdc-0.17/d/dmd/class.c 2005-10-13 03:06:51.000000000 +0200 @@ -183,6 +183,9 @@ void ClassDeclaration::semantic(Scope *s scx = scope; // save so we don't make redundant copies scope = NULL; } +#ifdef IN_GCC + methods.setDim(0); +#endif // See if there's a base class as first in baseclasses[] if (baseclasses.dim) diff -uNrp dmd-0.140/src/dmd/constfold.c gdc-0.17/d/dmd/constfold.c --- dmd-0.140/src/dmd/constfold.c 2005-11-24 01:02:22.000000000 +0100 +++ gdc-0.17/d/dmd/constfold.c 2005-11-28 05:17:52.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 +*/ + #include #include #include @@ -19,6 +25,15 @@ #include "mtype.h" #include "expression.h" +#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 @@ -253,7 +268,11 @@ Expression *MulExp::constFold() e2 = e2->constFold(); if (type->isfloating()) { complex_t c; +#ifdef IN_GCC + real_t r; +#else d_float80 r; +#endif if (e1->type->isreal()) { @@ -322,7 +341,11 @@ Expression *DivExp::constFold() e2 = e2->constFold(); if (type->isfloating()) { complex_t c; +#ifdef IN_GCC + real_t r; +#else d_float80 r; +#endif //e1->type->print(); //e2->type->print(); @@ -407,6 +430,8 @@ Expression *ModExp::constFold() #ifdef __DMC__ c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I; +#elif defined(IN_GCC) + c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2); #else c = complex_t(fmodl(e1->toReal(), r2), fmodl(e1->toImaginary(), r2)); #endif @@ -416,6 +441,8 @@ Expression *ModExp::constFold() #ifdef __DMC__ c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I; +#elif defined(IN_GCC) + c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2); #else c = complex_t(fmodl(e1->toReal(), i2), fmodl(e1->toImaginary(), i2)); #endif @@ -634,7 +661,7 @@ Expression *CmpExp::constFold() } #else // Don't rely on compiler, handle NAN arguments separately - if (isnan(r1) || isnan(r2)) // if unordered + if (real_isnan(&r1) || real_isnan(&r2)) // if unordered { switch (op) { @@ -760,7 +787,7 @@ Expression *EqualExp::constFold() #if __DMC__ cmp = (r1 == r2); #else - if (isnan(r1) || isnan(r2)) // if unordered + if (real_isnan(&r1) || real_isnan(&r2)) // if unordered { cmp = 0; } diff -uNrp dmd-0.140/src/dmd/dchar.c gdc-0.17/d/dmd/dchar.c --- dmd-0.140/src/dmd/dchar.c 2004-03-26 23:11:52.000000000 +0100 +++ gdc-0.17/d/dmd/dchar.c 2005-04-28 23:12:43.000000000 +0200 @@ -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, February 2005 +*/ + #include #include @@ -365,18 +371,21 @@ unsigned Dchar::calcHash(const dchar *st case 2: hash *= 37; - hash += *(unsigned short *)str; + hash += str[0] * 256 + str[1]; +/* hash += *(unsigned short *)str; */ return hash; case 3: hash *= 37; - hash += (*(unsigned short *)str << 8) + - ((unsigned char *)str)[2]; + hash += (str[0] * 256 + str[1]) * 256 + str[2]; +/* hash += (*(unsigned short *)str << 8) + + ((unsigned char *)str)[2]; */ return hash; default: hash *= 37; - hash += *(long *)str; + hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3]; +/* hash += *(long*)str; */ str += 4; len -= 4; break; diff -uNrp dmd-0.140/src/dmd/dchar.h gdc-0.17/d/dmd/dchar.h --- dmd-0.140/src/dmd/dchar.h 2004-03-26 23:11:52.000000000 +0100 +++ gdc-0.17/d/dmd/dchar.h 2005-05-29 23:09:19.000000000 +0200 @@ -7,11 +7,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, September 2004 +*/ + #ifndef DCHAR_H #define DCHAR_H -#if __GNUC__ +#if __GNUC__ && ! _WIN32 #include "gnuc.h" #endif @@ -138,7 +144,9 @@ struct Dchar #else #include +#ifndef GCC_SAFE_DMD #include +#endif typedef char dchar; #define TEXT(x) x @@ -156,6 +164,7 @@ struct Dchar static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); } static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); } static int isDigit(dchar c) { return '0' <= c && c <= '9'; } +#ifndef GCC_SAFE_DMD static int isAlpha(dchar c) { return isalpha(c); } static int isUpper(dchar c) { return isupper(c); } static int isLower(dchar c) { return islower(c); } @@ -165,6 +174,7 @@ struct Dchar static int toLower(dchar *p) { return toLower(*p); } static int toUpper(dchar c) { return islower(c) ? toupper(c) : c; } static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory? +#endif static dchar *chr(dchar *p, int c) { return strchr(p, c); } static dchar *rchr(dchar *p, int c) { return strrchr(p, c); } static dchar *memchr(dchar *p, int c, int count) diff -uNrp dmd-0.140/src/dmd/declaration.h gdc-0.17/d/dmd/declaration.h --- dmd-0.140/src/dmd/declaration.h 2005-09-18 22:14:22.000000000 +0200 +++ gdc-0.17/d/dmd/declaration.h 2005-10-02 16:17:55.000000000 +0200 @@ -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 +*/ + #ifndef DMD_DECLARATION_H #define DMD_DECLARATION_H @@ -339,6 +345,7 @@ struct FuncDeclaration : Declaration // scopes from having the same name VarDeclaration *vthis; // 'this' parameter VarDeclaration *v_arguments; // '_arguments' parameter + VarDeclaration *v_argptr; // '_argptr' variable Array *parameters; // Array of Argument's for parameters DsymbolTable *labtab; // statement label symbol table Declaration *overnext; // next in overload list diff -uNrp dmd-0.140/src/dmd/doc.c gdc-0.17/d/dmd/doc.c --- dmd-0.140/src/dmd/doc.c 2005-11-05 15:37:56.000000000 +0100 +++ gdc-0.17/d/dmd/doc.c 2005-11-27 17:28:26.000000000 +0100 @@ -7,11 +7,21 @@ // 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 2005 +*/ + + #include #include #include #include +#ifdef IN_GCC +#include "mem.h" +#else #if _WIN32 #include "..\root\mem.h" #elif linux @@ -19,6 +29,7 @@ #else #error "fix this" #endif +#endif #include "root.h" diff -uNrp dmd-0.140/src/dmd/dsymbol.c gdc-0.17/d/dmd/dsymbol.c --- dmd-0.140/src/dmd/dsymbol.c 2005-09-21 21:04:24.000000000 +0200 +++ gdc-0.17/d/dmd/dsymbol.c 2005-10-13 03:06:51.000000000 +0200 @@ -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, May 2005 +*/ + #include #include #include @@ -71,7 +77,7 @@ int Dsymbol::equals(Object *o) Dsymbol *Dsymbol::syntaxCopy(Dsymbol *s) { print(); - printf("%s %s\n", kind(), toChars()); + fprintf(stderr, "%s %s\n", kind(), toChars()); assert(0); return NULL; } @@ -290,27 +296,29 @@ void Dsymbol::addMember(Scope *sc, Scope void Dsymbol::error(const char *format, ...) { //printf("Dsymbol::error()\n"); + char *p = locToChars(); + if (!global.gag) { char *p = locToChars(); - if (*p) - printf("%s: ", p); + fprintf(stderr, "%s: ", p); mem.free(p); if (isAnonymous()) - printf("%s ", kind()); + fprintf(stderr, "%s ", kind()); else - printf("%s %s ", kind(), toPrettyChars()); + fprintf(stderr, "%s %s ", kind(), toPrettyChars()); 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(); @@ -325,18 +333,18 @@ void Dsymbol::error(Loc loc, const char p = locToChars(); if (*p) - printf("%s: ", p); + fprintf(stderr, "%s: ", p); mem.free(p); - printf("%s %s ", kind(), toPrettyChars()); + fprintf(stderr, "%s %s ", kind(), toPrettyChars()); 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++; diff -uNrp dmd-0.140/src/dmd/dsymbol.h gdc-0.17/d/dmd/dsymbol.h --- dmd-0.140/src/dmd/dsymbol.h 2005-10-24 00:01:24.000000000 +0200 +++ gdc-0.17/d/dmd/dsymbol.h 2005-10-26 03:33:56.000000000 +0200 @@ -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 +*/ + #ifndef DMD_DSYMBOL_H #define DMD_DSYMBOL_H @@ -61,7 +67,7 @@ struct ArrayScopeSymbol; struct SymbolDeclaration; struct Expression; -struct TYPE; +union tree_node; typedef union tree_node TYPE; enum PROT { diff -uNrp dmd-0.140/src/dmd/entity.c gdc-0.17/d/dmd/entity.c --- dmd-0.140/src/dmd/entity.c 2005-04-12 23:53:58.000000000 +0200 +++ gdc-0.17/d/dmd/entity.c 2005-04-28 23:12:43.000000000 +0200 @@ -7,6 +7,13 @@ // 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, April 2005 + Changes from Thomas Kuehne, November 2004 +*/ + #include @@ -23,6 +30,9 @@ struct NameId unsigned short value; }; +#if 0 +//TODO: Merge Walter's list with Thomas' + static NameId names[] = { // Entities @@ -299,3 +309,1065 @@ int HtmlNamedEntity(unsigned char *p, in } return -1; } + +#endif + +static NameId namesA[]={ + "Aacgr", 0x0386, + "aacgr", 0x03AC, + "Aacute", 0x00C1, + "aacute", 0x00E1, + "Abreve", 0x0102, + "abreve", 0x0103, + "Acirc", 0x00C2, + "acirc", 0x00E2, + "acute", 0x00B4, + "Acy", 0x0410, + "acy", 0x0430, + "AElig", 0x00C6, + "aelig", 0x00E6, + "Agr", 0x0391, + "agr", 0x03B1, + "Agrave", 0x00C0, + "agrave", 0x00E0, + "aleph", 0x2135, + "alpha", 0x03B1, + "Amacr", 0x0100, + "amacr", 0x0101, + "amalg", 0x2210, + "amp", 0x0026, + "and", 0x2227, + "ang", 0x2220, + "ang90", 0x221F, + "angmsd", 0x2221, + "angsph", 0x2222, + "angst", 0x212B, + "Aogon", 0x0104, + "aogon", 0x0105, + "ap", 0x2248, + "ape", 0x224A, + "apos", 0x0027, + "Aring", 0x00C5, + "aring", 0x00E5, + "ast", 0x002A, + "asymp", 0x224D, + "Atilde", 0x00C3, + "atilde", 0x00E3, + "Auml", 0x00C4, + "auml", 0x00E4, + NULL, 0 +}; + +static NameId namesB[]={ + "barwed", 0x22BC, + "Barwed", 0x2306, + "bcong", 0x224C, + "Bcy", 0x0411, + "bcy", 0x0431, + "becaus", 0x2235, + "bepsi", 0x220D, + "bernou", 0x212C, + "beta", 0x03B2, + "beth", 0x2136, + "Bgr", 0x0392, + "bgr", 0x03B2, + "blank", 0x2423, + "blk12", 0x2592, + "blk14", 0x2591, + "blk34", 0x2593, + "block", 0x2588, + "bottom", 0x22A5, + "bowtie", 0x22C8, + "boxdl", 0x2510, + "boxDL", 0x2555, + "boxdL", 0x2556, + "boxDl", 0x2557, + "boxdr", 0x250C, + "boxDR", 0x2552, + "boxDr", 0x2553, + "boxdR", 0x2554, + "boxh", 0x2500, + "boxH", 0x2550, + "boxhd", 0x252C, + "boxhD", 0x2564, + "boxHD", 0x2565, + "boxHd", 0x2566, + "boxhu", 0x2534, + "boxhU", 0x2567, + "boxHU", 0x2568, + "boxHu", 0x2569, + "boxul", 0x2518, + "boxUL", 0x255B, + "boxUl", 0x255C, + "boxuL", 0x255D, + "boxur", 0x2514, + "boxUR", 0x2558, + "boxuR", 0x2559, + "boxUr", 0x255A, + "boxv", 0x2502, + "boxV", 0x2551, + "boxvh", 0x253C, + "boxvH", 0x256A, + "boxVH", 0x256B, + "boxVh", 0x256C, + "boxvl", 0x2524, + "boxvL", 0x2561, + "boxVL", 0x2562, + "boxVl", 0x2563, + "boxvr", 0x251C, + "boxvR", 0x255E, + "boxVR", 0x255F, + "boxVr", 0x2560, + "bprime", 0x2035, + "breve", 0x02D8, + "brvbar", 0x00A6, + "bsim", 0x223D, + "bsime", 0x22CD, + "bsol", 0x005C, + "bull", 0x2022, + "bump", 0x224E, + "bumpe", 0x224F, + NULL, 0 +}; + +static NameId namesC[]={ + "Cacute", 0x0106, + "cacute", 0x0107, + "cap", 0x2229, + "Cap", 0x22D2, + "caret", 0x2041, + "caron", 0x02C7, + "Ccaron", 0x010C, + "ccaron", 0x010D, + "Ccedil", 0x00C7, + "ccedil", 0x00E7, + "Ccirc", 0x0108, + "ccirc", 0x0109, + "Cdot", 0x010A, + "cdot", 0x010B, + "cedil", 0x00B8, + "cent", 0x00A2, + "CHcy", 0x0427, + "chcy", 0x0447, + "check", 0x2713, + "chi", 0x03C7, + "cir", 0x25CB, + "circ", 0x005E, + "cire", 0x2257, + "clubs", 0x2663, + "colon", 0x003A, + "colone", 0x2254, + "comma", 0x002C, + "commat", 0x0040, + "comp", 0x2201, + "compfn", 0x2218, + "cong", 0x2245, + "conint", 0x222E, + "coprod", 0x2210, + "copy", 0x00A9, + "copysr", 0x2117, + "cross", 0x2717, + "cuepr", 0x22DE, + "cuesc", 0x22DF, + "cularr", 0x21B6, + "cup", 0x222A, + "Cup", 0x22D3, + "cupre", 0x227C, + "curarr", 0x21B7, + "curren", 0x00A4, + "cuvee", 0x22CE, + "cuwed", 0x22CF, + NULL, 0 +}; + +static NameId namesD[]={ + "dagger", 0x2020, + "Dagger", 0x2021, + "daleth", 0x2138, + "darr", 0x2193, + "dArr", 0x21D3, + "darr2", 0x21CA, + "dash", 0x2010, + "dashv", 0x22A3, + "dblac", 0x02DD, + "Dcaron", 0x010E, + "dcaron", 0x010F, + "Dcy", 0x0414, + "dcy", 0x0434, + "deg", 0x00B0, + "Delta", 0x0394, + "delta", 0x03B4, + "Dgr", 0x0394, + "dgr", 0x03B4, + "dharl", 0x21C3, + "dharr", 0x21C2, + "diam", 0x22C4, + "diams", 0x2666, + "die", 0x00A8, + "divide", 0x00F7, + "divonx", 0x22C7, + "DJcy", 0x0402, + "djcy", 0x0452, + "dlarr", 0x2199, + "dlcorn", 0x231E, + "dlcrop", 0x230D, + "dollar", 0x0024, + "Dot", 0x00A8, + "dot", 0x02D9, + "DotDot", 0x20DC, + "drarr", 0x2198, + "drcorn", 0x231F, + "drcrop", 0x230C, + "DScy", 0x0405, + "dscy", 0x0455, + "Dstrok", 0x0110, + "dstrok", 0x0111, + "dtri", 0x25BF, + "dtrif", 0x25BE, + "DZcy", 0x040F, + "dzcy", 0x045F, + NULL, 0 +}; + +static NameId namesE[]={ + "Eacgr", 0x0388, + "eacgr", 0x03AD, + "Eacute", 0x00C9, + "eacute", 0x00E9, + "Ecaron", 0x011A, + "ecaron", 0x011B, + "ecir", 0x2256, + "Ecirc", 0x00CA, + "ecirc", 0x00EA, + "ecolon", 0x2255, + "Ecy", 0x042D, + "ecy", 0x044D, + "Edot", 0x0116, + "edot", 0x0117, + "eDot", 0x2251, + "EEacgr", 0x0389, + "eeacgr", 0x03AE, + "EEgr", 0x0397, + "eegr", 0x03B7, + "efDot", 0x2252, + "Egr", 0x0395, + "egr", 0x03B5, + "Egrave", 0x00C8, + "egrave", 0x00E8, + "egs", 0x22DD, + "ell", 0x2113, + "els", 0x22DC, + "Emacr", 0x0112, + "emacr", 0x0113, + "empty", 0x2205, + "emsp", 0x2003, + "emsp13", 0x2004, + "emsp14", 0x2005, + "ENG", 0x014A, + "eng", 0x014B, + "ensp", 0x2002, + "Eogon", 0x0118, + "eogon", 0x0119, + "epsi", 0x220A, + "epsis", 0x220A, + "epsiv", 0x03B5, + "equals", 0x003D, + "equiv", 0x2261, + "erDot", 0x2253, + "esdot", 0x2250, + "eta", 0x03B7, + "ETH", 0x00D0, + "eth", 0x00F0, + "Euml", 0x00CB, + "euml", 0x00EB, + "excl", 0x0021, + "exist", 0x2203, + NULL, 0 +}; + +static NameId namesF[]={ + "Fcy", 0x0424, + "fcy", 0x0444, + "female", 0x2640, + "ffilig", 0xFB03, + "fflig", 0xFB00, + "ffllig", 0xFB04, + "filig", 0xFB01, + "flat", 0x266D, + "fllig", 0xFB02, + "fnof", 0x0192, + "forall", 0x2200, + "fork", 0x22D4, + "frac12", 0x00BD, + "frac13", 0x2153, + "frac14", 0x00BC, + "frac15", 0x2155, + "frac16", 0x2159, + "frac18", 0x215B, + "frac23", 0x2154, + "frac25", 0x2156, + "frac34", 0x00BE, + "frac35", 0x2157, + "frac38", 0x215C, + "frac45", 0x2158, + "frac56", 0x215A, + "frac58", 0x215D, + "frac78", 0x215E, + "frown", 0x2322, + NULL, 0 +}; + +static NameId namesG[]={ + "gacute", 0x01F5, + "Gamma", 0x0393, + "gamma", 0x03B3, + "gammad", 0x03DC, + "gap", 0x2273, + "Gbreve", 0x011E, + "gbreve", 0x011F, + "Gcedil", 0x0122, + "Gcirc", 0x011C, + "gcirc", 0x011D, + "Gcy", 0x0413, + "gcy", 0x0433, + "Gdot", 0x0120, + "gdot", 0x0121, + "ge", 0x2265, + "gE", 0x2267, + "gel", 0x22DB, + "gEl", 0x22DB, + "ges", 0x2265, + "Gg", 0x22D9, + "Ggr", 0x0393, + "ggr", 0x03B3, + "gimel", 0x2137, + "GJcy", 0x0403, + "gjcy", 0x0453, + "gl", 0x2277, + "gnap", 0xE411, + "gne", 0x2269, + "gnE", 0x2269, + "gnsim", 0x22E7, + "grave", 0x0060, + "gsdot", 0x22D7, + "gsim", 0x2273, + "gt", 0x003E, + "Gt", 0x226B, + "gvnE", 0x2269, + NULL, 0 +}; + +static NameId namesH[]={ + "hairsp", 0x200A, + "half", 0x00BD, + "hamilt", 0x210B, + "HARDcy", 0x042A, + "hardcy", 0x044A, + "harr", 0x2194, + "hArr", 0x21D4, + "harrw", 0x21AD, + "Hcirc", 0x0124, + "hcirc", 0x0125, + "hearts", 0x2665, + "hellip", 0x2026, + "horbar", 0x2015, + "Hstrok", 0x0126, + "hstrok", 0x0127, + "hybull", 0x2043, + "hyphen", 0x002D, + NULL, 0 +}; + +static NameId namesI[]={ + "Iacgr", 0x038A, + "iacgr", 0x03AF, + "Iacute", 0x00CD, + "iacute", 0x00ED, + "Icirc", 0x00CE, + "icirc", 0x00EE, + "Icy", 0x0418, + "icy", 0x0438, + "idiagr", 0x0390, + "Idigr", 0x03AA, + "idigr", 0x03CA, + "Idot", 0x0130, + "IEcy", 0x0415, + "iecy", 0x0435, + "iexcl", 0x00A1, + "iff", 0x21D4, + "Igr", 0x0399, + "igr", 0x03B9, + "Igrave", 0x00CC, + "igrave", 0x00EC, + "IJlig", 0x0132, + "ijlig", 0x0133, + "Imacr", 0x012A, + "imacr", 0x012B, + "image", 0x2111, + "incare", 0x2105, + "infin", 0x221E, + "inodot", 0x0131, + "int", 0x222B, + "intcal", 0x22BA, + "IOcy", 0x0401, + "iocy", 0x0451, + "Iogon", 0x012E, + "iogon", 0x012F, + "iota", 0x03B9, + "iquest", 0x00BF, + "isin", 0x220A, + "Itilde", 0x0128, + "itilde", 0x0129, + "Iukcy", 0x0406, + "iukcy", 0x0456, + "Iuml", 0x00CF, + "iuml", 0x00EF, + NULL, 0 +}; + +static NameId namesJ[]={ + "Jcirc", 0x0134, + "jcirc", 0x0135, + "Jcy", 0x0419, + "jcy", 0x0439, + "Jsercy", 0x0408, + "jsercy", 0x0458, + "Jukcy", 0x0404, + "jukcy", 0x0454, + NULL, 0 +}; + +static NameId namesK[]={ + "kappa", 0x03BA, + "kappav", 0x03F0, + "Kcedil", 0x0136, + "kcedil", 0x0137, + "Kcy", 0x041A, + "kcy", 0x043A, + "Kgr", 0x039A, + "kgr", 0x03BA, + "kgreen", 0x0138, + "KHcy", 0x0425, + "khcy", 0x0445, + "KHgr", 0x03A7, + "khgr", 0x03C7, + "KJcy", 0x040C, + "kjcy", 0x045C, + NULL, 0 +}; + +static NameId namesL[]={ + "lAarr", 0x21DA, + "Lacute", 0x0139, + "lacute", 0x013A, + "lagran", 0x2112, + "Lambda", 0x039B, + "lambda", 0x03BB, + "lang", 0x3008, + "lap", 0x2272, + "laquo", 0x00AB, + "larr", 0x2190, + "Larr", 0x219E, + "lArr", 0x21D0, + "larr2", 0x21C7, + "larrhk", 0x21A9, + "larrlp", 0x21AB, + "larrtl", 0x21A2, + "Lcaron", 0x013D, + "lcaron", 0x013E, + "Lcedil", 0x013B, + "lcedil", 0x013C, + "lceil", 0x2308, + "lcub", 0x007B, + "Lcy", 0x041B, + "lcy", 0x043B, + "ldot", 0x22D6, + "ldquo", 0x201C, + "ldquor", 0x201E, + "le", 0x2264, + "lE", 0x2266, + "leg", 0x22DA, + "lEg", 0x22DA, + "les", 0x2264, + "lfloor", 0x230A, + "lg", 0x2276, + "Lgr", 0x039B, + "lgr", 0x03BB, + "lhard", 0x21BD, + "lharu", 0x21BC, + "lhblk", 0x2584, + "LJcy", 0x0409, + "ljcy", 0x0459, + "Ll", 0x22D8, + "Lmidot", 0x013F, + "lmidot", 0x0140, + "lnap", 0xE2A2, + "lne", 0x2268, + "lnE", 0x2268, + "lnsim", 0x22E6, + "lowast", 0x2217, + "lowbar", 0x005F, + "loz", 0x25CA, + "lozf", 0x2726, + "lpar", 0x0028, + "lrarr2", 0x21C6, + "lrhar2", 0x21CB, + "lsh", 0x21B0, + "lsim", 0x2272, + "lsqb", 0x005B, + "lsquo", 0x2018, + "lsquor", 0x201A, + "Lstrok", 0x0141, + "lstrok", 0x0142, + "lt", 0x003C, + "Lt", 0x226A, + "lthree", 0x22CB, + "ltimes", 0x22C9, + "ltri", 0x25C3, + "ltrie", 0x22B4, + "ltrif", 0x25C2, + "lvnE", 0x2268, + NULL, 0 +}; + +static NameId namesM[]={ + "macr", 0x00AF, + "male", 0x2642, + "malt", 0x2720, + "map", 0x21A6, + "marker", 0x25AE, + "Mcy", 0x041C, + "mcy", 0x043C, + "mdash", 0x2014, + "Mgr", 0x039C, + "mgr", 0x03BC, + "micro", 0x00B5, + "mid", 0x2223, + "middot", 0x00B7, + "minus", 0x2212, + "minusb", 0x229F, + "mldr", 0x2026, + "mnplus", 0x2213, + "models", 0x22A7, + "mu", 0x03BC, + "mumap", 0x22B8, + NULL, 0 +}; + +static NameId namesN[]={ + "nabla", 0x2207, + "Nacute", 0x0143, + "nacute", 0x0144, + "nap", 0x2249, + "napos", 0x0149, + "natur", 0x266E, +// "nbsp", 0x00A0, + "nbsp", 32, // make non-breaking space appear as space + "Ncaron", 0x0147, + "ncaron", 0x0148, + "Ncedil", 0x0145, + "ncedil", 0x0146, + "ncong", 0x2247, + "Ncy", 0x041D, + "ncy", 0x043D, + "ndash", 0x2013, + "ne", 0x2260, + "nearr", 0x2197, + "nequiv", 0x2262, + "nexist", 0x2204, + "nge", 0x2271, + "ngE", 0x2271, + "nges", 0x2271, + "Ngr", 0x039D, + "ngr", 0x03BD, + "ngt", 0x226F, + "nharr", 0x21AE, + "nhArr", 0x21CE, + "ni", 0x220D, + "NJcy", 0x040A, + "njcy", 0x045A, + "nlarr", 0x219A, + "nlArr", 0x21CD, + "nldr", 0x2025, + "nle", 0x2270, + "nlE", 0x2270, + "nles", 0x2270, + "nlt", 0x226E, + "nltri", 0x22EA, + "nltrie", 0x22EC, + "nmid", 0x2224, + "not", 0x00AC, + "notin", 0x2209, + "npar", 0x2226, + "npr", 0x2280, + "npre", 0x22E0, + "nrarr", 0x219B, + "nrArr", 0x21CF, + "nrtri", 0x22EB, + "nrtrie", 0x22ED, + "nsc", 0x2281, + "nsce", 0x22E1, + "nsim", 0x2241, + "nsime", 0x2244, + "nsmid", 0xE2AA, + "nspar", 0x2226, + "nsub", 0x2284, + "nsube", 0x2288, + "nsubE", 0x2288, + "nsup", 0x2285, + "nsupe", 0x2289, + "nsupE", 0x2289, + "Ntilde", 0x00D1, + "ntilde", 0x00F1, + "nu", 0x03BD, + "num", 0x0023, + "numero", 0x2116, + "numsp", 0x2007, + "nvdash", 0x22AC, + "nvDash", 0x22AD, + "nVdash", 0x22AE, + "nVDash", 0x22AF, + "nwarr", 0x2196, + NULL, 0 +}; + +static NameId namesO[]={ + "Oacgr", 0x038C, + "oacgr", 0x03CC, + "Oacute", 0x00D3, + "oacute", 0x00F3, + "oast", 0x229B, + "ocir", 0x229A, + "Ocirc", 0x00D4, + "ocirc", 0x00F4, + "Ocy", 0x041E, + "ocy", 0x043E, + "odash", 0x229D, + "Odblac", 0x0150, + "odblac", 0x0151, + "odot", 0x2299, + "OElig", 0x0152, + "oelig", 0x0153, + "ogon", 0x02DB, + "Ogr", 0x039F, + "ogr", 0x03BF, + "Ograve", 0x00D2, + "ograve", 0x00F2, + "OHacgr", 0x038F, + "ohacgr", 0x03CE, + "OHgr", 0x03A9, + "ohgr", 0x03C9, + "ohm", 0x2126, + "olarr", 0x21BA, + "Omacr", 0x014C, + "omacr", 0x014D, + "Omega", 0x03A9, + "omega", 0x03C9, + "ominus", 0x2296, + "oplus", 0x2295, + "or", 0x2228, + "orarr", 0x21BB, + "order", 0x2134, + "ordf", 0x00AA, + "ordm", 0x00BA, + "oS", 0x24C8, + "Oslash", 0x00D8, + "oslash", 0x00F8, + "osol", 0x2298, + "Otilde", 0x00D5, + "otilde", 0x00F5, + "otimes", 0x2297, + "Ouml", 0x00D6, + "ouml", 0x00F6, + NULL, 0 +}; + +static NameId namesP[]={ + "par", 0x2225, + "para", 0x00B6, + "part", 0x2202, + "Pcy", 0x041F, + "pcy", 0x043F, + "percnt", 0x0025, + "period", 0x002E, + "permil", 0x2030, + "perp", 0x22A5, + "Pgr", 0x03A0, + "pgr", 0x03C0, + "PHgr", 0x03A6, + "phgr", 0x03C6, + "Phi", 0x03A6, + "phis", 0x03C6, + "phiv", 0x03D5, + "phmmat", 0x2133, + "phone", 0x260E, + "Pi", 0x03A0, + "pi", 0x03C0, + "piv", 0x03D6, + "planck", 0x210F, + "plus", 0x002B, + "plusb", 0x229E, + "plusdo", 0x2214, + "plusmn", 0x00B1, + "pound", 0x00A3, + "pr", 0x227A, + "prap", 0x227E, + "pre", 0x227C, + "prime", 0x2032, + "Prime", 0x2033, + "prnap", 0x22E8, + "prnE", 0xE2B3, + "prnsim", 0x22E8, + "prod", 0x220F, + "prop", 0x221D, + "prsim", 0x227E, + "PSgr", 0x03A8, + "psgr", 0x03C8, + "Psi", 0x03A8, + "psi", 0x03C8, + "puncsp", 0x2008, + NULL, 0 +}; + +static NameId namesQ[]={ + "quest", 0x003F, + "quot", 0x0022, + NULL, 0 +}; + +static NameId namesR[]={ + "rAarr", 0x21DB, + "Racute", 0x0154, + "racute", 0x0155, + "radic", 0x221A, + "rang", 0x3009, + "raquo", 0x00BB, + "rarr", 0x2192, + "Rarr", 0x21A0, + "rArr", 0x21D2, + "rarr2", 0x21C9, + "rarrhk", 0x21AA, + "rarrlp", 0x21AC, + "rarrtl", 0x21A3, + "rarrw", 0x219D, + "Rcaron", 0x0158, + "rcaron", 0x0159, + "Rcedil", 0x0156, + "rcedil", 0x0157, + "rceil", 0x2309, + "rcub", 0x007D, + "Rcy", 0x0420, + "rcy", 0x0440, + "rdquo", 0x201D, + "rdquor", 0x201C, + "real", 0x211C, + "rect", 0x25AD, + "reg", 0x00AE, + "rfloor", 0x230B, + "Rgr", 0x03A1, + "rgr", 0x03C1, + "rhard", 0x21C1, + "rharu", 0x21C0, + "rho", 0x03C1, + "rhov", 0x03F1, + "ring", 0x02DA, + "rlarr2", 0x21C4, + "rlhar2", 0x21CC, + "rpar", 0x0029, + "rpargt", 0xE291, + "rsh", 0x21B1, + "rsqb", 0x005D, + "rsquo", 0x2019, + "rsquor", 0x2018, + "rthree", 0x22CC, + "rtimes", 0x22CA, + "rtri", 0x25B9, + "rtrie", 0x22B5, + "rtrif", 0x25B8, + "rx", 0x211E, + NULL, 0 +}; + +static NameId namesS[]={ + "Sacute", 0x015A, + "sacute", 0x015B, + "samalg", 0x2210, + "sbsol", 0xFE68, + "sc", 0x227B, + "scap", 0x227F, + "Scaron", 0x0160, + "scaron", 0x0161, + "sccue", 0x227D, + "sce", 0x227D, + "Scedil", 0x015E, + "scedil", 0x015F, + "Scirc", 0x015C, + "scirc", 0x015D, + "scnap", 0x22E9, + "scnE", 0xE2B5, + "scnsim", 0x22E9, + "scsim", 0x227F, + "Scy", 0x0421, + "scy", 0x0441, + "sdot", 0x22C5, + "sdotb", 0x22A1, + "sect", 0x00A7, + "semi", 0x003B, + "setmn", 0x2216, + "sext", 0x2736, + "sfgr", 0x03C2, + "sfrown", 0x2322, + "Sgr", 0x03A3, + "sgr", 0x03C3, + "sharp", 0x266F, + "SHCHcy", 0x0429, + "shchcy", 0x0449, + "SHcy", 0x0428, + "shcy", 0x0448, + "shy", 0x00AD, + "Sigma", 0x03A3, + "sigma", 0x03C3, + "sigmav", 0x03C2, + "sim", 0x223C, + "sime", 0x2243, + "smid", 0xE301, + "smile", 0x2323, + "SOFTcy", 0x042C, + "softcy", 0x044C, + "sol", 0x002F, + "spades", 0x2660, + "spar", 0x2225, + "sqcap", 0x2293, + "sqcup", 0x2294, + "sqsub", 0x228F, + "sqsube", 0x2291, + "sqsup", 0x2290, + "sqsupe", 0x2292, + "squ", 0x25A1, + "square", 0x25A1, + "squf", 0x25AA, + "ssetmn", 0x2216, + "ssmile", 0x2323, + "sstarf", 0x22C6, + "star", 0x22C6, + "starf", 0x2605, + "sub", 0x2282, + "Sub", 0x22D0, + "sube", 0x2286, + "subE", 0x2286, + "subne", 0x228A, + "subnE", 0x228A, + "sum", 0x2211, + "sung", 0x2669, + "sup", 0x2283, + "Sup", 0x22D1, + "sup1", 0x00B9, + "sup2", 0x00B2, + "sup3", 0x00B3, + "supe", 0x2287, + "supE", 0x2287, + "supne", 0x228B, + "supnE", 0x228B, + "szlig", 0x00DF, + NULL, 0 +}; + +static NameId namesT[]={ + "target", 0x2316, + "tau", 0x03C4, + "Tcaron", 0x0164, + "tcaron", 0x0165, + "Tcedil", 0x0162, + "tcedil", 0x0163, + "Tcy", 0x0422, + "tcy", 0x0442, + "tdot", 0x20DB, + "telrec", 0x2315, + "Tgr", 0x03A4, + "tgr", 0x03C4, + "there4", 0x2234, + "Theta", 0x0398, + "thetas", 0x03B8, + "thetav", 0x03D1, + "THgr", 0x0398, + "thgr", 0x03B8, + "thinsp", 0x2009, + "thkap", 0x2248, + "thksim", 0x223C, + "THORN", 0x00DE, + "thorn", 0x00FE, + "tilde", 0x02DC, + "times", 0x00D7, + "timesb", 0x22A0, + "top", 0x22A4, + "tprime", 0x2034, + "trade", 0x2122, + "trie", 0x225C, + "TScy", 0x0426, + "tscy", 0x0446, + "TSHcy", 0x040B, + "tshcy", 0x045B, + "Tstrok", 0x0166, + "tstrok", 0x0167, + "twixt", 0x226C, + NULL, 0 +}; + +static NameId namesU[]={ + "Uacgr", 0x038E, + "uacgr", 0x03CD, + "Uacute", 0x00DA, + "uacute", 0x00FA, + "uarr", 0x2191, + "uArr", 0x21D1, + "uarr2", 0x21C8, + "Ubrcy", 0x040E, + "ubrcy", 0x045E, + "Ubreve", 0x016C, + "ubreve", 0x016D, + "Ucirc", 0x00DB, + "ucirc", 0x00FB, + "Ucy", 0x0423, + "ucy", 0x0443, + "Udblac", 0x0170, + "udblac", 0x0171, + "udiagr", 0x03B0, + "Udigr", 0x03AB, + "udigr", 0x03CB, + "Ugr", 0x03A5, + "ugr", 0x03C5, + "Ugrave", 0x00D9, + "ugrave", 0x00F9, + "uharl", 0x21BF, + "uharr", 0x21BE, + "uhblk", 0x2580, + "ulcorn", 0x231C, + "ulcrop", 0x230F, + "Umacr", 0x016A, + "umacr", 0x016B, + "uml", 0x00A8, + "Uogon", 0x0172, + "uogon", 0x0173, + "uplus", 0x228E, + "upsi", 0x03C5, + "Upsi", 0x03D2, + "urcorn", 0x231D, + "urcrop", 0x230E, + "Uring", 0x016E, + "uring", 0x016F, + "Utilde", 0x0168, + "utilde", 0x0169, + "utri", 0x25B5, + "utrif", 0x25B4, + "Uuml", 0x00DC, + "uuml", 0x00FC, + NULL, 0 +}; + +static NameId namesV[]={ + "varr", 0x2195, + "vArr", 0x21D5, + "Vcy", 0x0412, + "vcy", 0x0432, + "vdash", 0x22A2, + "vDash", 0x22A8, + "Vdash", 0x22A9, + "veebar", 0x22BB, + "vellip", 0x22EE, + "verbar", 0x007C, + "Verbar", 0x2016, + "vltri", 0x22B2, + "vprime", 0x2032, + "vprop", 0x221D, + "vrtri", 0x22B3, + "vsubne", 0x228A, + "vsubnE", 0xE2B8, + "vsupne", 0x228B, + "vsupnE", 0x228B, + "Vvdash", 0x22AA, + NULL, 0 +}; + +static NameId namesW[]={ + "Wcirc", 0x0174, + "wcirc", 0x0175, + "wedgeq", 0x2259, + "weierp", 0x2118, + "wreath", 0x2240, + NULL, 0 +}; + +static NameId namesX[]={ + "xcirc", 0x25CB, + "xdtri", 0x25BD, + "Xgr", 0x039E, + "xgr", 0x03BE, + "xharr", 0x2194, + "xhArr", 0x2194, + "Xi", 0x039E, + "xi", 0x03BE, + "xlArr", 0x21D0, + "xrArr", 0x21D2, + "xutri", 0x25B3, + NULL, 0 +}; + +static NameId namesY[]={ + "Yacute", 0x00DD, + "yacute", 0x00FD, + "YAcy", 0x042F, + "yacy", 0x044F, + "Ycirc", 0x0176, + "ycirc", 0x0177, + "Ycy", 0x042B, + "ycy", 0x044B, + "yen", 0x00A5, + "YIcy", 0x0407, + "yicy", 0x0457, + "YUcy", 0x042E, + "yucy", 0x044E, + "yuml", 0x00FF, + "Yuml", 0x0178, + NULL, 0 +}; + +static NameId namesZ[]={ + "Zacute", 0x0179, + "zacute", 0x017A, + "Zcaron", 0x017D, + "zcaron", 0x017E, + "Zcy", 0x0417, + "zcy", 0x0437, + "Zdot", 0x017B, + "zdot", 0x017C, + "zeta", 0x03B6, + "Zgr", 0x0396, + "zgr", 0x03B6, + "ZHcy", 0x0416, + "zhcy", 0x0436, + NULL, 0 +}; + +// @todo@ order namesTable and names? by frequency +static NameId* namesTable[] = { + namesA, namesB, namesC, namesD, namesE, namesF, namesG, namesH, namesI, + namesJ, namesK, namesL, namesM, namesN, namesO, namesP, namesQ, namesR, + namesS, namesT, namesU, namesV, namesW, namesX, namesY, namesZ, NULL +}; + +int HtmlNamedEntity(unsigned char *p, int length) +{ + int tableIndex = tolower(*p) - 'a'; + if (tableIndex >= 0 && tableIndex < 26) { + NameId* names = namesTable[tableIndex]; + int i; + + for (i = 0; names[i].name; i++){ + if (strncmp(names[i].name, (char *)p, length) == 0){ + return names[i].value; + } + } + } + error("unrecognized character entity \"%.*s\"", length, p); + return -1; +} diff -uNrp dmd-0.140/src/dmd/expression.c gdc-0.17/d/dmd/expression.c --- dmd-0.140/src/dmd/expression.c 2005-11-24 17:12:24.000000000 +0100 +++ gdc-0.17/d/dmd/expression.c 2005-11-28 05:17:52.000000000 +0100 @@ -7,16 +7,30 @@ // 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 #include #include -#if _WIN32 -#include "..\root\mem.h" +#ifdef __APPLE__ +#define integer_t dmd_integer_t #endif -#if linux + +#if IN_GCC +#include "mem.h" +#elif _WIN32 +#include "..\root\mem.h" +#elif linux #include "../root/mem.h" #endif #include "port.h" @@ -232,6 +246,16 @@ void functionArguments(Loc loc, Scope *s case Tsarray: case Tarray: { // Create a static array variable v of type arg->type +#ifdef IN_GCC + /* GCC 4.0 does not like zero length arrays used like + this; pass a null array value instead. Could also + just make a one-element array. */ + if (nargs - i == 0) + { + arg = new NullExp(loc); + break; + } +#endif char name[10+6+1]; static int idn; sprintf(name, "__arrayArg%d", ++idn); @@ -395,7 +419,7 @@ Expression *Expression::copy() { Expression *e; if (!size) - printf("No expression copy for: %s\n", toChars()); + fprintf(stderr, "No expression copy for: %s\n", toChars()); e = (Expression *)mem.malloc(size); return (Expression *)memcpy(e, this, size); } @@ -419,8 +443,8 @@ Expression *Expression::semantic(Scope * void Expression::print() { - printf("%s\n", toChars()); - fflush(stdout); + fprintf(stderr, "%s\n", toChars()); + fflush(stderr); } char *Expression::toChars() @@ -438,16 +462,16 @@ void Expression::error(const char *forma char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stderr, "%s: ", p); mem.free(p); 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++; @@ -503,7 +527,11 @@ real_t Expression::toImaginary() complex_t Expression::toComplex() { error("Floating point constant expression expected instead of %s", toChars()); +#ifdef IN_GCC + return complex_t(real_t(0)); // %% nicer +#else return 0; +#endif } void Expression::toCBuffer(OutBuffer *buf) @@ -860,19 +888,33 @@ char *RealExp::toChars() { static char buffer[sizeof(value) * 3 + 8 + 1 + 1]; +#ifdef IN_GCC + value.format(buffer, sizeof(buffer)); + if (type->isimaginary()) + strcat(buffer, "i"); +#else sprintf(buffer, type->isimaginary() ? "%Lgi" : "%Lg", value); +#endif assert(strlen(buffer) < sizeof(buffer)); return buffer; } integer_t RealExp::toInteger() { +#ifdef IN_GCC + return toReal().toInt(); +#else return (sinteger_t) toReal(); +#endif } uinteger_t RealExp::toUInteger() { +#ifdef IN_GCC + return (uinteger_t) toReal().toInt(); +#else return (uinteger_t) toReal(); +#endif } real_t RealExp::toReal() @@ -905,13 +947,23 @@ Expression *RealExp::semantic(Scope *sc) int RealExp::isBool(int result) { +#ifdef IN_GCC + return result ? (! value.isZero()) : (value.isZero()); +#else return result ? (value != 0) : (value == 0); +#endif } void RealExp::toCBuffer(OutBuffer *buf) { +#ifdef IN_GCC + char buffer[8 + 3 * sizeof(value) + 1]; + value.format(buffer, sizeof(buffer)); + buf->writestring(buffer); +#else buf->printf("%Lg", value); +#endif if (type->isimaginary()) buf->writeByte('i'); } @@ -920,6 +972,11 @@ void RealExp::toCBuffer(OutBuffer *buf) void RealExp::toMangleBuffer(OutBuffer *buf) { unsigned char *p = (unsigned char *)&value; +#ifdef IN_GCC + unsigned char buffer[32]; + value.toBytes(buffer, sizeof(buffer)); + p = buffer; +#endif buf->writeByte('e'); for (int i = 0; i < REALSIZE-REALPAD; i++) buf->printf("%02x", p[i]); @@ -940,19 +997,27 @@ char *ComplexExp::toChars() { static char buffer[sizeof(value) * 3 + 8 + 1]; +#ifdef IN_GCC + char buf1[sizeof(value) * 3 + 8 + 1]; + char buf2[sizeof(value) * 3 + 8 + 1]; + creall(value).format(buf1, sizeof(buf1)); + cimagl(value).format(buf2, sizeof(buf2)); + sprintf(buffer, "(%s+%si)", buf1, buf2); +#else sprintf(buffer, "(%Lg+%Lgi)", creall(value), cimagl(value)); assert(strlen(buffer) < sizeof(buffer)); +#endif return buffer; } integer_t ComplexExp::toInteger() { - return (sinteger_t) toReal(); + return (sinteger_t) toReal().toInt(); } uinteger_t ComplexExp::toUInteger() { - return (uinteger_t) toReal(); + return (uinteger_t) toReal().toInt(); } real_t ComplexExp::toReal() @@ -987,7 +1052,15 @@ int ComplexExp::isBool(int result) void ComplexExp::toCBuffer(OutBuffer *buf) { +#ifdef IN_GCC + char buf1[sizeof(value) * 3 + 8 + 1]; + char buf2[sizeof(value) * 3 + 8 + 1]; + creall(value).format(buf1, sizeof(buf1)); + cimagl(value).format(buf2, sizeof(buf2)); + buf->printf("(%s+%si)", buf1, buf2); +#else buf->printf("(%Lg+%Lgi)", creall(value), cimagl(value)); +#endif } void ComplexExp::toMangleBuffer(OutBuffer *buf) @@ -997,6 +1070,11 @@ void ComplexExp::toMangleBuffer(OutBuffe for (int j = 0; j < 2; j++) { unsigned char *p = (unsigned char *)&r; +#ifdef IN_GCC + unsigned char buffer[32]; + r.toBytes(buffer, sizeof(buffer)); + p = buffer; +#endif for (int i = 0; i < REALSIZE-REALPAD; i++) buf->printf("%02x", p[i]); r = toImaginary(); diff -uNrp dmd-0.140/src/dmd/expression.h gdc-0.17/d/dmd/expression.h --- dmd-0.140/src/dmd/expression.h 2005-11-20 23:15:04.000000000 +0100 +++ gdc-0.17/d/dmd/expression.h 2005-11-28 05:17:52.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 +*/ + #ifndef DMD_EXPRESSION_H #define DMD_EXPRESSION_H @@ -37,7 +43,7 @@ struct ClassDeclaration; // Back end struct IRState; -struct elem; +union tree_node; typedef union tree_node elem; struct dt_t; Expression *resolveProperties(Scope *sc, Expression *e); diff -uNrp dmd-0.140/src/dmd/func.c gdc-0.17/d/dmd/func.c --- dmd-0.140/src/dmd/func.c 2005-10-16 14:56:50.000000000 +0200 +++ gdc-0.17/d/dmd/func.c 2005-10-24 23:48:04.000000000 +0200 @@ -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 @@ -24,6 +30,10 @@ #include "statement.h" #include "template.h" +#ifdef IN_GCC +#include "d-dmd-gcc.h" +#endif + /********************************* FuncDeclaration ****************************/ @@ -44,6 +54,7 @@ FuncDeclaration::FuncDeclaration(Loc loc localsymtab = NULL; vthis = NULL; v_arguments = NULL; + v_argptr = NULL; parameters = NULL; labtab = NULL; overnext = NULL; @@ -128,6 +139,13 @@ void FuncDeclaration::semantic(Scope *sc } #endif +#ifdef IN_GCC + AggregateDeclaration *ad; + + ad = parent->isAggregateDeclaration(); + if (ad) + ad->methods.push(this); +#endif sd = parent->isStructDeclaration(); if (sd) { @@ -455,7 +473,11 @@ void FuncDeclaration::semantic3(Scope *s } if (f->linkage == LINKd || (parameters && parameters->dim)) { // Declare _argptr +#ifndef IN_GCC t = Type::tvoid->pointerTo(); +#else + t = d_gcc_builtin_va_list_d_type; +#endif argptr = new VarDeclaration(0, t, Id::_argptr, NULL); argptr->semantic(sc2); sc2->insert(argptr); @@ -687,7 +709,7 @@ void FuncDeclaration::semantic3(Scope *s { Expression *e; if (global.params.warnings) - { printf("warning - "); + { fprintf(stderr, "warning - "); error("no return at end of function"); } @@ -729,6 +751,7 @@ void FuncDeclaration::semantic3(Scope *s if (argptr) { // Initialize _argptr to point past non-variadic arg +#ifndef IN_GCC Expression *e1; Expression *e; Type *t = argptr->type; @@ -746,7 +769,13 @@ void FuncDeclaration::semantic3(Scope *s e = new AssignExp(0, e1, e); e->type = t; a->push(new ExpStatement(0, e)); +#else + // Handled in FuncDeclaration::toObjFile + v_argptr = argptr; + v_argptr->init = new VoidInitializer(loc); +#endif } + // Merge contracts together with body into one compound statement @@ -1617,7 +1646,11 @@ void StaticCtorDeclaration::semantic(Sco if (!m) m = sc->module; if (m) - m->needmoduleinfo = 1; + { m->needmoduleinfo = 1; +#ifdef IN_GCC + m->strictlyneedmoduleinfo = 1; +#endif + } } AggregateDeclaration *StaticCtorDeclaration::isThis() @@ -1680,7 +1713,11 @@ void StaticDtorDeclaration::semantic(Sco if (!m) m = sc->module; if (m) - m->needmoduleinfo = 1; + { m->needmoduleinfo = 1; +#ifdef IN_GCC + m->strictlyneedmoduleinfo = 1; +#endif + } } AggregateDeclaration *StaticDtorDeclaration::isThis() diff -uNrp dmd-0.140/src/dmd/html.c gdc-0.17/d/dmd/html.c --- dmd-0.140/src/dmd/html.c 2005-05-25 20:51:30.000000000 +0200 +++ gdc-0.17/d/dmd/html.c 2005-11-27 16:59:45.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2005 by Digital Mars +// Copyright (c) 1999-2002 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 + Modified by Thomas Kuehne, November 2004 +*/ /* HTML parser */ @@ -23,11 +29,11 @@ #include #include "root.h" -#include "../mars/mars.h" +//#include "../mars/mars.h" -#if __GNUC__ -int memicmp(const char *s1, const char *s2, int n); -#endif +//#if __GNUC__ +//int memicmp(const char *s1, const char *s2, int n); +//#endif extern int HtmlNamedEntity(unsigned char *p, int length); @@ -38,7 +44,7 @@ extern int HtmlNamedEntity(unsigned char inline int istagstart(int c) { - return (isalpha(c) || c == '_'); + return (isalpha(c) || c == '_' || c == '!'); } inline int istag(int c) @@ -46,12 +52,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; @@ -69,18 +104,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(); } /********************************************** @@ -104,16 +140,27 @@ 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; } @@ -443,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 '<' @@ -527,6 +626,7 @@ int Html::charEntity() } else hex = 0; + if (p[1] == ';') goto Linvalid; while (1) @@ -630,10 +730,8 @@ 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; diff -uNrp dmd-0.140/src/dmd/identifier.c gdc-0.17/d/dmd/identifier.c --- dmd-0.140/src/dmd/identifier.c 2005-04-01 15:11:12.000000000 +0200 +++ gdc-0.17/d/dmd/identifier.c 2005-05-29 23:09:19.000000000 +0200 @@ -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, May 2005 +*/ + #include #include @@ -45,7 +51,7 @@ char *Identifier::toChars() void Identifier::print() { - printf("%s",string); + fprintf(stderr, "%s",string); } int Identifier::dyncast() diff -uNrp dmd-0.140/src/dmd/idgen.c gdc-0.17/d/dmd/idgen.c --- dmd-0.140/src/dmd/idgen.c 2005-06-02 00:10:00.000000000 +0200 +++ gdc-0.17/d/dmd/idgen.c 2005-09-09 23:27:05.000000000 +0200 @@ -173,6 +173,7 @@ Msgtable msgtable[] = // For pragma's { "lib" }, { "msg" }, + { "GNU_asm" }, // For toHash { "tohash", "toHash" }, diff -uNrp dmd-0.140/src/dmd/lexer.c gdc-0.17/d/dmd/lexer.c --- dmd-0.140/src/dmd/lexer.c 2005-10-17 19:39:06.000000000 +0200 +++ gdc-0.17/d/dmd/lexer.c 2005-10-26 03:33:56.000000000 +0200 @@ -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 +*/ + /* Lexical Analyzer */ #include @@ -19,6 +25,13 @@ #include #include +#ifdef IN_GCC + +#include +#include "mem.h" + +#else + #if __GNUC__ #include extern "C" long double strtold(const char *p,char **endp); @@ -26,12 +39,14 @@ extern "C" long double strtold(const cha #if _WIN32 #include "..\root\mem.h" -#elif linux +#elif ! defined(_WIN32) #include "../root/mem.h" #else #error "fix this" #endif +#endif + #include "stringtable.h" #include "lexer.h" @@ -98,7 +113,7 @@ void *Token::operator new(size_t size) void Token::print() { - printf("%s\n", toChars()); + fprintf(stderr, "%s\n", toChars()); } char *Token::toChars() @@ -109,14 +124,14 @@ char *Token::toChars() switch (value) { case TOKint32v: - sprintf(buffer,"%ld",int32value); + sprintf(buffer,"%ld",(d_int32)int64value); break; case TOKuns32v: case TOKcharv: case TOKwcharv: case TOKdcharv: - sprintf(buffer,"%luU",uns32value); + sprintf(buffer,"%luU",(d_uns32)uns64value); break; case TOKint64v: @@ -127,6 +142,20 @@ char *Token::toChars() sprintf(buffer,"%lluUL",uns64value); break; +#if IN_GCC + case TOKfloat32v: + case TOKfloat64v: + case TOKfloat80v: + float80value.format(buffer, sizeof(buffer)); + break; + case TOKimaginary32v: + case TOKimaginary64v: + case TOKimaginary80v: + float80value.format(buffer, sizeof(buffer)); + // %% buffer + strcat(buffer, "i"); + break; +#else case TOKfloat32v: sprintf(buffer,"%Lgf", float80value); break; @@ -150,6 +179,7 @@ char *Token::toChars() case TOKimaginary80v: sprintf(buffer,"%gLi", float80value); break; +#endif case TOKstring: @@ -233,18 +263,18 @@ void Lexer::error(const char *format, .. { char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stderr, "%s: ", p); mem.free(p); va_list ap; va_start(ap, format); - vprintf(format, ap); + vfprintf(stderr, format, ap); va_end(ap); - printf("\n"); - fflush(stdout); - - if (global.errors >= 20) // moderate blizzard of cascading messages + fprintf(stderr, "\n"); + fflush(stderr); + + if (global.errors > 20) // moderate blizzard of cascading messages fatal(); } global.errors++; @@ -256,18 +286,18 @@ void Lexer::error(Loc loc, const char *f { char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stderr, "%s: ", p); mem.free(p); 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); - if (global.errors >= 20) // moderate blizzard of cascading messages + if (global.errors > 20) // moderate blizzard of cascading messages fatal(); } global.errors++; @@ -1929,19 +1959,31 @@ done: char *save = __locale_decpoint; __locale_decpoint = "."; #endif +#ifdef IN_GCC + t->float80value = real_t::parse((char *)stringbuffer.data, real_t::LongDouble); +#else t->float80value = strtold((char *)stringbuffer.data, NULL); +#endif errno = 0; switch (*p) { case 'F': case 'f': +#ifdef IN_GCC + real_t::parse((char *)stringbuffer.data, real_t::Float); +#else strtof((char *)stringbuffer.data, NULL); +#endif result = TOKfloat32v; p++; break; default: +#ifdef IN_GCC + real_t::parse((char *)stringbuffer.data, real_t::Double); +#else strtod((char *)stringbuffer.data, NULL); +#endif result = TOKfloat64v; break; diff -uNrp dmd-0.140/src/dmd/lexer.h gdc-0.17/d/dmd/lexer.h --- dmd-0.140/src/dmd/lexer.h 2005-09-29 19:25:16.000000000 +0200 +++ gdc-0.17/d/dmd/lexer.h 2005-10-13 03:06:51.000000000 +0200 @@ -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_LEXER_H #define DMD_LEXER_H @@ -196,7 +202,11 @@ struct Token d_uns64 uns64value; // Floats +#ifdef IN_GCC + // real_t float80value; // can't use this in a union! +#else d_float80 float80value; +#endif struct { unsigned char *ustring; // UTF8 string @@ -206,12 +216,15 @@ struct Token Identifier *ident; }; +#ifdef IN_GCC + real_t float80value; // can't use this in a union! +#endif static char *tochars[TOKMAX]; static void *operator new(size_t sz); int isKeyword(); - void print(); + void print(); char *toChars(); static char *toChars(enum TOK); }; diff -uNrp dmd-0.140/src/dmd/macro.c gdc-0.17/d/dmd/macro.c --- dmd-0.140/src/dmd/macro.c 2005-10-14 20:41:22.000000000 +0200 +++ gdc-0.17/d/dmd/macro.c 2005-10-24 23:48:04.000000000 +0200 @@ -15,6 +15,9 @@ #include #include +#ifdef IN_GCC +#include "mem.h" +#else #if _WIN32 #include "..\root\mem.h" #elif linux @@ -22,6 +25,7 @@ #else #error "fix this" #endif +#endif #include "root.h" #include "macro.h" diff -uNrp dmd-0.140/src/dmd/mangle.c gdc-0.17/d/dmd/mangle.c --- dmd-0.140/src/dmd/mangle.c 2005-11-21 23:20:46.000000000 +0100 +++ gdc-0.17/d/dmd/mangle.c 2005-05-29 23:09:19.000000000 +0200 @@ -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, May 2005 +*/ + #include #include #include @@ -62,7 +68,7 @@ char *Declaration::mangle() return ident->toChars(); default: - printf("'%s', linkage = %d\n", toChars(), linkage); + fprintf(stderr, "'%s', linkage = %d\n", toChars(), linkage); assert(0); } } diff -uNrp dmd-0.140/src/dmd/mars.h gdc-0.17/d/dmd/mars.h --- dmd-0.140/src/dmd/mars.h 2005-10-26 00:37:58.000000000 +0200 +++ gdc-0.17/d/dmd/mars.h 2005-11-27 17:28:26.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 +*/ + #ifndef DMD_MARS_H #define DMD_MARS_H @@ -60,6 +66,8 @@ struct Param unsigned versionlevel; // version level Array *versionids; // version identifiers + bool dump_source; + // Hidden debug switches char debuga; char debugb; @@ -109,9 +117,11 @@ extern Global global; #ifdef __DMC__ typedef _Complex long double complex_t; #else +#ifndef IN_GCC #include "complex_t.h" +#endif #ifdef __APPLE__ -#include "complex.h" +//#include "complex.h"//This causes problems with include the c++ and not the C "complex.h" #define integer_t dmd_integer_t #endif #endif @@ -123,7 +133,6 @@ typedef unsigned long long integer_t; typedef long long sinteger_t; typedef unsigned long long uinteger_t; -typedef long double real_t; typedef signed char d_int8; typedef unsigned char d_uns8; @@ -138,19 +147,29 @@ typedef float d_float32; typedef double d_float64; typedef long double d_float80; +// Note: this will be 2 bytes on Win32 systems, and 4 bytes under linux. typedef d_uns8 d_char; typedef d_uns16 d_wchar; typedef d_uns32 d_dchar; +#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 #endif -#if linux +// This needs a configuration test... +#ifndef _WIN32 #define writewchar write4 #endif +#ifdef IN_GCC +#include "d-gcc-complex_t.h" +#endif struct Module; @@ -177,8 +196,10 @@ struct Loc char *toChars(); }; +#ifndef GCC_SAFE_DMD #define TRUE 1 #define FALSE 0 +#endif #define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry // in interface vtbl[]'s diff -uNrp dmd-0.140/src/dmd/mem.c gdc-0.17/d/dmd/mem.c --- dmd-0.140/src/dmd/mem.c 2005-04-27 00:21:12.000000000 +0200 +++ gdc-0.17/d/dmd/mem.c 2005-05-29 23:09:19.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-0.140/src/dmd/mem.h gdc-0.17/d/dmd/mem.h --- dmd-0.140/src/dmd/mem.h 2004-03-26 23:11:52.000000000 +0100 +++ gdc-0.17/d/dmd/mem.h 2004-10-26 02:41:27.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 -typedef unsigned size_t; +#include // for size_t typedef void (*FINALIZERPROC)(void* pObj, void* pClientData); diff -uNrp dmd-0.140/src/dmd/module.c gdc-0.17/d/dmd/module.c --- dmd-0.140/src/dmd/module.c 2005-10-09 23:51:00.000000000 +0200 +++ gdc-0.17/d/dmd/module.c 2005-10-24 23:48:04.000000000 +0200 @@ -7,10 +7,18 @@ // 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 +#include "gdc_alloca.h" + #include "mars.h" #include "module.h" #include "parse.h" @@ -23,6 +31,10 @@ #define MARS 1 #include "html.h" +#ifdef IN_GCC +#include "d-dmd-gcc.h" +#endif + ClassDeclaration *Module::moduleinfo; DsymbolTable *Module::modules; @@ -51,6 +63,9 @@ Module::Module(char *filename, Identifie isHtml = 0; isDocFile = 0; needmoduleinfo = 0; +#ifdef IN_GCC + strictlyneedmoduleinfo = 0; +#endif insearch = 0; searchCacheIdent = NULL; searchCacheSymbol = NULL; @@ -204,6 +219,10 @@ Module *Module::load(Loc loc, Array *pac m->read(loc); m->parse(); +#ifdef IN_GCC + d_gcc_magic_module(m); +#endif + return m; } @@ -250,7 +269,7 @@ inline unsigned readlongBE(unsigned *p) (((unsigned char *)p)[0] << 24); } -void Module::parse() +void Module::parse(bool dump_source) { char *srcname; unsigned char *buf; unsigned buflen; @@ -421,6 +440,13 @@ void Module::parse() } } +#ifdef IN_GCC + // dump utf-8 encoded source + if(dump_source){ + // %% srcname could contain a path ... + d_gcc_dump_source(srcname, "utf-8", buf, buflen); + } +#endif /* IN_GCC */ /* If it starts with the string "Ddoc", then it's a documentation * source file. */ @@ -439,6 +465,12 @@ void Module::parse() h.extractCode(dbuf); buf = dbuf->data; buflen = dbuf->offset; +#ifdef IN_GCC + // dump extracted source + if(dump_source) { + d_gcc_dump_source(srcname, "d.utf-8", buf, buflen); + } +#endif } Parser p(this, buf, buflen, docfile != NULL); members = p.parseModule(); @@ -512,6 +544,7 @@ void Module::semantic() s = (Dsymbol *)members->data[i]; //printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars()); s->semantic(sc); + runDeferredSemantic(); } diff -uNrp dmd-0.140/src/dmd/module.h gdc-0.17/d/dmd/module.h --- dmd-0.140/src/dmd/module.h 2005-10-09 11:31:28.000000000 +0200 +++ gdc-0.17/d/dmd/module.h 2005-10-24 23:48:04.000000000 +0200 @@ -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 +*/ + #ifndef DMD_MODULE_H #define DMD_MODULE_H @@ -23,7 +29,7 @@ struct ModuleDeclaration; struct Macro; // Back end -struct elem; +union tree_node; typedef union tree_node elem; struct Package : ScopeDsymbol { @@ -56,6 +62,9 @@ struct Module : Package int isHtml; // if it is an HTML file int isDocFile; // if it is a documentation input file, not D source int needmoduleinfo; +#ifdef IN_GCC + int strictlyneedmoduleinfo; +#endif int insearch; Identifier *searchCacheIdent; @@ -91,7 +100,7 @@ struct Module : Package char *kind(); void setDocfile(); // set docfile member void read(Loc loc); // read file - void parse(); // syntactic parse + void parse(bool dump_source = false); // syntactic parse void semantic(); // semantic analysis void semantic2(); // pass 2 semantic analysis void semantic3(); // pass 3 semantic analysis diff -uNrp dmd-0.140/src/dmd/mtype.c gdc-0.17/d/dmd/mtype.c --- dmd-0.140/src/dmd/mtype.c 2005-11-23 14:47:42.000000000 +0100 +++ gdc-0.17/d/dmd/mtype.c 2005-11-28 05:17:52.000000000 +0100 @@ -7,26 +7,58 @@ // 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 "gdc_alloca.h" + #ifdef __DMC__ #include #endif #include +// 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 +#ifndef __GNUC__ +// includes the wrong complex.h in C++ #include +#endif #ifdef __APPLE__ #include 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 "mtype.h" @@ -96,7 +128,7 @@ Type::Type(TY ty, Type *next) Type *Type::syntaxCopy() { print(); - printf("ty = %d\n", ty); + fprintf(stderr, "ty = %d\n", ty); assert(0); return this; } @@ -167,7 +199,7 @@ void Type::init() for (i = 0; i < TMAX; i++) { if (!mangleChar[i]) - printf("ty = %d\n", i); + fprintf(stderr, "ty = %d\n", i); assert(mangleChar[i]); } @@ -581,18 +613,19 @@ void Type::error(Loc loc, const char *fo { char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stderr, "%s: ", p); mem.free(p); 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(); } Identifier *Type::getTypeInfoIdent(int internal) @@ -863,7 +896,11 @@ Expression *TypeBasic::getProperty(Loc l { Expression *e; d_int64 ivalue; +#ifdef IN_GCC + real_t fvalue; +#else d_float80 fvalue; +#endif //printf("TypeBasic::getProperty('%s')\n", ident->toChars()); if (ident == Id::max) @@ -885,6 +922,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: @@ -935,13 +1004,18 @@ Expression *TypeBasic::getProperty(Loc l case Tfloat32: case Tfloat64: case Tfloat80: -#if __GNUC__ +#ifdef IN_GCC + // mode doesn't matter, will be converted in RealExp anyway + fvalue = real_t::getnan(real_t::LongDouble); +#elif __GNUC__ { // gcc nan's have the sign bit set by default, so turn it off // Need the volatile to prevent gcc from doing incorrect // constant folding. volatile d_float80 foo; foo = NAN; - foo = -foo; + // This doesn't seem to be the case on the systems I'm using %% + if ( signbit(foo) ) + foo = -foo; fvalue = foo; } #else @@ -963,7 +1037,9 @@ Expression *TypeBasic::getProperty(Loc l case Tfloat32: case Tfloat64: case Tfloat80: -#if __GNUC__ +#ifdef IN_GCC + fvalue = real_t::getinfinity(); +#elif __GNUC__ fvalue = 1 / zero; #else fvalue = INFINITY; @@ -1133,7 +1209,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: @@ -1163,7 +1239,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: @@ -1362,7 +1438,7 @@ Expression *TypeArray::dotExp(Scope *sc, assert(size); nm = name[n->ty == Tbit][ident == Id::dup]; - fd = FuncDeclaration::genCfunc(Type::tindex, nm); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm); ec = new VarExp(0, fd); e = e->castTo(n->arrayOf()); // convert to dynamic array arguments = new Array(); @@ -1442,7 +1518,7 @@ void TypeArray::toCBuffer2(OutBuffer *bu buf->writeByte('['); dim = ((TypeSArray *)t)->dim; if (dim) - buf->printf("%d", dim->toInteger()); + buf->printf("%lld", dim->toInteger()); buf->writeByte(']'); t = t->next; } while (t->ty == Tsarray); @@ -1911,7 +1987,7 @@ Expression *TypeAArray::dotExp(Scope *sc else #endif strcpy(aakeys, "_aaKeys"); - fd = FuncDeclaration::genCfunc(Type::tindex, aakeys); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), aakeys); ec = new VarExp(0, fd); arguments = new Array(); arguments->push(e); @@ -1926,7 +2002,7 @@ Expression *TypeAArray::dotExp(Scope *sc FuncDeclaration *fd; Array *arguments; - fd = FuncDeclaration::genCfunc(Type::tindex, "_aaValues"); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), "_aaValues"); ec = new VarExp(0, fd); arguments = new Array(); arguments->push(e); @@ -1941,7 +2017,7 @@ Expression *TypeAArray::dotExp(Scope *sc FuncDeclaration *fd; Array *arguments; - fd = FuncDeclaration::genCfunc(Type::tint64, "_aaRehash"); + fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), "_aaRehash"); ec = new VarExp(0, fd); arguments = new Array(); arguments->push(e->addressOf()); diff -uNrp dmd-0.140/src/dmd/mtype.h gdc-0.17/d/dmd/mtype.h --- dmd-0.140/src/dmd/mtype.h 2005-11-09 10:25:10.000000000 +0100 +++ gdc-0.17/d/dmd/mtype.h 2005-11-28 05:17:52.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 +*/ + #ifndef DMD_MTYPE_H #define DMD_MTYPE_H @@ -35,7 +41,8 @@ enum LINK; struct TypeBasic; // Back end -typedef struct TYPE type; +union tree_node; typedef union tree_node TYPE; +typedef TYPE type; struct Symbol; enum TY diff -uNrp dmd-0.140/src/dmd/opover.c gdc-0.17/d/dmd/opover.c --- dmd-0.140/src/dmd/opover.c 2005-04-14 20:51:14.000000000 +0200 +++ gdc-0.17/d/dmd/opover.c 2005-05-29 23:09:19.000000000 +0200 @@ -6,16 +6,31 @@ // 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 #include #include -#if linux -#include "../root/mem.h" +#ifdef __APPLE__ +#define integer_t dmd_integer_t #endif -#if _WIN32 + +#if IN_GCC +#include "mem.h" +#elif linux +#include "../root/mem.h" +#elif _WIN32 #include "..\root\mem.h" #endif diff -uNrp dmd-0.140/src/dmd/parse.c gdc-0.17/d/dmd/parse.c --- dmd-0.140/src/dmd/parse.c 2005-11-10 10:59:38.000000000 +0100 +++ gdc-0.17/d/dmd/parse.c 2005-11-28 05:17:52.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 +*/ + #include #include @@ -3659,12 +3665,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; @@ -3724,17 +3730,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-0.140/src/dmd/root.c gdc-0.17/d/dmd/root.c --- dmd-0.140/src/dmd/root.c 2005-10-02 10:11:12.000000000 +0200 +++ gdc-0.17/d/dmd/root.c 2005-10-13 03:06:51.000000000 +0200 @@ -7,21 +7,25 @@ // 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 #include #include -#if _MSC_VER -#include -#endif +#include "gdc_alloca.h" #if _WIN32 #include #endif -#if linux +#ifndef _WIN32 #include #include #include @@ -115,11 +119,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); } @@ -130,11 +134,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); } @@ -154,11 +158,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 ********************************/ @@ -180,7 +184,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() @@ -298,7 +302,7 @@ char *String::toChars() void String::print() { - printf("String '%s'\n",str); + fprintf(stderr, "String '%s'\n",str); } @@ -320,14 +324,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++; } @@ -374,7 +378,7 @@ Array *FileName::splitPath(const char *p #if _WIN32 case ';': #endif -#if linux +#ifndef _WIN32 case ':': #endif p++; @@ -388,7 +392,7 @@ Array *FileName::splitPath(const char *p case '\r': continue; // ignore carriage returns -#if linux +#ifndef _WIN32 case '~': buf.writestring(getenv("HOME")); continue; @@ -416,7 +420,8 @@ Array *FileName::splitPath(const char *p unsigned FileName::hashCode() { -#if linux +#ifndef _WIN32 + // darwin HFS is case insensitive, though... return String::hashCode(); #endif #if _WIN32 @@ -461,7 +466,7 @@ unsigned FileName::hashCode() int FileName::compare(Object *obj) { -#if linux +#ifndef _WIN32 return String::compare(obj); #endif #if _WIN32 @@ -471,7 +476,7 @@ int FileName::compare(Object *obj) int FileName::equals(Object *obj) { -#if linux +#ifndef _WIN32 return String::equals(obj); #endif #if _WIN32 @@ -490,7 +495,7 @@ int FileName::absolute(const char *name) (*name == '/') || (*name && name[1] == ':'); #endif -#if linux +#ifndef _WIN32 return (*name == '/'); #endif } @@ -511,11 +516,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 +555,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 +593,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 +629,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 +705,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 +724,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 +766,7 @@ char *FileName::searchPath(Array *path, int FileName::exists(const char *name) { -#if linux +#ifndef _WIN32 struct stat st; if (stat(name, &st) < 0) @@ -830,7 +837,7 @@ void File::mark() int File::read() { -#if linux +#ifndef _WIN32 off_t size; ssize_t numread; int fd; @@ -854,21 +861,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; } @@ -877,7 +884,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; } @@ -962,7 +969,7 @@ err1: int File::mmread() { -#if linux +#ifndef _WIN32 return read(); #endif #if _WIN32 @@ -1016,7 +1023,7 @@ Lerr: int File::write() { -#if linux +#ifndef _WIN32 int fd; ssize_t numwritten; char *name; @@ -1087,7 +1094,7 @@ err: int File::append() { -#if linux +#ifndef _WIN32 return 1; #endif #if _WIN32 @@ -1167,7 +1174,7 @@ void File::appendv() int File::exists() { -#if linux +#ifndef _WIN32 return 0; #endif #if _WIN32 @@ -1192,7 +1199,7 @@ int File::exists() void File::remove() { -#if linux +#ifndef _WIN32 ::remove(this->name->toChars()); #endif #if _WIN32 @@ -1207,7 +1214,7 @@ Array *File::match(char *n) Array *File::match(FileName *n) { -#if linux +#ifndef _WIN32 return NULL; #endif #if _WIN32 @@ -1245,7 +1252,7 @@ Array *File::match(FileName *n) int File::compareTime(File *f) { -#if linux +#ifndef _WIN32 return 0; #endif #if _WIN32 @@ -1259,7 +1266,7 @@ int File::compareTime(File *f) void File::stat() { -#if linux +#ifndef _WIN32 if (!touchtime) { touchtime = mem.calloc(1, sizeof(struct stat)); @@ -1564,7 +1571,7 @@ void OutBuffer::vprintf(const char *form break; psize *= 2; #endif -#if linux +#ifndef _WIN32 count = vsnprintf(p,psize,format,args); if (count == -1) psize *= 2; @@ -1596,7 +1603,7 @@ void OutBuffer::vprintf(const wchar_t *f break; psize *= 2; #endif -#if linux +#ifndef _WIN32 count = vsnwprintf(p,psize,format,args); if (count == -1) psize *= 2; diff -uNrp dmd-0.140/src/dmd/root.h gdc-0.17/d/dmd/root.h --- dmd-0.140/src/dmd/root.h 2005-10-01 12:21:10.000000000 +0200 +++ gdc-0.17/d/dmd/root.h 2005-10-13 03:06:51.000000000 +0200 @@ -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 @@ -27,9 +33,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 diff -uNrp dmd-0.140/src/dmd/scope.c gdc-0.17/d/dmd/scope.c --- dmd-0.140/src/dmd/scope.c 2005-09-13 14:14:00.000000000 +0200 +++ gdc-0.17/d/dmd/scope.c 2005-10-02 16:17:55.000000000 +0200 @@ -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, May 2005 +*/ + #include #include @@ -226,7 +232,7 @@ Dsymbol *Scope::search(Identifier *ident sc->enclosing && sc->enclosing->search(ident, NULL)) { - printf("warning - "); + fprintf(stderr, "warning - "); error("array 'length' hides other 'length' name in outer scope"); } diff -uNrp dmd-0.140/src/dmd/statement.c gdc-0.17/d/dmd/statement.c --- dmd-0.140/src/dmd/statement.c 2005-08-25 23:54:26.000000000 +0200 +++ gdc-0.17/d/dmd/statement.c 2005-10-02 16:17:55.000000000 +0200 @@ -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 @@ -40,8 +46,8 @@ Statement *Statement::syntaxCopy() void Statement::print() { - printf("%s\n", toChars()); - fflush(stdout); + fprintf(stderr, "%s\n", toChars()); + fflush(stderr); } char *Statement::toChars() @@ -85,16 +91,16 @@ void Statement::error(const char *format { char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stderr, "%s: ", p); mem.free(p); 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++; } @@ -396,7 +402,7 @@ int CompoundStatement::fallOffEnd() if (!falloff && global.params.warnings && !s->comeFrom()) { - printf("warning - "); + fprintf(stderr, "warning - "); s->error("statement is not reachable"); } falloff = s->fallOffEnd(); @@ -1146,12 +1152,12 @@ Statement *PragmaStatement::semantic(Sco if (e->op == TOKstring) { StringExp *se = (StringExp *)e; - printf("%.*s", se->len, se->string); + fprintf(stderr, "%.*s", se->len, se->string); } else error("string expected for message, not '%s'", e->toChars()); } - printf("\n"); + fprintf(stderr, "\n"); } } else if (ident == Id::lib) @@ -1304,7 +1310,7 @@ Statement *SwitchStatement::semantic(Sco if (!sc->sw->sdefault) { if (global.params.warnings) - { printf("warning - "); + { fprintf(stderr, "warning - "); error("switch statement has no default"); } @@ -1440,6 +1446,7 @@ DefaultStatement::DefaultStatement(Loc l : Statement(loc) { this->statement = s; + cblock = NULL; } Statement *DefaultStatement::syntaxCopy() @@ -2144,6 +2151,7 @@ void Catch::semantic(Scope *sc) //printf("Catch::semantic()\n"); +#ifndef IN_GCC if (sc->tf) { /* This is because the _d_local_unwind() gets the stack munged @@ -2154,6 +2162,7 @@ void Catch::semantic(Scope *sc) */ error(loc, "cannot put catch statement inside finally block"); } +#endif sym = new ScopeDsymbol(); sym->parent = sc->scopesym; @@ -2449,6 +2458,7 @@ LabelDsymbol::LabelDsymbol(Identifier *i : Dsymbol(ident) { statement = NULL; + asmLabelNum = 0; } LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()? diff -uNrp dmd-0.140/src/dmd/statement.h gdc-0.17/d/dmd/statement.h --- dmd-0.140/src/dmd/statement.h 2005-06-30 00:41:36.000000000 +0200 +++ gdc-0.17/d/dmd/statement.h 2005-08-12 05:36:58.000000000 +0200 @@ -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 +*/ + #ifndef DMD_STATEMENT_H #define DMD_STATEMENT_H @@ -40,8 +46,8 @@ struct StaticAssert; // Back end struct IRState; struct Blockx; -struct block; -struct elem; +union tree_node; typedef union tree_node block; +union tree_node; typedef union tree_node elem; struct code; struct Statement : Object @@ -348,6 +354,7 @@ struct CaseStatement : Statement struct DefaultStatement : Statement { Statement *statement; + block *cblock; // back end: label for the block DefaultStatement(Loc loc, Statement *s); Statement *syntaxCopy(); @@ -593,6 +600,7 @@ struct LabelStatement : Statement struct LabelDsymbol : Dsymbol { LabelStatement *statement; + unsigned asmLabelNum; // GCC-specific LabelDsymbol(Identifier *ident); LabelDsymbol *isLabel(); diff -uNrp dmd-0.140/src/dmd/struct.c gdc-0.17/d/dmd/struct.c --- dmd-0.140/src/dmd/struct.c 2005-09-24 00:45:10.000000000 +0200 +++ gdc-0.17/d/dmd/struct.c 2005-10-13 03:06:51.000000000 +0200 @@ -236,6 +236,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(); diff -uNrp dmd-0.140/src/dmd/template.c gdc-0.17/d/dmd/template.c --- dmd-0.140/src/dmd/template.c 2005-11-20 23:24:52.000000000 +0100 +++ gdc-0.17/d/dmd/template.c 2005-11-28 05:17:52.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 +*/ + // Handle template implementation #include @@ -799,7 +805,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); @@ -807,11 +813,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()); } @@ -978,12 +984,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) @@ -1168,13 +1174,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"); } @@ -1238,6 +1244,9 @@ TemplateInstance::TemplateInstance(Loc l this->argsym = NULL; this->aliasdecl = NULL; this->semanticdone = 0; +#ifdef IN_GCC + this->objFileModule = NULL; +#endif } @@ -1280,10 +1289,25 @@ void TemplateInstance::addIdent(Identifi idents.push(ident); } +#ifdef IN_GCC +#include "d-dmd-gcc.h" +#endif + void TemplateInstance::semantic(Scope *sc) { #if LOG - printf("+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); + printf("+TemplateInstance::semantic('%s' (%p), this=%p)\n", toChars(), this, 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 { @@ -1406,16 +1430,54 @@ void TemplateInstance::semantic(Scope *s #if 1 { 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 { + //fprintf(stderr, "\t2: adding %s to module %s\n", tempdecl->toChars(), sc->module->importedFrom->toChars()); //printf("\t2: adding to module %s\n", sc->module->importedFrom->toChars()); a = sc->module->importedFrom->members; +#ifdef IN_GCC + objFileModule = sc->module->importedFrom; +#endif } for (i = 0; 1; i++) { diff -uNrp dmd-0.140/src/dmd/template.h gdc-0.17/d/dmd/template.h --- dmd-0.140/src/dmd/template.h 2005-09-19 10:29:16.000000000 +0200 +++ gdc-0.17/d/dmd/template.h 2005-11-28 05:17:52.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, May 2005 +*/ + #ifndef DMD_TEMPLATE_H #define DMD_TEMPLATE_H @@ -184,6 +190,12 @@ struct TemplateInstance : ScopeDsymbol // sole member int semanticdone; // has semantic() been done? int nest; // for recursion detection +#ifdef IN_GCC + /* On some targets, it is necessary to know whether a symbol + will be emitted in the output or not before the symbol + is used. This can be different from getModule(). */ + Module * objFileModule; +#endif TemplateInstance(Loc loc, Identifier *temp_id); Dsymbol *syntaxCopy(Dsymbol *); diff -uNrp dmd-0.140/src/dmd/tocsym.c gdc-0.17/d/dmd/tocsym.c --- dmd-0.140/src/dmd/tocsym.c 2005-05-31 17:55:54.000000000 +0200 +++ gdc-0.17/d/dmd/tocsym.c 2005-06-22 05:13:40.000000000 +0200 @@ -11,6 +11,9 @@ #include #include #include +#ifndef alloca +#include +#endif #include "mars.h" #include "module.h" @@ -78,7 +81,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()); assert(0); // BUG: implement return NULL; } @@ -214,7 +217,7 @@ Symbol *VarDeclaration::toSymbol() break; default: - printf("linkage = %d\n", linkage); + fprintf(stderr, "linkage = %d\n", linkage); assert(0); } type_setmangle(&t, m); @@ -315,7 +318,7 @@ Symbol *FuncDeclaration::toSymbol() break; default: - printf("linkage = %d\n", linkage); + fprintf(stderr, "linkage = %d\n", linkage); assert(0); } } diff -uNrp dmd-0.140/src/dmd/todt.c gdc-0.17/d/dmd/todt.c --- dmd-0.140/src/dmd/todt.c 2005-11-10 11:31:50.000000000 +0100 +++ gdc-0.17/d/dmd/todt.c 2005-11-28 05:17:52.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 +*/ + /* 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 @@ -15,12 +21,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" @@ -31,12 +42,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(); @@ -275,8 +288,6 @@ dt_t *ArrayInitializer::toDtBit() dt_t **pdtend; Type *tb = type->toBasetype(); - //printf("ArrayInitializer::toDtBit('%s')\n", toChars()); - Bits databits; Bits initbits; @@ -337,7 +348,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: @@ -395,6 +410,8 @@ dt_t **Expression::toDt(dt_t **pdt) return pdt; } +#ifndef IN_GCC + dt_t **IntegerExp::toDt(dt_t **pdt) { unsigned sz; @@ -438,7 +455,7 @@ dt_t **RealExp::toDt(dt_t **pdt) break; default: - printf("%s\n", toChars()); + fprintf(stderr, "%s\n", toChars()); type->print(); assert(0); break; @@ -484,6 +501,9 @@ dt_t **ComplexExp::toDt(dt_t **pdt) return pdt; } + +#endif + dt_t **NullExp::toDt(dt_t **pdt) { assert(type); @@ -499,14 +519,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, (char *)string); +#else + pdt = dtnwords(pdt, len, string, sz); +#endif if (tsa->dim) { dim = tsa->dim->toInteger(); @@ -519,11 +547,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; @@ -758,8 +790,13 @@ dt_t **TypeSArray::toDt(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-0.140/src/dmd/toobj.c gdc-0.17/d/dmd/toobj.c --- dmd-0.140/src/dmd/toobj.c 2005-10-24 00:51:42.000000000 +0200 +++ gdc-0.17/d/dmd/toobj.c 2005-10-26 03:33:56.000000000 +0200 @@ -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()) @@ -132,6 +198,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; @@ -165,13 +247,11 @@ void Module::genmoduleinfo() } /* ================================================================== */ - void Dsymbol::toObjFile() { //printf("Dsymbol::toObjFile('%s')\n", toChars()); // ignore } - /* ================================================================== */ void ClassDeclaration::toObjFile() @@ -829,6 +909,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) @@ -848,6 +929,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 { @@ -893,6 +986,15 @@ void VarDeclaration::toObjFile() if (isExport()) 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 } /* ================================================================== */ diff -uNrp dmd-0.140/src/dmd/typinf.c gdc-0.17/d/dmd/typinf.c --- dmd-0.140/src/dmd/typinf.c 2005-05-02 21:16:28.000000000 +0200 +++ gdc-0.17/d/dmd/typinf.c 2005-06-08 02:53:40.000000000 +0200 @@ -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 @@ -27,6 +33,7 @@ #include "aggregate.h" #include +#ifndef IN_GCC #include "cc.h" #include "global.h" #include "oper.h" @@ -36,6 +43,11 @@ #include "cgcv.h" #include "outbuf.h" #include "irstate.h" +#else +#include "symbol.h" +#include "dt.h" +#include "d-dmd-gcc.h" +#endif /******************************************* @@ -530,7 +542,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-0.140/src/phobos/acinclude.m4 gdc-0.17/d/phobos/acinclude.m4 --- dmd-0.140/src/phobos/acinclude.m4 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/acinclude.m4 2005-05-29 23:09:19.000000000 +0200 @@ -0,0 +1,226 @@ +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])]) + +dnl -pthread doesn't work because, by putting it in specs, it is passed +dnl to the linker instead of being interpreted by the driver... +dnl -lc_r ins't quite right because there is also a -lc_r_p +# -pthread + +if test -z "$d_thread_lib"; then + AC_MSG_CHECKING([for thread library linker argument]) + d_thread_lib=error + for thrd_lib in "" -lc_r -lpthread -ldce; do + d_savelibs=$LIBS + LIBS="$LIBS $thrd_lib" + + AC_TRY_LINK([#include ],[ + pthread_create(0,0,0,0);], + [d_thread_lib=$thrd_lib], + :) + + LIBS=$d_savelibs + + if test "$d_thread_lib" != "error"; then + break + fi + done + case "$d_thread_lib" in + error) AC_MSG_ERROR([Not found! You may need to use --enable-thread-lib]) ;; + -*) AC_MSG_RESULT([$d_thread_lib]) ;; + *) AC_MSG_RESULT([none needed]) ;; + esac +fi +LIBS="$LIBS $d_thread_lib" + +dnl BSD socket configuration. Since there is only Windows vs. Unix +dnl configuration for std.socket... + +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" ;; + *) 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]) + +RECLS_CXXFLAGS="$RECLS_CXXFLAGS -Dunix" +D_RECLS_OS=unix + +D_EXTRA_OBJS="gcc/configunix.o gcc/cbridge_fdset.o std/c/unix/unix.o $D_EXTRA_OBJS" +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 "$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 + ;; + *) 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_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 + +]) \ Ingen nyrad vid filslut diff -uNrp dmd-0.140/src/phobos/aclocal.m4 gdc-0.17/d/phobos/aclocal.m4 --- dmd-0.140/src/phobos/aclocal.m4 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/aclocal.m4 2005-05-29 23:09:19.000000000 +0200 @@ -0,0 +1,239 @@ +# aclocal.m4 generated automatically by aclocal 1.6.3 -*- Autoconf -*- + +# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# 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. + +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])]) + +dnl -pthread doesn't work because, by putting it in specs, it is passed +dnl to the linker instead of being interpreted by the driver... +dnl -lc_r ins't quite right because there is also a -lc_r_p +# -pthread + +if test -z "$d_thread_lib"; then + AC_MSG_CHECKING([for thread library linker argument]) + d_thread_lib=error + for thrd_lib in "" -lc_r -lpthread -ldce; do + d_savelibs=$LIBS + LIBS="$LIBS $thrd_lib" + + AC_TRY_LINK([#include ],[ + pthread_create(0,0,0,0);], + [d_thread_lib=$thrd_lib], + :) + + LIBS=$d_savelibs + + if test "$d_thread_lib" != "error"; then + break + fi + done + case "$d_thread_lib" in + error) AC_MSG_ERROR([Not found! You may need to use --enable-thread-lib]) ;; + -*) AC_MSG_RESULT([$d_thread_lib]) ;; + *) AC_MSG_RESULT([none needed]) ;; + esac +fi +LIBS="$LIBS $d_thread_lib" + +dnl BSD socket configuration. Since there is only Windows vs. Unix +dnl configuration for std.socket... + +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" ;; + *) 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]) + +RECLS_CXXFLAGS="$RECLS_CXXFLAGS -Dunix" +D_RECLS_OS=unix + +D_EXTRA_OBJS="gcc/configunix.o gcc/cbridge_fdset.o std/c/unix/unix.o $D_EXTRA_OBJS" +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 "$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 + ;; + *) 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_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-0.140/src/phobos/etc/c/stlsoft/stlsoft.h gdc-0.17/d/phobos/etc/c/stlsoft/stlsoft.h --- dmd-0.140/src/phobos/etc/c/stlsoft/stlsoft.h 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/stlsoft/stlsoft.h 2005-08-12 04:32:44.000000000 +0200 @@ -378,7 +378,8 @@ # define __STLSOFT_COMPILER_IS_GCC # define __STLSOFT_COMPILER_LABEL_STRING "GNU C/C++" # if __GNUC__ != 2 && \ - __GNUC__ != 3 + __GNUC__ != 3 && \ + __GNUC__ != 4 # error GNU C/C++ compilers whose major version is not 2 or 3 are not currently supported by the STLSoft libraries # elif __GNUC__ == 2 # if __GNUC_MINOR__ < 95 @@ -396,6 +397,8 @@ # else # define __STLSOFT_COMPILER_VERSION_STRING "GNU C/C++ >3.2 - you should be aware that this version may not be supported correctly" # endif /* __GNUC__ != 2 */ +# elif __GNUC__ == 4 +# define __STLSOFT_COMPILER_VERSION_STRING "GNU C/C++ >= 4.0 - you should be aware that this version may not be supported correctly" # endif /* __GNUC__ */ #elif defined(__INTEL_COMPILER) diff -uNrp dmd-0.140/src/phobos/etc/c/stlsoft/unixstl_glob_sequence.h gdc-0.17/d/phobos/etc/c/stlsoft/unixstl_glob_sequence.h --- dmd-0.140/src/phobos/etc/c/stlsoft/unixstl_glob_sequence.h 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/stlsoft/unixstl_glob_sequence.h 2005-08-12 04:32:44.000000000 +0200 @@ -56,6 +56,12 @@ * * ////////////////////////////////////////////////////////////////////////// */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + #ifndef _INCL_UNIXSTL_H_UNIXSTL_GLOB_SEQUENCE #define _INCL_UNIXSTL_H_UNIXSTL_GLOB_SEQUENCE @@ -82,6 +88,7 @@ #endif /* !_STLSOFT_INCL_H_STLSOFT_ITERATOR */ #include #include +#include #include /* ///////////////////////////////////////////////////////////////////////////// @@ -182,7 +189,7 @@ public: > const_reverse_iterator; public: - enum + enum flags { includeDots = 0x0008 /*!< Requests that dots directories be included in the returned sequence */ , directories = 0x0010 /*!< Causes the search to include directories */ @@ -364,7 +371,11 @@ private: if((m_flags & (directories | files)) == directories) { +#ifdef GLOB_ONLYDIR glob_flags |= GLOB_ONLYDIR; +#else +#define UNIXSTL_GLOB_SEQUENCE_ULTRA_CAUTIOUS +#endif } if(0 == glob(pattern, glob_flags, NULL, &m_gl)) @@ -416,11 +427,15 @@ private: // We should be able to trust glob() to return only directories when // asked, so we assume the following only needs to be done when // have asked for files alone +#ifdef GLOB_ONLYDIR #ifdef UNIXSTL_GLOB_SEQUENCE_ULTRA_CAUTIOUS if((m_flags & (directories | files)) != (directories | files)) #else /* ? UNIXSTL_GLOB_SEQUENCE_ULTRA_CAUTIOUS */ if((m_flags & (directories | files)) == files) #endif /* UNIXSTL_GLOB_SEQUENCE_ULTRA_CAUTIOUS */ +#else + if (1) +#endif { char_type **begin = base; char_type **end = begin + cItems; diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/adler32.c gdc-0.17/d/phobos/etc/c/zlib/adler32.c --- dmd-0.140/src/phobos/etc/c/zlib/adler32.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/adler32.c 2004-10-26 02:41:27.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: adler32.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/ChangeLog gdc-0.17/d/phobos/etc/c/zlib/ChangeLog --- dmd-0.140/src/phobos/etc/c/zlib/ChangeLog 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/ChangeLog 2004-10-26 02:41:27.000000000 +0200 @@ -466,7 +466,7 @@ Changes in 1.0.6 (19 Jan 1998) - use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) - added makelcc.bat for lcc-win32 (Tom St Denis) - in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- Avoid expanded $Id: ChangeLog,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. - check for unistd.h in configure (for off_t) - remove useless check parameter in inflate_blocks_free - avoid useless assignment of s->check to itself in inflate_blocks_new diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/compress.c gdc-0.17/d/phobos/etc/c/zlib/compress.c --- dmd-0.140/src/phobos/etc/c/zlib/compress.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/compress.c 2004-10-26 02:41:27.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: compress.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/crc32.c gdc-0.17/d/phobos/etc/c/zlib/crc32.c --- dmd-0.140/src/phobos/etc/c/zlib/crc32.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/crc32.c 2004-10-26 02:41:27.000000000 +0200 @@ -9,7 +9,7 @@ * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ -/* @(#) $Id$ */ +/* @(#) $Id: crc32.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #ifdef MAKECRCH # include diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/deflate.c gdc-0.17/d/phobos/etc/c/zlib/deflate.c --- dmd-0.140/src/phobos/etc/c/zlib/deflate.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/deflate.c 2004-10-26 02:41:27.000000000 +0200 @@ -47,7 +47,7 @@ * */ -/* @(#) $Id$ */ +/* @(#) $Id: deflate.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include "deflate.h" diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/deflate.h gdc-0.17/d/phobos/etc/c/zlib/deflate.h --- dmd-0.140/src/phobos/etc/c/zlib/deflate.h 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/deflate.h 2004-10-26 02:41:27.000000000 +0200 @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id$ */ +/* @(#) $Id: deflate.h,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #ifndef DEFLATE_H #define DEFLATE_H diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/example.c gdc-0.17/d/phobos/etc/c/zlib/example.c --- dmd-0.140/src/phobos/etc/c/zlib/example.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/example.c 2004-10-26 02:41:27.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: example.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include #include "zlib.h" diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/gzio.c gdc-0.17/d/phobos/etc/c/zlib/gzio.c --- dmd-0.140/src/phobos/etc/c/zlib/gzio.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/gzio.c 2004-10-26 02:41:27.000000000 +0200 @@ -5,7 +5,7 @@ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. */ -/* @(#) $Id$ */ +/* @(#) $Id: gzio.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/minigzip.c gdc-0.17/d/phobos/etc/c/zlib/minigzip.c --- dmd-0.140/src/phobos/etc/c/zlib/minigzip.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/minigzip.c 2004-10-26 02:41:27.000000000 +0200 @@ -13,7 +13,7 @@ * or in pipe mode. */ -/* @(#) $Id$ */ +/* @(#) $Id: minigzip.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include #include "zlib.h" diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/trees.c gdc-0.17/d/phobos/etc/c/zlib/trees.c --- dmd-0.140/src/phobos/etc/c/zlib/trees.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/trees.c 2004-10-26 02:41:27.000000000 +0200 @@ -29,7 +29,7 @@ * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ -/* @(#) $Id$ */ +/* @(#) $Id: trees.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ /* #define GEN_TREES_H */ diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/uncompr.c gdc-0.17/d/phobos/etc/c/zlib/uncompr.c --- dmd-0.140/src/phobos/etc/c/zlib/uncompr.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/uncompr.c 2004-10-26 02:41:27.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: uncompr.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #define ZLIB_INTERNAL #include "zlib.h" diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/zconf.h gdc-0.17/d/phobos/etc/c/zlib/zconf.h --- dmd-0.140/src/phobos/etc/c/zlib/zconf.h 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/zconf.h 2004-10-26 02:41:27.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: zconf.h,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #ifndef ZCONF_H #define ZCONF_H diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/zconf.in.h gdc-0.17/d/phobos/etc/c/zlib/zconf.in.h --- dmd-0.140/src/phobos/etc/c/zlib/zconf.in.h 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/zconf.in.h 2004-10-26 02:41:27.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: zconf.in.h,v 1.1 2004/09/29 02:19:34 davidfriedman Exp $ */ #ifndef ZCONF_H #define ZCONF_H diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/zutil.c gdc-0.17/d/phobos/etc/c/zlib/zutil.c --- dmd-0.140/src/phobos/etc/c/zlib/zutil.c 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/zutil.c 2004-10-26 02:41:27.000000000 +0200 @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: zutil.c,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #include "zutil.h" diff -uNrp dmd-0.140/src/phobos/etc/c/zlib/zutil.h gdc-0.17/d/phobos/etc/c/zlib/zutil.h --- dmd-0.140/src/phobos/etc/c/zlib/zutil.h 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/etc/c/zlib/zutil.h 2004-10-26 02:41:27.000000000 +0200 @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id$ */ +/* @(#) $Id: zutil.h,v 1.2 2004/09/29 02:26:32 davidfriedman Exp $ */ #ifndef ZUTIL_H #define ZUTIL_H diff -uNrp dmd-0.140/src/phobos/etc/gamma.d gdc-0.17/d/phobos/etc/gamma.d --- dmd-0.140/src/phobos/etc/gamma.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/etc/gamma.d 2005-10-29 04:40:46.000000000 +0200 @@ -0,0 +1,512 @@ +/** +Macros: + GAMMA = Γ + INTEGRAL = ∫ +*/ +module etc.gamma; + +private import std.math; +private import std.stdio; + +//------------------------------------------------------------------ +const real SQRT2PI = 2.50662827463100050242E0L; // sqrt(2pi) +// 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 +]; + +static real GammaDenominatorCoeffs[] = [ + 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 + -0x1.4fcf4026afa2f7ecp-1, // -0.65587807152025406846 + -0x1.5815e8fa24d7e306p-5, // -0.042002635034033440541 + 0x1.5512320aea2ad71ap-3, // 0.16653861137208052067 + -0x1.59af0fb9d82e216p-5, // -0.042197733607059154702 + -0x1.3b4b61d3bfdf244ap-7, // -0.0096220233604062716456 + 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 + -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 +]; + +static real logGammaStirlingCoeffs[] = [ + 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 +]; + +static real logGammaNumerator[] = [ + -0x1.0edd25913aaa40a2p+23, // -8875666.7836507038022 + -0x1.31c6ce2e58842d1ep+24, // -20039374.181038151756 + -0x1.f015814039477c3p+23, // -16255680.62543700591 + -0x1.74ffe40c4b184b34p+22, // -6111225.0120052143001 + -0x1.0d9c6d08f9eab55p+20, // -1104326.8146914642612 + -0x1.54c6b71935f1fc88p+16, // -87238.715228435114593 + -0x1.0e761b42932b2aaep+11 // -2163.6908276438128575 +]; + +static real logGammaDenominator[] = [ + -0x1.4055572d75d08c56p+24, // -20993367.177578958762 + -0x1.deeb6013998e4d76p+24, // -31386464.076561826621 + -0x1.106f7cded5dcc79ep+24, // -17854332.870450781569 + -0x1.25e17184848c66d2p+22, // -4814940.3794118821866 + -0x1.301303b99a614a0ap+19, // -622744.11640662195015 + -0x1.09e76ab41ae965p+15, // -34035.708405343046707 + -0x1.00f95ced9e5f54eep+9, // -513.94814844353701437 + 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)) + +*/ +real gammaStirling(real x) +{ + 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; +} + +/***************************************************** + * The Gamma function, $(GAMMA)(x) + * + * Generalizes the factorial function to real and complex numbers. + * Like x!, $(GAMMA)(x+1) = x*$(GAMMA)(x). + * + * Mathematically, if z.re > 0 then + * $(GAMMA)(z) =$(INTEGRAL)0&infintz-1e-tdt + * + * This function is equivalent to tgamma() in the C programming language. + * + * + * + *
Special Values
x $(GAMMA)(x) invalid? + *
NAN NAN yes + *
±0.0 ±∞ yes + *
integer > 0 (x-1)! no + *
integer < 0 NAN yes + *
+∞ +∞ no + *
-∞ NAN yes + *
+ * + * References: + * cephes, http://en.wikipedia.org/wiki/Gamma_function + * + */ +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. + + 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 )); + } else { + return z / (x * poly( x, GammaSmallCoeffs )); + } + } + } + + 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 ); +} + +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); +} + +/***************************************************** + * Natural logarithm of gamma function. + * + * Returns the base e (2.718...) logarithm of the absolute + * value of the gamma function of the argument. + * + * For reals, lgamma is equivalent to log(fabs(tgamma(x)). + * + * + * + *
Special Values
x log$(GAMMA)(x) invalid? + *
NaN NaN yes + *
integer <= 0 +∞ yes + *
1, 2 +0.0 no + *
±∞ +∞ no + *
+ * + */ +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 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 ); + } + + 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)); + } 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; + + /* 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 ; +} + +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, + 4.57477139169563904215E1L, + 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); +} + +/** + 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) { @@ -105,7 +110,7 @@ extern (C) long _adReverseChar(char[] a) hi = hi - 1 + (stridehi - stridelo); } } - return *cast(long*)(&a); + return *cast(Array*)(&a); } unittest @@ -137,7 +142,7 @@ unittest * reversed. */ -extern (C) long _adReverseWchar(wchar[] a) +extern (C) Array _adReverseWchar(wchar[] a) { if (a.length > 1) { @@ -195,7 +200,7 @@ extern (C) long _adReverseWchar(wchar[] hi = hi - 1 + (stridehi - stridelo); } } - return *cast(long*)(&a); + return *cast(Array*)(&a); } unittest @@ -215,15 +220,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, int szelem) +extern (C) Array _adReverse(Array a, int szelem) out (result) { - assert(result is *cast(long*)(&a)); + assert(result is a); } body { @@ -262,7 +415,7 @@ extern (C) long _adReverse(Array a, int //delete tmp; } } - return *cast(long*)(&a); + return a; } unittest @@ -407,10 +560,10 @@ unittest * Support for array.dup property. */ -extern (C) long _adDup(Array a, int szelem) +extern (C) Array _adDup(Array a, int szelem) out (result) { - assert(memcmp((*cast(Array*)&result).ptr, a.ptr, a.length * szelem) == 0); + assert(memcmp(result.ptr, a.ptr, a.length * szelem) == 0); } body { @@ -421,7 +574,7 @@ extern (C) long _adDup(Array a, int szel r.ptr = cast(void *) new byte[size]; r.length = a.length; memcpy(r.ptr, a.ptr, size); - return *cast(long*)(&r); + return r; } unittest @@ -444,10 +597,10 @@ unittest * Support for array.dup property for bit[]. */ -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 { @@ -458,7 +611,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 @@ -531,8 +684,8 @@ extern (C) int _adEqBit(Array a1, Array if (a1.length != a2.length) return 0; // not equal - byte *p1 = cast(byte*)a1.ptr; - byte *p2 = cast(byte*)a2.ptr; + ubyte *p1 = cast(ubyte*)a1.ptr; + ubyte *p2 = cast(ubyte*)a2.ptr; uint n = a1.length / 8; for (i = 0; i < n; i++) { @@ -607,151 +760,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. @@ -777,6 +785,8 @@ extern (C) int _adCmpBit(Array a1, Array { ubyte mask = 1 << j; int c; + // need != 0, otherwise comparison on bit 31 would be wrong... + //c = (int)((p1[i] & mask) != 0) - (int)((p2[i] & mask) != 0); c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask); if (c) return c; diff -uNrp dmd-0.140/src/phobos/internal/cmain.d gdc-0.17/d/phobos/internal/cmain.d --- dmd-0.140/src/phobos/internal/cmain.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/cmain.d 2005-04-28 23:12:43.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-0.140/src/phobos/internal/critical.c gdc-0.17/d/phobos/internal/critical.c --- dmd-0.140/src/phobos/internal/critical.c 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/internal/critical.c 2005-04-28 23:12:43.000000000 +0200 @@ -2,6 +2,14 @@ // All Rights Reserved // 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 +*/ + +#include "config.h" + /* ================================= Win32 ============================ */ #if _WIN32 @@ -73,16 +81,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. @@ -115,7 +129,7 @@ void _d_criticalenter(D_CRITICAL_SECTION { dcs->next = dcs_list; dcs_list = dcs; - pthread_mutex_init(&dcs->cs, &_criticals_attr); + pthread_mutex_init(&dcs->cs, & _criticals_attr); } pthread_mutex_unlock(&critical_section.cs); } @@ -124,7 +138,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); } @@ -133,7 +147,7 @@ void _STI_critical_init() if (!dcs_list) { //printf("_STI_critical_init()\n"); pthread_mutexattr_init(&_criticals_attr); - pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE); // The global critical section doesn't need to be recursive pthread_mutex_init(&critical_section.cs, 0); diff -uNrp dmd-0.140/src/phobos/internal/dgccmain2.d gdc-0.17/d/phobos/internal/dgccmain2.d --- dmd-0.140/src/phobos/internal/dgccmain2.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/dgccmain2.d 2005-09-09 23:27:05.000000000 +0200 @@ -0,0 +1,97 @@ + +/* 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.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(); + +/*********************************** + * 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 servers 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; + // Win32: original didn't do this -- what about Gcc? + _STI_monitor_staticctor(); + _STI_critical_init(); + gc_init(); + version (GNU_CBridge_Stdio) + _d_gnu_cbridge_init_stdio(); + am = cast(char[] *) malloc(argc * (char[]).sizeof); + + try + { + _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(); + } + catch (Object o) + { + printf("Error: "); + o.print(); + exit(EXIT_FAILURE); + } + + free(am); + _STD_critical_term(); + _STD_monitor_staticdtor(); + + return result; +} diff -uNrp dmd-0.140/src/phobos/internal/gc/gcbits.d gdc-0.17/d/phobos/internal/gc/gcbits.d --- dmd-0.140/src/phobos/internal/gc/gcbits.d 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gcbits.d 2004-10-26 02:41:27.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.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-0.140/src/phobos/internal/gc/gc_c.h gdc-0.17/d/phobos/internal/gc/gc_c.h --- dmd-0.140/src/phobos/internal/gc/gc_c.h 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gc_c.h 2005-04-28 23:12:43.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-0.140/src/phobos/internal/gc/gc.d gdc-0.17/d/phobos/internal/gc/gc.d --- dmd-0.140/src/phobos/internal/gc/gc.d 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gc.d 2005-11-27 16:59:45.000000000 +0100 @@ -19,8 +19,18 @@ * be misrepresented as being the original software. * o This notice may not be removed or altered from any source * distribution. + * + * Modifications from original software: + * + * 2004-09-24 David Friedman -- Modified to work with the D GCC compiler */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // Storage allocation @@ -193,37 +203,70 @@ void _d_delclass(Object *p) } } -ulong _d_new(uint length, uint size) +Array _d_new(uint length, uint 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; } +/+ +byte[] _d_new(uint length, uint size) +{ + void *p; -ulong _d_newarrayi(uint length, uint size, ...) + debug(PRINTF) printf("_d_newarray(length = %d, size = %d)\n", length, size); + if (length && size) + { + p = _gc.malloc(length * size); + debug(PRINTF) printf(" p = %p\n", p); + memset(p, 0, length * size); + return (cast(byte*)p)[0..length]; + } else + return null; +} ++/ + +Array _d_newarrayi(uint length, uint size, ...) { 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!(uint)(q, size); // q is pointer to ... initializer + version (BigEndian) + { + switch(size) { + case 1: q = cast(va_list)( cast(byte*)q + 3 ); break; + case 2: q = cast(va_list)( cast(byte*)q + 2 ); break; + default: + ; + } + } p = _gc.malloc(length * size + 1); debug(PRINTF) printf(" p = %p\n", p); if (size == 1) @@ -235,28 +278,57 @@ ulong _d_newarrayi(uint length, uint siz memcpy(p + u * size, q, size); } } - 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_newbitarray(uint length, bit value) +Array _d_newarrayip(uint length, uint size, void * init) +{ + Array result; + + if (length && size) + { + result.length = length; + result.data = cast(byte*) _gc.malloc(length * size + 1); + if (size == 1) + memset(result.data, * cast(ubyte*) init, length); + else + { + void * p = result.data; + for (uint u = 0; u < length; u++) + { + memcpy(p, init, size); + p += size; + } + } + } + return result; +} + + +Array _d_newbitarray(uint length, bit value) { void *p; - ulong result; + Array result; debug(PRINTF) printf("_d_newbitarray(length = %d, value = %d)\n", length, value); + /* if (length == 0) result = 0; else - { uint size = (length + 8) >> 3; // number of bytes + */ + if (length) + { uint size = ((length + 31) >> 5) * 4 + 1; // number of bytes + // (not sure what the extra byte is for...) ubyte fill = value ? 0xFF : 0; p = _gc.malloc(size); debug(PRINTF) printf(" p = %p\n", p); memset(p, fill, size); - result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); + result.length = length; + result.data = cast(byte*)p; } return result; } @@ -442,7 +514,7 @@ bit[] _d_arraysetlengthb(uint newlength, */ extern (C) -long _d_arrayappend(Array *px, byte[] y, uint size) +Array _d_arrayappend(Array *px, byte[] y, uint size) { uint cap = _gc.capacity(px.data); @@ -458,11 +530,11 @@ long _d_arrayappend(Array *px, byte[] y, } px.length = newlength; memcpy(px.data + length * size, y, y.length * size); - return *cast(long*)px; + return *px; } extern (C) -long _d_arrayappendb(Array *px, bit[] y) +Array _d_arrayappendb(Array *px, bit[] y) { uint cap = _gc.capacity(px.data); @@ -489,7 +561,7 @@ long _d_arrayappendb(Array *px, bit[] y) x[length + u] = y[u]; } } - return *cast(long*)px; + return *px; } @@ -577,7 +649,20 @@ byte[] _d_arrayappendc(inout byte[] x, i byte *argp = cast(byte *)(&size + 1); *cast(size_t *)&x = newlength; - (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; + version (LittleEndian) { + (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; + } else { + switch (size) { + case 1: + (cast(byte*)x)[length] = *(argp+3); + break; + case 2: + (cast(short*)x)[length] = *cast(short*)(argp+2); + break; + default: + (cast(byte *)x)[length * size .. newlength * size] = argp[0 .. size]; + } + } assert((cast(uint)x.ptr & 15) == 0); assert(_gc.capacity(x.ptr) > x.length * size); return x; diff -uNrp dmd-0.140/src/phobos/internal/gc/gc_dyld.c gdc-0.17/d/phobos/internal/gc/gc_dyld.c --- dmd-0.140/src/phobos/internal/gc/gc_dyld.c 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gc_dyld.c 2005-04-28 23:12:43.000000000 +0200 @@ -0,0 +1,80 @@ +// 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 } +}; + + +/* This should never be called by a thread holding the lock */ +static void +on_dyld_add_image(struct mach_header* hdr, unsigned long slide) { + unsigned i; + unsigned long start, end; + const struct section *sec; + + for (i = 0; + i < sizeof(GC_dyld_sections) / sizeof(GC_dyld_sections[0]); + i++) { + + sec = getsectbynamefromheader(hdr, GC_dyld_sections[i].seg, + GC_dyld_sections[i].sect); + 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(struct mach_header* hdr, unsigned long slide) { + unsigned i; + unsigned long start, end; + const struct section *sec; + + for(i = 0; + i < sizeof(GC_dyld_sections) / sizeof(GC_dyld_sections[0]); + i++) { + + sec = getsectbynamefromheader(hdr, + GC_dyld_sections[i].seg, GC_dyld_sections[i].sect); + 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-0.140/src/phobos/internal/gc/gc_freebsd.c gdc-0.17/d/phobos/internal/gc/gc_freebsd.c --- dmd-0.140/src/phobos/internal/gc/gc_freebsd.c 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gc_freebsd.c 2005-05-29 23:09:19.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-0.140/src/phobos/internal/gc/gcgcc.d gdc-0.17/d/phobos/internal/gc/gcgcc.d --- dmd-0.140/src/phobos/internal/gc/gcgcc.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gcgcc.d 2005-08-12 04:32:44.000000000 +0200 @@ -0,0 +1,245 @@ +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(uint 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, uint offset, uint nbytes) + { + return 0; + } + + int os_mem_decommit(void *base, uint offset, uint nbytes) + { + return 0; + } + + int os_mem_unmap(void *base, uint nbytes) + { + return munmap(base, nbytes); + } + +} +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) + return cast(void*) 0xc0000000; + 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, uint *nbytes) +{ + // Can't assume the input addresses are word-aligned + static void * adjust_up(void * p) + { + const int S = (void *).sizeof; + return p + ((S - (cast(uint)p & (S-1))) & (S-1)); // cast ok even if 64-bit + } + static void * adjust_down(void * p) + { + const int S = (void *).sizeof; + return p - (cast(uint) 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) + version (GNU_BitsPerPointer32) { + enum Ofs { + Write_Prot = 19, + Start_Addr = 0, + End_Addr = 9, + Addr_Len = 8, + } + } else version (GNU_BitsPerPointer64) { + 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-0.140/src/phobos/internal/gc/gcgccextern.d gdc-0.17/d/phobos/internal/gc/gcgccextern.d --- dmd-0.140/src/phobos/internal/gc/gcgccextern.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gcgccextern.d 2005-05-29 23:09:19.000000000 +0200 @@ -0,0 +1,62 @@ +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 (bsd) + { + // 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 (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 (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 } + } +} + +enum DataSegmentTracking { + ExecutableOnly, + LoadTimeLibrariesOnly, + Dynamic +} diff -uNrp dmd-0.140/src/phobos/internal/gc/gc_guess_stack.d gdc-0.17/d/phobos/internal/gc/gc_guess_stack.d --- dmd-0.140/src/phobos/internal/gc/gc_guess_stack.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gc_guess_stack.d 2005-04-28 23:12:43.000000000 +0200 @@ -0,0 +1,3 @@ +module gcc.gc_guess_stack; +void * stackOriginGuess; + diff -uNrp dmd-0.140/src/phobos/internal/gc/gcx.d gdc-0.17/d/phobos/internal/gc/gcx.d --- dmd-0.140/src/phobos/internal/gc/gcx.d 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/gcx.d 2005-08-12 04:32:44.000000000 +0200 @@ -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, September 2004 +*/ + // D Garbage Collector implementation /************** Debugging ***************************/ @@ -36,16 +42,28 @@ import std.outofmemory; import std.gc; import gcstats; +version (GNU) +{ + private import gcc.builtins; +} + version (Win32) { import win32; } - -version (linux) +else version (GNU) +{ + private import gcgcc; +} +else version (linux) { import gclinux; } +version (BigEndian) + private import std.intrinsic; + + version (MULTI_THREADED) { @@ -55,6 +73,8 @@ version (MULTI_THREADED) //alias GC* gc_t; alias GC gc_t; +version (X86) version (D_InlineAsm) { version = Asm86; } + /* ======================= Leak Detector =========================== */ debug (LOGGING) @@ -181,7 +201,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()); } @@ -543,7 +567,13 @@ class GC //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"); } @@ -553,7 +583,13 @@ class GC uint nbytes; os_query_staticdataseg(&pbot, &nbytes); - g.removeRange(pbot); + version (GNU) { + if (pbot) { + g.removeRange(pbot); + } + } else { + g.removeRange(pbot); + } } @@ -939,7 +975,7 @@ 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) { @@ -963,7 +999,7 @@ 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--;) { @@ -1360,15 +1396,30 @@ struct Gcx // get put on the stack so they'll be scanned void *sp; uint result; - asm + 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; } @@ -1437,7 +1488,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()); @@ -1508,6 +1570,8 @@ struct Gcx *b = 0; o = pool.baseAddr + (b - bbase) * 32 * 16; + version (BigEndian) + bitm = bswap(bitm); if (!(bitm & 0xFFFF)) { bitm >>= 16; @@ -1751,7 +1815,7 @@ struct Gcx Log log; log.p = p; - log.sizeof = size; + log.size = size; log.line = GC.line; log.file = GC.file; log.parent = null; diff -uNrp dmd-0.140/src/phobos/internal/gc/win32.d gdc-0.17/d/phobos/internal/gc/win32.d --- dmd-0.140/src/phobos/internal/gc/win32.d 2005-11-24 17:12:56.000000000 +0100 +++ gdc-0.17/d/phobos/internal/gc/win32.d 2005-04-28 23:12:43.000000000 +0200 @@ -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-0.140/src/phobos/internal/memset.d gdc-0.17/d/phobos/internal/memset.d --- dmd-0.140/src/phobos/internal/memset.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/internal/memset.d 2005-05-29 23:09:19.000000000 +0200 @@ -21,6 +21,11 @@ * 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) { @@ -42,7 +47,7 @@ short *_memset16(short *p, short value, int *_memset32(int *p, int value, int count) { -version (X86) +version (Asm86) { asm { diff -uNrp dmd-0.140/src/phobos/internal/monitor.c gdc-0.17/d/phobos/internal/monitor.c --- dmd-0.140/src/phobos/internal/monitor.c 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/internal/monitor.c 2004-10-26 02:41:27.000000000 +0200 @@ -1,8 +1,17 @@ + + // Copyright (c) 2000-2004 by Digital Mars // All Rights Reserved // 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, September 2004 +*/ + +#include "config.h" #include @@ -87,14 +96,17 @@ void _d_monitorrelease(Object *h) /* =============================== linux ============================ */ -#if linux - -// Includes attribute fixes from David Friedman's GDC port +// needs to be else.. +#if linux || PHOBOS_USE_PTHREADS #include #include "mars.h" +#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; static volatile int inited; @@ -102,10 +114,9 @@ static volatile int inited; void _STI_monitor_staticctor() { if (!inited) - { - pthread_mutexattr_init(&_monitors_attr); - pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP); - pthread_mutex_init(&_monitor_critsec, 0); + { pthread_mutexattr_init(&_monitors_attr); + pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_monitor_critsec, 0); // the global critical section doesn't need to be recursive inited = 1; } } diff -uNrp dmd-0.140/src/phobos/internal/object.d gdc-0.17/d/phobos/internal/object.d --- dmd-0.140/src/phobos/internal/object.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/internal/object.d 2005-10-13 03:06:51.000000000 +0200 @@ -31,6 +31,12 @@ * 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; @@ -523,7 +529,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, xsize) == 0); @@ -541,7 +553,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, xsize); diff -uNrp dmd-0.140/src/phobos/internal/qsort.d gdc-0.17/d/phobos/internal/qsort.d --- dmd-0.140/src/phobos/internal/qsort.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/internal/qsort.d 2005-04-28 23:12:43.000000000 +0200 @@ -13,6 +13,12 @@ _adSort() is required. */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + /* ** Sorts an array starting at base, of length nbr_elements, each @@ -47,7 +53,7 @@ an array of large structures to be sorte structures. The default value is optimized for a high cost for compares. */ -extern (C) long _adSort(Array a, TypeInfo ti) +extern (C) Array _adSort(Array a, TypeInfo ti) { byte* base; byte*[40] stack; // stack @@ -127,7 +133,7 @@ extern (C) long _adSort(Array a, TypeInf limit = sp[1]; } else // else stack empty, all done - return *cast(long*)(&a); + return a; } } diff -uNrp dmd-0.140/src/phobos/internal/rundmain.d gdc-0.17/d/phobos/internal/rundmain.d --- dmd-0.140/src/phobos/internal/rundmain.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/internal/rundmain.d 2005-04-28 23:12:43.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-0.140/src/phobos/libgphobos.spec.in gdc-0.17/d/phobos/libgphobos.spec.in --- dmd-0.140/src/phobos/libgphobos.spec.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/libgphobos.spec.in 2005-05-29 23:09:19.000000000 +0200 @@ -0,0 +1,7 @@ +# +# This spec file is read by gdc when linking. +# It is used to specify the standard libraries we need in order +# to link with libphobos. +# +%rename lib liborig +*lib: @LIBS@ %(liborig) diff -uNrp dmd-0.140/src/phobos/Makefile.in gdc-0.17/d/phobos/Makefile.in --- dmd-0.140/src/phobos/Makefile.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/Makefile.in 2005-11-28 05:17:52.000000000 +0100 @@ -0,0 +1,312 @@ +# 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 + +target_alias = @target_alias@ +host_alias = @host_alias@ + +AR = @AR@ +RANLIB = @RANLIB@ + +CFLAGS=@CFLAGS@ +OUR_CFLAGS=@DEFS@ -I $(srcdir)/etc/c/stlsoft -I . -I $(srcdir)/gcc + +D_GC_FLAGS=@D_GC_FLAGS@ + +# Because parts of Phobos are generated (and are in flux), we need +# to prevent this build from getting tripped up on an already installed +# version. Add -nostdinc to handle this. + +# Only the GC routines need D_GC_FLAGS + +DFLAGS=@DFLAGS@ $(D_GC_FLAGS) -nostdinc + +D_ENABLE_RECLS=@D_ENABLE_RECLS@ +D_RECLS_OS=@D_RECLS_OS@ + +D_GENERATE_FRAGMENTS=@D_GENERATE_FRAGMENTS@ +D_FRAGMENT_SRCDIR=@D_FRAGMENT_SRCDIR@ + +EXEEXT=@EXEEXT@ + +INSTALL=@INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_HEADER = $(INSTALL_DATA) +# %% fix when part of normal build process +mkinstalldirs = $(INSTALL) -d + +# %% remove for automake.. +STAMP = echo timestamp > + +# Note that the real gdc knows what LIBS to use +LIBS=@LIBS@ +CC=@CC@ +GDC=@GDC@ +CXX=@CXX@ + +# For recls +CXXFLAGS=@CXXFLAGS@ +RECLS_CXXFLAGS=@RECLS_CXXFLAGS@ +OUR_CXXFLAGS=@DEFS@ -I $(srcdir)/etc/c/stlsoft + +srcdir=@srcdir@ +VPATH = @srcdir@ + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +phobos_toolexecdir = @phobos_toolexecdir@ +phobos_toolexeclibdir = @phobos_toolexeclibdir@ +toolexecdir = $(phobos_toolexecdir) +toolexeclibdir = $(phobos_toolexeclibdir) + +gdc_include_dir=@gdc_include_dir@ + +all: libgphobos.a + +%.o : %.c + $(CC) -o $@ $(OUR_CFLAGS) $(CFLAGS) -c $< + +%.o : %.cpp + $(CXX) -o $@ $(CXXFLAGS) $(OUR_CXXFLAGS) $(RECLS_CXXFLAGS) -c $< + +%.o : %.d $(host_alias)/gcc/config.d + $(GDC) -o $@ $(DFLAGS) -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +%.t.o : %.d $(host_alias)/gcc/config.d + $(GDC) -o $@ $(DFLAGS) -fno-release -funittest -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +internal/gc/gcx.t.o: $(srcdir)/internal/gc/gcx.d + $(GDC) -o $@ $(DFLAGS) -funittest -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< +%.t.o : %.o + cp $< $@ + +#%.o : $(host_alias)/%.d $(host_alias)/gcc/config.d +# $(GDC) -o $@ $(DFLAGS) -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< + +Makefile: Makefile.in + ./config.status + +unittest: unittest.o libgphobos_t.a + $(CC) -o $@ $(CFLAGS) unittest.o -L./ -lgphobos_t $(LIBS) + +internal/gc/testgc.o: $(host_alias)/gcc/config.d $(srcdir)/internal/gc/testgc.d + $(GDC) -o $@ $(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 + $(CC) -o $@ $(CFLAGS) internal/gc/testgc.o -L./ -lgphobos_t $(LIBS) + + +#$(GDC) -o $@ $(DFLAGS) unittest.o -L./ + +TI=ti_AC.o ti_Aa.o ti_Adchar.o ti_Ag.o ti_Aint.o ti_Along.o ti_Ashort.o \ + ti_Aubyte.o ti_Auint.o ti_Aulong.o ti_Aushort.o ti_Awchar.o ti_C.o \ + ti_bit.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_Abit.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 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/qsort.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/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/boxer.o std/demangle.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 + +# 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 + +ifdef D_ENABLE_RECLS +RECLS_OBJS=etc/c/recls/recls_api.o \ + etc/c/recls/recls_fileinfo.o \ + etc/c/recls/recls_internal.o \ + etc/c/recls/recls_util.o \ + etc/c/recls/recls_api_$(D_RECLS_OS).o \ + etc/c/recls/recls_fileinfo_$(D_RECLS_OS).o \ + etc/c/recls/recls_util_$(D_RECLS_OS).o \ + std/recls.o +else +RECLS_OBJS= +endif + +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 + +# until I figure out how to deal with weak module references +WEAK_OBJS = + +# 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 $@ + +gen_config1: config/gen_config1.o + $(CC) -o $@ $^ + +$(host_alias)/gcc/config.d: $(CONFIG_D_FRAGMENTS) stamp-tgtdir + cat $^ > $@ + +gcc/config.o: $(host_alias)/gcc/config.d + $(GDC) -o $@ $(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) -o $@ $^ + +config/gen_unix.o: config/gen_unix.c config/makestruct.h + +gen_unix: config/gen_unix.o + $(CC) -o $@ $^ + +ifdef 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: gen_config1 + cp $(D_FRAGMENT_SRCDIR)/$@ $@ +frag-unix: gen_unix + cp $(D_FRAGMENT_SRCDIR)/$@ $@ +frag-math: gen_math + cp $(D_FRAGMENT_SRCDIR)/$@ $@ +endif + +$(host_alias)/gcc/configunix.d: $(CONFIG_UNIX_FRAGMENTS) stamp-tgtdir + cat $^ > $@ + +gcc/configunix.o: $(host_alias)/gcc/configunix.d $(host_alias)/gcc/config.d + $(GDC) -o $@ $(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 $(host_alias)/gcc/config.d + $(GDC) -o $@ $(DFLAGS) -fdeprecated -I $(srcdir) -I $(srcdir)/internal/gc -I ./$(host_alias) -c $< +std/stream.t.o: std/stream.d $(host_alias)/gcc/config.d + $(GDC) -o $@ $(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) $(RECLS_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) $@ + +.PHONY: info dvi TAGS install-info installcheck mostlyclean distclean maintainer-clean check + +check: unittest testgc + ./unittest + ./testgc + +info: +dvi: +TAGS: +install-info: +installcheck: +mostlyclean: clean +distclean: clean +maintainer-clean: clean + +#echo "XXX" $(mkinstalldirs) $(DESTDIR)$(gdc_include_dir)/$$i; \ +#echo "YYY" $(INSTALL_HEADER) $(srcdir)/$$i/*.[hd] $(DESTDIR)$(gdc_include_dir)/$$i; \ + +# 3.3.x install-sh can't handle multiple source arguments +# $(INSTALL_HEADER) $(srcdir)/$$i/*.[hd] $(DESTDIR)$(gdc_include_dir)/$$i; done +install: $(host_alias)/gcc/config.d libgphobos.a + for i in etc etc/c etc/c/recls etc/c/stlsoft etc/c/zlib \ + gcc std std/c \ + std/c/darwin std/c/linux std/c/mach 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)/gcc + $(INSTALL_HEADER) $(host_alias)/gcc/config.d $(DESTDIR)$(gdc_include_dir)/$(host_alias)/gcc + if test -f $(host_alias)/gcc/configunix.d; then $(INSTALL_HEADER) $(host_alias)/gcc/configunix.d $(DESTDIR)$(gdc_include_dir)/$(host_alias)/gcc; fi + $(INSTALL) phobos-ver-syms $(DESTDIR)$(gdc_include_dir)/$(host_alias) + $(mkinstalldirs) $(DESTDIR)$(toolexeclibdir) + $(INSTALL) libgphobos.a $(DESTDIR)$(toolexeclibdir) + $(RANLIB) $(DESTDIR)$(toolexeclibdir)/libgphobos.a + $(INSTALL) libgphobos.spec $(DESTDIR)$(toolexeclibdir) + +clean: + echo 'Removing files...' + 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 $(host_alias)/gcc/config.d $(host_alias)/gcc/configunix.d + rm -f libgphobos.a + rm -f libgphobos_t.a diff -uNrp dmd-0.140/src/phobos/phobos-ver-syms.in gdc-0.17/d/phobos/phobos-ver-syms.in --- dmd-0.140/src/phobos/phobos-ver-syms.in 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/phobos-ver-syms.in 2005-10-29 04:40:46.000000000 +0200 @@ -0,0 +1,15 @@ +@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@ diff -uNrp dmd-0.140/src/phobos/std/boxer.d gdc-0.17/d/phobos/std/boxer.d --- dmd-0.140/src/phobos/std/boxer.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/boxer.d 2005-10-13 03:06:51.000000000 +0200 @@ -1,9 +1,19 @@ /* This module is written by Burton Radons and 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 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 @@ -74,6 +84,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; + /** A box object contains a value in a generic fashion, allowing it to be * passed from one place to another without having to know its type. It is * created by calling the box function, and you can recover the value by @@ -88,7 +103,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) @@ -98,7 +113,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) @@ -201,7 +216,13 @@ struct Box args[0..(char[]).sizeof] = (cast(void*) &format)[0..(char[]).sizeof]; args[(char[]).sizeof..length] = data; - std.format.doFormat(&putc, arguments, args); + version (GNU) + { + va_list dummy = void; + std.format.doFormat(&putc, arguments, dummy, args); + } + else + std.format.doFormat(&putc, arguments, args); delete args; return string; @@ -313,7 +334,25 @@ in } body { - return box(_arguments[0], _argptr); + version (GNU) + { + void * p; + version (BigEndian) + { + byte b; + short s; + switch (_arguments[0].tsize()) { + case 1: b = va_arg!(byte)(_argptr); p = & b; break; + case 2: s = va_arg!(short)(_argptr); p = & s; break; + default: p = cast(void *) _argptr; + } + } + else + p = cast(void *) _argptr; + return box(_arguments[0], p); + } + else + return box(_arguments[0], _argptr); } /** Assign the parameters, copying data as needed. */ @@ -359,7 +398,7 @@ Box[] boxArray(TypeInfo[] types, void* d /** 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. */ diff -uNrp dmd-0.140/src/phobos/std/c/darwin/darwin.d gdc-0.17/d/phobos/std/c/darwin/darwin.d --- dmd-0.140/src/phobos/std/c/darwin/darwin.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/darwin/darwin.d 2004-10-26 02:41:27.000000000 +0200 @@ -0,0 +1,170 @@ +/* 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.darwin.darwin; + +import gcc.configunix; + +/+ +alias int time_t; +alias long off_t; + +enum : int +{ + SIGHUP = 1, + SIGINT = 2, + SIGQUIT = 3, + SIGILL = 4, + SIGTRAP = 5, + SIGABRT = 6, + SIGIOT = SIGABRT, + SIGEMT = 7, + SIGFPE = 8, + SIGKILL = 9, + SIGBUS = 10, + SIGSEGV = 11, + SIGSYS = 12, + SIGPIPE = 13, + SIGALRM = 14, + SIGTERM = 15, + SIGURG = 16, + SIGSTOP = 17, + SIGTSTP = 18, + SIGCONT = 19, + SIGCHLD = 20, + SIGTTIN = 21, + SIGTTOU = 22, + SIGIO = 23, + SIGXCPU = 24, + SIGXFSZ = 25, + SIGVTALRM = 26, + SIGPROF = 27, + SIGWINCH = 28, + SIGINFO = 29, + SIGUSR1 = 30, + SIGUSR2 = 31 +} + +enum +{ + O_RDONLY = 0x0000, + O_WRONLY = 0x0001, + O_RDWR = 0x0002, + O_ACCMODE = 0x0003, + O_NONBLOCK = 0x0004, + O_APPEND = 0x0008, + O_SHLOCK = 0x0010, + O_EXLOCK = 0x0020, + O_ASYNC = 0x0040, + O_FSYNC = 0x0080, + O_NOFOLLOW = 0x0100, + O_CREAT = 0x0200, + O_TRUNC = 0x0400, + O_EXCL = 0x0800 + +} + +struct timespec { + time_t tv_sec; /* seconds */ + int tv_nsec; /* and nanoseconds */ +}; + +struct struct_stat { + int st_dev; /* inode's device */ + uint st_ino; /* inode's number */ + ushort st_mode; /* inode protection mode */ + ushort st_nlink; /* number of hard links */ + uint st_uid; /* user ID of the file's owner */ + uint st_gid; /* group ID of the file's group */ + int st_rdev; /* device type */ + version (None) { // #ifndef _POSIX_SOURCE + timespec st_atimespec; /* time of last access */ + timespec st_mtimespec; /* time of last data modification */ + timespec st_ctimespec; /* time of last file status change */ + } else { + time_t st_atime; /* time of last access */ + int st_atimensec; /* nsec of last access */ + time_t st_mtime; /* time of last data modification */ + int st_mtimensec; /* nsec of last data modification */ + time_t st_ctime; /* time of last file status change */ + int st_ctimensec; /* nsec of last file status change */ + } + off_t st_size; /* file size, in bytes */ + long st_blocks; /* blocks allocated for file */ + uint st_blksize; /* optimal blocksize for I/O */ + uint st_flags; /* user defined flags for file */ + uint st_gen; /* file generation number */ + int st_lspare; + long st_qspare[2]; +}; + +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 +} + +extern (C) +{ + int open(char*, int, ...); + int read(int, void*, size_t); + int write(int, void*, size_t); + int close(int); + off_t lseek(int, off_t, int); + int fstat(int, struct_stat*); + int stat(char*, struct_stat*); + int getErrno(); + int chdir(char*); + int mkdir(char*, int); + int rmdir(char*); + char* getcwd(char*, int); +} + +struct timeval { + int tv_sec; /* seconds */ + int tv_usec; /* and microseconds */ +}; + +struct tm { + int tm_sec; /* seconds after the minute [0-60] */ + int tm_min; /* minutes after the hour [0-59] */ + int tm_hour; /* hours since midnight [0-23] */ + int tm_mday; /* day of the month [1-31] */ + int tm_mon; /* months since January [0-11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday [0-6] */ + int tm_yday; /* days since January 1 [0-365] */ + int tm_isdst; /* Daylight Savings Time flag */ + int tm_gmtoff; /* offset from CUT in seconds */ + char *tm_zone; /* timezone abbreviation */ +}; + +extern (C) +{ + int gettimeofday(timeval*, void*); + time_t time(time_t*); + tm *localtime(time_t*); +} ++/ diff -uNrp dmd-0.140/src/phobos/std/c/darwin/ldblcompat.d gdc-0.17/d/phobos/std/c/darwin/ldblcompat.d --- dmd-0.140/src/phobos/std/c/darwin/ldblcompat.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/darwin/ldblcompat.d 2005-10-02 16:17:55.000000000 +0200 @@ -0,0 +1,36 @@ +/* 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 (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-0.140/src/phobos/std/c/dirent.d gdc-0.17/d/phobos/std/c/dirent.d --- dmd-0.140/src/phobos/std/c/dirent.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/dirent.d 2004-10-26 02:41:27.000000000 +0200 @@ -0,0 +1,50 @@ +/* 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; + +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 *); + +} + +char[] readdirD(DIR * dir) +{ + dirent* ent = readdir(dir); + if (ent) + return toString(ent.d_name); + else + return null; +} diff -uNrp dmd-0.140/src/phobos/std/c/mach/mach.d gdc-0.17/d/phobos/std/c/mach/mach.d --- dmd-0.140/src/phobos/std/c/mach/mach.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/mach/mach.d 2005-01-10 04:30:55.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 __builtin_abi_uint natural_t; + +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-0.140/src/phobos/std/c/mach/mach_extern.d gdc-0.17/d/phobos/std/c/mach/mach_extern.d --- dmd-0.140/src/phobos/std/c/mach/mach_extern.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/mach/mach_extern.d 2004-10-26 02:41:27.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-0.140/src/phobos/std/c/math.d gdc-0.17/d/phobos/std/c/math.d --- dmd-0.140/src/phobos/std/c/math.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/math.d 2005-10-13 03:06:51.000000000 +0200 @@ -8,6 +8,12 @@ /* 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 2005 +*/ + module std.c.math; extern (C): @@ -49,6 +55,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); + + int lrint(double x); + int lrintf(float x); + + long llrint(double x); + long llrintf(float x); + + double round(double x); + float roundf(float x); + + int lround(double x); + int 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); real acosl(real x); @@ -276,6 +517,8 @@ real fminl(real x, real y); double fma(double x, double y, double z); float fmaf(float x, float y, float z); real fmal(real x, real y, real z); +} + int isgreater(real x, real y) { return !(x !> y); } int isgreaterequal(real x, real y) { return !(x !>= y); } diff -uNrp dmd-0.140/src/phobos/std/c/stdarg.d gdc-0.17/d/phobos/std/c/stdarg.d --- dmd-0.140/src/phobos/std/c/stdarg.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/stdarg.d 2005-10-02 16:17:55.000000000 +0200 @@ -1,3 +1,4 @@ + /* * Placed in public domain. * Written by Hauke Duden and Walter Bright @@ -5,15 +6,45 @@ /* 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) +{ + 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))); + */ } } @@ -21,18 +52,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-0.140/src/phobos/std/c/stddef.d gdc-0.17/d/phobos/std/c/stddef.d --- dmd-0.140/src/phobos/std/c/stddef.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/stddef.d 2005-10-02 16:17:55.000000000 +0200 @@ -15,6 +15,10 @@ else version (linux) { alias dchar wchar_t; } +else version (Unix) +{ + alias dchar wchar_t; +} else { static assert(0); diff -uNrp dmd-0.140/src/phobos/std/c/stdio.d gdc-0.17/d/phobos/std/c/stdio.d --- dmd-0.140/src/phobos/std/c/stdio.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/stdio.d 2005-10-26 03:33:56.000000000 +0200 @@ -5,6 +5,12 @@ * Placed into Public Domain. */ +/* 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; @@ -14,7 +20,18 @@ 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; @@ -26,8 +43,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; @@ -52,7 +68,7 @@ struct _iobuf int _bufsiz; int __tmpnum; } - version (linux) + else version (linux) { char* _read_ptr; char* _read_end; @@ -75,6 +91,10 @@ struct _iobuf char[1] _shortbuf; void* _lock; } + else version (GNU) { + byte[gcc.config.FILE_struct_size] opaque; + } + } alias _iobuf FILE; @@ -96,8 +116,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) @@ -129,16 +154,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) +{ + version (GNU_BitsPerPointer32) + { + 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 version (GNU_BitsPerPointer64) + { + 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; @@ -149,7 +217,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; @@ -213,8 +285,47 @@ 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 (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-0.140/src/phobos/std/c/stdlib.d gdc-0.17/d/phobos/std/c/stdlib.d --- dmd-0.140/src/phobos/std/c/stdlib.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/stdlib.d 2005-09-09 23:27:05.000000000 +0200 @@ -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.c.stdlib; extern (C): @@ -27,7 +33,13 @@ struct lldiv_t { long quot,rem; } void exit(int); void _exit(int); - void *alloca(uint); + version (GNU) + { + private import gcc.builtins; + alias gcc.builtins.__builtin_alloca alloca; + } else { + void *alloca(uint); + } void *calloc(uint, uint); void *malloc(uint); @@ -41,6 +53,12 @@ struct lldiv_t { long quot,rem; } char* getenv(char*); + version (GNU) + { + private import gcc.config; + alias gcc.config.RAND_MAX RAND_MAX; + } + int rand(); void srand(uint); int random(int num); @@ -56,7 +74,19 @@ int atoi(char *); int atol(char *); float strtof(char *,char **); double strtod(char *,char **); -real strtold(char *,char **); + +//real strtold(char *,char **); +version (darwin) +{ + private import std.c.darwin.ldblcompat; + real strtold(char *, char **); pragma(GNU_asm,strtold,"strtold"~__DARWIN_LDBL_COMPAT); +} +else +{ + private import gcc.config; + alias gcc.config.cstrtold strtold; +} + long strtol(char *,char **,int); uint strtoul(char *,char **,int); long atoll(char *); diff -uNrp dmd-0.140/src/phobos/std/c/time.d gdc-0.17/d/phobos/std/c/time.d --- dmd-0.140/src/phobos/std/c/time.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/time.d 2004-12-19 18:51:04.000000000 +0100 @@ -13,6 +13,11 @@ extern (C): version (Windows) { const uint CLOCKS_PER_SEC = 1000; } +else version (GNU) +{ + private import gcc.config; + alias gcc.config.CLOCKS_PER_SEC CLOCKS_PER_SEC; +} else version (linux) { const uint CLOCKS_PER_SEC = 1000000; } diff -uNrp dmd-0.140/src/phobos/std/c/unix/unix.d gdc-0.17/d/phobos/std/c/unix/unix.d --- dmd-0.140/src/phobos/std/c/unix/unix.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.17/d/phobos/std/c/unix/unix.d 2005-05-13 01:32:29.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. */ + +import gcc.configunix; + +// DMD linux.d has dirent.h declarations +import std.c.dirent; diff -uNrp dmd-0.140/src/phobos/std/conv.d gdc-0.17/d/phobos/std/conv.d --- dmd-0.140/src/phobos/std/conv.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/conv.d 2005-05-29 23:09:19.000000000 +0200 @@ -847,6 +847,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; @@ -857,7 +859,7 @@ float toFloat(in char[] s) f = strtof(sz, &endptr); if (getErrno() == ERANGE) goto Lerr; - if (endptr && (endptr == s || *endptr != 0)) + if (endptr && (endptr == sz || *endptr != 0)) goto Lerr; return f; @@ -910,6 +912,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; @@ -920,7 +924,7 @@ double toDouble(in char[] s) f = strtod(sz, &endptr); if (getErrno() == ERANGE) goto Lerr; - if (endptr && (endptr == s || *endptr != 0)) + if (endptr && (endptr == sz || *endptr != 0)) goto Lerr; return f; @@ -977,6 +981,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; @@ -987,7 +993,7 @@ real toReal(in char[] s) f = strtold(sz, &endptr); if (getErrno() == ERANGE) goto Lerr; - if (endptr && (endptr == s || *endptr != 0)) + if (endptr && (endptr == sz || *endptr != 0)) goto Lerr; return f; diff -uNrp dmd-0.140/src/phobos/std/date.d gdc-0.17/d/phobos/std/date.d --- dmd-0.140/src/phobos/std/date.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/date.d 2005-11-28 05:17:52.000000000 +0100 @@ -12,6 +12,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; @@ -466,7 +472,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); @@ -530,7 +536,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); @@ -764,7 +770,98 @@ 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 ); + /+ + int t; + tm * t_tm; + + time(&t); + t_tm = localtime(&t); // this will set timezone + // %%TODO: handle systems without tm_gmtoff + // %%TODO: configurate on _timezone instead of this.. + version (cygwin) { + return _timzone * TicksPerSecond; + } else { + return -(t_tm.tm_gmtoff * TicksPerSecond); + } + +/ + } + + /* + * Get daylight savings time adjust for time dt. + */ + + int DaylightSavingTA(d_time dt) + { + tm *tmp; + int t; + int dst = 0; + + if (dt != d_time_nan) + { + d_time seconds = dt / TicksPerSecond; + t = cast(int) seconds; + if (t == seconds) // if in range + { + tmp = localtime(&t); + if (tmp.tm_isdst > 0) + dst = TicksPerHour; // BUG: Assume daylight savings time is plus one hour. + } + else // out of range for system time, use our own calculation + { // Daylight savings time goes from 2 AM the first Sunday + // in April through 2 AM the last Sunday in October + + dt -= LocalTZA; + + int year = YearFromTime(dt); + int leap = LeapYear(dt); + //writefln("year = %s, leap = %s, month = %s", year, leap, MonthFromTime(dt)); + + d_time start = TimeFromYear(year); // Jan 1 + d_time end = start; + // Move fwd to Apr 1 + start += cast(d_time)(mdays[3] + leap) * TicksPerDay; + // Advance a day at a time until we find Sunday (0) + while (WeekDay(start) != 0) + start += TicksPerDay; + + // Move fwd to Oct 30 + end += cast(d_time)(mdays[9] + leap + 30) * TicksPerDay; + // Back up a day at a time until we find Sunday (0) + while (WeekDay(end) != 0) // 0 is Sunday + end -= TicksPerDay; + + dt -= 2 * TicksPerHour; // 2 AM + if (dt >= start && dt <= end) + dst = TicksPerHour; + //writefln("start = %s, dt = %s, end = %s, dst = %s", start, dt, end, dst); + } + } + return dst; + } +} +else version (linux) { private import std.c.linux.linux; diff -uNrp dmd-0.140/src/phobos/std/demangle.d gdc-0.17/d/phobos/std/demangle.d --- dmd-0.140/src/phobos/std/demangle.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/demangle.d 2005-11-28 05:17:52.000000000 +0100 @@ -1,3 +1,8 @@ +/* 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. */ @@ -318,9 +323,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 = (ascii2hex(name[ni + i * 2]) << 4) + @@ -460,8 +465,12 @@ unittest [ "_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi", "int test.bar!(wchar[3] \"abc\"w, dchar[3] \"def\"d).x" ], ]; - 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-0.140/src/phobos/std/file.d gdc-0.17/d/phobos/std/file.d --- dmd-0.140/src/phobos/std/file.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/file.d 2005-11-28 05:17:52.000000000 +0100 @@ -23,8 +23,15 @@ * be misrepresented as being the original software. * 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, September 2004 +*/ + module std.file; private import std.c.stdio; @@ -407,7 +414,7 @@ char[] getcwd() wchar c; len = GetCurrentDirectoryW(0, &c); - if (!len) + if (!len) goto Lerr; dir = new wchar[len]; len = GetCurrentDirectoryW(len, dir); @@ -552,10 +559,29 @@ void copy(char[] from, char[] to) /* =========================== linux ======================= */ -version (linux) +// else version (GNU) +/* + { + version (Unix) { + private import std.c.unix.unix; + } + } + */ + +version (linux) { + version = Unix; +} + +version (Unix) { + version (GNU) { + private import std.c.unix.unix; + alias std.c.unix.unix unix; + } else version (linux) { + private import std.c.linux.linux; + alias std.c.linux.linux unix; + } -private import std.c.linux.linux; extern (C) char* strerror(int); @@ -601,7 +627,7 @@ void[] read(char[] name) namez = toStringz(name); //printf("file.read('%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()); @@ -609,7 +635,7 @@ 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; @@ -617,14 +643,14 @@ void[] read(char[] name) size = statbuf.st_size; buf = new byte[size]; - 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; @@ -633,7 +659,7 @@ void[] read(char[] name) return buf; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: delete buf; @@ -654,21 +680,21 @@ void write(char[] name, void[] buffer) 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, buffer.length); + numwritten = unix.write(fd, buffer, 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()); } @@ -685,21 +711,21 @@ void append(char[] name, void[] buffer) 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, buffer.length); + numwritten = unix.write(fd, buffer, 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()); } @@ -743,7 +769,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()); @@ -751,14 +777,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; @@ -767,7 +793,7 @@ ulong getSize(char[] name) return size; err2: - std.c.linux.linux.close(fd); + unix.close(fd); err: err1: throw new FileException(name, getErrno()); @@ -784,7 +810,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()); } @@ -805,7 +831,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; } @@ -842,7 +868,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()); } @@ -854,7 +880,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()); } @@ -866,7 +892,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()); } @@ -877,19 +903,34 @@ void rmdir(char[] pathname) */ char[] getcwd() -{ char* p; - - p = std.c.linux.linux.getcwd(null, 0); +{ + version(all) + { + char buf[PATH_MAX]; + if (! unix.getcwd(buf, buf.length)) + { + throw new FileException("cannot get cwd", getErrno()); + } + size_t len = strlen(buf); + char[] result = new char[len]; + result[] = buf[0..len]; + return result; + } + else + { + char* p; + p = unix.getcwd(null, 0); if (!p) { throw new FileException("cannot get cwd", getErrno()); } - size_t len = std.string.strlen(p); char[] buf = new char[len]; buf[] = p[0 .. len]; std.c.stdlib.free(p); return buf; + } + } /*************************************************** diff -uNrp dmd-0.140/src/phobos/std/format.d gdc-0.17/d/phobos/std/format.d --- dmd-0.140/src/phobos/std/format.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/format.d 2005-12-02 02:00:23.000000000 +0100 @@ -44,6 +44,10 @@ version (Windows) { version = DigitalMarsC; } + version (GNU) + { + version = GNU_MinGW_MSVCRT; + } } version (DigitalMarsC) @@ -434,7 +438,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; @@ -572,7 +577,10 @@ void doFormat(void delegate(dchar) putc, { int n; sl = fbuf.length; - n = snprintf(fbuf, sl, format, field_width, precision, v); + version (GNU_MinGW_MSVCRT) + n = snprintf(fbuf, sl, format, field_width, precision, cast(double) v); + else + n = snprintf(fbuf, sl, format, field_width, precision, v); //printf("format = '%s', n = %d\n", cast(char*)format, n); if (n >= 0 && n < sl) { sl = n; @@ -593,7 +601,7 @@ void doFormat(void delegate(dchar) putc, putc('['); size_t tsize = ti.tsize(); while (len--) { - doFormat(putc, (&ti)[0 .. 1], p); + doFormat(putc, (&ti)[0 .. 1], argptr, p); p += tsize; if (len > 0) putc(','); } @@ -601,6 +609,7 @@ void doFormat(void delegate(dchar) putc, } //printf("formatArg(fc = '%c', m = '%c')\n", fc, m); + if (! p_args) switch (m) { case Mangle.Tbit: @@ -780,6 +789,190 @@ void doFormat(void delegate(dchar) putc, default: goto Lerror; } + else + { + switch (m) + { + case Mangle.Tbit: + vbit = *cast(bit*)(p_args); p_args += bit.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(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(ulong)*cast(void**)p_args; p_args += void_ponter_t.sizeof; + 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; + } + 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 (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; + + default: + goto Lerror; + } + } Lnumber: switch (fc) @@ -904,6 +1097,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: @@ -924,6 +1118,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++]; @@ -960,7 +1178,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 != '%') @@ -1078,7 +1302,12 @@ unittest * is for %A. */ version (linux) - assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan"); + { + version (GNU) + assert(s == "1.67 -0XA.3D70A3D70A3D800P-3 nan"); + else + assert(s == "1.67 -0XA.3D70A3D70A3D8P-3 nan"); + } else assert(s == "1.67 -0X1.47AE147AE147BP+0 nan"); diff -uNrp dmd-0.140/src/phobos/std/intrinsic.d gdc-0.17/d/phobos/std/intrinsic.d --- dmd-0.140/src/phobos/std/intrinsic.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/intrinsic.d 2004-12-19 18:51:04.000000000 +0100 @@ -5,11 +5,77 @@ // 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, September 2004 +*/ + /* These functions are built-in intrinsics to the compiler. */ module std.intrinsic; +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 +} +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 +} +int bt(uint *p, uint bitnum) +{ + return (*p & (1<>>8)|((v&0xFF000000)>>>24); +} + +ubyte inp(uint p) { return 0; } +ushort inpw(uint p) { return 0; } +uint inpl(uint p) { return 0; } + +ubyte outp(uint p, ubyte v) { return v; } +ushort outpw(uint p, ushort v) { return v; } +uint outpl(uint p, uint v) { return v; } +} +else +{ int bsf(uint v); int bsr(uint v); int bt(uint *p, uint bitnum); @@ -26,5 +92,6 @@ uint inpl(uint); ubyte outp(uint, ubyte); ushort outpw(uint, ushort); uint outpl(uint, uint); +} diff -uNrp dmd-0.140/src/phobos/std/loader.d gdc-0.17/d/phobos/std/loader.d --- dmd-0.140/src/phobos/std/loader.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/loader.d 2005-08-12 04:32:44.000000000 +0200 @@ -56,6 +56,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, October 2004 (applied patches from Anders F Björklund.) +*/ /** \file D/std/loader.d This file contains the \c D standard library @@ -109,6 +139,104 @@ 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 + + // #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; @@ -325,7 +453,7 @@ else version(linux) private void ExeModule_Uninit_() { if(0 == --s_init) - { + { } } @@ -336,11 +464,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 { @@ -415,7 +543,7 @@ else version(linux) { record_error_(); } - delete s_modules[name]; + s_modules.remove(name); delete mi; } @@ -473,6 +601,258 @@ 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 ) + { + // 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"; + 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 ) && + 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; @@ -530,6 +910,10 @@ public: { m_hModule = ExeModule_AddRef(hModule); } + else version (darwin) + { + m_hModule = ExeModule_AddRef(hModule); + } else static assert(0); } @@ -554,6 +938,12 @@ public: 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 @@ -585,6 +975,10 @@ public: { ExeModule_Release(m_hModule); } + else version (darwin) + { + ExeModule_Release(m_hModule); + } else static assert(0); } @@ -618,6 +1012,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); @@ -669,6 +1072,10 @@ public: { return ExeModule_GetPath_(m_hModule); } + else version (darwin) + { + return ExeModule_GetPath_(m_hModule); + } else static assert(0); } diff -uNrp dmd-0.140/src/phobos/std/math2.d gdc-0.17/d/phobos/std/math2.d --- dmd-0.140/src/phobos/std/math2.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/math2.d 2005-11-27 17:28:26.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 @@ -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); } /************************************* @@ -654,7 +702,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)); } /************************************* @@ -673,15 +721,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)); } /************************************* @@ -700,15 +748,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)); } /************************************* @@ -876,7 +924,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; } @@ -925,6 +973,18 @@ char[] toString(real x) psize *= 2; p = cast(char*) alloca(psize); } + else version(GNU) + { + // %% Lg on dawrin? + count = std.c.stdio.snprintf(p, psize, "%Lg", x); + if (count == -1) + psize *= 2; + else if (count >= psize) + psize = count + 1; + else + break; + p = cast(char*) alloca(psize); + } else version(linux) { count = snprintf(p, psize, "%Lg", x); diff -uNrp dmd-0.140/src/phobos/std/math.d gdc-0.17/d/phobos/std/math.d --- dmd-0.140/src/phobos/std/math.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/math.d 2005-11-27 17:28:26.000000000 +0100 @@ -45,6 +45,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; @@ -55,6 +61,19 @@ 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; + + version (X86) + version (D_InlineAsm) + version = UseAsmX86; +} + class NotImplemented : Error { this(char[] msg) @@ -104,6 +123,7 @@ const real SQRT1_2 = 0.70710678118654752 * ) */ +version(GNU) alias gcc.config.cosl cos; else real cos(real x); /* intrinsic */ /*********************************** @@ -117,6 +137,7 @@ real cos(real x); /* intrinsic */ * ) */ +version(GNU) alias gcc.config.sinl sin; else real sin(real x); /* intrinsic */ @@ -131,6 +152,7 @@ real sin(real x); /* intrinsic */ * ) */ +version(GNU) alias gcc.config.tanl tan; else real tan(real x) { asm @@ -205,6 +227,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); @@ -345,8 +373,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) @@ -409,6 +440,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); } /****************************************** @@ -426,6 +458,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); } @@ -450,6 +483,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; @@ -497,6 +532,23 @@ real frexp(real value, out int exp) vu[4] = (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; + } + } } @@ -527,6 +579,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]; @@ -564,6 +618,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 */ /************************************** @@ -620,6 +675,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); } /***************************************** @@ -698,6 +754,7 @@ real cbrt(real x) { return std.c.math.c * ±∞ +∞ * ) */ +version (GNU) alias gcc.config.fabsl fabs; else real fabs(real x); /* intrinsic */ @@ -809,6 +866,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]; @@ -826,6 +886,7 @@ unittest * * error function */ +version (GNU_msvcrt_math) { /* nothing */ } else real erf(real x) { return std.c.math.erfl(x); } /********************************** @@ -833,6 +894,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); } /*********************************** @@ -882,6 +944,12 @@ real lgamma(real x) * cephes, $(LINK http://en.wikipedia.org/wiki/Gamma_function) */ /* 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); @@ -908,6 +976,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); } /********************************** @@ -918,6 +991,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 */ /*************************************** @@ -937,6 +1011,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); } /********************************************** @@ -958,6 +1064,24 @@ long lround(real x) * * This is also know 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); } /**************************************************** @@ -994,6 +1118,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; @@ -1002,6 +1127,8 @@ int isnan(real e) return (pe[4] & 0x7FFF) == 0x7FFF && *ps & 0x7FFFFFFFFFFFFFFF; } +else version(GNU) + alias gcc.config.isnan isnan; unittest { @@ -1017,12 +1144,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 { @@ -1040,6 +1170,7 @@ unittest * be converted to normal reals. */ +version (X86) int isnormal(float x) { uint *p = cast(uint *)&x; @@ -1049,9 +1180,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; @@ -1060,9 +1194,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; @@ -1070,6 +1206,7 @@ int isnormal(real e) return (pe[4] & 0x7FFF) != 0x7FFF && *ps < 0; } +else version(GNU) { /* nothing, handled above */ } unittest { @@ -1091,6 +1228,7 @@ unittest * be converted to normal reals. */ +version (X86) int issubnormal(float f) { uint *p = cast(uint *)&f; @@ -1098,6 +1236,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 { @@ -1109,12 +1249,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 { @@ -1126,6 +1268,7 @@ unittest /// ditto +version (X86) int issubnormal(real e) { ushort* pe = cast(ushort *)&e; @@ -1133,6 +1276,7 @@ int issubnormal(real e) return (pe[4] & 0x7FFF) == 0 && *ps > 0; } +else version(GNU) { /* nothing, handled above */ } unittest { @@ -1146,6 +1290,7 @@ unittest * Return !=0 if e is ±∞. */ +version (X86) int isinf(real e) { ushort* pe = cast(ushort *)&e; @@ -1154,7 +1299,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)); @@ -1169,6 +1316,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; @@ -1176,6 +1324,8 @@ int signbit(real e) //printf("e = %Lg\n", e); return (pe[9] & 0x80) != 0; } +else version (GNU) + alias gcc.config.signbit signbit; unittest { @@ -1192,6 +1342,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; @@ -1202,6 +1353,8 @@ real copysign(real to, real from) return to; } +else version (GNU) + alias gcc.config.copysignl copysign; unittest { @@ -1226,6 +1379,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)); } /****************************************** @@ -1369,7 +1525,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 real.nan; @@ -1492,6 +1649,10 @@ private int mfeq(real x, real y, real pr return fabs(x - y) <= precision; } +version (X86) +{ +// These routines assume Intel 80-bit floating point format + private int iabs(int i) { return i >= 0 ? i : -i; @@ -1597,6 +1758,12 @@ unittest assert(feqrel(real.max,-real.max)==0); } +} // version(X86) +else +{ + // not implemented +} + /*********************************** * Evaluate polynomial A(x) = a0 + a1x + a2x² + a3x³ ... @@ -1612,7 +1779,7 @@ in } body { - version (D_InlineAsm) + version (none/*D_InlineAsm*/) { asm // assembler by W. Bright { @@ -1640,6 +1807,34 @@ body ; } } + else version (UseAsmX86) + { + asm // above code with modifications for GCC + { + // 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; diff -uNrp dmd-0.140/src/phobos/std/md5.d gdc-0.17/d/phobos/std/md5.d --- dmd-0.140/src/phobos/std/md5.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/md5.d 2005-10-24 23:48:04.000000000 +0200 @@ -87,12 +87,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. */ @@ -168,14 +178,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 diff -uNrp dmd-0.140/src/phobos/std/mmfile.d gdc-0.17/d/phobos/std/mmfile.d --- dmd-0.140/src/phobos/std/mmfile.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/mmfile.d 2005-10-02 16:17:55.000000000 +0200 @@ -8,6 +8,12 @@ * Memory mapped files. */ +/* 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; @@ -30,9 +36,10 @@ version (Win32) dwVersion = GetVersion(); } } -else version (linux) +else version (Unix) { - private import std.c.linux.linux; + private import std.c.unix.unix; + alias std.c.unix.unix unix; } else { @@ -178,7 +185,7 @@ class MmFile errNo(); } - else version (linux) + else version (Unix) { char* namez = toStringz(filename); void* p; @@ -221,26 +228,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, size - 1, SEEK_SET); + unix.lseek(fd, 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; @@ -255,7 +262,7 @@ 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(); } @@ -281,9 +288,9 @@ class MmFile errNo(); hFile = INVALID_HANDLE_VALUE; } - else version (linux) + else version (Unix) { - if (fd != -1 && std.c.linux.linux.close(fd) == -1) + if (fd != -1 && unix.close(fd) == -1) errNo(); fd = -1; } @@ -303,7 +310,7 @@ class MmFile { FlushViewOfFile(data, data.length); } - else version (linux) + else version (Unix) { int i; @@ -460,7 +467,7 @@ class MmFile HANDLE hFileMap = null; uint dwDesiredAccess; } - else version (linux) + else version (Unix) { int fd; int prot; @@ -479,7 +486,7 @@ class MmFile { throw new FileException(filename, GetLastError()); } - else version (linux) + else version (Unix) { throw new FileException(filename, getErrno()); } @@ -499,7 +506,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); diff -uNrp dmd-0.140/src/phobos/std/moduleinit.d gdc-0.17/d/phobos/std/moduleinit.d --- dmd-0.140/src/phobos/std/moduleinit.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/moduleinit.d 2005-04-28 23:12:43.000000000 +0200 @@ -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; @@ -42,8 +48,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 @@ -68,7 +82,7 @@ extern (C) int _fatexit(void *); extern (C) void _moduleCtor() { debug printf("_moduleCtor()\n"); - version (linux) + version (ModRefStyle) { int len = 0; ModuleReference *mr; diff -uNrp dmd-0.140/src/phobos/std/outbuffer.d gdc-0.17/d/phobos/std/outbuffer.d --- dmd-0.140/src/phobos/std/outbuffer.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/outbuffer.d 2005-10-02 16:17:55.000000000 +0200 @@ -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 @@ -257,7 +263,17 @@ class OutBuffer 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); + 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); if (count == -1) @@ -290,10 +306,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); + } } /***************************************** diff -uNrp dmd-0.140/src/phobos/std/path.d gdc-0.17/d/phobos/std/path.d --- dmd-0.140/src/phobos/std/path.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/path.d 2005-10-13 03:06:51.000000000 +0200 @@ -8,6 +8,12 @@ * 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 +*/ + // File name parsing module std.path; @@ -26,7 +32,7 @@ version(Win32) const char[1] curdir = "."; /// String representing the current directory. const char[2] pardir = ".."; /// String representing the parent directory. } -version(linux) +else version(Unix) { const char[1] sep = "/"; /// String used to separate directory names in a path. const char[0] altsep; /// Alternate version of sep[], used in Windows. @@ -35,6 +41,11 @@ version(linux) const char[1] curdir = "."; /// String representing the current directory. const char[2] pardir = ".."; /// String representing the parent directory. } +else +{ + static assert(0); +} + /************************** * Get extension. @@ -56,7 +67,7 @@ char[] getExt(char[] fullname) if (fullname[i] == ':' || fullname[i] == '\\') break; } - version(linux) + else version(Unix) { if (fullname[i] == '/') break; @@ -73,28 +84,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, ""); @@ -126,7 +137,7 @@ char[] getBaseName(char[] fullname) if (fullname[i - 1] == ':' || fullname[i - 1] == '\\') break; } - version(linux) + else version(Unix) { if (fullname[i - 1] == '/') break; @@ -143,7 +154,7 @@ unittest version (Win32) 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"); @@ -151,7 +162,7 @@ unittest version (Win32) result = getBaseName("a\\b"); - version (linux) + version (Unix) result = getBaseName("a/b"); i = cmp(result, "b"); assert(i == 0); @@ -183,7 +194,7 @@ char[] getDirName(char[] fullname) break; } } - version(linux) + else version(Unix) { if (fullname[i - 1] == '/') { i--; @@ -218,7 +229,7 @@ char[] getDrive(char[] fullname) } return null; } - version(linux) + else version(Unix) { return null; } @@ -329,7 +340,7 @@ char[] join(char[] p1, char[] p2) } } } - version(linux) + else version(Unix) { if (p2[0] == sep[0]) { @@ -357,7 +368,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); @@ -365,7 +376,7 @@ unittest { p = join("foo\\", "bar"); i = cmp(p, "foo\\bar"); } - version (linux) + version (Unix) { p = join("foo/", "bar"); i = cmp(p, "foo/bar"); } @@ -375,7 +386,7 @@ unittest { p = join("foo", "\\bar"); i = cmp(p, "\\bar"); } - version (linux) + version (Unix) { p = join("foo", "/bar"); i = cmp(p, "/bar"); } @@ -385,7 +396,7 @@ unittest { p = join("foo\\", "\\bar"); i = cmp(p, "\\bar"); } - version (linux) + version (Unix) { p = join("foo/", "/bar"); i = cmp(p, "/bar"); } @@ -447,10 +458,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; } + */ } /************************************ @@ -578,7 +596,7 @@ unittest version (Win32) assert(fnmatch("foo", "Foo")); - version (linux) + version (Unix) assert(!fnmatch("foo", "Foo")); assert(fnmatch("foo", "*")); assert(fnmatch("foo.bar", "*")); diff -uNrp dmd-0.140/src/phobos/std/perf.d gdc-0.17/d/phobos/std/perf.d --- dmd-0.140/src/phobos/std/perf.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/perf.d 2005-06-22 05:13:40.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-0.140/src/phobos/std/process.d gdc-0.17/d/phobos/std/process.d --- dmd-0.140/src/phobos/std/process.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/process.d 2005-05-29 23:09:19.000000000 +0200 @@ -24,6 +24,12 @@ * 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 +*/ + module std.process; @@ -49,6 +55,12 @@ private void toAStringz(char[][] a, char /* ========================================================== */ +version (GNU_Need_spawnvp) +{ + // TODO: implement +} +else +{ int spawnvp(int mode, char[] pathname, char[][] argv) { char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); @@ -57,6 +69,7 @@ int spawnvp(int mode, char[] pathname, c return std.c.process.spawnvp(mode, toStringz(pathname), argv_); } +} /* ========================================================== */ @@ -91,7 +104,7 @@ int execvp(char[] pathname, char[][] arg int execvpe(char[] pathname, char[][] argv, char[][] envp) { -version(linux) +version (GNU_Need_execvpe) { // Is pathname rooted? if(pathname[0] == '/') diff -uNrp dmd-0.140/src/phobos/std/random.d gdc-0.17/d/phobos/std/random.d --- dmd-0.140/src/phobos/std/random.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/random.d 2005-10-13 03:06:51.000000000 +0200 @@ -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; } @@ -95,7 +105,7 @@ static this() { QueryPerformanceCounter(&s); } - version(linux) + else version(Unix) { // time.h // sys/time.h diff -uNrp dmd-0.140/src/phobos/std/recls.d gdc-0.17/d/phobos/std/recls.d --- dmd-0.140/src/phobos/std/recls.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/recls.d 2005-06-22 05:13:40.000000000 +0200 @@ -60,6 +60,12 @@ * * ////////////////////////////////////////////////////////////////////////// */ +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + //////////////////////////////////////////////////////////////////////////////// @@ -72,7 +78,11 @@ module std.recls; import std.string; -version (linux) +version (Unix) +{ + private import std.c.unix.unix; +} +else version (linux) { private import std.c.time; private import std.c.linux.linux; @@ -101,6 +111,14 @@ version(Windows) /// Win32 file size type alias ulong recls_filesize_t; } +else version(Unix) +{ + /// UNIX time type + typedef time_t recls_time_t; + + /// UNIX file size type + typedef off_t recls_filesize_t; +} else version(linux) { /// UNIX time type @@ -206,7 +224,10 @@ version(Windows) private uint Recls_GetFileProperty(in recls_info_t fileInfo, in char *buffer, in uint cchBuffer); +version(Windows) +{ private uint Recls_GetShortFileProperty(in recls_info_t fileInfo, in char *buffer, in uint cchBuffer); +} private uint Recls_GetFileNameProperty(in recls_info_t fileInfo, in char *buffer, in uint cchBuffer); @@ -424,6 +445,8 @@ body return str; } +version(Windows) +{ public char[] Search_GetEntryShortFile(in recls_info_t entry) in { @@ -440,6 +463,14 @@ body return str; } +} +else +{ +public char[] Search_GetEntryShortFile(in recls_info_t entry) +{ + return Search_GetEntryFile(entry); +} +} public char[] Search_GetEntryFileName(in recls_info_t entry) in @@ -539,7 +570,9 @@ body { recls_filesize_t size; - return (Recls_GetSizeProperty(entry, &size), size); + //return (Recls_GetSizeProperty(entry, &size), size); + Recls_GetSizeProperty(entry, &size); + return size; } public recls_time_t Search_GetEntryCreationTime(in recls_info_t entry) diff -uNrp dmd-0.140/src/phobos/std/regexp.d gdc-0.17/d/phobos/std/regexp.d --- dmd-0.140/src/phobos/std/regexp.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/regexp.d 2005-04-28 23:12:43.000000000 +0200 @@ -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 +*/ + /* Escape sequences: @@ -1751,8 +1757,9 @@ class Range buf.fill0(b - maxb + 1); base = &buf.data[u]; maxb = b + 1; - bits = (cast(bit*)this.base)[0 .. maxc + 1]; - } + // %% moved array recreate out of this condition + } + bits = (cast(bit*)this.base)[0 .. maxc + 1]; } } diff -uNrp dmd-0.140/src/phobos/std/socket.d gdc-0.17/d/phobos/std/socket.d --- dmd-0.140/src/phobos/std/socket.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/socket.d 2005-06-22 05:13:40.000000000 +0200 @@ -24,16 +24,22 @@ 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 +*/ + module std.socket; private import std.string, std.stdint, std.c.stdlib; -version(linux) +version(Unix) { version = BsdSockets; } - + version(Win32) { private import std.c.windows.windows, std.c.windows.winsock; @@ -50,10 +56,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; @@ -80,7 +86,7 @@ class SocketException: Exception { errorCode = err; - version(linux) + version(Unix) { if(errorCode > 0) { @@ -756,7 +762,14 @@ class SocketSet else version(BsdSockets) { maxfd = -1; - buf[0 .. nbytes] = 0; + version(GNU) + { + FD_ZERO(_fd_set); + } + else + { + buf[0 .. nbytes] = 0; + } } } @@ -771,7 +784,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 @@ -871,6 +892,12 @@ enum SocketOptionLevel: int 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) { @@ -879,8 +906,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 @@ -891,7 +928,6 @@ extern(C) struct linger } } - enum SocketOption: int { DEBUG = SO_DEBUG, @@ -1047,7 +1083,7 @@ class Socket if(WSAEWOULDBLOCK == err) return; } - else version(linux) + else version(Unix) { if(EINPROGRESS == err) return; @@ -1405,7 +1441,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-0.140/src/phobos/std/stdarg.d gdc-0.17/d/phobos/std/stdarg.d --- dmd-0.140/src/phobos/std/stdarg.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/stdarg.d 2005-10-02 16:17:55.000000000 +0200 @@ -6,17 +6,34 @@ /* 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; } } diff -uNrp dmd-0.140/src/phobos/std/stdio.d gdc-0.17/d/phobos/std/stdio.d --- dmd-0.140/src/phobos/std/stdio.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/stdio.d 2005-08-13 01:51:59.000000000 +0200 @@ -4,6 +4,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, September 2004 +*/ + module std.stdio; import std.c.stdio; @@ -40,10 +46,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 @@ -75,6 +82,9 @@ void writefx(FILE* fp, TypeInfo[] argume } else if (orientation > 0) // wide orientation { + version (GNU_Have_fwide) + { + version (Windows) { void putcw(dchar c) @@ -94,7 +104,7 @@ void writefx(FILE* fp, TypeInfo[] argume } } } - else version (linux) + else version (Unix) { void putcw(dchar c) { @@ -109,6 +119,8 @@ void writefx(FILE* fp, TypeInfo[] argume std.format.doFormat(&putcw, arguments, argptr); if (newline) FPUTWC('\n', fp); + + } } } finally diff -uNrp dmd-0.140/src/phobos/std/stream.d gdc-0.17/d/phobos/std/stream.d --- dmd-0.140/src/phobos/std/stream.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/stream.d 2005-10-13 03:06:51.000000000 +0200 @@ -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: @@ -182,7 +188,6 @@ interface InputStream { wchar[] readStringW(size_t length); - /*** * Read and return the next character in the stream. * @@ -191,6 +196,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 @@ -223,7 +230,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. @@ -342,14 +349,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. * @@ -676,7 +682,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,7 +1131,7 @@ class Stream : InputStream, OutputStream break; psize *= 2; p = cast(char*) alloca(psize); - } else version (linux) { + } else version (Unix) { count = vsnprintf(p, psize, f, args); if (count == -1) psize *= 2; @@ -1144,10 +1150,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) { @@ -1168,7 +1178,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(""); @@ -1766,8 +1776,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; } @@ -1777,7 +1787,7 @@ class File: Stream { version (Win32) { private HANDLE hFile; } - version (linux) { + version (Unix) { private HANDLE hFile = -1; } @@ -1786,7 +1796,7 @@ class File: Stream { version (Win32) { hFile = null; } - version (linux) { + version (Unix) { hFile = -1; } isopen = false; @@ -1843,8 +1853,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) @@ -1871,7 +1881,7 @@ class File: Stream { createMode = CREATE_ALWAYS; // resets file } } - version (linux) { + version (Unix) { if (mode & FileMode.In) { access = O_RDONLY; share = 0660; @@ -1909,8 +1919,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; } } @@ -1934,8 +1944,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; } @@ -1947,8 +1957,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; } @@ -1963,8 +1973,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, offset, rel); + } else version (Unix) { + ulong result = std.c.unix.unix.lseek(hFile, offset, rel); if (result == 0xFFFFFFFF) throw new SeekException("unable to move file pointer"); } @@ -2003,7 +2013,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()); @@ -2023,7 +2033,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); @@ -2031,7 +2041,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()); @@ -2120,7 +2130,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()); @@ -2140,7 +2150,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); @@ -2148,7 +2158,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()); diff -uNrp dmd-0.140/src/phobos/std/string.d gdc-0.17/d/phobos/std/string.d --- dmd-0.140/src/phobos/std/string.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/string.d 2005-11-28 05:17:52.000000000 +0100 @@ -23,6 +23,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 @@ -40,19 +46,37 @@ private import std.stdarg; extern (C) { // Functions from the C library. - int strlen(char *); - int strcmp(char *, char *); - char* strcat(char *, char *); - int memcmp(void *, void *, uint); + version (GNU) // should be: GNU_Use_Builtins / -f[no-]builtins + { + private import gcc.builtins; + alias __builtin_strlen strlen; + alias __builtin_strcmp strcmp; + alias __builtin_strcat strcat; + alias __builtin_memcmp memcmp; + alias __builtin_strcpy strcpy; + alias __builtin_strstr strstr; + alias __builtin_strchr strchr; + alias __builtin_strrchr strrchr; + alias __builtin_memcpy memcpy; + //alias __builtin_memmove memmove;// not in 3.3 + alias __builtin_memset memset; + } + else + { + int strlen(char *); + int strcmp(char *, char *); + char* strcat(char *, char *); + int memcmp(void *, void *, uint); + char *strcpy(char *, char *); + char *strstr(char *, char *); + char *strchr(char *, char); + char *strrchr(char *, char); + void *memcpy(void *, void *, uint); + void *memset(void *, uint, uint); + } + void *memmove(void *, void *, uint); int memicmp(char *, char *, uint); - char *strcpy(char *, char *); - char *strstr(char *, char *); - char *strchr(char *, char); - char *strrchr(char *, char); char *memchr(char *, char, uint); - void *memcpy(void *, void *, uint); - void *memmove(void *, void *, uint); - void *memset(void *, uint, uint); char* strerror(int); int wcslen(wchar *); @@ -154,7 +178,7 @@ int icmp(char[] s1, char[] s2) { result = memicmp(s1, s2, len); } - version (linux) + version (Unix) { for (size_t i = 0; i < len; i++) { @@ -828,7 +852,7 @@ char[] tolower(char[] s) if ('A' <= c && c <= 'Z') { if (!changed) - { r = s.dup; + { r = s.dup; changed = 1; } r[i] = c + (cast(char)'a' - 'A'); @@ -1390,7 +1414,6 @@ 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) diff -uNrp dmd-0.140/src/phobos/std/system.d gdc-0.17/d/phobos/std/system.d --- dmd-0.140/src/phobos/std/system.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/system.d 2004-10-26 02:41:27.000000000 +0200 @@ -4,6 +4,12 @@ * Placed into Public Domain */ +/* 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; @@ -16,6 +22,7 @@ const { Win32 = 1, // Microsoft 32 bit Windows systems linux, // all linux systems + Unix, // all other } version (Win32) @@ -26,6 +33,10 @@ const { Family family = Family.linux; } + else version (Unix) + { + Family family = Family.Unix; + } else { static assert(0); diff -uNrp dmd-0.140/src/phobos/std/thread.d gdc-0.17/d/phobos/std/thread.d --- dmd-0.140/src/phobos/std/thread.d 2005-11-24 17:12:54.000000000 +0100 +++ gdc-0.17/d/phobos/std/thread.d 2005-06-22 05:13:40.000000000 +0200 @@ -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, September 2004 +*/ + module std.thread; //debug=thread; @@ -333,6 +339,7 @@ class Thread { if (allThreadsDim) { + version (GNU) { /* unresolved issue: this CloseHandle call causes crashes later... */ } else CloseHandle(allThreads[0].hdl); allThreads[0].hdl = GetCurrentThread(); } @@ -382,9 +389,509 @@ void *os_query_stackBottom() } +/* ================================ GCC ================================= */ + +else version (GNU) +{ + +private import std.c.unix.unix; +private import gcc.builtins; + +version (GNU_pthread_suspend) +{ + // nothing +} +else +{ + private import gcc.threadsem; +} + +private extern (C) void* _d_gcc_query_stack_origin(); + + +class ThreadError : Error +{ + this(char[] s) + { + super("Thread error: " ~ s); + } +} + +class Thread +{ + this() + { + } + + this(int (*fp)(void *), void *arg) + { + this.fp = fp; + this.arg = arg; + } + + this(int delegate() dg) + { + this.dg = dg; + } + + pthread_t id; + void* stackBottom; + void* stackTop; + + void start() + { + if (state != TS.INITIAL) + error("already started"); + + synchronized (threadLock) + { + for (int i = 0; 1; i++) + { + if (i == allThreads.length) + error("too many threads"); + if (!allThreads[i]) + { allThreads[i] = this; + idx = i; + if (i >= allThreadsDim) + allThreadsDim = i + 1; + break; + } + } + nthreads++; + + state = TS.RUNNING; + int result; + //printf("creating thread x%x\n", this); + result = pthread_create(&id, null, &threadstart, 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); + } + + int run() + { + if (fp) + return fp(arg); + else if (dg) + return dg(); + } + + void wait() + { + if (this is getThis()) + error("wait on self"); + if (state == TS.RUNNING) + { int result; + void *value; + + result = pthread_join(id, &value); + if (result) + error("failed to wait"); + } + } + + void wait(uint milliseconds) + { + wait(); + /+ not implemented + if (this is getThis()) + error("wait on self"); + if (state == TS.RUNNING) + { DWORD dw; + + dw = WaitForSingleObject(hdl, milliseconds); + } + +/ + } + + enum TS + { + INITIAL, + RUNNING, + TERMINATED + } + + TS getState() + { + return state; + } + + enum PRIORITY + { + INCREASE, + DECREASE, + IDLE, + CRITICAL + } + + void setPriority(PRIORITY p) + { + /+ not implemented + int nPriority; + + switch (p) + { + case PRIORITY.INCREASE: + nPriority = THREAD_PRIORITY_ABOVE_NORMAL; + break; + case PRIORITY.DECREASE: + nPriority = THREAD_PRIORITY_BELOW_NORMAL; + break; + case PRIORITY.IDLE: + nPriority = THREAD_PRIORITY_IDLE; + break; + case PRIORITY.CRITICAL: + nPriority = THREAD_PRIORITY_TIME_CRITICAL; + break; + } + + if (SetThreadPriority(hdl, nPriority) == THREAD_PRIORITY_ERROR_RETURN) + error("set priority"); + +/ + } + + int isSelf() + { + //printf("id = %d, self = %d\n", id, pthread_self()); + return pthread_equal(pthread_self(), id); + } + + static Thread getThis() + { + pthread_t id; + Thread result; + + //printf("getThis(), allThreadsDim = %d\n", allThreadsDim); + synchronized (threadLock) + { + id = pthread_self(); + //printf("id = %d\n", id); + for (int i = 0; i < allThreadsDim; i++) + { + Thread t = allThreads[i]; + //printf("allThreads[%d] = x%x, id = %d\n", i, t, (t ? t.id : 0)); + if (t && pthread_equal(id, t.id)) + { + return t; + } + } + } + printf("didn't find it\n"); + assert(result); + return result; + } + + static Thread[] getAll() + { + return allThreads[0 .. allThreadsDim]; + } + + void pause() + { + if (state == TS.RUNNING) + { + version (GNU_pthread_suspend) + { + if (pthread_suspend_np(id) != 0) + error("cannot pause"); + } + else + { int result; + + result = pthread_kill(id, SIGUSR1); + if (result) + error("cannot pause"); + else + flagSuspend.wait(); // wait for acknowledgement + } + } + else + error("cannot pause"); + } + + void resume() + { + if (state == TS.RUNNING) + { + 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"); + } + } + else + error("cannot resume"); + } + + static void pauseAll() + { + version (GNU_pthread_suspend) + { + if (nthreads > 1) + { + Thread tthis = getThis(); + + 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; + + for (int i = 0; i < allThreadsDim; i++) + { Thread t; + + t = allThreads[i]; + if (t && t !is tthis && t.state == TS.RUNNING) + { int result; + + result = pthread_kill(t.id, SIGUSR1); + if (result) + getThis().error("cannot pause"); + else + npause++; // count of paused threads + } + } + + // Wait for each paused thread to acknowledge + while (npause--) + { + flagSuspend.wait(); + } + } + + } + } + + static void resumeAll() + { + if (nthreads > 1) + { + Thread tthis = getThis(); + + for (int i = 0; i < allThreadsDim; i++) + { Thread t; + + t = allThreads[i]; + if (t && t !is tthis && t.state == TS.RUNNING) + t.resume(); + } + } + } + + static void yield() + { + sched_yield(); + } + + static uint nthreads = 1; + + private: + + static uint allThreadsDim; + static Object threadLock; + static Thread[/*_POSIX_THREAD_THREADS_MAX*/ 100] allThreads; + version (GNU_pthread_suspend) + { + // nothing + } + else + { + static Semaphore flagSuspend; + } + + TS state; + int idx = -1; // index into allThreads[] + int flags = 0; + + int (*fp)(void *); + void *arg; + + int delegate() dg; + + void error(char[] msg) + { + throw new ThreadError(msg); + } + + + /************************************************ + * This is just a wrapper to interface between C rtl and Thread.run(). + */ + + extern (C) static void *threadstart(void *p) + { + Thread t = cast(Thread)p; + int result; + + debug (thread) printf("Starting thread x%x (%d)\n", t, t.idx); + + // Need to set t.id here, because thread is off and running + // before pthread_create() sets it. + t.id = pthread_self(); + + t.stackBottom = getESP(); + try + { + result = t.run(); + } + catch (Object o) + { + printf("Error: "); + o.print(); + result = 1; + } + + debug (thread) printf("Ending thread %d\n", t.idx); + t.state = TS.TERMINATED; + allThreads[t.idx] = null; + t.idx = -1; + nthreads--; + return cast(void*)result; + } + + + /************************************** + * Create a Thread for global main(). + */ + + static void thread_init() + { + threadLock = new Object(); + + Thread t = new Thread(); + + t.state = TS.RUNNING; + t.id = pthread_self(); + t.stackBottom = cast(void*) _d_gcc_query_stack_origin(); + + assert(!allThreads[0]); + allThreads[0] = t; + allThreadsDim = 1; + t.idx = 0; + + version (GNU_pthread_suspend) + { + // nothing + } + else + { + /* 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; + + if (! flagSuspend.create()) + goto Lfail; + } + + return; + + Lfail: + getThis().error("cannot initialize threads"); + } + + version (GNU_pthread_suspend) + { + // nothing + } + else + { + + /********************************** + * This gets called when a thread gets SIGUSR1. + */ + + extern (C) static void pauseHandler(int sig) + { int result; + + // Save all registers on the stack so they'll be scanned by the GC + __builtin_unwind_init(); + + + assert(sig == SIGUSR1); + // %% moved call to sem_post + + 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. + */ + + extern (C) static void resumeHandler(int sig) + { + Thread t = getThis(); + + t.flags |= 1; + } + } + + static void* getESP() + { + // TODO add builtin for using stack_pointer_rtx + int dummy; + void * p = & dummy + 1; // +1 doesn't help much; also assume stack grows down + return p; + } +} + + +} + + /* ================================ linux ================================= */ -version (linux) +else version (linux) { private import std.c.linux.linux; @@ -492,7 +999,6 @@ class Thread } } nthreads++; - } state = TS.RUNNING; int result; @@ -504,6 +1010,7 @@ class Thread idx = -1; error("failed to start"); // BUG: should report errno } + } // %% changed end of sync region //printf("t = x%x, id = %d\n", this, id); } @@ -841,7 +1348,7 @@ class Thread } assert(sig == SIGUSR1); - sem_post(&flagSuspend); + // %% moved call to sem_post sigset_t sigmask; result = sigfillset(&sigmask); @@ -852,6 +1359,7 @@ class Thread Thread t = getThis(); t.stackTop = getESP(); t.flags &= ~1; + sem_post(&flagSuspend); while (1) { sigsuspend(&sigmask); // suspend until SIGUSR2