diff -uNr dmd-0.146/dmd/src/dmd/aggregate.h dmd-0.147/dmd/src/dmd/aggregate.h --- dmd-0.146/dmd/src/dmd/aggregate.h 2006-02-09 15:12:42.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/aggregate.h 2006-02-11 17:34:52.000000000 +0100 @@ -101,6 +101,8 @@ struct StructDeclaration : AggregateDeclaration { + static StructDeclaration *match; // set to object._Match + int zeroInit; // !=0 if initialize with 0 fill StructDeclaration(Loc loc, Identifier *id); diff -uNr dmd-0.146/dmd/src/dmd/class.c dmd-0.147/dmd/src/dmd/class.c --- dmd-0.146/dmd/src/dmd/class.c 2006-02-09 15:26:36.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/class.c 2006-02-13 23:01:58.000000000 +0100 @@ -508,11 +508,13 @@ void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { - buf->printf("%s ", kind()); if (!isAnonymous()) + { + buf->printf("%s ", kind()); buf->writestring(toChars()); - if (baseclasses.dim) - buf->writestring(" : "); + if (baseclasses.dim) + buf->writestring(" : "); + } for (int i = 0; i < baseclasses.dim; i++) { BaseClass *b = (BaseClass *)baseclasses.data[i]; diff -uNr dmd-0.146/dmd/src/dmd/constfold.c dmd-0.147/dmd/src/dmd/constfold.c --- dmd-0.146/dmd/src/dmd/constfold.c 2006-02-04 20:37:14.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/constfold.c 2006-02-10 23:57:44.000000000 +0100 @@ -19,6 +19,13 @@ #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 @@ -282,7 +289,11 @@ e2 = e2->constFold(); if (type->isfloating()) { complex_t c; - d_float80 r; +#ifdef IN_GCC + real_t r; +#else + d_float80 r; +#endif if (e1->type->isreal()) { @@ -351,7 +362,11 @@ e2 = e2->constFold(); if (type->isfloating()) { complex_t c; - d_float80 r; +#ifdef IN_GCC + real_t r; +#else + d_float80 r; +#endif //e1->type->print(); //e2->type->print(); @@ -436,6 +451,8 @@ #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 @@ -445,6 +462,8 @@ #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 @@ -674,7 +693,11 @@ } #else // Don't rely on compiler, handle NAN arguments separately +#if IN_GCC + if (real_isnan(&r1) || real_isnan(&r2)) // if unordered +#else if (isnan(r1) || isnan(r2)) // if unordered +#endif { switch (op) { diff -uNr dmd-0.146/dmd/src/dmd/dchar.c dmd-0.147/dmd/src/dmd/dchar.c --- dmd-0.146/dmd/src/dmd/dchar.c 2004-03-26 23:11:52.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/dchar.c 2006-02-12 21:59:06.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2002 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -365,18 +365,30 @@ case 2: hash *= 37; +#if __I86__ hash += *(unsigned short *)str; +#else + hash += str[0] * 256 + str[1]; +#endif return hash; case 3: hash *= 37; +#if __I86__ hash += (*(unsigned short *)str << 8) + ((unsigned char *)str)[2]; +#else + hash += (str[0] * 256 + str[1]) * 256 + str[2]; +#endif return hash; default: hash *= 37; +#if __I86__ hash += *(long *)str; +#else + hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3]; +#endif str += 4; len -= 4; break; diff -uNr dmd-0.146/dmd/src/dmd/dchar.h dmd-0.147/dmd/src/dmd/dchar.h --- dmd-0.146/dmd/src/dmd/dchar.h 2004-03-26 23:11:52.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/dchar.h 2006-02-12 22:02:16.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2002 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -11,7 +11,7 @@ #ifndef DCHAR_H #define DCHAR_H -#if __GNUC__ +#if __GNUC__ && !_WIN32 #include "gnuc.h" #endif @@ -138,7 +138,10 @@ #else #include + +#ifndef GCC_SAFE_DMD #include +#endif typedef char dchar; #define TEXT(x) x @@ -156,6 +159,7 @@ 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 +169,7 @@ 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 -uNr dmd-0.146/dmd/src/dmd/declaration.c dmd-0.147/dmd/src/dmd/declaration.c --- dmd-0.146/dmd/src/dmd/declaration.c 2006-02-09 12:05:54.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/declaration.c 2006-02-15 01:51:48.000000000 +0100 @@ -387,7 +387,9 @@ assert(this != aliassym); //static int count; if (++count == 10) *(char*)0=0; if (inSemantic) - error("recursive alias declaration"); + { error("recursive alias declaration"); +// return this; + } Dsymbol *s = aliassym ? aliassym->toAlias() : this; return s; } @@ -772,7 +774,12 @@ { if (storage_class & STCconst) buf->writestring("const "); - type->toCBuffer(buf, ident, hgs); + if (storage_class & STCstatic) + buf->writestring("static "); + if (type) + type->toCBuffer(buf, ident, hgs); + else + buf->writestring(ident->toChars()); if (init) { buf->writestring(" = "); init->toCBuffer(buf, hgs); diff -uNr dmd-0.146/dmd/src/dmd/declaration.h dmd-0.147/dmd/src/dmd/declaration.h --- dmd-0.146/dmd/src/dmd/declaration.h 2006-01-08 01:12:48.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/declaration.h 2006-02-12 22:03:50.000000000 +0100 @@ -354,6 +354,9 @@ // scopes from having the same name VarDeclaration *vthis; // 'this' parameter VarDeclaration *v_arguments; // '_arguments' parameter +#if IN_GCC + VarDeclaration *v_argptr; // '_argptr' variable +#endif Array *parameters; // Array of Argument's for parameters DsymbolTable *labtab; // statement label symbol table Declaration *overnext; // next in overload list diff -uNr dmd-0.146/dmd/src/dmd/doc.c dmd-0.147/dmd/src/dmd/doc.c --- dmd-0.146/dmd/src/dmd/doc.c 2006-01-08 01:02:08.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/doc.c 2006-02-12 22:05:04.000000000 +0100 @@ -13,6 +13,9 @@ #include #include +#ifdef IN_GCC +#include "mem.h" +#else #if _WIN32 #include "..\root\mem.h" #elif linux @@ -20,6 +23,7 @@ #else #error "fix this" #endif +#endif #include "root.h" diff -uNr dmd-0.146/dmd/src/dmd/dsymbol.c dmd-0.147/dmd/src/dmd/dsymbol.c --- dmd-0.146/dmd/src/dmd/dsymbol.c 2006-02-08 22:49:30.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/dsymbol.c 2006-02-11 00:43:54.000000000 +0100 @@ -348,21 +348,21 @@ char *p = locToChars(); if (*p) - printf("%s: ", p); + fprintf(stdmsg, "%s: ", p); mem.free(p); if (isAnonymous()) - printf("%s ", kind()); + fprintf(stdmsg, "%s ", kind()); else - printf("%s %s ", kind(), toPrettyChars()); + fprintf(stdmsg, "%s %s ", kind(), toPrettyChars()); va_list ap; va_start(ap, format); - vprintf(format, ap); + vfprintf(stdmsg, format, ap); va_end(ap); - printf("\n"); - fflush(stdout); + fprintf(stdmsg, "\n"); + fflush(stdmsg); } global.errors++; @@ -378,18 +378,18 @@ p = locToChars(); if (*p) - printf("%s: ", p); + fprintf(stdmsg, "%s: ", p); mem.free(p); - printf("%s %s ", kind(), toPrettyChars()); + fprintf(stdmsg, "%s %s ", kind(), toPrettyChars()); va_list ap; va_start(ap, format); - vprintf(format, ap); + vfprintf(stdmsg, format, ap); va_end(ap); - printf("\n"); - fflush(stdout); + fprintf(stdmsg, "\n"); + fflush(stdmsg); } global.errors++; diff -uNr dmd-0.146/dmd/src/dmd/dsymbol.h dmd-0.147/dmd/src/dmd/dsymbol.h --- dmd-0.146/dmd/src/dmd/dsymbol.h 2006-02-08 19:28:48.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/dsymbol.h 2006-02-12 22:06:22.000000000 +0100 @@ -63,7 +63,12 @@ struct DeleteDeclaration; struct HdrGenState; +#if IN_GCC +union tree_node; +typedef union tree_node TYPE; +#else struct TYPE; +#endif enum PROT { diff -uNr dmd-0.146/dmd/src/dmd/entity.c dmd-0.147/dmd/src/dmd/entity.c --- dmd-0.146/dmd/src/dmd/entity.c 2005-04-12 23:53:58.000000000 +0200 +++ dmd-0.147/dmd/src/dmd/entity.c 2006-02-12 22:13:32.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2005 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -23,6 +23,1069 @@ unsigned short value; }; +#if IN_GCC +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; +} + +#else //TODO: Merge Walter's list with Thomas' + static NameId names[] = { // Entities @@ -299,3 +1362,5 @@ } return -1; } + +#endif diff -uNr dmd-0.146/dmd/src/dmd/expression.c dmd-0.147/dmd/src/dmd/expression.c --- dmd-0.146/dmd/src/dmd/expression.c 2006-02-09 12:00:18.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/expression.c 2006-02-14 23:16:56.000000000 +0100 @@ -21,12 +21,23 @@ extern "C" char * __cdecl __locale_decpoint; #endif -#if _WIN32 -#include "..\root\mem.h" +#if IN_GCC +// Issues with using -include total.h (defines integer_t) and then complex.h fails... +#undef integer_t +#endif + +#ifdef __APPLE__ +#define integer_t dmd_integer_t #endif -#if linux + +#if IN_GCC +#include "mem.h" +#elif _WIN32 +#include "..\root\mem.h" +#elif linux #include "../root/mem.h" #endif + #include "port.h" #include "mtype.h" #include "init.h" @@ -370,6 +381,16 @@ 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); @@ -554,7 +575,7 @@ { Expression *e; if (!size) - printf("No expression copy for: %s\n", toChars()); + fprintf(stdmsg, "No expression copy for: %s\n", toChars()); e = (Expression *)mem.malloc(size); return (Expression *)memcpy(e, this, size); } @@ -578,8 +599,8 @@ void Expression::print() { - printf("%s\n", toChars()); - fflush(stdout); + fprintf(stdmsg, "%s\n", toChars()); + fflush(stdmsg); } char *Expression::toChars() @@ -599,16 +620,16 @@ char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stdmsg, "%s: ", p); mem.free(p); va_list ap; va_start(ap, format); - vprintf(format, ap); + vfprintf(stdmsg, format, ap); va_end(ap); - printf("\n"); - fflush(stdout); + fprintf(stdmsg, "\n"); + fflush(stdmsg); } global.errors++; @@ -664,7 +685,11 @@ 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, HdrGenState *hgs) @@ -762,7 +787,9 @@ #endif if (!type->checkBoolean()) + { error("expression %s of type %s does not have a boolean value", toChars(), type->toChars()); + } return this; } @@ -1320,6 +1347,11 @@ 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(); @@ -1858,6 +1890,8 @@ else { buffer.writeUTF16(c); newlen++; + if (c >= 0x10000) + newlen++; } } buffer.writeUTF16(0); @@ -2427,7 +2461,7 @@ argsToCBuffer(buf, newargs, hgs); buf->writeByte(')'); } - buf->writestring(" class"); + buf->writestring(" class "); if (arguments && arguments->dim) { buf->writeByte('('); @@ -4473,6 +4507,11 @@ return this; } +void DeleteExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + buf->writestring("delete "); + expToCBuffer(buf, hgs, e1, precedence[op]); +} /************************************************************/ @@ -6465,6 +6504,62 @@ } +/************************************************************/ + +MatchExp::MatchExp(enum TOK op, Loc loc, Expression *e1, Expression *e2) + : BinExp(loc, op, sizeof(MatchExp), e1, e2) +{ + assert(op == TOKmatch || op == TOKnotmatch); +} + +Expression *MatchExp::semantic(Scope *sc) +{ Expression *e; + + if (type) + return this; + + BinExp::semanticp(sc); + + e = op_overload(sc); + if (e) + { + if (op == TOKnotmatch) + { + e = new NotExp(e->loc, e); + e = e->semantic(sc); + } + return e; + } + + // Both operands must be of type char[] + Type *t = Type::tchar->arrayOf(); + e1 = e1->implicitCastTo(t); + e2 = e2->implicitCastTo(t); + + // Call the internal function void* _d_match(e1, e2) + FuncDeclaration *fdmatch = FuncDeclaration::genCfunc(StructDeclaration::match->type->pointerTo(), "_d_match"); + + Expression *ec = new VarExp(0, fdmatch); + Array *args = new Array(); + args->push(e1); + args->push(e2); + e = new CallExp(loc, ec, args); + e->type = fdmatch->type->next; // don't run semantic() on e + + if (op == TOKnotmatch) + { + e = new NotExp(e->loc, e); + e = e->semantic(sc); + } + return e; +} + +int MatchExp::isBit() +{ + return FALSE; +} + + /****************************************************************/ CondExp::CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2) diff -uNr dmd-0.146/dmd/src/dmd/expression.h dmd-0.147/dmd/src/dmd/expression.h --- dmd-0.146/dmd/src/dmd/expression.h 2006-02-09 22:33:06.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/expression.h 2006-02-15 13:48:22.000000000 +0100 @@ -684,6 +684,7 @@ Expression *semantic(Scope *sc); Expression *checkToBoolean(); void checkSideEffect(int flag); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); elem *toElem(IRState *irs); }; @@ -1192,6 +1193,20 @@ elem *toElem(IRState *irs); }; +// ~~ and !~ + +struct MatchExp : BinExp +{ + MatchExp(enum TOK op, Loc loc, Expression *e1, Expression *e2); + Expression *semantic(Scope *sc); + int isBit(); + + // For operator overloading + Identifier *opId(); + + elem *toElem(IRState *irs); +}; + /****************************************************************/ struct CondExp : BinExp diff -uNr dmd-0.146/dmd/src/dmd/identifier.c dmd-0.147/dmd/src/dmd/identifier.c --- dmd-0.146/dmd/src/dmd/identifier.c 2005-12-12 00:53:14.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/identifier.c 2006-02-14 23:07:30.000000000 +0100 @@ -65,7 +65,7 @@ void Identifier::print() { - printf("%s",string); + fprintf(stdmsg, "%s",string); } int Identifier::dyncast() diff -uNr dmd-0.146/dmd/src/dmd/idgen.c dmd-0.147/dmd/src/dmd/idgen.c --- dmd-0.146/dmd/src/dmd/idgen.c 2005-12-04 11:26:50.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/idgen.c 2006-02-14 23:08:20.000000000 +0100 @@ -55,6 +55,7 @@ { "classinfo" }, { "typeinfo" }, { "Exception" }, + { "_Match" }, { "withSym", "__withSym" }, { "result", "__result" }, { "returnLabel", "__returnLabel" }, @@ -77,6 +78,7 @@ { "TypeInfo_Delegate" }, { "_arguments" }, { "_argptr" }, + { "_match" }, { "LINE", "__LINE__" }, { "FILE", "__FILE__" }, @@ -165,6 +167,8 @@ { "slice", "opSlice" }, { "call", "opCall" }, { "cast", "opCast" }, + { "match", "opMatch" }, + { "next", "opNext" }, { "classNew", "new" }, { "classDelete", "delete" }, @@ -175,6 +179,7 @@ // For pragma's { "lib" }, { "msg" }, + { "GNU_asm" }, // For toHash { "tohash", "toHash" }, diff -uNr dmd-0.146/dmd/src/dmd/lexer.c dmd-0.147/dmd/src/dmd/lexer.c --- dmd-0.146/dmd/src/dmd/lexer.c 2006-02-09 11:59:26.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/lexer.c 2006-02-14 23:12:42.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2005 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -99,7 +99,7 @@ #ifdef DEBUG void Token::print() { - printf("%s\n", toChars()); + fprintf(stdmsg, "%s\n", toChars()); } #endif @@ -291,16 +291,16 @@ { char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stdmsg, "%s: ", p); mem.free(p); va_list ap; va_start(ap, format); - vprintf(format, ap); + vfprintf(stdmsg, format, ap); va_end(ap); - printf("\n"); - fflush(stdout); + fprintf(stdmsg, "\n"); + fflush(stdmsg); if (global.errors >= 20) // moderate blizzard of cascading messages fatal(); @@ -314,16 +314,16 @@ { char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stdmsg, "%s: ", p); mem.free(p); va_list ap; va_start(ap, format); - vprintf(format, ap); + vfprintf(stdmsg, format, ap); va_end(ap); - printf("\n"); - fflush(stdout); + fprintf(stdmsg, "\n"); + fflush(stdmsg); if (global.errors >= 20) // moderate blizzard of cascading messages fatal(); @@ -933,6 +933,10 @@ else t->value = TOKule; // !> } + else if (*p == '~') + { p++; + t->value = TOKnotmatch; // !~ + } else t->value = TOKnot; // ! return; @@ -952,6 +956,20 @@ t->value = TOKassign; // = return; + case '~': + p++; + if (*p == '=') + { p++; + t->value = TOKcatass; // ~= + } + else if (*p == '~') + { p++; + t->value = TOKmatch; // ~~ + } + else + t->value = TOKtilde; // ~ + return; + #define SINGLE(c,tok) case c: p++; t->value = tok; return; SINGLE('(', TOKlparen) @@ -982,7 +1000,6 @@ DOUBLE('*', TOKmul, '=', TOKmulass) DOUBLE('%', TOKmod, '=', TOKmodass) DOUBLE('^', TOKxor, '=', TOKxorass) - DOUBLE('~', TOKtilde, '=', TOKcatass) #undef DOUBLE @@ -1996,19 +2013,31 @@ 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; @@ -2572,6 +2601,8 @@ Token::tochars[TOKcall] = "call"; Token::tochars[TOKidentity] = "is"; Token::tochars[TOKnotidentity] = "!is"; + Token::tochars[TOKmatch] = "~~"; + Token::tochars[TOKnotmatch] = "!~"; Token::tochars[TOKorass] = "|="; diff -uNr dmd-0.146/dmd/src/dmd/lexer.h dmd-0.147/dmd/src/dmd/lexer.h --- dmd-0.146/dmd/src/dmd/lexer.h 2006-02-02 20:38:12.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/lexer.h 2006-02-14 23:14:00.000000000 +0100 @@ -35,6 +35,7 @@ ++ -- . -> : , ? && || + ~~ !~ */ enum TOK @@ -72,6 +73,7 @@ TOKle, TOKge, TOKequal, TOKnotequal, TOKidentity, TOKnotidentity, + TOKmatch, TOKnotmatch, TOKindex, TOKis, TOKbool, @@ -198,7 +200,11 @@ 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 @@ -208,6 +214,9 @@ 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); diff -uNr dmd-0.146/dmd/src/dmd/macro.c dmd-0.147/dmd/src/dmd/macro.c --- dmd-0.146/dmd/src/dmd/macro.c 2005-11-26 22:30:14.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/macro.c 2006-02-14 23:14:50.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2005 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -16,6 +16,9 @@ #include #include +#ifdef IN_GCC +#include "mem.h" +#else #if _WIN32 #include "..\root\mem.h" #elif linux @@ -23,6 +26,7 @@ #else #error "fix this" #endif +#endif #include "root.h" #include "macro.h" diff -uNr dmd-0.146/dmd/src/dmd/mangle.c dmd-0.147/dmd/src/dmd/mangle.c --- dmd-0.146/dmd/src/dmd/mangle.c 2005-12-04 11:25:54.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/mangle.c 2006-02-14 23:16:40.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2005 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -62,7 +62,7 @@ return ident->toChars(); default: - printf("'%s', linkage = %d\n", toChars(), linkage); + fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage); assert(0); } } diff -uNr dmd-0.146/dmd/src/dmd/mars.c dmd-0.147/dmd/src/dmd/mars.c --- dmd-0.146/dmd/src/dmd/mars.c 2006-02-04 00:58:48.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/mars.c 2006-02-10 17:13:48.000000000 +0100 @@ -53,7 +53,7 @@ copyright = "Copyright (c) 1999-2006 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.146"; + version = "v0.147"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); @@ -92,16 +92,16 @@ char *p = loc.toChars(); if (*p) - printf("%s: ", p); + fprintf(stdmsg, "%s: ", p); mem.free(p); va_list ap; va_start(ap, format); - printf("Error: "); - vprintf(format, ap); + fprintf(stdmsg, "Error: "); + vfprintf(stdmsg, format, ap); va_end( ap ); - printf("\n"); - fflush(stdout); + fprintf(stdmsg, "\n"); + fflush(stdmsg); } global.errors++; } @@ -157,7 +157,7 @@ -profile profile runtime performance of generated code\n\ -quiet suppress unnecessary messages\n\ -release compile release version\n\ - -run args... run resulting program, passing args\n\ + -run srcfile args... run resulting program, passing args\n\ -unittest compile in unit tests\n\ -v verbose\n\ -version=level compile in version code >= level\n\ @@ -436,8 +436,17 @@ else if (strcmp(p + 1, "run") == 0) { global.params.run = 1; global.params.runargs_length = ((i >= argcstart) ? argc : argcstart) - i - 1; - global.params.runargs = &argv[i + 1]; - i += global.params.runargs_length; + if (global.params.runargs_length) + { + files.push(argv[i + 1]); + global.params.runargs = &argv[i + 2]; + i += global.params.runargs_length; + global.params.runargs_length--; + } + else + { global.params.run = 0; + goto Lnoarg; + } } else { diff -uNr dmd-0.146/dmd/src/dmd/mars.h dmd-0.147/dmd/src/dmd/mars.h --- dmd-0.146/dmd/src/dmd/mars.h 2006-02-09 15:18:30.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/mars.h 2006-02-14 22:56:14.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2005 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -14,6 +14,10 @@ #pragma once #endif /* __DMC__ */ +#ifdef IN_GCC +/* Changes for the GDC compiler by David Friedman */ +#endif + struct Array; // Put command line switches in here diff -uNr dmd-0.146/dmd/src/dmd/mtype.c dmd-0.147/dmd/src/dmd/mtype.c --- dmd-0.146/dmd/src/dmd/mtype.c 2006-01-28 21:16:58.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/mtype.c 2006-02-14 01:33:14.000000000 +0100 @@ -84,6 +84,7 @@ ClassDeclaration *Type::typeinfofunction; ClassDeclaration *Type::typeinfodelegate; +Type *Type::tvoidptr; Type *Type::basic[TMAX]; unsigned char Type::mangleChar[TMAX]; StringTable Type::stringtable; @@ -192,6 +193,8 @@ basic[basetab[i]] = new TypeBasic(basetab[i]); basic[Terror] = basic[Tint32]; + tvoidptr = tvoid->pointerTo(); + if (global.params.isX86_64) { PTRSIZE = 8; @@ -3307,7 +3310,8 @@ } else { - assert(sym->memtype); + if (!sym->memtype) + goto Lfwd; e = sym->memtype->getProperty(loc, ident); } return e; @@ -3776,6 +3780,12 @@ return sym->zeroInit; } +int TypeStruct::checkBoolean() +{ + return FALSE; +} + + /***************************** TypeClass *****************************/ diff -uNr dmd-0.146/dmd/src/dmd/mtype.h dmd-0.147/dmd/src/dmd/mtype.h --- dmd-0.146/dmd/src/dmd/mtype.h 2006-01-08 00:58:56.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/mtype.h 2006-02-11 19:05:30.000000000 +0100 @@ -142,7 +142,7 @@ #define tshiftcnt tint32 // right side of shift expression #define tboolean tint32 // result of boolean expression #define tindex tint32 // array/ptr index - #define tvoidptr tint32 // size for void* + static Type *tvoidptr; // void* #define terror basic[Terror] // for error recovery #define tsize_t basic[Tsize_t] // matches size_t alias @@ -490,6 +490,7 @@ unsigned memalign(unsigned salign); Expression *defaultInit(); int isZeroInit(); + int checkBoolean(); dt_t **toDt(dt_t **pdt); MATCH deduceType(Type *tparam, Array *parameters, Array *atypes); TypeInfoDeclaration *getTypeInfoDeclaration(); diff -uNr dmd-0.146/dmd/src/dmd/opover.c dmd-0.147/dmd/src/dmd/opover.c --- dmd-0.146/dmd/src/dmd/opover.c 2005-04-14 20:51:14.000000000 +0200 +++ dmd-0.147/dmd/src/dmd/opover.c 2006-02-11 00:17:18.000000000 +0100 @@ -133,6 +133,8 @@ int EqualExp::isCommutative() { return TRUE; } Identifier *EqualExp::opId() { return Id::eq; } +Identifier *MatchExp::opId() { return Id::match; } + int CmpExp::isCommutative() { return TRUE; } Identifier *CmpExp::opId() { return Id::cmp; } diff -uNr dmd-0.146/dmd/src/dmd/parse.c dmd-0.147/dmd/src/dmd/parse.c --- dmd-0.146/dmd/src/dmd/parse.c 2006-02-02 20:39:00.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/parse.c 2006-02-11 00:36:52.000000000 +0100 @@ -4281,6 +4281,13 @@ e = new EqualExp(value, loc, e, e2); continue; + case TOKmatch: + case TOKnotmatch: + nextToken(); + e2 = parseRelExp(); + e = new MatchExp(value, loc, e, e2); + continue; + case TOKidentity: if (!global.params.useDeprecated) error("'===' is deprecated, use 'is' instead"); diff -uNr dmd-0.146/dmd/src/dmd/statement.c dmd-0.147/dmd/src/dmd/statement.c --- dmd-0.146/dmd/src/dmd/statement.c 2006-02-09 14:51:14.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/statement.c 2006-02-11 20:31:06.000000000 +0100 @@ -500,6 +500,7 @@ { condition = c; body = b; + match = NULL; } Statement *WhileStatement::syntaxCopy() @@ -511,12 +512,39 @@ Statement *WhileStatement::semantic(Scope *sc) { + if (condition->op == TOKmatch) + { + /* Rewrite while (condition) body as: + * if (condition) + * do + * body + * while ((_match = _match.opNext), _match); + */ + + Expression *ew = new IdentifierExp(0, Id::_match); + ew = new DotIdExp(0, ew, Id::next); + ew = new AssignExp(0, new IdentifierExp(0, Id::_match), ew); + ////ew = new EqualExp(TOKnotequal, 0, ew, new NullExp(0)); + Expression *ev = new IdentifierExp(0, Id::_match); + //ev = new CastExp(0, ev, Type::tvoidptr); + ew = new CommaExp(0, ew, ev); + Statement *sw = new DoStatement(loc, body, ew); + Statement *si = new IfStatement(loc, condition, sw, NULL); + return si->semantic(sc); + } + condition = condition->semantic(sc); condition = resolveProperties(sc, condition); condition = condition->checkToBoolean(); sc->noctor++; - body = body->semanticScope(sc, this, this); + + Scope *scd = sc->push(); + scd->sbreak = this; + scd->scontinue = this; + body = body->semantic(scd); + scd->pop(); + sc->noctor--; return this; @@ -575,7 +603,11 @@ sc->noctor--; condition = condition->semantic(sc); condition = resolveProperties(sc, condition); - condition = condition->checkToBoolean(); + + // Only check boolean if it's not _Match +// if (!condition->type->equals(StructDeclaration::match->type)) + condition = condition->checkToBoolean(); + return this; } @@ -1099,6 +1131,7 @@ this->condition = condition; this->ifbody = ifbody; this->elsebody = elsebody; + this->match = NULL; } Statement *IfStatement::syntaxCopy() @@ -1117,9 +1150,12 @@ Statement *IfStatement::semantic(Scope *sc) { + int domatch = (condition->op == TOKmatch); + condition = condition->semantic(sc); condition = resolveProperties(sc, condition); - condition = condition->checkToBoolean(); + if (!domatch) + condition = condition->checkToBoolean(); // If we can short-circuit evaluate the if statement, don't do the // semantic analysis of the skipped code. @@ -1130,7 +1166,36 @@ unsigned cs0 = sc->callSuper; unsigned cs1; - ifbody = ifbody->semanticScope(sc, NULL, NULL); + Scope *scd; + if (domatch) + { /* Declare _match, which we will set to be the + * result of condition. _match will give us access to the + * regular expression match strings in the scope of ifbody. + */ + ScopeDsymbol *sym = new ScopeDsymbol(); + sym->parent = sc->scopesym; + scd = sc->push(sym); + + match = new VarDeclaration(loc, condition->type, Id::_match, NULL); + match->noauto = 1; + match->semantic(scd); + if (!scd->insert(match)) + assert(0); + match->parent = sc->func; + + /* Generate: + * (_match = condition), _match + */ + VarExp *v = new VarExp(0, match); + condition = new AssignExp(loc, v, condition); + //condition = new CastExp(0, condition, Type::tvoidptr); + condition = condition->semantic(scd); + } + else + scd = sc->push(); + ifbody = ifbody->semantic(scd); + scd->pop(); + cs1 = sc->callSuper; sc->callSuper = cs0; if (elsebody) diff -uNr dmd-0.146/dmd/src/dmd/statement.h dmd-0.147/dmd/src/dmd/statement.h --- dmd-0.146/dmd/src/dmd/statement.h 2006-01-23 13:58:02.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/statement.h 2006-02-11 12:54:08.000000000 +0100 @@ -181,6 +181,8 @@ Expression *condition; Statement *body; + VarDeclaration *match; // for MatchExpression results + WhileStatement(Loc loc, Expression *c, Statement *b); Statement *syntaxCopy(); Statement *semantic(Scope *sc); @@ -267,6 +269,8 @@ Statement *ifbody; Statement *elsebody; + VarDeclaration *match; // for MatchExpression results + IfStatement(Loc loc, Expression *condition, Statement *ifbody, Statement *elsebody); Statement *syntaxCopy(); Statement *semantic(Scope *sc); diff -uNr dmd-0.146/dmd/src/dmd/struct.c dmd-0.147/dmd/src/dmd/struct.c --- dmd-0.146/dmd/src/dmd/struct.c 2006-01-21 13:48:56.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/struct.c 2006-02-11 17:34:48.000000000 +0100 @@ -193,6 +193,8 @@ /********************************* StructDeclaration ****************************/ +StructDeclaration *StructDeclaration::match; + StructDeclaration::StructDeclaration(Loc loc, Identifier *id) : AggregateDeclaration(loc, id) { @@ -200,6 +202,10 @@ // For forward references type = new TypeStruct(this); + + // BUG: What if this is the wrong _Match, i.e. it is nested? + if (!match && id == Id::_Match) + match = this; } Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s) diff -uNr dmd-0.146/dmd/src/dmd/template.c dmd-0.147/dmd/src/dmd/template.c --- dmd-0.146/dmd/src/dmd/template.c 2006-02-09 11:46:36.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/template.c 2006-02-15 01:56:30.000000000 +0100 @@ -254,11 +254,14 @@ dedtypes->zero(); -//printf("TemplateDeclaration::matchWithInstance(this = %p, ti = %p)\n", this, ti); -//printf("dim = %d, parameters->dim = %d\n", dim, parameters->dim); +//printf("dedtypes->dim = %d, parameters->dim = %d\n", dim, parameters->dim); //if (ti->tiargs->dim) //printf("ti->tiargs->dim = %d, [0] = %p\n", ti->tiargs->dim, ti->tiargs->data[0]); + // If more arguments than parameters, no match + if (ti->tiargs->dim > parameters->dim) + return MATCHnomatch; + assert(dim == parameters->dim); assert(dim >= ti->tiargs->dim); @@ -399,7 +402,8 @@ } // Temporary Array to hold deduced types - dedtypes.setDim(parameters->dim); + //dedtypes.setDim(parameters->dim); + dedtypes.setDim(td2->parameters->dim); // Attempt a type deduction if (td2->matchWithInstance(&ti, &dedtypes, 1)) @@ -466,6 +470,7 @@ tp->toCBuffer(&buf, &hgs); } buf.writeByte(')'); + buf.writeByte(0); return (char *)buf.extractData(); } @@ -1290,6 +1295,7 @@ this->aliasdecl = NULL; this->semanticdone = 0; this->withsym = NULL; + this->nest = 0; } @@ -1683,7 +1689,9 @@ tempdecl = s->isTemplateDeclaration(); if (!tempdecl) { - Dsymbol *sp = s->parent->toAlias(); + if (!s->parent && global.errors) + return NULL; + assert(s->parent); TemplateInstance *ti = s->parent->isTemplateInstance(); if (ti && (ti->idents.data[ti->idents.dim - 1] == id || diff -uNr dmd-0.146/dmd/src/dmd/tocsym.c dmd-0.147/dmd/src/dmd/tocsym.c --- dmd-0.146/dmd/src/dmd/tocsym.c 2005-12-04 11:23:22.000000000 +0100 +++ dmd-0.147/dmd/src/dmd/tocsym.c 2006-02-11 19:15:04.000000000 +0100 @@ -300,6 +300,7 @@ break; case LINKpascal: + t->Tty = TYnpfunc; t->Tmangle = mTYman_pas; break; diff -uNr dmd-0.146/dmd/src/phobos/etc/c/stlsoft/stlsoft.h dmd-0.147/dmd/src/phobos/etc/c/stlsoft/stlsoft.h --- dmd-0.146/dmd/src/phobos/etc/c/stlsoft/stlsoft.h 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/etc/c/stlsoft/stlsoft.h 2006-02-15 13:48:56.000000000 +0100 @@ -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 -uNr dmd-0.146/dmd/src/phobos/internal/arraycat.d dmd-0.147/dmd/src/phobos/internal/arraycat.d --- dmd-0.146/dmd/src/phobos/internal/arraycat.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/internal/arraycat.d 2006-02-15 13:48:54.000000000 +0100 @@ -21,6 +21,7 @@ * distribution. */ +module arraycat; import object; import std.string; diff -uNr dmd-0.146/dmd/src/phobos/internal/match.d dmd-0.147/dmd/src/phobos/internal/match.d --- dmd-0.146/dmd/src/phobos/internal/match.d 1970-01-01 01:00:00.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/internal/match.d 2006-02-15 13:48:54.000000000 +0100 @@ -0,0 +1,47 @@ + +/* + * Copyright (C) 2006 by Digital Mars, www.digitalmars.com + * Written by Walter Bright + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, in both source and binary form, subject to the following + * restrictions: + * + * o The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * o Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * o This notice may not be removed or altered from any source + * distribution. + */ + +module internal.match; + +import std.regexp; + +/****************************** + * Return handle to results if input[] matches regular expression pattern[], + * null if not. + */ + +extern (C) _Match* _d_match(char[] pattern, char[] input) +{ + return cast(_Match*)std.regexp.search(input, pattern); +} + +/****************************** + * Returns !=null for next match. + */ + +extern (C) _Match* _d_match_next(_Match* h) +{ + RegExp r = cast(RegExp)h; + return r.test() ? h : null; +} diff -uNr dmd-0.146/dmd/src/phobos/internal/object.d dmd-0.147/dmd/src/phobos/internal/object.d --- dmd-0.146/dmd/src/phobos/internal/object.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/internal/object.d 2006-02-15 13:48:54.000000000 +0100 @@ -611,3 +611,43 @@ } //extern (C) int nullext = 0; + +/* ***************************** _Match **************************** */ + +/* ** + * Default type for _match. + * Implemented as a proxy for RegExp, so that object doesn't pull in + * the entire std.regexp. + */ + +import std.regexp; + +struct _Match +{ + char[] match(size_t n) + { + return (cast(RegExp)this).match(n); + } + + _Match* opNext() + { + RegExp r = (cast(RegExp)this).opNext(); + if (r) + return cast(_Match*)this; + r = cast(RegExp)this; + delete r; + return null; + } + + char[] pre() + { + return (cast(RegExp)this).pre(); + } + + char[] post() + { + return (cast(RegExp)this).post(); + } +} + + diff -uNr dmd-0.146/dmd/src/phobos/linux.mak dmd-0.147/dmd/src/phobos/linux.mak --- dmd-0.146/dmd/src/phobos/linux.mak 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/linux.mak 2006-02-15 13:48:52.000000000 +0100 @@ -57,7 +57,7 @@ process.o syserror.o \ socket.o socketstream.o stdarg.o stdio.o format.o \ perf.o openrj.o uni.o trace.o boxer.o \ - demangle.o cover.o \ + demangle.o cover.o mangle.o \ ti_wchar.o ti_uint.o ti_short.o ti_ushort.o \ ti_byte.o ti_ubyte.o ti_long.o ti_ulong.o ti_ptr.o \ ti_float.o ti_double.o ti_real.o ti_delegate.o \ @@ -137,7 +137,7 @@ internal/memset.d internal/arraycast.d internal/aaA.d internal/adi.d \ internal/dmain2.d internal/cast.d internal/qsort.d internal/deh2.d \ internal/cmath2.d internal/obj.d internal/mars.h internal/aApply.d \ - internal/object.d internal/trace.d internal/qsort2.d + internal/object.d internal/trace.d internal/qsort2.d internal/match.d SRC_STD_WIN= std/windows/registry.d \ std/windows/iunknown.d std/windows/charset.d @@ -438,6 +438,9 @@ llmath.o : internal/llmath.d $(DMD) -c $(DFLAGS) internal/llmath.d +match.o : internal/match.d + $(DMD) -c $(DFLAGS) internal/match.d + memset.o : internal/memset.d $(DMD) -c $(DFLAGS) internal/memset.d diff -uNr dmd-0.146/dmd/src/phobos/object.d dmd-0.147/dmd/src/phobos/object.d --- dmd-0.146/dmd/src/phobos/object.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/object.d 2006-02-15 13:48:54.000000000 +0100 @@ -129,3 +129,14 @@ this(char[] msg, Error next); } +// Default type for _match + +struct _Match +{ + void* handle; + + char[] match(size_t n); + _Match* opNext(); + char[] pre(); + char[] post(); +} diff -uNr dmd-0.146/dmd/src/phobos/std/file.d dmd-0.147/dmd/src/phobos/std/file.d --- dmd-0.146/dmd/src/phobos/std/file.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/file.d 2006-02-15 13:48:54.000000000 +0100 @@ -31,6 +31,7 @@ private import std.c.stdlib; private import std.path; private import std.string; +private import std.regexp; /* =========================== Win32 ======================= */ @@ -555,12 +556,13 @@ /***************************************************** * Return all the files in the directory and its subdirectories - * that match pattern. + * that match pattern or regular expression r. * Params: * pathname = Directory name * pattern = String with wildcards, such as $(RED "*.d"). The supported * wildcard strings are described under fnmatch() in * $(LINK2 std_path.html, std.path). + * r = Regular expression, for more powerful _pattern matching. * Example: * This program lists all the files with a "d" extension in * the path passed as the first argument. @@ -576,6 +578,21 @@ * writefln(d); * } * ---- + * A regular expression version that searches for all files with "d" or + * "obj" extensions: + * ---- + * import std.stdio; + * import std.file; + * import std.regexp; + * + * void main(char[][] args) + * { + * char[][] d_source_files = std.file.listdir(args[1], RegExp(r"\.(d|obj)$")); + * + * foreach (char[] d; d_source_files) + * writefln(d); + * } + * ---- */ char[][] listdir(char[] pathname, char[] pattern) @@ -596,6 +613,26 @@ return result; } +/** Ditto */ + +char[][] listdir(char[] pathname, RegExp r) +{ char[][] result; + + bool callback(DirEntry* de) + { + if (de.isdir) + listdir(de.name, &callback); + else + { if (r.test(de.name)) + result ~= de.name; + } + return true; // continue + } + + listdir(pathname, &callback); + return result; +} + /****************************************************** * For each file and directory name in pathname[], * pass it to the callback delegate. @@ -1228,6 +1265,24 @@ return result; } +char[][] listdir(char[] pathname, RegExp r) +{ char[][] result; + + bool callback(DirEntry* de) + { + if (de.isdir) + listdir(de.name, &callback); + else + { if (r.test(de.name)) + result ~= de.name; + } + return true; // continue + } + + listdir(pathname, &callback); + return result; +} + void listdir(char[] pathname, bool delegate(char[] filename) callback) { bool listing(DirEntry* de) diff -uNr dmd-0.146/dmd/src/phobos/std/format.d dmd-0.147/dmd/src/phobos/std/format.d --- dmd-0.146/dmd/src/phobos/std/format.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/format.d 2006-02-15 13:48:54.000000000 +0100 @@ -757,6 +757,8 @@ dchar[] sd = va_arg!(dchar[])(argptr); s = toUTF8(sd); Lputstr: + if (fc != 's') + throw new FormatError("string"); if (flags & FLprecision && precision < s.length) s = s[0 .. precision]; putstr(s); diff -uNr dmd-0.146/dmd/src/phobos/std/path.d dmd-0.147/dmd/src/phobos/std/path.d --- dmd-0.146/dmd/src/phobos/std/path.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/path.d 2006-02-15 13:48:54.000000000 +0100 @@ -511,7 +511,8 @@ /************************************* * Checks if path is absolute. * - * Returns: non zero if the path starts from the root directory, + * Returns: non-zero if the path starts from the root directory (Linux) or + * drive letter and root directory (Windows), * zero otherwise. * * Throws: Nothing. diff -uNr dmd-0.146/dmd/src/phobos/std/process.d dmd-0.147/dmd/src/phobos/std/process.d --- dmd-0.146/dmd/src/phobos/std/process.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/process.d 2006-02-15 13:48:54.000000000 +0100 @@ -49,18 +49,98 @@ /* ========================================================== */ -version (Windows) +//version (Windows) +//{ +// int spawnvp(int mode, char[] pathname, char[][] argv) +// { +// char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); +// +// toAStringz(argv, argv_); +// +// return std.c.process.spawnvp(mode, toStringz(pathname), argv_); +// } +//} + +// Incorporating idea (for spawnvp() on linux) from Dave Fladebo + +alias std.c.process._P_WAIT P_WAIT; +alias std.c.process._P_NOWAIT P_NOWAIT; + +int spawnvp(int mode, char[] pathname, char[][] argv) { - int spawnvp(int mode, char[] pathname, char[][] argv) - { - char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); + char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); - toAStringz(argv, argv_); + toAStringz(argv, argv_); - return std.c.process.spawnvp(mode, toStringz(pathname), argv_); + version(linux) + { + return _spawnvp(mode, toStringz(pathname), argv_); + } + else + { + return std.c.process.spawnvp(mode, toStringz(pathname), argv_); } } +version(linux) +{ +private import std.c.linux.linux; +int _spawnvp(int mode, char *pathname, char **argv) +{ + int retval = 0; + pid_t pid = fork(); + + if(!pid) + { // child + std.c.process.execvp(pathname, argv); + goto Lerror; + } + else if(pid > 0) + { // parent + if(mode == _P_NOWAIT) + { + retval = pid; // caller waits + } + else + { + while(1) + { + int status; + pid_t wpid = waitpid(pid, &status, 0); + if(exited(status)) + { + retval = exitstatus(status); + break; + } + else if(signaled(status)) + { + retval = -termsig(status); + break; + } + else if(stopped(status)) // ptrace support + continue; + else + goto Lerror; + } + } + + return retval; + } + +Lerror: + retval = getErrno; + throw new Exception("Cannot spawn " ~ toString(pathname) ~ "; " ~ toString(strerror(retval)) ~ " [errno " ~ toString(retval) ~ "]"); +} // _spawnvp +private +{ +bool stopped(int status) { return cast(bool)((status & 0xff) == 0x7f); } +bool signaled(int status) { return cast(bool)((cast(char)((status & 0x7f) + 1) >> 1) > 0); } +int termsig(int status) { return status & 0x7f; } +bool exited(int status) { return cast(bool)((status & 0x7f) == 0); } +int exitstatus(int status) { return (status & 0xff00) >> 8; } +} // private +} // version(linux) + /* ========================================================== */ int execv(char[] pathname, char[][] argv) diff -uNr dmd-0.146/dmd/src/phobos/std/regexp.d dmd-0.147/dmd/src/phobos/std/regexp.d --- dmd-0.146/dmd/src/phobos/std/regexp.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/regexp.d 2006-02-15 13:48:54.000000000 +0100 @@ -23,6 +23,41 @@ * distribution. */ +/********************************************** + * $(LINK2 "../../ctg/regular.html", Regular expressions) + * are a powerful method of string pattern matching. + * The regular expression + * language used is the same as that commonly used, however, some of the very + * advanced forms may behave slightly differently. + * + * In the following guide, $(I pattern)[] refers to a + * $(LINK2 "../../ctg/regular.html", regular expression). + * The $(I attributes)[] refers to + a string controlling the interpretation + of the regular expression. + It consists of a sequence of one or more + of the following characters: + + + + + + + + +
Attribute + Action +
$(B g) + global; repeat over the whole input string +
$(B i) + case insensitive +
$(B m) + treat as multiple lines separated by newlines +
+ + * Macros: + * WIKI = StdRegexp + */ /* Escape sequences: @@ -67,18 +102,18 @@ import std.outbuffer; } -/** Regexp to extract an email address */ +/** Regular expression to extract an _email address */ const char[] email = r"[a-zA-Z]([.]?([[a-zA-Z0-9_]-]+)*)?@([[a-zA-Z0-9_]\-_]+\.)+[a-zA-Z]{2,6}"; -/** Regexp to extract a url */ +/** Regular expression to extract a _url */ const char[] url = r"(([h|H][t|T]|[f|F])[t|T][p|P]([s|S]?)\:\/\/|~/|/)?([\w]+:\w+@)?(([a-zA-Z]{1}([\w\-]+\.)+([\w]{2,5}))(:[\d]{1,5})?)?((/?\w+/)+|/?)(\w+\.[\w]{3,4})?([,]\w+)*((\?\w+=\w+)?(&\w+=\w+)*([,]\w*)*)?"; /************************************ - * One of these gets thrown on compilation error + * One of these gets thrown on compilation errors */ -class RegExpError : Error +class RegExpException : Exception { this(char[] msg) { @@ -94,14 +129,340 @@ private alias char rchar; // so we can make a wchar version +/****************************************************** + * Search string for matches with regular expression + * pattern with attributes. + * Replace each match with string generated from format. + * Params: + * string = String to search. + * pattern = Regular expression pattern. + * format = Replacement string format. + * attributes = Regular expression attributes. + * Returns: the resulting string. + */ + +char[] sub(char[] string, char[] pattern, char[] format, char[] attributes = null) +{ + RegExp r = new RegExp(pattern, attributes); + char[] result = r.replace(string, format); + delete r; + return result; +} + +unittest +{ + debug(regexp) printf("regexp.sub.unittest\n"); + + char[] r = sub("hello", "ll", "ss"); + assert(r == "hesso"); +} + +/******************************************************* + * Search string for matches with regular expression + * pattern with attributes. + * Pass each match to delegate dg. + * Replace each match with the return value from dg. + * Params: + * string = String to search. + * pattern = Regular expression pattern. + * dg = Delegate + * attributes = Regular expression attributes. + * Returns: the resulting string. + */ + +char[] sub(char[] string, char[] pattern, char[] delegate(RegExp) dg, char[] attributes = null) +{ + RegExp r = new RegExp(pattern, attributes); + rchar[] result; + int lastindex; + int offset; + + result = string; + lastindex = 0; + offset = 0; + while (r.test(string, lastindex)) + { + int so = r.pmatch[0].rm_so; + int eo = r.pmatch[0].rm_eo; + + rchar[] replacement = dg(r); + result = replaceSlice(result, result[offset + so .. offset + eo], replacement); + + if (r.attributes & RegExp.REA.global) + { + offset += replacement.length - (eo - so); + + if (lastindex == eo) + lastindex++; // always consume some source + else + lastindex = eo; + } + else + break; + } + delete r; + + return result; +} + +unittest +{ + debug(regexp) printf("regexp.sub.unittest\n"); + + char[] foo(RegExp r) { return "ss"; } + + char[] r = sub("hello", "ll", delegate char[](RegExp r) { return "ss"; }); + assert(r == "hesso"); +} + + +/************************************************* + * Search string[] for first match with pattern[] with attributes[]. + * Params: + * string = String to search. + * pattern = Regular expression pattern. + * attributes = Regular expression attributes. + * Returns: + * index into string[] of match if found, -1 if no match. + */ + +int find(rchar[] string, char[] pattern, char[] attributes = null) +{ + int i = -1; + + RegExp r = new RegExp(pattern, attributes); + if (r.test(string)) + { + i = r.pmatch[0].rm_so; + } + delete r; + return i; +} + +unittest +{ + debug(regexp) printf("regexp.find.unittest\n"); + + int i; + i = find("xabcy", "abc"); + assert(i == 1); + i = find("cba", "abc"); + assert(i == -1); +} + + + +/************************************************* + * Search string[] for last match with pattern[] with attributes[]. + * Params: + * string = String to search. + * pattern = Regular expression pattern. + * attributes = Regular expression attributes. + * Returns: + * index into string[] of match if found, -1 if no match. + */ + +int rfind(rchar[] string, char[] pattern, char[] attributes = null) +{ + int i = -1; + int lastindex = 0; + + RegExp r = new RegExp(pattern, attributes); + while (r.test(string, lastindex)) + { int eo = r.pmatch[0].rm_eo; + i = r.pmatch[0].rm_so; + if (lastindex == eo) + lastindex++; // always consume some source + else + lastindex = eo; + } + delete r; + return i; +} + +unittest +{ + int i; + + debug(regexp) printf("regexp.rfind.unittest\n"); + i = rfind("abcdefcdef", "c"); + assert(i == 6); + i = rfind("abcdefcdef", "cd"); + assert(i == 6); + i = rfind("abcdefcdef", "x"); + assert(i == -1); + i = rfind("abcdefcdef", "xy"); + assert(i == -1); + i = rfind("abcdefcdef", ""); + assert(i == 10); +} + + +/******************************************** + * Split string[] into an array of strings, using the regular + * expression pattern[] with attributes[] as the separator. + * string = String to search. + * pattern = Regular expression pattern. + * attributes = Regular expression attributes. + * Returns: + * array of slices into string[] + */ + +char[][] split(char[] string, char[] pattern, char[] attributes = null) +{ + RegExp r = new RegExp(pattern, attributes); + char[][] result = r.split(string); + delete r; + return result; +} + +unittest +{ + debug(regexp) printf("regexp.split.unittest()\n"); + char[][] result; + + result = split("ab", "a*"); + assert(result.length == 2); + assert(result[0] == ""); + assert(result[1] == "b"); +} + +/**************************************************** + * Search string[] for first match with pattern[] with attributes[]. + * Params: + * string = String to search. + * pattern = Regular expression pattern. + * attributes = Regular expression attributes. + * Returns: + * corresponding RegExp if found, null if not. + */ + +RegExp search(char[] string, char[] pattern, char[] attributes = null) +{ + RegExp r = new RegExp(pattern, attributes); + + if (r.test(string)) + { + } + else + { delete r; + r = null; + } + return r; +} + +/* ********************************* RegExp ******************************** */ + +/***************************** + * RegExp is a class to handle regular expressions. + * + * It is the core foundation for adding powerful string pattern matching + * capabilities to programs like grep, text editors, awk, sed, etc. + */ class RegExp { - public this(rchar[] pattern, rchar[] attributes) + /***** + * Construct a RegExp object. Compile pattern + * with attributes into + * an internal form for fast execution. + * Params: + * pattern = regular expression + * attributes = _attributes + * Throws: RegExpException if there are any compilation errors. + */ + public this(rchar[] pattern, rchar[] attributes = null) { pmatch = (&gmatch)[0 .. 1]; compile(pattern, attributes); } + /***** + * Generate instance of RegExp. + * Params: + * pattern = regular expression + * attributes = _attributes + * Throws: RegExpException if there are any compilation errors. + */ + public static RegExp opCall(rchar[] pattern, rchar[] attributes = null) + { + return new RegExp(pattern, attributes); + } + + /********** + * Determine if there is an initial match with string[]. + * Returns: + * $(B this) if there is a match, null if not + * Example: + * This makes it possible + * to use RegExp's in a $(I MatchExpression): + * --- + * if (RegExp("^abc") ~~ string) + * writefln("string starts with 'abc'"); + * --- + */ + public RegExp opMatch(char[] string) + { + return test(input, 0) ? this : null; + } + + /************ + * Determine next match in string. + * Returns: + * $(B this) if there is a match, null if not + * Example: + * This makes it possible, along with $(B opMatch) operator overload, + * to use RegExp's in a $(I WhileStatement): + * --- + * RegExp r = new RegExp("[a..c]"); + * writef("'"); + * while (r ~~ "abdd3cce") + * writef(_match.match(0)); + * writefln("'"); // writes 'abcc' + * --- + */ + public RegExp opNext() + { + return test(input, pmatch[0].rm_eo) ? this : null; + } + + /****************** + * Retrieve match n. + * + * n==0 means the matched substring, n>0 means the + * n'th parenthesized subexpression. + * if n is larger than the number of parenthesized subexpressions, + * null is returned. + */ + public char[] match(size_t n) + { + if (n >= pmatch.length) + return null; + else + { size_t rm_so, rm_eo; + rm_so = pmatch[n].rm_so; + rm_eo = pmatch[n].rm_eo; + if (rm_so == rm_eo) + return null; + return input[rm_so .. rm_eo]; + } + } + + /******************* + * Return the slice of the input that precedes the matched substring. + */ + public char[] pre() + { + return input[0 .. pmatch[0].rm_so]; + } + + /******************* + * Return the slice of the input that follows the matched substring. + */ + public char[] post() + { + return input[pmatch[0].rm_eo .. $]; + } + uint re_nsub; // number of parenthesized subexpression matches regmatch_t[] pmatch; // array [re_nsub + 1] @@ -187,8 +548,8 @@ private uint inf = ~0u; -/********************************* - * Throws RegExpError on error +/* ******************************** + * Throws RegExpException on error */ public void compile(rchar[] pattern, rchar[] attributes) @@ -347,10 +708,9 @@ } /************************************************* - * Search string[] for match. + * Search string[] for match with regular expression. * Returns: - * >=0 index of match - * -1 no match + * index of match if successful, -1 if not found */ public int find(rchar[] string) @@ -383,8 +743,8 @@ /************************************************* * Search string[] for match. * Returns: - * if global, return same value as exec(string) - * if not global, return array of all matches + * If global attribute, return same value as exec(string). + * If not global attribute, return array of all matches. */ public rchar[][] match(rchar[] string) @@ -437,10 +797,10 @@ /************************************************* * Find regular expression matches in string[]. Replace those matches - * with a new string composed of format[] merged with the result of the + * with a new _string composed of format[] merged with the result of the * matches. * If global, replace all matches. Otherwise, replace first match. - * Return the new string. + * Returns: the new _string */ public rchar[] replace(rchar[] string, rchar[] format) @@ -510,7 +870,8 @@ } /************************************************* - * Search string[] for next match. + * Pick up where last exec(string) or exec() left off, + * searching string[] for next match. * Returns: * array of slices into string[] representing matches */ @@ -536,9 +897,7 @@ /************************************************ * Search string[] for match. - * Returns: - * 0 no match - * !=0 match + * Returns: 0 for no match, !=0 for match */ public int test(rchar[] string) @@ -547,10 +906,8 @@ } /************************************************ - * Pick up where last test() left off, and search again. - * Returns: - * 0 no match - * !=0 match + * Pick up where last test(string) or test() left off, and search again. + * Returns: 0 for no match, !=0 for match */ public int test() @@ -559,10 +916,8 @@ } /************************************************ - * Test input[] starting at startindex against compiled in pattern[]. - * Returns: - * 0 no match - * !=0 match + * Test string[] starting at startindex against regular expression. + * Returns: 0 for no match, !=0 for match */ public int test(char[] string, int startindex) @@ -1966,7 +2321,7 @@ debug(regexp) printf("error: %.*s\n", msg); //assert(0); //*(char*)0=0; - throw new RegExpError(msg); + throw new RegExpException(msg); } // p is following the \ char @@ -2346,73 +2701,40 @@ /* ==================== replace ======================= */ -/************************************ - * This version of replace() uses: - * & replace with the match - * \n replace with the nth parenthesized match, n is 1..9 - * \c replace with char c +/*********************** + * After a match is found with test(), this function + * will take the match results and, using the format + * string, generate and return a new string. + * The format string has the formatting characters: + * + $(TR $(TH Format) $(TH Replaced With)) + $(TR + $(TD $(B $$)) $(TD $) + ) + $(TR + $(TD $(B $&)) $(TD The matched substring.) + ) + $(TR + $(TD $(B $`)) $(TD The portion of string that precedes the matched substring.) + ) + $(TR + $(TD $(B $')) $(TD The portion of string that follows the matched substring.) + ) + $(TR + $(TD $(B $n)) $(TD The nth capture, where n is a single digit 1-9 + and $n is not followed by a decimal digit.) + ) + $(TR + $(TD $(B $nn)) $(TD The nnth capture, where nn is a two-digit decimal + number 01-99. + If nnth capture is undefined or more than the number + of parenthesized subexpressions, use the empty + string instead.) + ) +
+ Any other $ are left as is. */ -public rchar[] replaceOld(rchar[] format) -{ - OutBuffer buf; - rchar[] result; - rchar c; - -//printf("replace: this = %p so = %d, eo = %d\n", this, pmatch[0].rm_so, pmatch[0].rm_eo); -//printf("3input = '%.*s'\n", input); - buf = new OutBuffer(); - buf.reserve(format.length * rchar.sizeof); - for (uint i; i < format.length; i++) - { - c = format[i]; - switch (c) - { - case '&': -//printf("match = '%.*s'\n", input[pmatch[0].rm_so .. pmatch[0].rm_eo]); - buf.write(input[pmatch[0].rm_so .. pmatch[0].rm_eo]); - break; - - case '\\': - if (i + 1 < format.length) - { - c = format[++i]; - if (c >= '1' && c <= '9') - { uint i; - - i = c - '0'; - if (i <= re_nsub && pmatch[i].rm_so != pmatch[i].rm_eo) - buf.write(input[pmatch[i].rm_so .. pmatch[i].rm_eo]); - break; - } - } - buf.write(c); - break; - - default: - buf.write(c); - break; - } - } - result = cast(rchar[])buf.toBytes(); - return result; -} - -// This version of replace uses: -// $$ $ -// $& The matched substring. -// $` The portion of string that precedes the matched substring. -// $' The portion of string that follows the matched substring. -// $n The nth capture, where n is a single digit 1-9 -// and $n is not followed by a decimal digit. -// $nn The nnth capture, where nn is a two-digit decimal -// number 01-99. -// If nnth capture is undefined or more than the number -// of parenthesized subexpressions, use the empty -// string instead. -// -// Any other $ are left as is. - public rchar[] replace(rchar[] format) { return replace3(format, input, pmatch[0 .. re_nsub + 1]); @@ -2517,198 +2839,70 @@ return result; } -} - -/**************************************************** - * Search str for regular expression pattern. - * If match, return a RegExp for the match. - * If no match, return null. - */ - -RegExp search(char[] str, char[] pattern, char[] attributes = null) -{ - RegExp r = new RegExp(pattern, attributes); - - if (r.test(str)) - { - } - else - { delete r; - r = null; - } - return r; -} - - -/****************************************************** - * Search str for pattern, replace occurrences with format. - */ - -char[] sub(char[] str, char[] pattern, char[] format, char[] attributes = null) -{ - RegExp r = new RegExp(pattern, attributes); - char[] result = r.replace(str, format); - delete r; - return result; -} - -unittest -{ - debug(regexp) printf("regexp.sub.unittest\n"); - - char[] r = sub("hello", "ll", "ss"); - assert(r == "hesso"); -} - -/******************************************************* - * Search str for pattern, replace occurrences with string - * returned from dg. +/************************************ + * Like replace(char[] format), but uses old style formatting: + + + + + + + +
Format + Description +
& + replace with the match +
\n + replace with the nth parenthesized match, n is 1..9 +
\c + replace with char c. +
*/ -char[] sub(char[] str, char[] pattern, char[] delegate(RegExp) dg, char[] attributes = null) +public rchar[] replaceOld(rchar[] format) { - RegExp r = new RegExp(pattern, attributes); + OutBuffer buf; rchar[] result; - int lastindex; - int offset; + rchar c; - result = str; - lastindex = 0; - offset = 0; - while (r.test(str, lastindex)) +//printf("replace: this = %p so = %d, eo = %d\n", this, pmatch[0].rm_so, pmatch[0].rm_eo); +//printf("3input = '%.*s'\n", input); + buf = new OutBuffer(); + buf.reserve(format.length * rchar.sizeof); + for (uint i; i < format.length; i++) { - int so = r.pmatch[0].rm_so; - int eo = r.pmatch[0].rm_eo; + c = format[i]; + switch (c) + { + case '&': +//printf("match = '%.*s'\n", input[pmatch[0].rm_so .. pmatch[0].rm_eo]); + buf.write(input[pmatch[0].rm_so .. pmatch[0].rm_eo]); + break; - rchar[] replacement = dg(r); - result = replaceSlice(result, result[offset + so .. offset + eo], replacement); + case '\\': + if (i + 1 < format.length) + { + c = format[++i]; + if (c >= '1' && c <= '9') + { uint i; - if (r.attributes & RegExp.REA.global) - { - offset += replacement.length - (eo - so); + i = c - '0'; + if (i <= re_nsub && pmatch[i].rm_so != pmatch[i].rm_eo) + buf.write(input[pmatch[i].rm_so .. pmatch[i].rm_eo]); + break; + } + } + buf.write(c); + break; - if (lastindex == eo) - lastindex++; // always consume some source - else - lastindex = eo; + default: + buf.write(c); + break; } - else - break; } - delete r; - + result = cast(rchar[])buf.toBytes(); return result; } -unittest -{ - debug(regexp) printf("regexp.sub.unittest\n"); - - char[] foo(RegExp r) { return "ss"; } - - char[] r = sub("hello", "ll", delegate char[](RegExp r) { return "ss"; }); - assert(r == "hesso"); } - -/************************************************* - * Search string[] for match with pattern[]. - * Returns: - * >=0 index of match - * -1 no match - */ - -int find(rchar[] string, char[] pattern, char[] attributes = null) -{ - int i = -1; - - RegExp r = new RegExp(pattern, attributes); - if (r.test(string)) - { - i = r.pmatch[0].rm_so; - } - delete r; - return i; -} - -unittest -{ - debug(regexp) printf("regexp.find.unittest\n"); - - int i; - i = find("xabcy", "abc"); - assert(i == 1); - i = find("cba", "abc"); - assert(i == -1); -} - - - -/************************************************* - * Search string[] for last match with pattern[]. - * Returns: - * >=0 index of match - * -1 no match - */ - -int rfind(rchar[] string, char[] pattern, char[] attributes = null) -{ - int i = -1; - int lastindex = 0; - - RegExp r = new RegExp(pattern, attributes); - while (r.test(string, lastindex)) - { int eo = r.pmatch[0].rm_eo; - i = r.pmatch[0].rm_so; - if (lastindex == eo) - lastindex++; // always consume some source - else - lastindex = eo; - } - delete r; - return i; -} - -unittest -{ - int i; - - debug(regexp) printf("regexp.rfind.unittest\n"); - i = rfind("abcdefcdef", "c"); - assert(i == 6); - i = rfind("abcdefcdef", "cd"); - assert(i == 6); - i = rfind("abcdefcdef", "x"); - assert(i == -1); - i = rfind("abcdefcdef", "xy"); - assert(i == -1); - i = rfind("abcdefcdef", ""); - assert(i == 10); -} - - -/******************************************** - * Split string[] into an array of strings, using the regular - * expression as the separator. - * Returns: - * array of slices into string[] - */ - -char[][] split(char[] string, char[] pattern, char[] attributes = null) -{ - RegExp r = new RegExp(pattern, attributes); - char[][] result = r.split(string); - delete r; - return result; -} - -unittest -{ - debug(regexp) printf("regexp.split.unittest()\n"); - char[][] result; - - result = split("ab", "a*"); - assert(result.length == 2); - assert(result[0] == ""); - assert(result[1] == "b"); -} diff -uNr dmd-0.146/dmd/src/phobos/std/stdio.d dmd-0.147/dmd/src/phobos/std/stdio.d --- dmd-0.146/dmd/src/phobos/std/stdio.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/stdio.d 2006-02-15 13:48:54.000000000 +0100 @@ -4,6 +4,14 @@ * Placed in the Public Domain. */ +/******************************** + * Standard I/O functions that extend $(B std.c.stdio). + * $(B std.c.stdio) is automatically imported when importing + * $(B std.stdio). + * Macros: + * WIKI=Phobos/StdStdio + */ + module std.stdio; import std.c.stdio; @@ -118,21 +126,42 @@ } +/*********************************** + * Arguments are formatted per the + * $(LINK2 std_format.html#format-string, format strings) + * and written to $(B stdout). + */ + void writef(...) { writefx(stdout, _arguments, _argptr, 0); } +/*********************************** + * Same as $(B writef), but a newline is appended + * to the output. + */ + void writefln(...) { writefx(stdout, _arguments, _argptr, 1); } +/*********************************** + * Same as $(B writef), but output is sent to the + * stream fp instead of $(B stdout). + */ + void fwritef(FILE* fp, ...) { writefx(fp, _arguments, _argptr, 0); } +/*********************************** + * Same as $(B writefln), but output is sent to the + * stream fp instead of $(B stdout). + */ + void fwritefln(FILE* fp, ...) { writefx(fp, _arguments, _argptr, 1); diff -uNr dmd-0.146/dmd/src/phobos/std/string.d dmd-0.147/dmd/src/phobos/std/string.d --- dmd-0.146/dmd/src/phobos/std/string.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/string.d 2006-02-15 13:48:54.000000000 +0100 @@ -84,6 +84,12 @@ const dchar LS = '\u2028'; /// UTF line separator const dchar PS = '\u2029'; /// UTF paragraph separator +/// Newline sequence for this system +version (Windows) + const char[2] newline = "\r\n"; +else version (linux) + const char[2] newline = "\n"; + /********************************** * Returns !=0 if c is whitespace */ diff -uNr dmd-0.146/dmd/src/phobos/std/uri.d dmd-0.147/dmd/src/phobos/std/uri.d --- dmd-0.146/dmd/src/phobos/std/uri.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/uri.d 2006-02-15 13:48:54.000000000 +0100 @@ -32,6 +32,8 @@ * See_Also: * $(LINK2 http://www.ietf.org/rfc/rfc3986.txt, RFC 3986)
* $(LINK2 http://en.wikipedia.org/wiki/Uniform_resource_identifier, Wikipedia) + * Macros: + * WIKI = StdUri */ module std.uri; diff -uNr dmd-0.146/dmd/src/phobos/std/utf.d dmd-0.147/dmd/src/phobos/std/utf.d --- dmd-0.146/dmd/src/phobos/std/utf.d 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/std/utf.d 2006-02-15 13:48:54.000000000 +0100 @@ -36,6 +36,8 @@ * $(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia)
* $(LINK http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8)
* $(LINK http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335) + * Macros: + * WIKI = StdUtf */ module std.utf; diff -uNr dmd-0.146/dmd/src/phobos/win32.mak dmd-0.147/dmd/src/phobos/win32.mak --- dmd-0.146/dmd/src/phobos/win32.mak 2006-02-09 22:36:02.000000000 +0100 +++ dmd-0.147/dmd/src/phobos/win32.mak 2006-02-15 13:48:52.000000000 +0100 @@ -21,6 +21,7 @@ DFLAGS=-O -release #DFLAGS=-unittest -g +#DFLAGS=-unittest -cov -g CC=dmc @@ -72,7 +73,7 @@ socket.obj socketstream.obj loader.obj stdarg.obj format.obj stdio.obj \ perf.obj openrj.obj uni.obj winsock.obj oldsyserror.obj \ errno.obj boxer.obj cstream.obj charset.obj \ - realtest.obj gamma.obj demangle.obj \ + realtest.obj gamma.obj demangle.obj cover.obj match.obj \ ti_Aa.obj ti_Ag.obj ti_C.obj ti_int.obj ti_char.obj \ ti_wchar.obj ti_uint.obj ti_short.obj ti_ushort.obj \ ti_byte.obj ti_ubyte.obj ti_long.obj ti_ulong.obj ti_ptr.obj \ @@ -92,7 +93,11 @@ $(DOC)\std_random.html $(DOC)\std_file.html $(DOC)\std_date.html \ $(DOC)\std_md5.html $(DOC)\std_zip.html $(DOC)\std_zlib.html \ $(DOC)\std_demangle.html \ + $(DOC)\std_uri.html \ $(DOC)\std_utf.html \ + $(DOC)\std_cover.html \ + $(DOC)\std_regexp.html \ + $(DOC)\std_stdio.html \ $(DOC)\std_windows_charset.html SRC= errno.c object.d unittest.d crc32.d gcstats.d @@ -106,7 +111,7 @@ std\regexp.d std\random.d std\stream.d std\process.d std\recls.d \ std\socket.d std\socketstream.d std\loader.d std\stdarg.d std\format.d \ std\stdio.d std\perf.d std\openrj.d std\uni.d std\boxer.d \ - std\cstream.d std\demangle.d + std\cstream.d std\demangle.d std\cover.d SRC_STD_C= std\c\process.d std\c\stdlib.d std\c\time.d std\c\stdio.d \ std\c\math.d std\c\stdarg.d std\c\stddef.d @@ -143,7 +148,7 @@ internal\memset.d internal\arraycast.d internal\aaA.d internal\adi.d \ internal\dmain2.d internal\cast.d internal\qsort.d internal\deh2.d \ internal\cmath2.d internal\obj.d internal\mars.h internal\aApply.d \ - internal\object.d internal\trace.d internal\qsort2.d + internal\object.d internal\trace.d internal\qsort2.d internal\match.d SRC_STD_WIN= std\windows\registry.d \ std\windows\iunknown.d std\windows\syserror.d std\windows\charset.d @@ -422,6 +427,9 @@ invariant.obj : internal\invariant.d $(DMD) -c $(DFLAGS) internal\invariant.d +match.obj : internal\match.d + $(DMD) -c $(DFLAGS) internal\match.d + memset.obj : internal\memset.d $(DMD) -c $(DFLAGS) internal\memset.d @@ -463,6 +471,9 @@ conv.obj : std\conv.d $(DMD) -c $(DFLAGS) std\conv.d +cover.obj : std\cover.d + $(DMD) -c $(DFLAGS) std\cover.d + cstream.obj : std\cstream.d $(DMD) -c $(DFLAGS) std\cstream.d @@ -763,6 +774,9 @@ $(DOC)\std_compiler.html : std.ddoc std\compiler.d $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_compiler.html std.ddoc std\compiler.d +$(DOC)\std_cover.html : std.ddoc std\cover.d + $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_cover.html std.ddoc std\cover.d + $(DOC)\std_date.html : std.ddoc std\date.d $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_date.html std.ddoc std\date.d @@ -790,12 +804,21 @@ $(DOC)\std_random.html : std.ddoc std\random.d $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_random.html std.ddoc std\random.d +$(DOC)\std_regexp.html : std.ddoc std\regexp.d + $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_regexp.html std.ddoc std\regexp.d + +$(DOC)\std_stdio.html : std.ddoc std\stdio.d + $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_stdio.html std.ddoc std\stdio.d + $(DOC)\std_stream.html : std.ddoc std\stream.d $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_stream.html -d std.ddoc std\stream.d $(DOC)\std_string.html : std.ddoc std\string.d $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_string.html std.ddoc std\string.d +$(DOC)\std_uri.html : std.ddoc std\uri.d + $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_uri.html std.ddoc std\uri.d + $(DOC)\std_utf.html : std.ddoc std\utf.d $(DMD) -c -o- $(DFLAGS) -Df$(DOC)\std_utf.html std.ddoc std\utf.d