changeset 107:20f7d813bb0f

Translation: now has a file for each locale, instead of a file for each section. Items updated; all strings translated. New unittest for Translation; I realised the old one wasn't run anymore. Changed unittest data and conf dirs.
author Diggory Hardy <diggory.hardy@gmail.com>
date Sun, 30 Nov 2008 17:17:56 +0000
parents 7f7b40fed72b
children c9fc2d303178
files data/L10n/FontOptions.mtt data/L10n/MiscOptions.mtt data/L10n/VideoOptions.mtt data/L10n/en-GB.mtt data/conf/gui.mtt mde/content/Items.d mde/input/Input.d mde/lookup/Translation.d mde/mde.d mde/setup/paths.d unittest/InputConfig.mtt unittest/Translation.mtt unittest/conf/InputConfig.mtt unittest/data/L10n/locale-1.mtt unittest/data/L10n/locale-2.mtt unittest/data/L10n/locale-3.mtt unittest/data/L10n/locale-4.mtt
diffstat 17 files changed, 202 insertions(+), 180 deletions(-) [+]
line wrap: on
line diff
--- a/data/L10n/FontOptions.mtt	Sat Nov 29 16:43:44 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{MT01}
-{en-GB}
-<entry|FontOptions={0:"Font options"}>
-<entry|lcdFilter={0:"LCD filtering",1:"Enable or disable sub-pixel rendering. Note that the FreeType library may be compiled without support due to patent issues."}>
-<entry|renderMode={0:"Font rendering mode",1:"Controls how fonts are rendered: in gray-scale, or for LCDs (with a horizontal (usual) or vertical layout, with an RGB (usual) or BGR sub-pixel mode."}>
--- a/data/L10n/MiscOptions.mtt	Sat Nov 29 16:43:44 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-{MT01}
-{en-GB}
-<entry|MiscOptions={0:"Miscellaneous options"}>
-<entry|maxThreads={0:"Max threads",1:"Maximum number of threads to use in mde (currently only applies to init stages run in parallel)."}>
-<entry|logLevel={0:"Logging level",1:"Lowest level to log messages; 0=trace, 1=info (default), 2=warn, 3=error, 4=fatal, 5=none."}>
-<entry|logOutput={0:"Logging output",1:"Output to: 0=nowhere, 1=the console, 2=a file, 3=both"}>
-<entry|L10n={0:"Localisation",1:"Specifies the language to use."}>
-<entry|pollInterval={0:"Polling interval",1:"Delay in main loop to limit CPU usage"}>
-<entry|exitImmediately={0:"Exit immediately",1:"Load files and exit immediately, without running main loop (for debugging)"}>
--- a/data/L10n/VideoOptions.mtt	Sat Nov 29 16:43:44 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-{MT01}
-{en-GB}
-<entry|VideoOptions={0:"Video options"}>
-<entry|fullscreen={0:"Fullscreen",1:"If true use the whole screen, if false use a window."}>
-<entry|hardware={0:"Hardware",1:"Create the video surface in hardware or software memory."}>
-<entry|resizable={0:"Resizable",1:"In windowed mode, allow the window to be resized by the window manager."}>
-<entry|noFrame={0:"No frame",1:"In windowed mode, don't draw a window border."}>
-<entry|screenW={0:"Screen width",1:"Horizontal resolution (fullscreen mode)."}>
-<entry|screenH={0:"Screen height",1:"Vertical resolution (fullscreen mode)."}>
-<entry|windowW={0:"Window width",1:"Horizontal size (windowed mode)."}>
-<entry|windowH={0:"Window height",1:"Vertical size (windowed mode)."}>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/L10n/en-GB.mtt	Sun Nov 30 17:17:56 2008 +0000
@@ -0,0 +1,27 @@
+{MT01}
+{imde}
+<entry|quit={0:"Quit"}>
+{Options}
+<entry|Options={0:"Options"}>
+{FontOptions}
+<entry|FontOptions={0:"Font options"}>
+<entry|lcdFilter={0:"LCD filtering",1:"Enable or disable sub-pixel rendering. Note that the FreeType library may be compiled without support due to patent issues."}>
+<entry|renderMode={0:"Font rendering mode",1:"Controls how fonts are rendered: in gray-scale, or for LCDs (with a horizontal (usual) or vertical layout, with an RGB (usual) or BGR sub-pixel mode."}>
+{MiscOptions}
+<entry|MiscOptions={0:"Miscellaneous options"}>
+<entry|maxThreads={0:"Max threads",1:"Maximum number of threads to use in mde (currently only applies to init stages run in parallel)."}>
+<entry|logLevel={0:"Logging level",1:"Lowest level to log messages; 0=trace, 1=info (default), 2=warn, 3=error, 4=fatal, 5=none."}>
+<entry|logOutput={0:"Logging output",1:"Output to: 0=nowhere, 1=the console, 2=a file, 3=both"}>
+<entry|L10n={0:"Localisation",1:"Specifies the language to use."}>
+<entry|pollInterval={0:"Polling interval",1:"Delay in main loop to limit CPU usage"}>
+<entry|exitImmediately={0:"Exit immediately",1:"Load files and exit immediately, without running main loop (for debugging)"}>
+{VideoOptions}
+<entry|VideoOptions={0:"Video options"}>
+<entry|fullscreen={0:"Fullscreen",1:"If true use the whole screen, if false use a window."}>
+<entry|hardware={0:"Hardware",1:"Create the video surface in hardware or software memory."}>
+<entry|resizable={0:"Resizable",1:"In windowed mode, allow the window to be resized by the window manager."}>
+<entry|noFrame={0:"No frame",1:"In windowed mode, don't draw a window border."}>
+<entry|screenW={0:"Screen width",1:"Horizontal resolution (fullscreen mode)."}>
+<entry|screenH={0:"Screen height",1:"Vertical resolution (fullscreen mode)."}>
+<entry|windowW={0:"Window width",1:"Horizontal size (windowed mode)."}>
+<entry|windowH={0:"Window height",1:"Vertical size (windowed mode)."}>
--- a/data/conf/gui.mtt	Sat Nov 29 16:43:44 2008 +0000
+++ b/data/conf/gui.mtt	Sun Nov 30 17:17:56 2008 +0000
@@ -5,8 +5,9 @@
 <WidgetData|root={0:[0xC100,0,3,3],1:["square","blank","square","blank","floating","blank","square","blank","square"]}>
 <WidgetData|square={0:[0x1,6,6]}>
 <WidgetData|blank={0:[0x2]}>
