changeset 6:dcb24afa0dce

Some fixes from mde/text/format.d unittests plus a few more fixes. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 10 Jan 2008 18:33:24 +0000
parents 76d0adc92f2e
children b544c3a7c9ca
files mde/init.d mde/mergetag/dataset.d mde/mergetag/read.d mde/text/format.d mde/text/parse.d
diffstat 5 files changed, 44 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/mde/init.d	Sun Jan 06 17:47:11 2008 +0000
+++ b/mde/init.d	Thu Jan 10 18:33:24 2008 +0000
@@ -129,12 +129,12 @@
     * call isn't going to mess things up. The extra function called by runCleanupFcts won't cause
     * any harm either. */
     static bool initialised = false;
+    static void cleanup () {	initialised = false;	}
         
     static void init () {
         initialised = true;
         Init.addCleanupFct (&cleanup);
     }
-    static void cleanup () {	initialised = false;	}
         
     init();
     assert (initialised);
--- a/mde/mergetag/dataset.d	Sun Jan 06 17:47:11 2008 +0000
+++ b/mde/mergetag/dataset.d	Thu Jan 10 18:33:24 2008 +0000
@@ -196,7 +196,6 @@
     //END DATA
     
     void addTag (char[] tp, ID id, char[] dt) {	/// Supports all standard types.
-        try {
             if (tp.length == 0) throw new MTUnknownTypeException;
             // split list up a bit for performance:
             if (tp[0] < 'l') {
@@ -240,9 +239,7 @@
                     ~ `else throw new MTUnknownTypeException;` );
                 }
             }
-        } catch (TextParseException) {
-            throw new MTaddTagParseException;
-        }
+        // try-catch block removed (caught by read)
     }
     private template addTag_elifIsType_add(T) {
         const addTag_elifIsType_add =
--- a/mde/mergetag/read.d	Sun Jan 06 17:47:11 2008 +0000
+++ b/mde/mergetag/read.d	Thu Jan 10 18:33:24 2008 +0000
@@ -315,13 +315,16 @@
                     try {
                         dsec.addTag (type, tagID, data);
                     }
-                    catch (MTaddTagParseException) {
+                    catch (TextParseException) {
                         logger.warn("Above error occured" ~ ErrInFile);	// following a parse error
                     }
                     catch (MTUnknownTypeException e) {
                         logger.warn ("Unsupported type \"" ~ type ~ "\" " ~ ErrInFile /*~ ":"*/);
                         //logger.warn (e.msg); needless; the above includes enough details.
                     }
+                    catch (Object e) {
+                        logger.error ("Unknown error occured" ~ ErrInFile);
+                    }
                 } else comment = false;			// cancel comment status now
             }
             else if (fbuf[pos] == '{') {
--- a/mde/text/format.d	Sun Jan 06 17:47:11 2008 +0000
+++ b/mde/text/format.d	Thu Jan 10 18:33:24 2008 +0000
@@ -60,7 +60,7 @@
 }
 unittest {
     char[] X = format!(char[][char]) (['a':cast(char[])"animal", 'b':['b','u','s']]);
-    char[] Y = `['a':"animal",'b':["bus"]]`;
+    char[] Y = `['a':"animal",'b':"bus"]`;
     assert (X == Y);
 }
 
