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)0∞tz-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 @@
-
+
-
-Last update $(DATETIME)
-
|
@@ -97,21 +98,18 @@
|
-$(TITLE)
+$(TITLE)
$(BODY)
|
-Feedback and Comments
- Add feedback and comments regarding this
- page.
+
+Copyright © 1999-$(YEAR) by Digital Mars, All Rights Reserved |
+Page generated by $(LINK2 http://www.digitalmars.com/d/ddoc.html, Ddoc).
+
-
-$(SMALL Copyright © 1999-$(YEAR) by Digital Mars, All Rights Reserved
-Page generated by $(LINK2 http://www.digitalmars.com/d/ddoc.html, Ddoc).)
-
|