-<WidgetData|opts={0:[0x2031,0x6030,0],1:["Options","optCls"]}>
-<WidgetData|optCls={0:[0xC100,0,2,1],1:["optName","optVars"]}>
+<WidgetData|opts={0:[0x2031,0xC100,0,2,1],1:["Options","optName","optSecs"]}>
+<WidgetData|optSecs={0:[0x6030,0],1:["optSec"]}>
+<WidgetData|optSec={0:[0xC100,0,2,1],1:["optName","optVars"]}>
 <WidgetData|optVars={0:[0x6030,0],1:["optDBox"]}>
 <WidgetData|optDBox={0:[0xC100,1,2,1],1:["optBox","optDesc"]}>
 <WidgetData|optBox={0:[0xC100,1,1,3],1:["optName","optSep","optVal"]}>
@@ -14,9 +15,7 @@
 <WidgetData|optDesc={0:[0x4020, 2, 0xaf6000]}>
 <WidgetData|optVal={0:[0x6030]}>
 <WidgetData|optSep={0:[0x21, 0xff],1:["="]}>
-<WidgetData|floating={0:[0x8200,6,14,6],1:["L10n","blank","opts"]}>
-<WidgetData|L10n={0:[0x2031,0xC100,0,2,1],1:["Options.MiscOptions.L10n","optBox2","apply"]}>
-<WidgetData|optBox2={0:[0xC100,0,1,3],1:["optName","optSep","optVal"]}>!{cloned to avoid bug #4}
-<WidgetData|apply={0:[0x2031,0x4043],1:["quit"]}>
+<WidgetData|floating={0:[0x8200,6,14,6],1:["quit","blank","opts"]}>
+<WidgetData|quit={0:[0x2031,0x4043],1:["imde.quit"]}>
 {Basic}
 <WidgetData|root={0:[0x21,0x90D970],1:["A string!"]}>
--- a/mde/content/Items.d	Sat Nov 29 16:43:44 2008 +0000
+++ b/mde/content/Items.d	Sun Nov 30 17:17:56 2008 +0000
@@ -51,7 +51,9 @@
 			list[i++] = opts.contentList;
 		    }
 		    Options.allContentList = new ContentList (h, list);
