From 6bcb07f73a9038a659d334bf0d553984d335b691 Mon Sep 17 00:00:00 2001 From: handa Date: Sat, 30 May 2009 00:36:05 +0000 Subject: [PATCH] *** empty log message *** --- MDatabase.cs | 492 +++++++++++++++++++++++++++++++++++++++++----------------- MPlist.cs | 5 +- MText.cs | 2 +- Makefile | 2 +- symbol.cs | 1 + 5 files changed, 358 insertions(+), 144 deletions(-) diff --git a/MDatabase.cs b/MDatabase.cs index 5557257..dca37f6 100644 --- a/MDatabase.cs +++ b/MDatabase.cs @@ -6,147 +6,202 @@ using M17N.Core; namespace M17N.Core { + internal class MDatabaseDir + { + private const string ListFileName = "mdb.dir"; + + public string Dirname; + public DirectoryInfo DirInfo; + public FileInfo ListInfo; + public DateTime LastScanned; + + public MDatabaseDir (string dirname) + { + Dirname = dirname; + if (dirname != null) + { + try { + DirInfo = new DirectoryInfo (dirname); + try { + ListInfo = DirInfo.GetFiles (ListFileName)[0]; + } catch { + ListInfo = null; + } + } catch { + DirInfo = null; + ListInfo = null; + } + } + } + + public bool CheckStatus () + { + if (DirInfo != null) + { + try { + DirInfo.Refresh (); + } catch { + DirInfo = null; + ListInfo = null; + LastScanned = new DateTime (0); + return true; + } + if (ListInfo != null) + try { + ListInfo.Refresh (); + } catch { + ListInfo = null; + return true; + } + else + { + try { + ListInfo = DirInfo.GetFiles (ListFileName)[0]; + return true; + } catch { + ListInfo = null; + } + } + return (LastScanned < DirInfo.LastWriteTime + || (ListInfo != null + && LastScanned < ListInfo.LastWriteTime)); + } + else + { + if (Dirname != null && Directory.Exists (Dirname)) + { + DirInfo = new DirectoryInfo (Dirname); + try { + ListInfo = DirInfo.GetFiles (ListFileName)[0]; + } catch { + ListInfo = null; + } + return true; + } + return false; + } + } + + public void UpdateStatus () + { + if (DirInfo != null) + LastScanned = DateTime.UtcNow; + } + + public FileInfo[] Scan (string filename) + { + if (DirInfo == null) + return null; + DirInfo.Refresh (); + return DirInfo.GetFiles (filename); + } + } + public class MDatabase { + /// Tags to identify a MDatabase. public struct Tag { - public MSymbol Tag0, Tag1, Tag2, Tag3; + public MSymbol[] Tags; public Tag (MSymbol tag0) { - Tag0 = tag0; Tag1 = Tag2 = Tag3 = MSymbol.nil; + Tags = new MSymbol[4]; + Tags[0] = tag0; Tags[1] = Tags[2] = Tags[3] = MSymbol.nil; } public Tag (MSymbol tag0, MSymbol tag1) { - Tag0 = tag0; Tag1 = tag1; Tag2 = Tag3 = MSymbol.nil; + Tags = new MSymbol[4]; + Tags[0] = tag0; Tags[1] = tag1; Tags[2] = Tags[3] = MSymbol.nil; } public Tag (MSymbol tag0, MSymbol tag1, MSymbol tag2) { - Tag0 = tag0; Tag1 = tag1; Tag2 = tag2; Tag3 = MSymbol.nil; + Tags = new MSymbol[4]; + Tags[0] = tag0; Tags[1] = tag1; Tags[2] = tag2; Tags[3] = MSymbol.nil; } public Tag (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3) { - Tag0 = tag0; Tag1 = tag1; Tag2 = tag2; Tag3 = tag3; + Tags = new MSymbol[4]; + Tags[0] = tag0; Tags[1] = tag1; Tags[2] = tag2; Tags[3] = tag3; } - } - - public delegate object Loader (Tag tag, object extra_info); - - private class MDatabaseDir - { - private const string ListFileName = "mdb.dir"; - public string Dirname; - public DirectoryInfo DirInfo; - public DateTime LastScanned; - public FileInfo ListInfo; - - private static void GetInfo (string dirname, out DirectoryInfo dirinfo, - out FileInfo listinfo) + public bool Match (Tag tag) { - if (Directory.Exists (dirname)) - try { dirinfo = new DirectoryInfo (dirname); - try { listinfo = dirinfo.GetFiles (ListFileName)[0]; - } catch { listinfo = null; } - } catch { dirinfo = null; listinfo = null; } - else + for (int i = 0; i < 4; i++) { - dirinfo = null; - listinfo = null; - } - } - - public MDatabaseDir (string dirname) - { - Dirname = dirname; - GetInfo (dirname, out DirInfo, out ListInfo); - } - - public bool StatusChanged { - get { - bool exists = Directory.Exists (Dirname); - - if (DirInfo != null) - { - if (! exists) - { - DirInfo = null; - ListInfo = null; - LastScanned = new DateTime (0); - } - if (LastScanned.Year == 0) - return true; - DirInfo.Refresh (); - if (ListInfo != null) - ListInfo.Refresh (); - return (LastScanned < DirInfo.LastWriteTime - || LastScanned < ListInfo.LastWriteTime); - } - else - { - if (exists) - { - DirInfo = new DirectoryInfo (Dirname); - try { - ListInfo = DirInfo.GetFiles (ListFileName)[0]; - } catch { - ListInfo = null; - } - return true; - } + if (tag.Tags[i] == Mwildcard || Tags[i] == Mwildcard) + return true; + if (tag.Tags[i] != Tags[i]) return false; - } - } - } - - public void UpdateStatus () - { - if (DirInfo != null) - LastScanned = DateTime.UtcNow; + } + return true; } - public FileInfo[] Scan (string filename) + public override string ToString () { - if (DirInfo == null) - return null; - DirInfo.Refresh (); - return DirInfo.GetFiles (filename); + return ("<" + + Tags[0] + "," + Tags[1] + "," + Tags[2] + "," + Tags[3] + + ">"); } } + public delegate object Loader (Tag tag, object extra_info); + internal class MDatabaseInfo { - internal DirectoryInfo Dir; + // -2: absolute, -1: unknown 0: DBDirs[0], 1: DBDirs[1], 2: DBDirs[2] + internal int DirIndex; internal string Description; - internal MText Filename; + internal string Filename; internal FileInfo FileInfo; internal FileInfo Validater; internal int Version; internal MSymbol Format; internal MSymbol Schema; - internal MText SchemaFile; + internal string SchemaFile; internal DateTime ModifiedTime; internal MPlist Props; + + public MDatabaseInfo () + { + Format = Schema = MSymbol.nil; + DirIndex = -1; + } + + public override string ToString () + { + string str = ("#"; + } } - private static Dictionary DBDict - = new Dictionary (); + private static Dictionary DBDict + = new Dictionary (); + + private static Dictionary DBDictMulti + = new Dictionary (); private static MDatabaseDir[] DBDirs = new MDatabaseDir[3]; - private const string SystemDirectory = "/usr/share/m17n"; private static readonly MSymbol Mversion = MSymbol.Of ("version"); + private static readonly MSymbol Mwildcard = MSymbol.Of ("*"); + private static readonly MSymbol Mchar_table = MSymbol.Of ("char-table"); + private static readonly MSymbol Mcharset = MSymbol.Of ("charset"); + /// Type of database private enum MDBType { - /// The database was defined automatically from mdb.dir - /// file(s) with no wildcard tag. + /// The database was defined automatically from one of mdb.dir + /// files with no wildcard tag. AUTO, - /// The database was defined automatically from mdb.dir - /// file(s) with a wildcard tag to define multiple databases + /// The database was defined automatically from one of mdb.dir + /// files with a wildcard tag to define multiple databases /// of the same kind. MULTIPLE, /// The database was defined explicitely by MDatabase.Define @@ -155,6 +210,9 @@ namespace M17N.Core /// The database was defined explicitely by MDatabase.Define /// to use a special loader. UNKNOWN, + /// The database is for defining multiple databases of the + /// same kind with a wildcard tag. + WILDCARD, }; /// Status of database @@ -175,7 +233,7 @@ namespace M17N.Core INVALID, }; - public readonly Tag tag; + public Tag tag; private Loader loader; private object ExtraInfo; private MDBType DBType; @@ -183,8 +241,6 @@ namespace M17N.Core internal DateTime LoadedTime; internal MDatabaseInfo Info; - public static string ApplicationDirectory; - static MDatabase () { string share_dir = (Environment.GetFolderPath @@ -197,37 +253,107 @@ namespace M17N.Core } catch (ArgumentException) { DBDirs[0] = new MDatabaseDir (Path.Combine (usr_dir, "_m17n_d")); } - DBDirs[1] = null; + DBDirs[1] = new MDatabaseDir (null); DBDirs[2] = new MDatabaseDir (Path.Combine (share_dir, "m17n")); } - private MDatabase (Tag tag, Loader loader, object extra_info) + public static string ApplicationDir + { get { return (DBDirs[1].Dirname); } + set { DBDirs[1].Dirname = value; DBDirs[1].CheckStatus (); } } + + private static bool update_database_directories () + { + bool updated = false; + for (int i = 0; i < 3; i++) + if (DBDirs[i].CheckStatus ()) + { + delete_databases (i); + if (DBDirs[i].ListInfo != null) + update_databases (i); + updated = true; + } + return updated; + } + + public static void ListDirs () + { + update_database_directories (); + for (int i = 0; i < 3; i++) + if (DBDirs[i].Dirname != null) + { + Console.Write ("{0}:{1}", i, DBDirs[i].Dirname); + if (DBDirs[i].DirInfo != null) + { + if (DBDirs[i].ListInfo != null) + Console.WriteLine (" {0}", DBDirs[i].ListInfo); + else + Console.WriteLine (".. no mdb.dir"); + } + else + Console.WriteLine (".. not exist"); + } + } + + private void register (int priority) + { + Dictionary dict + = DBType == MDBType.WILDCARD ? DBDictMulti : DBDict; + MDatabase[] mdbs; + + if (! dict.TryGetValue (tag, out mdbs)) + { + mdbs = new MDatabase[4]; + dict.Add (tag, mdbs); + } + mdbs[priority] = this; + } + + public MDatabase (Tag tag, Loader loader, object extra_info) { this.tag = tag; this.loader = loader; + DBType = MDBType.UNKNOWN; + DBStatus = MDBStatus.UPDATED; ExtraInfo = extra_info; + this.register (0); } - private MDatabase (Tag tag, string filename) + public MDatabase (Tag tag, string filename) { this.tag = tag; + DBType = MDBType.EXPLICIT; + DBStatus = MDBStatus.OUTDATED; Info = new MDatabaseInfo (); - Info.Filename = new MText (filename); + Info.Filename = filename; + Info.DirIndex = Path.IsPathRooted (filename) ? -2 : -1; + this.register (0); } - private MDatabase (MPlist plist) + private MDatabase (MPlist plist, int priority) { - MSymbol[] tags = new MSymbol[4]; - int i; - - for (i = 0; plist.IsSymbol; i++, plist = plist.Next) - tags[i] = plist.Symbol; - while (i < 4) - tags[i++] = MSymbol.nil; - tag = new Tag (tags[0], tags[1], tags[2], tags[3]); + tag = new Tag (MSymbol.nil); + DBType = MDBType.AUTO; + DBStatus = MDBStatus.OUTDATED; + for (int i = 0; plist.IsSymbol; i++, plist = plist.Next) + { + if (DBType == MDBType.WILDCARD) + tag.Tags[i] = MSymbol.nil; + else + { + tag.Tags[i] = plist.Symbol; + if (tag.Tags[i] == Mwildcard) + DBType = MDBType.WILDCARD; + } + } + + Info = new MDatabaseInfo (); + if (tag.Tags[0] == Mchar_table || tag.Tags[0] == Mcharset) + Info.Format = tag.Tags[0]; + else + Info.Format = MSymbol.plist; if (plist.IsMText) { - Info.Filename = plist.Text; + Info.Filename = plist.Text.ToString (); plist = plist.Next; } else if (plist.IsPlist) @@ -235,7 +361,7 @@ namespace M17N.Core MPlist p = plist.Plist; if (p.IsMText) - Info.Filename = plist.Text; + Info.Filename = plist.Text.ToString (); p = p.Next; if (! p.IsEmpty) { @@ -248,12 +374,15 @@ namespace M17N.Core Info.Schema = p.Symbol; p = p.Next; if (p.IsMText) - Info.SchemaFile = p.Text; + Info.SchemaFile = p.Text.ToString (); } } plist = plist.Next; } - DBStatus = MDBStatus.OUTDATED;; + else + throw new Exception ("Invalid source definition:" + plist); + + Info.DirIndex = Path.IsPathRooted (Info.Filename) ? -2 : -1; Info.Version = 0; Info.Props = new MPlist (); foreach (MPlist pl in plist) @@ -271,6 +400,15 @@ namespace M17N.Core } Info.Props.Put (pl.Key, pl.Val); } + this.register (priority); + } + + public override String ToString () { + string str = "#"; } private static int parse_version (MPlist plist) @@ -289,53 +427,127 @@ namespace M17N.Core return ((major << 16) | (minor << 8) | release); } - public static MDatabase Define (Tag tag, Loader loader, object extra_info) + private static void delete_databases (int list_idx) { - MDatabase db = MDatabase.Find (tag); + foreach (KeyValuePair item in DBDict) + item.Value[list_idx + 1] = null; + foreach (KeyValuePair item in DBDictMulti) + item.Value[list_idx + 1] = null; + } - if (db != null) + private static void update_databases (int list_idx) + { + MDatabaseDir dbdir = DBDirs[list_idx]; + FileInfo dblist = dbdir.ListInfo; + MPlist plist = null; + + using (FileStream stream = File.OpenRead (dblist.FullName)) { - db.loader = loader; - db.ExtraInfo = extra_info; - db.DBType = MDBType.EXPLICIT; - db.DBStatus = MDBStatus.OUTDATED; - db.Info = null; - return db; + MStreamReader reader = new MStreamReader (stream); + plist = new MPlist (reader); + } + if (plist == null) + return; + foreach (MPlist pl in plist) + { + if (! pl.IsPlist) + continue; + try + { + new MDatabase (pl.Plist, list_idx + 1); + } + catch (Exception e) + { + Console.WriteLine (e.Message); + } } - return new MDatabase (tag, loader, extra_info); } - public static MDatabase Define (Tag tag, string filename) + private void expand_wildcard (int priority) { - MDatabase db = MDatabase.Find (tag); - - if (db != null) + if (Info.DirIndex == -2) { - db.loader = null; - db.DBType = MDBType.EXPLICIT; - db.DBStatus = MDBStatus.OUTDATED; - db.Info = new MDatabaseInfo (); - db.Info.Filename = new MText (filename); - - return db; + } - return new MDatabase (tag, filename); + } - private void update () + private void update_status () { - for (int i = 0; i < 3; i++) + if (Info.DirIndex == -2) { - if (DBDirs[0].StatusChanged) - break; } } public static MDatabase Find (Tag tag) { - MDatabase db; + MDatabase[] mdbs; + MDatabase mdb = null; + + if (DBDict.TryGetValue (tag, out mdbs)) + { + if (mdbs[0] != null) + return mdbs[0]; + for (int i = 1; i < 4; i++) + if ((mdb = mdbs[i]) != null) + break; + } + if (! update_database_directories ()) + return mdb; + if (! DBDict.TryGetValue (tag, out mdbs)) + return null; + for (int i = 1; i < 4; i++) + if (mdbs[i] != null) + return mdbs[i]; + return null; + } - return (DBDict.TryGetValue (tag, out db) ? db : null); + public static List List (Tag tag) + { + List list = new List (); + + update_database_directories (); + foreach (KeyValuePair item in DBDictMulti) + if (item.Key.Match (tag)) + for (j = 0; j < 4; j++) + if (item.Value[j] != null) + if (item.Value[j].DBStatus == MDBStatus.OUTDATED) + item.Value[j].expand_wildcard (j); + + for (int i = 0; i < 4 && tag.Tags[i] == Mwildcard; i++); + if (i == 4) + { + // No wildcard. + if (DBDict.TryGetValue (tag, out mdbs)) + for (int j = 0; j < 4; j++) + if (mdbs[j] != null) + { + mdbs[j].update_status (); + if (mdbs[j].DBStatus != MDBStatus.DISABLED) + { + list.Add (mdbs[j]); + break; + } + } + } + else + { + // With wildcard. We must scan all databases. + foreach (KeyValuePair item in DBDict) + if (item.Key.Match (tag)) + for (int j = 0; j < 4; j++) + if (item.Value[j] != null) + { + MDatabase mdb = item.Value[j]; + mdb.update_status (); + if (mdb.DBStatus != MDBStatus.DISABLED) + { + list.Add (mdb); + break; + } + } + } + return list; } public object Load () @@ -355,8 +567,6 @@ namespace M17N.Core { LoadedTime = DateTime.UtcNow; - - return null; } } diff --git a/MPlist.cs b/MPlist.cs index 67977b3..f607bc7 100644 --- a/MPlist.cs +++ b/MPlist.cs @@ -82,7 +82,10 @@ namespace M17N.Core && p.Key != MSymbol.plist && p.Key != MSymbol.mtext) str += p.Key + ":"; - str += p.Val; + if (p.Key == MSymbol.mtext) + str += "\"" + p.Val + "\""; + else + str += p.Val; } return str + ")"; } diff --git a/MText.cs b/MText.cs index f8d7379..a46a95d 100644 --- a/MText.cs +++ b/MText.cs @@ -186,7 +186,7 @@ namespace M17N.Core return this.sb.ToString ().CompareTo (other.sb.ToString ()); } - public override String ToString () { return "\"" + sb.ToString () + "\""; } + public override string ToString () { return sb.ToString (); } private static bool surrogate_high_p (char c) { diff --git a/Makefile b/Makefile index 8cb4029..3b4f590 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CS=gmcs M17N_SRC = M17N.cs CORE_SRC = MSymbol.cs MPlist.cs MText.cs MDatabase.cs -TEST_PROG = symbol.exe plist.exe mtext.exe textprop.exe \ +TEST_PROG = symbol.exe plist.exe mtext.exe textprop.exe database.exe \ rearsticky.exe frontsticky.exe sensitive.exe all: ${TEST_PROG} diff --git a/symbol.cs b/symbol.cs index 32be8e3..d6b8b18 100644 --- a/symbol.cs +++ b/symbol.cs @@ -34,5 +34,6 @@ public class Test } sym4 = MSymbol.PropertyKey ("symbol", MProperty.Flags.None); sym4 = MSymbol.PropertyKey ("symbol"); + Console.WriteLine (sym4); } } -- 1.7.10.4