diff -uNr dmd-0.135/dmd/src/dmd/cond.c dmd-0.136/dmd/src/dmd/cond.c --- dmd-0.135/dmd/src/dmd/cond.c 2005-10-03 02:30:44.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/cond.c 2005-10-05 14:00:16.000000000 +0200 @@ -214,6 +214,7 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s) { + //printf("StaticIfCondition::include()\n"); if (inc == 0) { if (!sc) @@ -223,7 +224,7 @@ return 0; } - sc = sc->push(); + sc = sc->push(sc->scopesym); sc->sd = s; sc->flags |= SCOPEstaticif; Expression *e = exp->semantic(sc); diff -uNr dmd-0.135/dmd/src/dmd/constfold.c dmd-0.136/dmd/src/dmd/constfold.c --- dmd-0.135/dmd/src/dmd/constfold.c 2005-09-08 19:12:40.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/constfold.c 2005-10-11 12:44:44.000000000 +0200 @@ -334,15 +334,58 @@ e1 = e1->constFold(); e2 = e2->constFold(); - if (type->isreal()) - { real_t c; - - c = fmodl(e1->toReal(), e2->toReal()); - e = new RealExp(loc, c, type); - } - else if (type->isfloating()) + if (type->isfloating()) { - assert(0); +#if 1 + complex_t c; + + if (e2->type->isreal()) + { real_t r2 = e2->toReal(); + +#ifdef __DMC__ + c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I; +#else + c = complex_t(fmodl(e1->toReal(), r2), fmodl(e1->toImaginary(), r2)); +#endif + } + else if (e2->type->isimaginary()) + { real_t i2 = e2->toImaginary(); + +#ifdef __DMC__ + c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I; +#else + c = complex_t(fmodl(e1->toReal(), i2), fmodl(e1->toImaginary(), i2)); +#endif + } + else + assert(0); + + if (type->isreal()) + e = new RealExp(loc, creall(c), type); + else if (type->isimaginary()) + e = new ImaginaryExp(loc, cimagl(c), type); + else if (type->iscomplex()) + e = new ComplexExp(loc, c, type); + else + assert(0); +#else + if (type->isreal()) + { real_t c; + + c = fmodl(e1->toReal(), e2->toReal()); + e = new RealExp(loc, c, type); + } + else if (type->isimaginary()) + { real_t c; + + c = fmodl(e1->toImaginary(), e2->toImaginary()); + e = new RealExp(loc, c, type); + } + else + { + assert(0); + } +#endif } else { sinteger_t n1; diff -uNr dmd-0.135/dmd/src/dmd/doc.c dmd-0.136/dmd/src/dmd/doc.c --- dmd-0.135/dmd/src/dmd/doc.c 2005-10-02 21:20:18.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/doc.c 2005-10-14 21:47:42.000000000 +0200 @@ -249,6 +249,7 @@ emitMemberComments(sc); } + //printf("BODY= '%.*s'\n", buf.offset, buf.data); Macro::define(¯otable, (unsigned char *)"BODY", 4, buf.data, buf.offset); OutBuffer buf2; @@ -288,6 +289,7 @@ } // Transfer image to file + assert(docfile); docfile->setbuffer(buf.data, buf.offset); docfile->ref = 1; docfile->writev(); @@ -402,6 +404,7 @@ emitDitto(sc); return; } + dc->pmacrotable = &sc->module->macrotable; buf->writestring(ddoc_decl_s); o = buf->offset; @@ -431,6 +434,7 @@ emitDitto(sc); return; } + dc->pmacrotable = &sc->module->macrotable; buf->writestring(ddoc_decl_s); toDocBuffer(buf); @@ -460,6 +464,7 @@ emitDitto(sc); return; } + dc->pmacrotable = &sc->module->macrotable; ScopeDsymbol *ss = this; @@ -497,6 +502,8 @@ } return; } + if (isAnonymous()) + return; OutBuffer *buf = sc->docbuf; DocComment *dc = DocComment::parse(sc, this, comment); @@ -506,6 +513,7 @@ emitDitto(sc); return; } + dc->pmacrotable = &sc->module->macrotable; buf->writestring(ddoc_decl_s); toDocBuffer(buf); @@ -535,6 +543,7 @@ emitDitto(sc); return; } + dc->pmacrotable = &sc->module->macrotable; buf->writestring(ddoc_decl_s); o = buf->offset; diff -uNr dmd-0.135/dmd/src/dmd/expression.c dmd-0.136/dmd/src/dmd/expression.c --- dmd-0.135/dmd/src/dmd/expression.c 2005-09-06 11:13:42.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/expression.c 2005-10-16 15:29:24.000000000 +0200 @@ -231,15 +231,19 @@ case Tsarray: case Tarray: { // Create a static array variable v of type arg->type - Identifier *id = Lexer::idPool("__arrayArg"); + char name[10+6+1]; + static int idn; + sprintf(name, "__arrayArg%d", ++idn); + Identifier *id = Lexer::idPool(name); Type *t = new TypeSArray(tb->next, new IntegerExp(nargs - i)); t = t->semantic(loc, sc); - VarDeclaration *v = new VarDeclaration(loc, t, id, NULL); + VarDeclaration *v = new VarDeclaration(loc, t, id, new VoidInitializer(loc)); v->semantic(sc); v->parent = sc->parent; //sc->insert(v); - Expression *c = NULL; + Expression *c = new DeclarationExp(0, v); + c->type = v->type; for (int u = i; u < nargs; u++) { Expression *a = (Expression *)arguments->data[u]; @@ -2688,6 +2692,9 @@ typeCombine(); e1->checkArithmetic(); e2->checkArithmetic(); + + if (op == TOKmodass && e2->type->iscomplex()) + error("cannot perform modulo complex arithmetic"); } return this; } @@ -4883,7 +4890,7 @@ Type *tb1 = e1->type->toBasetype(); Type *tb2 = e2->type->toBasetype(); - if ((tb1->ty == Tarray || tb1->ty == Tsarray) && + if ((tb1->ty == Tarray) && (tb2->ty == Tarray || tb2->ty == Tsarray) && e2->implicitConvTo(e1->type) //e1->type->next->equals(e2->type->next) @@ -4893,7 +4900,7 @@ type = e1->type; e = this; } - else if ((tb1->ty == Tarray || tb1->ty == Tsarray) && + else if ((tb1->ty == Tarray) && e2->implicitConvTo(tb1->next) ) { // Append element @@ -4903,7 +4910,7 @@ } else { - error("Can only concatenate arrays, not %s ~= %s", tb1->toChars(), tb2->toChars()); + error("Can only append to dynamic arrays, not %s ~= %s", tb1->toChars(), tb2->toChars()); type = Type::tint32; e = this; } @@ -5533,6 +5540,11 @@ typeCombine(); e1->checkArithmetic(); e2->checkArithmetic(); + if (type->isfloating()) + { type = e1->type; + if (e2->type->iscomplex()) + error("cannot perform modulo complex arithmetic"); + } return this; } @@ -5851,7 +5863,10 @@ else if (t1->ty == Tstruct || t2->ty == Tstruct || (t1->ty == Tclass && t2->ty == Tclass)) { - error("need member function opCmp() for %s %s to compare", t1->toDsymbol(sc)->kind(), t1->toChars()); + if (t2->ty == Tstruct) + error("need member function opCmp() for %s %s to compare", t2->toDsymbol(sc)->kind(), t2->toChars()); + else + error("need member function opCmp() for %s %s to compare", t1->toDsymbol(sc)->kind(), t1->toChars()); e = this; } #if 1 diff -uNr dmd-0.135/dmd/src/dmd/func.c dmd-0.136/dmd/src/dmd/func.c --- dmd-0.135/dmd/src/dmd/func.c 2005-08-27 16:14:20.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/func.c 2005-10-16 15:56:50.000000000 +0200 @@ -700,6 +700,7 @@ } else e = new HaltExp(endloc); + e = new CommaExp(0, e, type->next->defaultInit()); e = e->semantic(sc2); Statement *s = new ExpStatement(0, e); fbody = new CompoundStatement(0, fbody, s); @@ -871,7 +872,13 @@ { if (overnext) return overnext->overloadInsert(a); + if (!a->aliassym && a->type->ty != Tident && a->type->ty != Tinstance) + { + //printf("\ta = '%s'\n", a->type->toChars()); + return FALSE; + } overnext = a; + //printf("\ttrue: no conflict\n"); return TRUE; } f = s->isFuncDeclaration(); @@ -1284,7 +1291,8 @@ int FuncDeclaration::isNested() { -// if (!toParent()) printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent); + //if (!toParent()) + //printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent); //printf("\ttoParent() = '%s'\n", toParent()->toChars()); return ((storage_class & STCstatic) == 0) && (toParent()->isFuncDeclaration() != NULL); diff -uNr dmd-0.135/dmd/src/dmd/inline.c dmd-0.136/dmd/src/dmd/inline.c --- dmd-0.135/dmd/src/dmd/inline.c 2005-06-30 01:44:36.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/inline.c 2005-10-15 01:20:14.000000000 +0200 @@ -435,11 +435,17 @@ ids->from.push(vd); ids->to.push(vto); - ie = vd->init->isExpInitializer(); - assert(ie); - ieto = new ExpInitializer(ie->loc, ie->exp->doInline(ids)); - vto->init = ieto; - + if (vd->init->isVoidInitializer()) + { + vto->init = new VoidInitializer(vd->init->loc); + } + else + { + ie = vd->init->isExpInitializer(); + assert(ie); + ieto = new ExpInitializer(ie->loc, ie->exp->doInline(ids)); + vto->init = ieto; + } de->declaration = (Dsymbol *) (void *)vto; } } diff -uNr dmd-0.135/dmd/src/dmd/macro.c dmd-0.136/dmd/src/dmd/macro.c --- dmd-0.135/dmd/src/dmd/macro.c 2005-10-02 13:11:34.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/macro.c 2005-10-14 21:41:24.000000000 +0200 @@ -77,6 +77,7 @@ Macro *table; + //assert(ptable); for (table = *ptable; table; table = table->next) { if (table->namelen == namelen && @@ -325,7 +326,6 @@ u++; } - mem.free(arg); /* Second pass - replace other macros */ @@ -394,6 +394,7 @@ { //printf("\tmacro '%.*s'(%.*s) = '%.*s'\n", m->namelen, m->name, marglen, marg, m->textlen, m->text); #if 1 + marg = memdup(marg, marglen); // Insert replacement text buf->spread(v + 1, 2 + m->textlen + 2); buf->data[v + 1] = 0xFF; @@ -430,6 +431,7 @@ end -= v + 1 - u; u += mend - (v + 1); #endif + mem.free(marg); //printf("u = %d, end = %d\n", u, end); //printf("#%.*s#\n", end - u, &buf->data[u]); continue; @@ -446,6 +448,7 @@ } u++; } + mem.free(arg); *pend = end; nest--; } diff -uNr dmd-0.135/dmd/src/dmd/mars.c dmd-0.136/dmd/src/dmd/mars.c --- dmd-0.135/dmd/src/dmd/mars.c 2005-10-01 23:10:04.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/mars.c 2005-10-09 12:32:14.000000000 +0200 @@ -51,7 +51,7 @@ copyright = "Copyright (c) 1999-2005 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.135"; + version = "v0.136"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); @@ -592,6 +592,9 @@ break; } } + + if (global.params.objfiles->dim == 0) + global.params.link = 0; } } if (global.errors) diff -uNr dmd-0.135/dmd/src/dmd/module.c dmd-0.136/dmd/src/dmd/module.c --- dmd-0.135/dmd/src/dmd/module.c 2005-10-02 00:29:36.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/module.c 2005-10-10 00:51:00.000000000 +0200 @@ -42,7 +42,6 @@ FileName *hfilename; FileName *objfilename; FileName *symfilename; - FileName *docfilename; // printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars()); this->arg = filename; @@ -103,37 +102,45 @@ else objfilename = FileName::forceExt(argobj, global.obj_ext); - if (doDocComment) - { - char *argdoc; - if (global.params.docname) - argdoc = global.params.docname; - else if (global.params.preservePaths) - argdoc = filename; - else - argdoc = FileName::name(filename); - if (!FileName::absolute(argdoc)) - argdoc = FileName::combine(global.params.docdir, argdoc); - if (global.params.docname) - docfilename = new FileName(argdoc, 0); - else - docfilename = FileName::forceExt(argdoc, global.doc_ext); + symfilename = FileName::forceExt(filename, global.sym_ext); - if (docfilename->equals(srcfilename)) - { error("Source file and documentation file have same name '%s'", srcfilename->toChars()); - fatal(); - } + srcfile = new File(srcfilename); - docfile = new File(docfilename); + if (doDocComment) + { + setDocfile(); } - symfilename = FileName::forceExt(filename, global.sym_ext); - - srcfile = new File(srcfilename); objfile = new File(objfilename); symfile = new File(symfilename); } +void Module::setDocfile() +{ + FileName *docfilename; + char *argdoc; + + if (global.params.docname) + argdoc = global.params.docname; + else if (global.params.preservePaths) + argdoc = (char *)arg; + else + argdoc = FileName::name((char *)arg); + if (!FileName::absolute(argdoc)) + argdoc = FileName::combine(global.params.docdir, argdoc); + if (global.params.docname) + docfilename = new FileName(argdoc, 0); + else + docfilename = FileName::forceExt(argdoc, global.doc_ext); + + if (docfilename->equals(srcfile->name)) + { error("Source file and documentation file have same name '%s'", srcfile->name->str); + fatal(); + } + + docfile = new File(docfilename); +} + void Module::deleteObjFile() { if (global.params.obj) @@ -421,6 +428,8 @@ { comment = buf + 4; isDocFile = 1; + if (!docfile) + setDocfile(); return; } if (isHtml) @@ -569,6 +578,7 @@ { Dsymbol *s; s = (Dsymbol *)members->data[i]; + //printf("Module %s: %s.semantic3()\n", toChars(), s->toChars()); s->semantic3(sc); } diff -uNr dmd-0.135/dmd/src/dmd/module.h dmd-0.136/dmd/src/dmd/module.h --- dmd-0.135/dmd/src/dmd/module.h 2005-10-01 22:50:18.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/module.h 2005-10-09 12:31:28.000000000 +0200 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2004 by Digital Mars +// Copyright (c) 1999-2005 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -89,6 +89,7 @@ static Module *load(Loc loc, Array *packages, Identifier *ident); char *kind(); + void setDocfile(); // set docfile member void read(Loc loc); // read file void parse(); // syntactic parse void semantic(); // semantic analysis diff -uNr dmd-0.135/dmd/src/dmd/mtype.c dmd-0.136/dmd/src/dmd/mtype.c --- dmd-0.135/dmd/src/dmd/mtype.c 2005-09-27 13:36:36.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/mtype.c 2005-10-15 00:15:32.000000000 +0200 @@ -1274,7 +1274,12 @@ if (to->ty == Tbit) return MATCHnomatch; TypeBasic *tob = (TypeBasic *)to; - if (flags & TFLAGSfloating) + if (flags & TFLAGSintegral) + { + if (tob->flags & TFLAGSimaginary) + return MATCHnomatch; + } + else if (flags & TFLAGSfloating) { // Disallow implicit conversion of floating point to integer if (tob->flags & TFLAGSintegral) diff -uNr dmd-0.135/dmd/src/dmd/template.c dmd-0.136/dmd/src/dmd/template.c --- dmd-0.135/dmd/src/dmd/template.c 2005-09-19 13:44:44.000000000 +0200 +++ dmd-0.136/dmd/src/dmd/template.c 2005-10-05 14:01:12.000000000 +0200 @@ -1864,12 +1864,13 @@ void TemplateInstance::semantic3(Scope *sc) { int i; +#if LOG + printf("TemplateInstance::semantic3('%s'), semanticdone = %d\n", toChars(), semanticdone); +#endif +//if (toChars()[0] == 'D') *(char*)0=0; if (semanticdone >= 3) return; semanticdone = 3; -#if LOG - printf("TemplateInstance::semantic3('%s')\n", toChars()); -#endif if (members) { sc = tempdecl->scope; diff -uNr dmd-0.135/dmd/src/phobos/linux.mak dmd-0.136/dmd/src/phobos/linux.mak --- dmd-0.135/dmd/src/phobos/linux.mak 2005-10-03 13:02:50.000000000 +0200 +++ dmd-0.136/dmd/src/phobos/linux.mak 2005-10-17 00:40:30.000000000 +0200 @@ -147,7 +147,7 @@ SRC_STD_C_LINUX= std/c/linux/linux.d std/c/linux/linuxextern.d \ std/c/linux/socket.d -SRC_ETC= +SRC_ETC= etc/gamma.d etc/realtest.d SRC_ETC_C= etc/c/zlib.d diff -uNr dmd-0.135/dmd/src/phobos/std/math.d dmd-0.136/dmd/src/phobos/std/math.d --- dmd-0.135/dmd/src/phobos/std/math.d 2005-10-03 13:02:50.000000000 +0200 +++ dmd-0.136/dmd/src/phobos/std/math.d 2005-10-17 00:40:30.000000000 +0200 @@ -10,6 +10,8 @@ * * NAN = $(RED NAN) * SUP = $0 + * GAMMA = Γ + * INTEGRAL = ∫ */ /* @@ -625,9 +627,9 @@ * If x is subnormal, it is treated as if it were normalized. * For a positive, finite x: * - *
- *	1 <= x * FLT_RADIX$(SUP -logb(x)) < FLT_RADIX 
- *	
+ *
+ * 1 <= x * FLT_RADIX$(SUP -logb(x)) < FLT_RADIX 
+ * 
* * $(TABLE_SV * x logb(x) Divide by 0? @@ -833,25 +835,57 @@ real erfc(real x) { return std.c.math.erfcl(x); } /*********************************** - * Calculates ln |Γ(x)| + * 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))). + * + * $(TABLE_SV + * x log$(GAMMA)(x) invalid? + * NaN NaN yes + * integer <= 0 +∞ yes + * 1, 2 +0.0 no + * ±∞ +∞ no + * ) */ +/* Documentation prepared by Don Clugston */ real lgamma(real x) { - version (linux) - return std.c.math.lgammal(x); - else - throw new NotImplemented("lgamma"); + return std.c.math.lgammal(x); + + // Use etc.gamma.lgamma for those C systems that are missing it } /*********************************** - * Calculates the gamma function Γ(x) + * 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)0tz-1e-tdt + * + * $(TABLE_SV + * x $(GAMMA)(x) invalid? + * NAN NAN yes + * ±0.0 ±∞ yes + * integer > 0 (x-1)! no + * integer < 0 NAN yes + * +∞ +∞ no + * -∞ NAN yes + * ) + * + * References: + * cephes, $(LINK http://en.wikipedia.org/wiki/Gamma_function) */ +/* Documentation prepared by Don Clugston */ real tgamma(real x) { - version (linux) - return std.c.math.tgammal(x); - else - throw new NotImplemented("tgamma"); + return std.c.math.tgammal(x); + + // Use etc.gamma.tgamma for those C systems that are missing it } /************************************** @@ -1561,3 +1595,70 @@ assert(feqrel(-real.max,real.infinity)==0); assert(feqrel(real.max,-real.max)==0); } + + +/*********************************** + * Evaluate polynomial A(x) = a0 + a1x + a2x² + a3x³ ... + * + * Uses Horner's rule A(x) = a0 + x(a1 + x(a2 + x(a3 + ...))) + * Params: + * A = array of coefficients a0, a1, etc. + */ +real poly(real x, real[] A) +in +{ + assert(A.length > 0); +} +body +{ + version (D_InlineAsm) + { + asm // assembler by W. Bright + { + // EDX = (A.length - 1) * real.sizeof + mov ECX,A[EBP] ; // ECX = A.length + dec ECX ; + lea EDX,[ECX][ECX*8] ; + add EDX,ECX ; + add EDX,A+4[EBP] ; + fld real ptr [EDX] ; // ST0 = coeff[ECX] + jecxz return_ST ; + fld x[EBP] ; // ST0 = x + fxch ST(1) ; // ST1 = x, ST0 = r + align 4 ; + L2: fmul ST,ST(1) ; // r *= x + fld real ptr -10[EDX] ; + sub EDX,10 ; // deg-- + faddp ST(1),ST ; + dec ECX ; + jne L2 ; + fxch ST(1) ; // ST1 = r, ST0 = x + fstp ST(0) ; // dump x + align 4 ; + return_ST: ; + ; + } + } + else + { + i = A.length - 1; + real r = A[i]; + while (--i >= 0) + { + r *= x; + r += A[i]; + } + return r; + } +} + +unittest +{ + debug (math) printf("math.poly.unittest\n"); + real x = 3.1; + static real pp[] = [56.1, 32.7, 6]; + + assert( poly(x, pp) == (56.1L + (32.7L + 6L * x) * x) ); +} + + diff -uNr dmd-0.135/dmd/src/phobos/std/md5.d dmd-0.136/dmd/src/phobos/std/md5.d --- dmd-0.135/dmd/src/phobos/std/md5.d 2005-10-03 13:02:50.000000000 +0200 +++ dmd-0.136/dmd/src/phobos/std/md5.d 2005-10-17 00:40:30.000000000 +0200 @@ -2,6 +2,69 @@ * Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm. */ +/** + * Computes MD5 digests of arbitrary data. MD5 digests are 16 byte quantities that are like a checksum or crc, but are more robust. + * + * There are two ways to do this. The first does it all in one function call to + * sum(). The second is for when the data is buffered. + * + * Bugs: + * MD5 digests have been demonstrated to not be unique. + * + * Author: + * The routines and algorithms are derived from the + * $(I RSA Data Security, Inc. MD5 Message-Digest Algorithm). + * + * References: + * $(LINK2 http://en.wikipedia.org/wiki/Md5, Wikipedia on MD5) + * + * Macros: + * WIKI = StdMd5 + */ + +/++++++++++++++++++++++++++++++++ + Example: + +-------------------- +// This code is derived from the +// RSA Data Security, Inc. MD5 Message-Digest Algorithm. + +import std.md5; +import std.string; +import std.c.stdio; +import std.stdio; + +int main(char[][] args) +{ + foreach (char[] arg; args) + MDFile(arg); + return 0; +} + +/* Digests a file and prints the result. */ +void MDFile(char[] filename) +{ + FILE* file; + MD5_CTX context; + int len; + ubyte[4 * 1024] buffer; + ubyte digest[16]; + + if ((file = fopen(std.string.toStringz(filename), "rb")) == null) + writefln("%s can't be opened", filename); + else + { + context.start(); + while ((len = fread(buffer, 1, buffer.size, file)) != 0) + context.update(buffer[0 .. len]); + context.finish(digest); + fclose(file); + + writefln("MD5 (%s) = %s", filename, digestToString(digest)); + } +} +-------------------- + +/ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. @@ -30,7 +93,51 @@ import std.string; -/* MD5 context. */ +/*************************************** + * Computes MD5 digest of array of data. + */ + +void sum(ubyte[16] digest, void[] data) +{ + MD5_CTX context; + + context.start(); + context.update(data); + context.finish(digest); +} + +/****************** + * Prints a message digest in hexadecimal to stdout. + */ +void printDigest(ubyte digest[16]) +{ + foreach (ubyte u; digest) + printf("%02x", u); +} + +/**************************************** + * Converts MD5 digest to a string. + */ + +char[] digestToString(ubyte[16] digest) +{ + char[] result = new char[32]; + int i; + + foreach (ubyte u; digest) + { + result[i] = std.string.hexdigits[u >> 4]; + result[i + 1] = std.string.hexdigits[u & 15]; + i += 2; + } + return result; +} + +/** + * Holds context of MD5 computation. + * + * Used when data to be digested is buffered. + */ struct MD5_CTX { uint state[4] = /* state (ABCD) */ @@ -108,14 +215,15 @@ a += b; } - /* MD5 initialization. Begins an MD5 operation, writing a new context. + /** + * MD5 initialization. Begins an MD5 operation, writing a new context. */ void start() { *this = MD5_CTX.init; } - /* MD5 block update operation. Continues an MD5 message-digest + /** MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */ @@ -151,8 +259,8 @@ memcpy(&buffer[index], &input[i], inputLen-i); } - /* MD5 finalization. Ends an MD5 message-digest operation, writing the - * the message digest and zeroizing the context. + /** MD5 finalization. Ends an MD5 message-digest operation, writing the + * the message to digest and zeroing the context. */ void finish(ubyte[16] digest) /* message digest */ { @@ -334,27 +442,6 @@ } } -/************************************* - * Computes MD5 digest of array of data - */ - -void sum(ubyte[16] digest, void[] data) -{ - MD5_CTX context; - - context.start(); - context.update(data); - context.finish(digest); -} - -/* Prints a message digest in hexadecimal. - */ -void printDigest(ubyte digest[16]) -{ - foreach (ubyte u; digest) - printf("%02x", u); -} - unittest { debug(md5) printf("std.md5.unittest\n"); @@ -384,5 +471,7 @@ "1234567890123456789012345678901234567890"); assert(digest == cast(ubyte[])x"57edf4a22be3c955ac49da2e2107b67a"); + assert(digestToString(cast(ubyte[16])x"c3fcd3d76192e4007dfb496cca67e13b") + == "C3FCD3D76192E4007DFB496CCA67E13B"); } diff -uNr dmd-0.135/dmd/src/phobos/std/zip.d dmd-0.136/dmd/src/phobos/std/zip.d --- dmd-0.135/dmd/src/phobos/std/zip.d 2005-10-03 13:02:50.000000000 +0200 +++ dmd-0.136/dmd/src/phobos/std/zip.d 2005-10-17 00:40:30.000000000 +0200 @@ -1,4 +1,20 @@ +/** + * Read/write data in the $(LINK2 http://www.info-_zip.org, zip archive) format. + * Makes use of the etc.c.zlib compression library. + * + * Bugs: + * $(UL + * $(LI Multi-disk zips not supported.) + * $(LI Only Zip version 20 formats are supported.) + * $(LI Only supports compression modes 0 (no compression) and 8 (deflate).) + * $(LI Does not support encryption.) + * ) + * + * Macros: + * WIKI = StdZip + */ + module std.zip; private import std.zlib; @@ -7,9 +23,8 @@ //debug=print; -/* Throw this on errors. +/** Thrown on error. */ - class ZipException : Exception { this(char[] msg) @@ -18,27 +33,36 @@ } } +/** + * A member of the ZipArchive. + */ class ArchiveMember { - ushort madeVersion = 20; - ushort extractVersion = 20; - ushort flags; - ushort compressionMethod; - std.date.DosFileTime time; - uint crc32; - uint compressedSize; - uint expandedSize; - ushort diskNumber; - ushort internalAttributes; - uint externalAttributes; + ushort madeVersion = 20; /// Read Only + ushort extractVersion = 20; /// Read Only + ushort flags; /// Read/Write: normally set to 0 + ushort compressionMethod; /// Read/Write: 0 for compression, 8 for deflate + std.date.DosFileTime time; /// Read/Write: Last modified time of the member. It's in the DOS date/time format. + uint crc32; /// Read Only: cyclic redundancy check (CRC) value + uint compressedSize; /// Read Only: size of data of member in compressed form. + uint expandedSize; /// Read Only: size of data of member in expanded form. + ushort diskNumber; /// Read Only: should be 0. + ushort internalAttributes; /// Read/Write + uint externalAttributes; /// Read/Write private uint offset; + /** + * Read/Write: Usually the file name of the archive member; it is used to + * index the archive directory for the member. Each member must have a unique + * name[]. Do not change without removing member from the directory first. + */ char[] name; - ubyte[] extra; - char[] comment; - ubyte[] compressedData; - ubyte[] expandedData; + + ubyte[] extra; /// Read/Write: extra data for this member. + char[] comment; /// Read/Write: comment associated with this member. + ubyte[] compressedData; /// Read Only: data of member in compressed form. + ubyte[] expandedData; /// Read/Write: data of member in uncompressed form. debug(print) { @@ -60,16 +84,33 @@ } } +/** + * Object representing the entire archive. + * ZipArchives are collections of ArchiveMembers. + */ class ZipArchive { - ubyte[] data; // representing the entire Zip contents + ubyte[] data; /// Read Only: array representing the entire contents of the archive. uint endrecOffset; - uint diskNumber; - uint diskStartDir; - uint numEntries; - uint totalEntries; - char[] comment; + uint diskNumber; /// Read Only: 0 since multi-disk zip archives are not supported. + uint diskStartDir; /// Read Only: 0 since multi-disk zip archives are not supported. + uint numEntries; /// Read Only: number of ArchiveMembers in the directory. + uint totalEntries; /// Read Only: same as totalEntries. + char[] comment; /// Read/Write: the archive comment. Must be less than 65536 bytes in length. + + /** + * Read Only: array indexed by the name of each member of the archive. + * Example: + * All the members of the archive can be accessed with a foreach loop: + * -------------------- + * ZipArchive archive = new ZipArchive(data); + * foreach (ArchiveMember am; archive.directory) + * { + * writefln("member name is '%s'", am.name); + * } + * -------------------- + */ ArchiveMember[char[]] directory; debug (print) @@ -86,23 +127,36 @@ /* ============ Creating a new archive =================== */ - /* Constructor to use when creating a new archive. + /** Constructor to use when creating a new archive. */ - this() { } + /** Add de to the archive. + */ void addMember(ArchiveMember de) { directory[de.name] = de; } + /** Delete de from the archive. + */ void deleteMember(ArchiveMember de) { directory.remove(de.name); } + /** + * Construct an archive out of the current members of the archive. + * + * Fills in the properties data[], diskNumber, diskStartDir, numEntries, + * totalEntries, and directory[]. + * For each ArchiveMember, fills in properties crc32, compressedSize, + * compressedData[]. + * + * Returns: array representing the entire archive. + */ void[] build() { uint i; uint directoryOffset; @@ -224,7 +278,19 @@ /* ============ Reading an existing archive =================== */ - /* Constructor to use when reading an existing archive. + /** + * Constructor to use when reading an existing archive. + * + * Fills in the properties data[], diskNumber, diskStartDir, numEntries, + * totalEntries, comment[], and directory[]. + * For each ArchiveMember, fills in + * properties madeVersion, extractVersion, flags, compressionMethod, time, + * crc32, compressedSize, expandedSize, compressedData[], diskNumber, + * internalAttributes, externalAttributes, name[], extra[], comment[]. + * Use expand() to get the expanded data for each ArchiveMember. + * + * Params: + * buffer = the entire contents of the archive. */ this(void[] buffer) @@ -324,6 +390,13 @@ throw new ZipException("invalid directory entry 3"); } + /***** + * Decompress the contents of archive member de and return the expanded + * data. + * + * Fills in properties extractVersion, flags, compressionMethod, time, + * crc32, compressedSize, expandedSize, expandedData[], name[], extra[]. + */ ubyte[] expand(ArchiveMember de) { uint namelen; uint extralen; diff -uNr dmd-0.135/dmd/src/phobos/std/zlib.d dmd-0.136/dmd/src/phobos/std/zlib.d --- dmd-0.135/dmd/src/phobos/std/zlib.d 2005-10-03 13:02:50.000000000 +0200 +++ dmd-0.136/dmd/src/phobos/std/zlib.d 2005-10-17 00:40:30.000000000 +0200 @@ -1,5 +1,11 @@ -/* zlib.d - * A D interface to the zlib library, www.gzip.org/zlib +/** + * Compress/decompress data using the $(LINK2 http://www._zlib.net, zlib library). + * + * References: + * $(LINK2 http://en.wikipedia.org/wiki/Zlib, Wikipedia) + * + * Macros: + * WIKI = StdZlib */ @@ -45,6 +51,8 @@ } /************************************************** + * Compute the Adler32 checksum of the data in buf[]. adler is the starting + * value when computing a cumulative checksum. */ uint adler32(uint adler, void[] buf) @@ -65,6 +73,8 @@ } /********************************* + * Compute the CRC32 checksum of the data in buf[]. crc is the starting value + * when computing a cumulative checksum. */ uint crc32(uint crc, void[] buf) @@ -85,6 +95,11 @@ } /********************************************* + * Compresses the data in srcbuf[] using compression _level level. + * The default value + * for level is 6, legal values are 1..9, with 1 being the least compression + * and 9 being the most. + * Returns the compressed data. */ void[] compress(void[] srcbuf, int level) @@ -111,6 +126,7 @@ } /********************************************* + * ditto */ void[] compress(void[] buf) @@ -119,19 +135,14 @@ } /********************************************* + * Decompresses the data in srcbuf[]. + * Params: destlen = size of the uncompressed data. + * It need not be accurate, but the decompression will be faster if the exact + * size is supplied. + * Returns: the decompressed data. */ -void[] uncompress(void[] srcbuf) -{ - return uncompress(srcbuf, 0, 15); -} - -void[] uncompress(void[] srcbuf, uint destlen) -{ - return uncompress(srcbuf, destlen, 15); -} - -void[] uncompress(void[] srcbuf, uint destlen, int winbits) +void[] uncompress(void[] srcbuf, uint destlen = 0u, int winbits = 15) { int err; void[] destbuf; @@ -212,6 +223,7 @@ +/ /********************************************* + * Used when the data to be compressed is not all in one buffer. */ class Compress @@ -231,10 +243,10 @@ } public: - this() - { - } + /** + * Construct. level is the same as for D.zlib.compress(). + */ this(int level) in { @@ -245,6 +257,11 @@ this.level = level; } + /// ditto + this() + { + } + ~this() { int err; @@ -257,6 +274,11 @@ } } + /** + * Compress the data in buf and return the compressed data. + * The buffers + * returned from successive calls to this should be concatenated together. + */ void[] compress(void[] buf) { int err; void[] destbuf; @@ -291,12 +313,25 @@ return destbuf; } - void[] flush() - { - return flush(Z_FINISH); - } - - void[] flush(int mode) + /*** + * Compress and return any remaining data. + * The returned data should be appended to that returned by compress(). + * Params: + * mode = one of the following: + * $(DL + $(DT Z_SYNC_FLUSH ) + $(DD Syncs up flushing to the next byte boundary. + Used when more data is to be compressed later on.) + $(DT Z_FULL_FLUSH ) + $(DD Syncs up flushing to the next byte boundary. + Used when more data is to be compressed later on, + and the decompressor needs to be restartable at this + point.) + $(DT Z_FINISH) + $(DD (default) Used when finished compressing the data. ) + ) + */ + void[] flush(int mode = Z_FINISH) in { assert(mode == Z_FINISH || mode == Z_SYNC_FLUSH || mode == Z_FULL_FLUSH); @@ -333,6 +368,10 @@ } } +/****** + * Used when the data to be decompressed is not all in one buffer. + */ + class UnCompress { private: @@ -351,15 +390,20 @@ } public: - this() - { - } + /** + * Construct. destbufsize is the same as for D.zlib.uncompress(). + */ this(uint destbufsize) { this.destbufsize = destbufsize; } + /** ditto */ + this() + { + } + ~this() { int err; @@ -373,6 +417,11 @@ done = 1; } + /** + * Decompress the data in buf and return the decompressed data. + * The buffers returned from successive calls to this should be concatenated + * together. + */ void[] uncompress(void[] buf) in { @@ -414,6 +463,11 @@ return destbuf; } + /** + * Decompress and return any remaining data. + * The returned data should be appended to that returned by uncompress(). + * The UnCompress object cannot be used further. + */ void[] flush() in { diff -uNr dmd-0.135/dmd/src/phobos/std.ddoc dmd-0.136/dmd/src/phobos/std.ddoc --- dmd-0.135/dmd/src/phobos/std.ddoc 2005-10-03 13:02:50.000000000 +0200 +++ dmd-0.136/dmd/src/phobos/std.ddoc 2005-10-17 00:40:30.000000000 +0200 @@ -16,16 +16,17 @@ -www.digitalmars.com +
+ www.digitalmars.com -Home -| Search -| $(RED D) -| Comments + Home + | Search + | D + | Comments + +
Last update $(DATETIME)
+
-
-Last update $(DATETIME) -
@@ -97,21 +98,18 @@ -

$(TITLE)

+

$(TITLE)

$(BODY)
-

Feedback and Comments

- Add feedback and comments regarding this - page. + -
-$(SMALL Copyright © 1999-$(YEAR) by Digital Mars, All Rights Reserved
-Page generated by $(LINK2 http://www.digitalmars.com/d/ddoc.html, Ddoc).) -