-		    Options.allContentList.name ("Options");	//FIXME
+		    Translation trl = Translation.get (h);
+		    Translation.Entry trle = trl.getStruct (h);
+		    Options.allContentList.name (trle.name, trle.desc);
 		}
 		return Options.allContentList;
 	    }
@@ -68,9 +70,18 @@
 		if (q && item is null)	// enforce item is an exact match
 		    return *q;
 	    }
-	} else if (h == "quit" && item is null) {
-	    quit.name ("Quit");	//FIXME
-	    return quit;
+	} else if (h == "imde") {
+	    if (!imdeTransl) {
+		Translation trl = Translation.get (h);
+		Translation.Entry trle = trl.getStruct ("quit");
+		quit.name (trle.name, trle.desc);
+		imdeTransl = true;
+	    }
+	    h = head (item);
+	    if (h == "quit" && item is null) {
+		quit.name ("Quit");	//FIXME
+		return quit;
+	    }
 	}
 	throw new ContentItemException (h);
     }
@@ -92,7 +103,7 @@
     
     void loadTransl (Options p, char[] n) {
 	debug logger.trace ("Loading translation strings for Options."~n);
-	Translation trans = Translation.load ("L10n/"~n);
+	Translation trans = Translation.get (n);
 	Translation.Entry transled = trans.getStruct (n);
 	p.contentList = new ContentList (n, p.content);
 	p.contentList.name (transled.name, transled.desc);
@@ -101,3 +112,5 @@
 	    v.name (transled.name, transled.desc);
 	}
     }