@@ -88,9 +88,9 @@
     return format (toUtf8 (val));
 }
 char[] format(T : char[]) (T val) {
-    char[] ret;	ret.length = val.length * 2 + 2;	// Initial storage. This should ALWAYS be enough.
+    char[] ret = new char[val.length * 2 + 2];	// Initial storage. This should ALWAYS be enough.
     ret[0] = '"';
-    uint i = 0;
+    uint i = 1;
     for (uint t = 0; t < val.length;) {
         // process a block of non-escapable characters
         uint s = t;
@@ -111,7 +111,7 @@
 char[] format(T : ubyte[]) (T val) {
     static const char[16] digits = "0123456789abcdef";
     
-    char[val.length * 2] ret = void;	// exact length
+    char[] ret = new char[val.length * 2];	// exact length
     uint i = 0;
     foreach (ubyte x; val) {
         ret[i++] = digits[x >> 4];
@@ -120,13 +120,14 @@
     return ret;
 }
 unittest {
-    assert (format!(double[]) ([1.0, 1.0e-10]) == `[1,1e-10]`);		// generic array stuff
+    // generic array stuff:
+    assert (format!(double[]) ([1.0, 1.0e-10]) == `[1.00000000000000000,0.10000000000000000e-09]`);
     assert (format!(double[]) (cast(double[]) []) == `[]`);		// empty array
     
     // char[] conversions, with commas, escape sequences and multichar UTF8 characters:
     assert (format!(char[][]) ([ ".\""[], [',','\''] ,"!\b€" ]) == `[".\"",",\'","!\b€"]`);
     
-    assert (format!(ubyte[]) (cast(ubyte[]) [0x01, 0xF2, 0xAC]) == `01F2AC`);	// ubyte[] special notation
+    assert (format!(ubyte[]) (cast(ubyte[]) [0x01, 0xF2, 0xAC]) == `01f2ac`);	// ubyte[] special notation
 }
 
 // Support for outputting a wide char... I reccomend against trying to output these though.
@@ -143,7 +144,8 @@
     // Note: if (val > 127) "is invalid UTF-8 single char"
     // However we don't know what this is for, in particular if it will be recombined with other chars later
     
-    char[4] ret;	// max length for an escaped char
+    // Can't return reference to static array; making dynamic is cheaper than copying.
+    char[] ret = new char[4];	// max length for an escaped char
     ret[0] = '\'';
     
     if (!isEscapableChar (val)) {
@@ -159,7 +161,7 @@
     assert (false);
 }
 unittest {
-    assert (format!(char) ('\'') == '\'');
+    assert (format!(char) ('\'') == "\'\\\'\'");
 }
 
 char[] format(T : bool) (T val) {
@@ -194,28 +196,30 @@
     return formatLong (val);
 }
 unittest {
-    assert (format!(byte) (cast(byte) -5)) == "-5";
+    assert (format!(byte) (cast(byte) -5) == "-5");
     // annoyingly, octal syntax differs from D (blame tango):
-    assert (format!(uint[]) ([0b0100u,0724,0xFa59c,0xFFFFFFFF,0]) == "[0b100,0o724,0xFa59c,0xFFFFFFFF,0]");
+    assert (format!(uint[]) ([0b0100u,0724,0xFa59c,0xFFFFFFFF,0]) == "[4,468,1025436,4294967295,0]");
 }
 
+// Old calculation (not used):
+// t.dig+2+4+3	// should be sufficient length (mant + (neg, dot, e, exp neg) + exp (3,4,5 for float,double,real resp.))
 char[] format(T : float) (T val) {
-    // t.dig+2+4+3	// should be sufficient length (mant + (neg, dot, e, exp neg) + exp (3,4,5 for float,double,real resp.))
-    char[32] ret;	// minimum allowed by assert in format
-    return cFloat.format (ret, val, T.dig+2, true);	// from old C++ tests, T.dig+2 gives best(?) accuracy
+    char[] ret = new char[32];	// minimum allowed by assert in format
+    return cFloat.format (ret, val, T.dig+2, 1);	// from old C++ tests, T.dig+2 gives best(?) accuracy
 }
 char[] format(T : double) (T val) {
-    char[32] ret;
-    return cFloat.format (ret, val, T.dig+2, true);
+    char[] ret = new char[32];
+    return cFloat.format (ret, val, T.dig+2, 1);
 }
 char[] format(T : real) (T val) {
-    char[32] ret;
-    return cFloat.format (ret, val, T.dig+2, true);
+    char[] ret = new char[32];
+    return cFloat.format (ret, val, T.dig+2, 1);
 }
 unittest {
-    assert (format!(float) (0.0f) == "0");
-    assert (format!(double) (-1e25) == "-1e25");
-    assert (format!(real) (cast(real) 5.24e-269) == "5.24e-269");
+    // NOTE: these numbers are not particularly meaningful.
+    assert (format!(float) (0.0f) == "0.00000000");
+    assert (format!(double) (-1e25) == "-1.00000000000000000e+25");
+    assert (format!(real) (cast(real) 4.918e300) == "4.91800000000000000000e+300");
 }
 //END Convert templates
 
@@ -231,7 +235,7 @@
 
 //BEGIN Utility funcs
 private char[] formatLong (long val) {
-    try return cInt.toString (val, cInt.Style.Unsigned, cInt.Flags.Throw);
+    try return cInt.toString (val, cInt.Style.Signed, cInt.Flags.Throw);
     catch (Exception e) throwException (e.msg);
 }
 private bool isEscapableChar (char c) {
--- a/mde/text/parse.d	Sun Jan 06 17:47:11 2008 +0000
+++ b/mde/text/parse.d	Thu Jan 10 18:33:24 2008 +0000
@@ -42,10 +42,11 @@
 
 //BEGIN parse templates
 // Associative arrays
+const char[] AA_ERR = "Invalid associative array: ";
 T[S] parse(T : T[S], S) (char[] src) {
     src = Util.trim(src);
     if (src.length < 2 || src[0] != '[' || src[$-1] != ']')
-        throwException ("Invalid associative array: not [a:x, ..., c:z]");
+        throwException (AA_ERR ~ "not [ ... ]");	// bad braces.
     
     T[S] ret;
     foreach (char[] pair; split (src[1..$-1])) {
@@ -56,17 +57,22 @@
             if (c == '\'' || c == '"') {	// string or character
                 ++i;
                 while (i < pair.length && pair[i] != c) {
-                    if (pair[i] == '\\') ++i;	// escape seq.
+                    if (pair[i] == '\\') {
+                        if (i+2 >= pair.length) throwException (AA_ERR ~ "unfinished escape sequence within string/char");
+                        ++i;	// escape seq.
+                    }
                     ++i;
-                }	// Doesn't throw if no terminal quote at end of pair (in this case an error is thrown anyway)
+                }
+                if (i == pair.length) {
+                    debug logger.warn ("Pair is: " ~ pair);
+                    throwException (AA_ERR ~ "encountered [ ... KEY] (missing :DATA)");
+                }
             }
             ++i;
         }
         if (i == pair.length) {
-            debug logger.trace ("In pair: " ~ pair);
-            throwException ("Invalid key:value pair in associative array literal");
+            throwException (AA_ERR ~ "encountered [ ... KEY:] (missing DATA)");
         }
-        debug logger.trace ("pair is: " ~ pair[0..i] ~ " : " ~ pair[i+1..$]);
         ret[parse!(S) (pair[0..i])] = parse!(T) (pair[i+1..$]);
     }
     return ret;
@@ -108,7 +114,7 @@
             // process a block of escaped characters
             while (t < src.length && src[t] == '\\') {
                 t++;
-                if (t == src.length) throwException (`Warning: string ends \" !`);	// next char is "
+                if (t == src.length) throwException ("Invalid string: ends \\\" !");	// next char is "
                 ret[i++] = replaceEscapedChar (src[t++]);	// throws if it's invalid
             }
         }