+    
+    bool imdeTransl = false;	// Has section imde been translated?
--- a/mde/input/Input.d	Sat Nov 29 16:43:44 2008 +0000
+++ b/mde/input/Input.d	Sun Nov 30 17:17:56 2008 +0000
@@ -586,11 +586,11 @@
     * currently conf/input.mtt). */
     debug (mdeUnitTest) unittest {
         Input ut = new Input();
-        ut.loadConfig ("unittest/InputConfig");
-            
+        ut.loadConfig ("InputConfig");
+	
         int[6] counters;	// counters for callbacks
         // Should become: [2,2,0,2,1,1]
-            
+	
         //BEGIN Set up some callbacks
         ut.addButtonCallback (0x03F0, delegate void(inputID id, bool status) {
             assert (status == !counters[0]);	// true first call, false next
--- a/mde/lookup/Translation.d	Sat Nov 29 16:43:44 2008 +0000
+++ b/mde/lookup/Translation.d	Sun Nov 30 17:17:56 2008 +0000
@@ -56,8 +56,67 @@
 */
 class Translation : IDataSection
 {
-    final char[] name;      /// The module/package/... which the instance is for
-    final char[] L10n;      /// The localization loaded (e.g. en-GB)
+    /** Load the translation for the requested module/package/...
+    *
+    * Options (mde.options) must have been loaded before this is run.
+    *
+    * Params:
+    *   name The module/package/... to load strings for.
+    *
+    * Throws:
+    * If no localization exists for this name and the current locale (or any locale to be chain-
+    * loaded), or an error occurs while loading the database, a L10nLoadException will be thrown.
+    */
+    static {
+	/** Get Translation instance for _section section.
+	 *
+	 * On the first call, loads all Translation sections.
+	 * 
+	 * These are loaded from data/L10n/locale.mtt where locale is the current locale, as well
+	 * as any files named for locales specified in the header tag <char[][]|depends=[...]>.
+	 *
+	 * On errors, a message is logged and the function continues, likely resulting in some
+	 * symbol names being untranslated. */
+	Translation get (char[] section) {
+	    if (sections is null) {
+		char[][] files = [miscOpts.L10n()];	// initial locale plus dependencies
+		size_t read = 0;	// index in files of next file to read
+		while (read < files.length) {
+		    try {
+			IReader reader = dataDir.makeMTReader ("L10n/"~files[read++], PRIORITY.HIGH_LOW, null, true);
+			assert (reader.dataset.header);
+			auto dp = "depends" in reader.dataset.header._charAA;
+			if (dp) {	// append, making sure no duplicates are inserted
+			    f1: foreach (dep; *dp) {
+				foreach (f; files)
+				    if (f == dep)
+					continue f1;
+				files ~= dep;
+			    }
+			}
+			reader.dataSecCreator = delegate IDataSection(ID sec) {
+			    auto p = sec in sections;
+			    if (p) return *p;
+			    return new Translation (sec);
+			};
+			reader.read;
+		    } catch (MTException e) {
+			logger.error ("Mergetag exception occurred:");
+			logger.error (e.msg);
+		    }
+		}
+	    }
+	    auto p = section in sections;
+	    if (p is null) {
+		logger.warn ("Section "~section ~ " not found in files; strings will not be translated.");
+		return new Translation (section);
+	    }
+	    return *p;
+	}
+	Translation[char[]] sections;
+    }
+    
+    final char[] section;	// ONLY used to log an error message
     
     alias entry opCall;	    /// Convenience alias
     
@@ -96,60 +155,6 @@
         }
     }
     
-    /** Load the translation for the requested module/package/...
-    *
-    * Options (mde.options) must have been loaded before this is run.
-    *
-    * Params:
-    *   name The module/package/... to load strings for.
-    *
-    * Throws:
-    * If no localization exists for this name and the current locale (or any locale to be chain-
-    * loaded), or an error occurs while loading the database, a L10nLoadException will be thrown.
-    */
-    static Translation load (char[] name)
-    {
-        bool[ID] loadedSecs;        // set of all locales/sections loaded; used to prevent circular loading
-        ID[] secsToLoad             // locales/sections to load (dependancies may be added)
-        = [cast(ID) miscOpts.L10n];  // start by loading the current locale
-        
-        Translation transl = new Translation (name, miscOpts.L10n());
-        
-        IReader reader;
-        try {
-            reader = dataDir.makeMTReader (name, PRIORITY.HIGH_LOW);
-            /* Note: we don't want to load every translation section depended on to its own class
-            * instance, since we want to merge them. So make every mergetag section use the same
-            * instance. */
-            reader.dataSecCreator = delegate IDataSection(ID) {
-                return transl;
-            };
-        
-            while (secsToLoad.length) {                 // while we have sections left to load
-                ID sec = secsToLoad[0];                 // take current section
-                secsToLoad = secsToLoad[1..$];          // and remove from list
-                
-                if (sec in loadedSecs) continue;        // skip if it's already been loaded
-                loadedSecs[sec] = true;
-                
-                reader.read ([sec]);                    // Do the actual loading
-                
-                // Add dependancies to front of list:
-                secsToLoad = transl.depends ~ secsToLoad;
-            }
-            // When loop finishes, we're done loading.
-        } catch (MTException e) {
-            // If an error occurs, log a message but continue (strings will just be untranslated)
-            logger.error ("Mergetag exception occurred:");
-            logger.error (e.msg);
-        }
-        
-        delete transl.depends;      // Free memory
-        transl.depends = [];
-        
-        return transl;
-    }
-    
     static this() {
         logger = Log.getLogger ("mde.lookup.Translation");
     }
@@ -172,7 +177,7 @@
             
             Entry entry = deserialize!(Entry) (dt);
             if (entry.name is null) {   // This tag is invalid; ignore it
-                logger.error ("For name "~name~", L10n "~L10n~": tag with ID "~cast(char[])id~" has no data");
+                logger.error ("In L10n/*.mtt section "~section~": tag with ID "~cast(char[])id~" has no data");
                 return;
             }
             entries[cast(char[]) id] = entry;
@@ -194,12 +199,10 @@
     }
     
 private:
-    /* Sets name and L10n.
-    *
-    * Also ensures only load() can create instances. */
-    this (char[] n, char[] l) {
-        name = n;
-        L10n = l;
+    /* Sets name and ensures only Translation's static functions can create instances. */
+    this (char[] n) {
+        section = n;
+	sections[n] = this;
     }
     
     //BEGIN Data
@@ -211,42 +214,35 @@
     //END Data
     
     debug (mdeUnitTest) unittest {
-        /* Relies on file: conf/L10n/i18nUnitTest.mtt
-        * Contents:
-        *********
-        {MT01}
-        {test-1}
-        <entry|Str1=["Test 1"]>
-        <char[][]|depends=["test-2"]>
-        {test-2}
-        <entry|Str1=["Test 2"]>
-        <entry|Str2=["Test 3","Description",bogus,"entries",56]>
-        *********/
+        // Relies on files in unittest/data/L10n: locale-x.mtt for x in 1..4
         
-        // Hack a specific locale...
-        // Also to allow unittest to run without init.
-        TextContent realL10n = miscOpts.L10n;
-        miscOpts.L10n = new TextContent ("L10n", "test-1");
+        // Hack a specific locale. Also to allow unittest to run without init.
+        StringContent realL10n = miscOpts.L10n;
+        miscOpts.L10n = new StringContent ("L10n", "locale-1");
         
-        Translation transl = load ("unittest/Translation");
-        
-        // Simple get-string, check dependancy's entry doesn't override
-        assert (transl.entry ("Str1") == "Test 1");
-        
-        // Entry included from dependancy with description
-        char[] desc;
-        assert (transl.entry ("Str2", desc) == "Test 3");
-        assert (desc == "Description");
-        
-        // No entry: fallback to identifier string
-        assert (transl.entry ("Str3") == "Str3");
-        
-        // No checks for version info since it's not functionality of this module.
-        // Only check extra entries are allowed but ignored.
-        
+	// Struct tests
+	Translation t = get ("section-2");
+	Entry e = t.getStruct ("entry-1");
+	assert (e.name == "Test 1");
+	assert (e.desc == "Description");
+	e = t.getStruct ("entry-2");
+        assert (e.name == "Test 2");
+	assert (e.desc is null);
+	
+	// Dependency tests. Priority should be 1,2,3,4 (entries should come from first file in list that they appear in).
+	t = get ("section-1");
+	char[] d = "1";
+	assert (t.entry ("file-1", d) == "locale-1");
+	assert (d is null);
+	assert (t.entry ("file-2", d) == "locale-2");
+	assert (d == "desc2");
+	assert (t.entry ("file-3") == "locale-3");
+	assert (t.entry ("file-4") == "locale-4");
+	
         // Restore
 	delete miscOpts.L10n;
         miscOpts.L10n = realL10n;
+	sections = null;
         
         logger.info ("Unittest complete.");
     }
--- a/mde/mde.d	Sat Nov 29 16:43:44 2008 +0000
+++ b/mde/mde.d	Sun Nov 30 17:17:56 2008 +0000
@@ -33,6 +33,7 @@
 debug (mdeUnitTest) {                   // These modules contain unittests which wouldn't be run otherwise.
     import mde.file.ssi;
     import mde.file.mergetag.mdeUT;
+    import mde.lookup.Translation;
 }
 
 //BEGIN A simple drawable to print a message in the window.
--- a/mde/setup/paths.d	Sat Nov 29 16:43:44 2008 +0000
+++ b/mde/setup/paths.d	Sun Nov 30 17:17:56 2008 +0000
@@ -139,17 +139,6 @@
     {
         FilePath[] ret;
         
-        debug (mdeUnitTest) {
-        /* Alternate approach - just try from current directory.
-        * Really just for unittests, but with the if condition it shouldn't break anything else. */
-            if (pathsLen == 0) {
-                FilePath file = findFile (filename);
-                if (file !is null)
-                    ret ~= file;
-                return ret;
-            }
-        }
-        
         if (readOrder == PRIORITY.LOW_HIGH) {
             for (size_t i = 0; i < pathsLen; ++i) {
                 FilePath file = findFile (paths[i]~filename);
@@ -172,12 +161,14 @@
     
     // Unconditionally add a path
     void addPath (char[] path) {
+	assert (pathsLen < MAX_PATHS);
         paths[pathsLen++] = path~'/';
     }
     
     // Test a path and add if is a folder.
     bool tryPath (char[] path, bool create = false) {
-        FilePath fp = FilePath (path);
+	assert (pathsLen < MAX_PATHS);
+	FilePath fp = FilePath (path);
         if (fp.exists && fp.isFolder) {
             paths[pathsLen++] = path~'/';
             return true;
@@ -213,13 +204,17 @@
 char[] logDir;		/// Directory for log files
 
 //BEGIN Path resolution
-// These are used several times:
-const DATA = "/data";
-const CONF = "/conf";
-
-/** Find at least one path for each required directory.
-*
-* Note: the logger cannot be used yet, so only output is exception messages. */
+/** Find at least one path for each required directory. */
+debug (mdeUnitTest) {
+    /** In unittest mode, add paths unittest/data and unittest/conf before init runs. */
+    static this () {
+	dataDir.tryPath ("unittest/data");
+	confDir.tryPath ("unittest/conf");
+	if (!(dataDir.pathsLen && confDir.pathsLen))
+	    throw new mdeException ("Fatal: unittest/data and unittest/conf don't both exist");
+	// Don't bother with real paths or logDir or font dir(s) for unittest.
+    }
+}
 version (linux) {
     SortedMap!(char[],char[]) fontFiles;	// key is file name, value is CString path
     /** Get the actual path of a font file, or throw NoFileException if not found.
@@ -246,14 +241,14 @@
         
         // Static data paths:
         dataDir.addPath (staticPath.toString);      // we know this is valid anyway
-        dataDir.tryPath (userPath.toString ~ DATA);
+        dataDir.tryPath (userPath.toString ~ "/data");
         if (extraDataPath) dataDir.tryPath (extraDataPath);
         if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!");
         
         // Configuration paths:
-        confDir.tryPath (staticPath.toString ~ CONF);
+        confDir.tryPath (staticPath.toString ~ "/conf");
         confDir.tryPath ("/etc/mde");
-        confDir.tryPath (userPath.toString ~ CONF, true);
+        confDir.tryPath (userPath.toString ~ "/conf", true);
         if (extraConfPath) confDir.tryPath (extraConfPath);
         if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!");
         
@@ -293,14 +288,14 @@
         
         // Static data paths:
         dataDir.addPath (staticPath.toString);   // we know this is valid anyway
-        dataDir.tryPath (userPath.toString ~ DATA);
+	dataDir.tryPath (userPath.toString ~ "/data");
         if (extraDataPath) dataDir.tryPath (extraDataPath);
         if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!");
         
         // Configuration paths:
-        confDir.tryPath (staticPath.toString ~ CONF);
+        confDir.tryPath (staticPath.toString ~ "/conf");
         confDir.tryPath (installPath.append("user").toString);
-        confDir.tryPath (userPath.toString ~ CONF, true);
+        confDir.tryPath (userPath.toString ~ "/conf", true);
         if (extraConfPath) confDir.tryPath (extraConfPath);
         if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!");
         
@@ -324,8 +319,7 @@
         }
     }
     
-// The maximum number of paths for any one "directory".
-// There are NO CHECKS that this is not exceeded.
+    // The maximum number of paths for any one "directory".
     const MAX_PATHS = 4;
 
     /* Try each path in succession, returning the first to exist and be a folder.
--- a/unittest/InputConfig.mtt	Sat Nov 29 16:43:44 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-{MT01}
-!{Config for the input.Input unittest}
-{Default}
-<uint[][uint]|B=[
-	0x88000124 : [[0x1000, 0x00F0]],
-	0x40000003 : [[0x1000, 0x01F0]],
-	0x20002005 : [ [0x1000,0x02F0],[0x1000,0x03F0] ],
-	0x110D600C : [[0x1000,0x04F0]],
-	0x120D600C : [[0x1000,0x05F0]],
-	0x140D600C : [[0x1000,0x06F0]],
-	0x180D600C : [[0x1000,0x07F0]] ]>
-<uint[][uint]|A=[0x80001008 : [[0x1000,0x20F0]],0x130D600C : [[0x1000,0x21F0]] , 0x1C0D600C : [[0x1000,0x22F0]]]>
-<uint[][uint]|M=[ 0x88000000 : [[0x1000, 0x10F0], [0x1000, 0x11F0]], 0x40016064:[[0x1000,0x12F0]]]>
--- a/unittest/Translation.mtt	Sat Nov 29 16:43:44 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-{MT01}
-{test-1}
-<entry|Str1={0:"Test 1"}>
-<char[][]|depends=["test-2"]>
-{test-2}
-<entry|Str1={0:"Test 2"}>
-<entry|Str2={0:"Test 3",1:"Description"}>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unittest/conf/InputConfig.mtt	Sun Nov 30 17:17:56 2008 +0000
@@ -0,0 +1,13 @@
+{MT01}
+!{Config for the input.Input unittest}
+{Default}
+<uint[][uint]|B=[
+	0x88000124 : [[0x1000, 0x00F0]],
+	0x40000003 : [[0x1000, 0x01F0]],
+	0x20002005 : [ [0x1000,0x02F0],[0x1000,0x03F0] ],
+	0x110D600C : [[0x1000,0x04F0]],
+	0x120D600C : [[0x1000,0x05F0]],
+	0x140D600C : [[0x1000,0x06F0]],
+	0x180D600C : [[0x1000,0x07F0]] ]>
+<uint[][uint]|A=[0x80001008 : [[0x1000,0x20F0]],0x130D600C : [[0x1000,0x21F0]] , 0x1C0D600C : [[0x1000,0x22F0]]]>
+<uint[][uint]|M=[ 0x88000000 : [[0x1000, 0x10F0], [0x1000, 0x11F0]], 0x40016064:[[0x1000,0x12F0]]]>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unittest/data/L10n/locale-1.mtt	Sun Nov 30 17:17:56 2008 +0000
@@ -0,0 +1,7 @@
+{MT01}
+<char[][]|depends=["locale-2","locale-3"]>
+{section-1}
+<entry|file-1={0:"locale-1"}>
+{section-2}
+<entry|entry-2={0:"Test 2"}>
+<entry|entry-1={0:"Test 1",1:"Description"}>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unittest/data/L10n/locale-2.mtt	Sun Nov 30 17:17:56 2008 +0000
@@ -0,0 +1,5 @@
+{MT01}
+<char[][]|depends=["locale-4"]>
+{section-1}
+<entry|file-1={0:"locale-2",1:"desc2"}>
+<entry|file-2={0:"locale-2",1:"desc2"}>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unittest/data/L10n/locale-3.mtt	Sun Nov 30 17:17:56 2008 +0000
@@ -0,0 +1,6 @@
+{MT01}
+<char[][]|depends=[]>
+{section-1}
+<entry|file-1={0:"locale-3",1:"desc3"}>
+<entry|file-2={0:"locale-3",1:"desc3"}>
+<entry|file-3={0:"locale-3",1:"desc3"}>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unittest/data/L10n/locale-4.mtt	Sun Nov 30 17:17:56 2008 +0000
@@ -0,0 +1,6 @@
+{MT01}
+{section-1}
+<entry|file-1={0:"locale-4",1:"desc4"}>
+<entry|file-2={0:"locale-4",1:"desc4"}>
+<entry|file-3={0:"locale-4",1:"desc4"}>
+<entry|file-4={0:"locale-4",1:"desc4"}>