*** empty log message ***
authorhanda <handa>
Tue, 20 Oct 2009 06:50:55 +0000 (06:50 +0000)
committerhanda <handa>
Tue, 20 Oct 2009 06:50:55 +0000 (06:50 +0000)
MInputMethod.cs
XmlExpr.cs
input.cs

index c535112..da10788 100644 (file)
@@ -9,7 +9,7 @@ using M17N;
 using M17N.Core;
 using M17N.Input;
 
-using Xex = System.Xml.Expression.Xexpression;
+using Xex = System.Xml.Xexpression;
 
 namespace M17N.Input
 {
@@ -18,13 +18,6 @@ namespace M17N.Input
     // Delegaes
     public delegate bool Callback (Context ic, MPlist args);
 
-    // Class members
-    public static event Callback PreeditChanged;
-    public static event Callback StatusChanged;
-    public static event Callback CandidateChanged;
-    public static Callback GetSurroundingText;
-    public static Callback DeleteSurroundingText;
-
     internal static Xex.Domain im_domain
       = new Xex.Domain ("input-method", null);
     private static MSymbol Minput_method = "input-method";
@@ -40,6 +33,7 @@ namespace M17N.Input
     private static MSymbol Mstate = "state";
     internal static MSymbol Mcandidates = "candidates";
     private static MSymbol Mat_minus_zero = "@-0";
+    private static MSymbol Matat = "@@";
 
     private static Xex.Symbol Qxi_include = "xi:include";
     private static Xex.Symbol Qmap = "map";
@@ -70,6 +64,12 @@ namespace M17N.Input
     private static Xex.Symbol Qtitle = "title";
     private static Xex.Symbol Qeq = "=";
     private static Xex.Symbol Qeqeq = "==";
+    private static Xex.Symbol Qhide = "hide";
+    private static Xex.Symbol Qhide_candidates = "hide-candidates";
+    private static Xex.Symbol Qshow = "show";
+    private static Xex.Symbol Qshow_candidates = "show-candidates";
+    private static Xex.Symbol Qkey_count = "key-count";
+    private static Xex.Symbol Qsurrounding_text_flag = "surrounding-text-flag";
     private static Xex.Symbol Qcandidates_group_size = "candidates-group-size";
 
     private static Xex.Term Tnil = new Xex.Term ((Xex.Symbol) "nil");
@@ -804,7 +804,10 @@ namespace M17N.Input
         for (int i = 0, start = 0; i < nblocks; i++, list = list.next)
           start += (blocks[i] = new Block (index, list)).Count;
         if (column > 0)
-          group = new object[column];
+          {
+            group = new object[column];
+            fill_group (0);
+          }
        }
 
        public Candidates (Xex.Term[] candidates, int column)
@@ -815,7 +818,10 @@ namespace M17N.Input
         for (int i = 0, start = 0; i < nblocks; i++)
           start += (blocks[i] = new Block (index, candidates[i])).Count;
         if (column > 0)
-          group = new object[column];
+          {
+            group = new object[column];
+            fill_group (0);
+          }
        }
 
        public static void Detach (Context ic)
@@ -824,162 +830,162 @@ namespace M17N.Input
         ic.candidates = null;
         ic.changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos
                        | CandidateAll);
-      }
+       }
 
-      // Fill the array "group" by candidates stating from START.
-      // START must be a multiple of "column".  Return the number of
-      // valid candidates in "group".
+       // Fill the array "group" by candidates stating from START.
+       // START must be a multiple of "column".  Return the number of
+       // valid candidates in "group".
 
-      private int fill_group (int start)
-      {
-       int nitems = group.Length;
-       int r = row;
-       Block b = blocks[r];
+       private int fill_group (int start)
+       {
+        int nitems = group.Length;
+        int r = row;
+        Block b = blocks[r];
 
-       if (start < b.Index)
-         while (start < b.Index)
-            b = blocks[--r];
-       else
-         while (start >= b.Index + b.Count)
-           b = blocks[++r];
-       row = r;
+        if (start < b.Index)
+          while        (start < b.Index)
+            b = blocks[--r];
+        else
+          while        (start >= b.Index + b.Count)
+            b = blocks[++r];
+        row = r;
 
-       int count = b.Count;
-       start -= b.Index;
-       for (int i = 0; i < nitems; i++, start++)
-         {
-           if (start >= count)
-             {
-               r++;
-               if (r == blocks.Length)
-                 return i;
-               b = blocks[r];
-               count = b.Count;
-               start = 0;
-             }
-           group[i] = b[start];
-         }
-       return nitems;
-      }
+        int count = b.Count;
+        start -= b.Index;
+        for (int i = 0; i < nitems; i++, start++)
+          {
+            if (start >= count)
+              {
+                r++;
+                if (r == blocks.Length)
+                  return i;
+                b = blocks[r];
+                count = b.Count;
+                start = 0;
+              }
+            group[i] = b[start];
+          }
+        return nitems;
+       }
 
-      // Update "row" to what contains the first candidate of
-      // the previous candidate-group, update "current_index", and
-      // update "group" if necessary.  Return the previous
-      // candidate-group.  Set NITEMS to the number of valid
-      // candidates contained in that group.
+       // Update "row" to what contains the first candidate of
+       // the previous candidate-group, update "current_index", and
+       // update "group" if necessary.  Return the previous
+       // candidate-group.  Set NITEMS to the number of valid
+       // candidates contained in that group.
 
-      public int PrevGroup ()
-      {
-       int nitems;
-       int col = Column;
+       public int PrevGroup ()
+       {
+        int nitems;
+        int col = Column;
 
-       if (IsFixed)
-         {
-           nitems = group.Length;
-           if ((index -= col + nitems) < 0)
-             index = (Total / nitems) * nitems;
-           nitems = fill_group (index);
-         }
-       else
-         {
-           row = row > 0 ? row-- : blocks.Length - 1;
-           nitems = blocks[row].Count;
-           index = blocks[row].Index;
-         }
-       index += col < nitems ? col : nitems - 1;
-       return nitems;
-      }
+        if (IsFixed)
+          {
+            nitems = group.Length;
+            if ((index -= col + nitems) < 0)
+              index = (Total / nitems) * nitems;
+            nitems = fill_group (index);
+          }
+        else
+          {
+            row = row > 0 ? row-- : blocks.Length - 1;
+            nitems = blocks[row].Count;
+            index = blocks[row].Index;
+          }
+        index += col < nitems ? col : nitems - 1;
+        return nitems;
+       }
 
-      public int NextGroup ()
-      {
-       int nitems;
-       int col = Column;
+       public int NextGroup ()
+       {
+        int nitems;
+        int col = Column;
 
-       if (IsFixed)
-         {
-           nitems = group.Length;
-           if ((index += nitems - col) >= Total)
-             index = 0;
-           nitems = fill_group (index);
-         }
-       else
-         {
-           row = row < blocks.Length - 1 ? row + 1 : 0;
-           nitems = blocks[row].Count;
-           index = blocks[row].Count;
-         }
-       index += col < nitems ? col : nitems - 1;
-       return nitems;
-      }
+        if (IsFixed)
+          {
+            nitems = group.Length;
+            if ((index += nitems - col) >= Total)
+              index = 0;
+            nitems = fill_group (index);
+          }
+        else
+          {
+            row = row < blocks.Length - 1 ? row + 1 : 0;
+            nitems = blocks[row].Count;
+            index = blocks[row].Count;
+          }
+        index += col < nitems ? col : nitems - 1;
+        return nitems;
+       }
 
-      public void Prev ()
-      {
-       int col = Column;
+       public void Prev ()
+       {
+        int col = Column;
 
-       if (col == 0)
-         {
-           int nitems = PrevGroup ();
-           index += col < nitems - 1 ? col : nitems - 1;
-         }
-       else
-         index--;
-      }
+        if (col == 0)
+          {
+            int nitems = PrevGroup ();
+            index += col < nitems - 1 ? col : nitems - 1;
+          }
+        else
+          index--;
+       }
 
-      public void Next ()
-      {
-       int col = Column;
-       int nitems = GroupLength;
+       public void Next ()
+       {
+        int col = Column;
+        int nitems = GroupLength;
 
-       if (col == nitems - 1)
-         {
-           nitems = NextGroup ();
-           index -= Column;
-         }
-       else
-         index++;
-      }
+        if (col == nitems - 1)
+          {
+            nitems = NextGroup ();
+            index -= Column;
+          }
+        else
+          index++;
+       }
 
-      public void First ()
-      {
-       index -= Column;
-      }
+       public void First ()
+       {
+        index -= Column;
+       }
 
-      public void Last ()
-      {
-       index += GroupLength - (Column + 1);
-      }
+       public void Last ()
+       {
+        index += GroupLength - (Column + 1);
+       }
 
-      public object Select (int col)
-      {
-       int maxcol = GroupLength - 1;
-       if (col > maxcol)
-         col = maxcol;
-       index = index - Column + col;
-       return Current;
-      }
+       public object Select (int col)
+       {
+        int maxcol = GroupLength - 1;
+        if (col > maxcol)
+          col = maxcol;
+        index = index - Column + col;
+        return Current;
+       }
 
-      public object Select (Selector selector)
-      {
-       switch (selector.Tag)
-         {
-         case '<': First (); break;
-         case '>': Last (); break;
-         case '-': Prev (); break;
-         case '+': Next (); break;
-         case '[': PrevGroup (); break;
-         case ']': NextGroup (); break;
-         default: break;
-         }
-       return Current;
-      }
+       public object Select (Selector selector)
+       {
+        switch (selector.Tag)
+          {
+          case '<': First (); break;
+          case '>': Last (); break;
+          case '-': Prev (); break;
+          case '+': Next (); break;
+          case '[': PrevGroup (); break;
+          case ']': NextGroup (); break;
+          default: break;
+          }
+        return Current;
+       }
 
-      public override string ToString ()
-      {
-       return (String.Format ("<candidates row={0} col={1}>", row, index)
-               + Group
-               + "</candidates>");
-      }
-    }
+       public override string ToString ()
+       {
+        return (String.Format ("<candidates row={0} col={1}>", row, index)
+                + Group
+                + "</candidates>");
+       }
+     }
 
     internal class Selector : Xex.TermValue
     {
@@ -1133,12 +1139,12 @@ namespace M17N.Input
 
     internal class State
     {
-      public Xex.Symbol name;
+      public MSymbol name;
       public MText title;
       public Xex.Term[] enter_actions, fallback_actions;
       public Keymap keymap = new Keymap ();
 
-      public State (Xex.Symbol name, MText title)
+      public State (MSymbol name, MText title)
       {
        this.name = name;
        this.title = title;
@@ -1176,7 +1182,7 @@ namespace M17N.Input
       {
        if (! plist.IsSymbol)
          throw new Exception ("Invalid state: " + plist);
-       this.name = plist.Symbol.Name;
+       this.name = plist.Symbol;
        plist = plist.next;
        if (plist.IsMText)
          {
@@ -1233,8 +1239,7 @@ namespace M17N.Input
     internal Xex.Symbol[] var_names;
     internal Dictionary<MSymbol, Plugin> plugins;
     internal Dictionary<MSymbol, Map> maps;
-    internal Dictionary<Xex.Symbol, State> states;
-    internal State initial_state;
+    internal MPlist states;
 
     static MInputMethod ()
     {
@@ -1246,8 +1251,8 @@ namespace M17N.Input
       im_domain.DefSubr (Finsert_candidates, "insert-candidates", false, 1, -1);
       im_domain.DefSubr (Fdelete, "delete", false, 1, 1);
       im_domain.DefSubr (Fselect, "select", false, 1, 1);
-      im_domain.DefSubr (Fshow, "show", false, 0, 0);
-      im_domain.DefSubr (Fhide, "hide", false, 0, 0);
+      im_domain.DefSubr (Fshow, "show-candidates", false, 0, 0);
+      im_domain.DefSubr (Fhide, "hide-candidates", false, 0, 0);
       im_domain.DefSubr (Fmove, "move", false, 1, 1);
       im_domain.DefSubr (Fmark, "mark", false, 1, 1);
       im_domain.DefSubr (Fpushback, "pushback", false, 1, 1);
@@ -1258,7 +1263,7 @@ namespace M17N.Input
       im_domain.DefSubr (Fshift, "shift", false, 1, 1);
       im_domain.DefSubr (Fshiftback, "shiftback", false, 0, 0);
       im_domain.DefSubr (Fchar_at, "char-at", false, 1, 1);
-      im_domain.DefSubr (Fkey_count, "key-count", false, 1, 1);
+      im_domain.DefSubr (Fkey_count, "key-count", false, 0, 0);
       im_domain.DefSubr (Fsurrounding_flag, "surrounding-text-flag",
                         false, 0, 0);
 
@@ -1390,17 +1395,17 @@ namespace M17N.Input
 
     private void add_default_state ()
     {
-      Xex.Symbol Qinit = "init";
+      MSymbol Qinit = "init";
       State state = new State (Qinit, title);
       foreach (KeyValuePair<MSymbol, Map>kv in maps)
        state.keymap.AddMap (kv.Value, null);
-      states[Qinit] = initial_state = state;
+      states.Add (Qinit, state);
     }
 
     private void load (MPlist plist, bool full)
     {
       maps = new Dictionary<MSymbol, Map> ();
-      states = new Dictionary<Xex.Symbol, State> ();
+      states = new MPlist ();
 
       for (; ! plist.IsEmpty; plist = plist.next)
        if (plist.IsPlist)
@@ -1445,7 +1450,7 @@ namespace M17N.Input
        commands = new Command[0];
       if (! full)
        return;
-      if (states.Count == 0)
+      if (states.IsEmpty)
        add_default_state ();
     }
 
@@ -1454,7 +1459,7 @@ namespace M17N.Input
       bool skip_header = load_status == LoadStatus.Header;
 
       maps = new Dictionary<MSymbol, Map> ();
-      states = new Dictionary<Xex.Symbol, State> ();
+      states = new MPlist ();
 
       if (node.NodeType == XmlNodeType.Document)
        node = node.FirstChild;
@@ -1462,7 +1467,6 @@ namespace M17N.Input
        node = node.NextSibling;
       for (node = node.FirstChild; node != null; node = node.NextSibling)
        {
-         Console.WriteLine (this.tag + node.Name);
          if (node.NodeType != XmlNodeType.Element)
            continue;
          if (! skip_header)
@@ -1496,7 +1500,7 @@ namespace M17N.Input
        commands = new Command[0];
       if (! full)
        return;
-      if (states.Count == 0)
+      if (states.IsEmpty)
        add_default_state ();
     }
 
@@ -1552,8 +1556,9 @@ namespace M17N.Input
          Xex.Symbol name = (Xex.Symbol) p.Symbol.Name;
          var_names[i] = name;
          p = p.next;
-         string desc = (string) parse_description (p);
-         if (desc != null)
+         MText mt = parse_description (p);
+         string desc = mt == null ? null : (string) mt;
+         if (! p.IsEmpty)
            p = p.next;
          Xex.Variable vari = get_global_var (name);
          if (vari != null)
@@ -1776,9 +1781,7 @@ namespace M17N.Input
        if (plist.IsPlist)
          {
            State state = new State (this, plist.Plist);
-           states[state.name] = state;     
-           if (initial_state == null)
-             initial_state = state;
+           states.Add (state.name, state);         
          }
     }
 
@@ -1789,9 +1792,7 @@ namespace M17N.Input
          if (node.Name == Qstate)
            {
              State state = new State (this, node);
-             states[state.name] = state;
-             if (initial_state == null)
-               initial_state = state;
+             states.Add (state.name, state);
            }
          else if (node.Name == Qxi_include)
            parse_include (node);
@@ -1801,9 +1802,6 @@ namespace M17N.Input
     private void include_part (MSymbol language, MSymbol name, MSymbol subname,
                               MSymbol part, MSymbol section)
     {
-      Console.WriteLine ("including {0}:{1}:{2}:{3}:{4}",
-                        language, name, subname, part, section);
-
       MInputMethod im = MInputMethod.Find (language, name, subname);
       if (im == null)
        return;
@@ -1834,15 +1832,15 @@ namespace M17N.Input
        {
          if (section == MSymbol.nil)
            {
-             foreach (KeyValuePair<Xex.Symbol, State> kv in im.states)
-               states[kv.Key] = kv.Value;
+             for (MPlist p = im.states; ! p.IsEmpty; p = p.next)
+               states.Add (p.Key, p.Val);
            }
          else
            {
-             Xex.Symbol state_name = section.Name;
-             State state;
-             if (im.states.TryGetValue (state_name, out state))
-               states[state_name] = state;
+             MSymbol state_name = (string) section.Name;
+             State state = (State) im.states.Get (state_name);
+             if (state != null)
+               states.Add (state.name, state);
            }
        }
     }
@@ -2003,8 +2001,6 @@ namespace M17N.Input
            return parse_funcall_with_marker (p, name);
          if (name == Qshift)
            return parse_shift (p);
-         if (((string) name)[0] == '@')
-           return parse_char_at (sym);
          if (name == Qset || name == Qadd || name == Qsub
                   || name == Qmul || name == Qdiv)
            {
@@ -2019,6 +2015,10 @@ namespace M17N.Input
            {
              if (name == Qeq)
                name = Qeqeq;
+             else if (name == Qhide)
+               name = Qhide_candidates;
+             else if (name == Qshow)
+               name = Qshow_candidates;
              if (p.IsEmpty)
                return new Xex.Term (domain, name, null);
              else
@@ -2027,6 +2027,10 @@ namespace M17N.Input
        }
       else if (plist.IsSymbol)
        {
+         if (plist.Symbol == Matat)
+           return new Xex.Term (domain, Qkey_count, null);
+         if (plist.Symbol == Mat_minus_zero)
+           return new Xex.Term (domain, Qsurrounding_text_flag, null);
          if (plist.Symbol.Name[0] == '@')
            return parse_char_at (plist.Symbol);
          return new Xex.Term (domain, (Xex.Symbol) plist.Symbol.Name);
@@ -2262,11 +2266,11 @@ namespace M17N.Input
                                    Xex.Term[] args)
     {
       Context ic = (Context) domain.context;
-      State state;
-      if (ic.im.states.TryGetValue (args[0].Symval, out state))
-       ((Context) domain.context).shift (state);
-      else
-       throw new Exception ("Unknown state: " + args[0].Symval);
+      MSymbol state_name = (string) args[0].Symval;
+      State state = (State) ic.im.states.Get (state_name);
+      if (state == null)
+       throw new Exception ("Unknown state: " + state_name);
+      ((Context) domain.context).shift (state);
       return args[0];
     }
 
@@ -2287,7 +2291,8 @@ namespace M17N.Input
                                               Xex.Variable vari,
                                               Xex.Term[] args)
     {
-      return new Xex.Term (GetSurroundingText == null ? 0 : 1);
+      return new Xex.Term (((Context) domain.context).GetSurroundingText == null
+                          ? 0 : 1);
     }
 
     public override string ToString ()
@@ -2319,10 +2324,8 @@ namespace M17N.Input
       foreach (KeyValuePair<MSymbol, Map> kv in maps)
        str += " " + kv.Value;
       str += ") (states";
-      foreach (KeyValuePair<Xex.Symbol, State> kv in states)
-       {
-         str += " (" + kv.Key + " " + kv.Value.keymap + ")";
-       }
+      for (MPlist p = states; ! p.IsEmpty; p = p.next)
+       str += " (" + p.Key + " " + ((State) p.Val).keymap + ")";
       return str + "))";
     }
 
@@ -2332,6 +2335,12 @@ namespace M17N.Input
       internal Xex.Domain domain;
       private bool active;
 
+      public Callback PreeditChanged;
+      public Callback StatusChanged;
+      public Callback CandidateChanged;
+      public Callback GetSurroundingText;
+      public Callback DelSurroundingText;
+
       private MText status;
       private MText produced = new MText ();
       internal MText preedit = new MText ();
@@ -2342,7 +2351,7 @@ namespace M17N.Input
       private bool candidate_show;
       public bool CandidateShow { get { return candidate_show; } }
 
-      private State state, prev_state;
+      private State initial_state, state, prev_state;
       private MText state_preedit = new MText ();
       private int state_key_head;
       private object state_var_values, state_initial_var_values;
@@ -2379,7 +2388,7 @@ namespace M17N.Input
 
       internal void reset ()
       {
-       status = im.initial_state.title;
+       status = initial_state.title;
        produced.Del ();
        preedit.Del ();
 
@@ -2392,7 +2401,7 @@ namespace M17N.Input
        state_preedit.Del ();
        state_var_values = state_initial_var_values;
        state_pos = 0;
-       shift (im.initial_state);
+       shift (initial_state);
 
        preceding_text.Del ();
        following_text.Del ();
@@ -2505,10 +2514,10 @@ namespace M17N.Input
          {
            if (pos < 0)
              {
-               if (DeleteSurroundingText != null)
+               if (DelSurroundingText != null)
                  {
                    callback_arg.Set (MSymbol.integer, pos);
-                   if (DeleteSurroundingText (this, callback_arg))
+                   if (DelSurroundingText (this, callback_arg))
                      {
                        if (callback_arg.IsInteger)
                          deleted = callback_arg.Integer - cursor_pos;
@@ -2526,10 +2535,10 @@ namespace M17N.Input
          {
            if (pos > preedit.Length)
              {
-               if (DeleteSurroundingText != null)
+               if (DelSurroundingText != null)
                  {
                    callback_arg.Set (MSymbol.integer, pos - preedit.Length);
-                   if (DeleteSurroundingText (this, callback_arg))
+                   if (DelSurroundingText (this, callback_arg))
                      {
                        if (callback_arg.IsInteger)
                          deleted = callback_arg.Integer - cursor_pos;
@@ -2618,9 +2627,9 @@ namespace M17N.Input
 
       internal void commit ()
       {
+       Candidates.Detach (this);
        produced.Cat (preedit);
        preedit_replace (0, preedit.Length, null, null);
-       changed |= ChangedStatus.Preedit;
       }
 
       internal void shift (State state)
@@ -2632,7 +2641,7 @@ namespace M17N.Input
            state = prev_state;
          }
 
-       if (state == im.initial_state)
+       if (state == initial_state)
          {
            commit ();
            keys.keyseq.RemoveRange (0, key_head);
@@ -2665,6 +2674,7 @@ namespace M17N.Input
          throw new Exception ("Openging " + im.tag + " failed");
        this.im = im;
        domain = new Xex.Domain ("context", im.domain, this);
+       initial_state = (State) im.states.Val;
        state_initial_var_values = domain.SaveValues ();
        reset ();
        active = true;
@@ -2714,9 +2724,6 @@ namespace M17N.Input
 
       private bool handle_key ()
       {
-       Console.Write ("\nHandle ({0}[{1}]) in {2}",
-                      keys, key_head, state.name);
-
        Keymap sub = keymap.Lookup (keys, ref key_head);
 
        if (sub != keymap)
@@ -2756,13 +2763,13 @@ namespace M17N.Input
              }
            if (state == current_state)
              {
-               if (state == im.initial_state
+               if (state == initial_state
                    && key_head < keys.keyseq.Count)
                  return false;
                if (keymap != state.keymap)
                  shift (state);
                else if (keymap.branch_actions == null)
-                 shift (im.initial_state);
+                 shift (initial_state);
              }
          }
        return true;
@@ -2838,12 +2845,68 @@ namespace M17N.Input
          {
            CandidateChanged (this, callback_arg);
          }
+       return (! key_unhandled && produced.Length == 0);
+      }
+    }
 
-       Console.Write ("\nPreedit(\"{0}\"/{1}), Produced({2})",
-                      preedit, cursor_pos, produced);
+    public class Session
+    {
+      Context ic;
+      MText mt;
+      int pos;
 
-       return (! key_unhandled && produced.Length == 0);
+      public Session (MInputMethod im, MText mt, int pos)
+      {
+       ic = new Context (im);
+       this.mt = mt;
+       this.pos = pos;
+       ic.GetSurroundingText = get_surrounding_text;
+       ic.DelSurroundingText = del_surrounding_text;
+      }
+
+      private bool get_surrounding_text (Context ic, MPlist args)
+      {
+       int len = args.Integer;
+       if (len < 0)
+         args.Set (MSymbol.mtext, mt[0, pos]);
+       else
+         args.Set (MSymbol.mtext, mt[pos, mt.Length]);
+       return true;
       }
+
+      private bool del_surrounding_text (Context ic, MPlist args)
+      {
+       int pos = this.pos + args.Integer;
+       if (pos < this.pos)
+         {
+           mt.Del (pos, this.pos);
+           this.pos = pos;
+         }
+       else
+         mt.Del (this.pos, pos);
+       return true;
+      }
+
+      public bool HandleKey (Key key)
+      {
+       bool result = ic.Filter (key);
+         
+       if (! result)
+         {
+           MText produced = ic.Produced;
+           mt.Ins (pos, produced);
+           pos += produced.Length;
+           if (ic.UnhandledKey (out key))
+             {
+               mt.Ins (pos, key.ToChar ());
+               pos++;
+             }
+         }
+       return result;
+      }
+
+      public int CurrentPos { get { return pos; } }
+      public MText Preedit { get { return ic.Preedit; } }
     }
   }
 }
index 23ffd80..5251080 100644 (file)
@@ -4,11 +4,16 @@ using System.Collections.Generic;
 using System.IO;
 using System.Xml;
 
-namespace System.Xml.Expression
+namespace System.Xml
 {
   public class Xexpression
   {
-    public static int debug_level = 0;
+    private static int debug_depth = 0;
+
+    public static int DebugDepth {
+      get { return debug_depth; }
+      set { debug_depth = value; }
+    }
 
     public struct Symbol : IEquatable<Symbol>
     {
@@ -457,10 +462,10 @@ namespace System.Xml.Expression
          : base (domain, name, new Term (n), desc)
          {
            if (range != null && range.Length % 2 == 1)
-             throw new Exception ("Invalid range length: " + range.Length);
+             throw_exception ("Range length for {0} not even", name);
            this.range = range;
            if (! ValueP (val))
-             throw new Exception ("Invalid integer value: " + val);
+             throw_exception ("Invalid integer value for {0}: {1}", name, val);
          }
 
        public override bool ValueP (Term term)
@@ -510,7 +515,7 @@ namespace System.Xml.Expression
          {
            this.range = range;
            if (! ValueP (val))
-             throw new Exception ("Invalid string value: " + val);
+             throw_exception ("Invalid string value for {0}: {1}", name, val);
          }
 
        public override bool ValueP (Term term)
@@ -560,7 +565,7 @@ namespace System.Xml.Expression
          {
            this.range = range;
            if (! ValueP (val))
-             throw new Exception ("Invalid symbol value: " + val);
+             throw_exception ("Invalid symbol value for {0}: {1}", name, val);
          }
 
        public override bool ValueP (Term term)
@@ -622,19 +627,15 @@ namespace System.Xml.Expression
       }
     }
 
-#if false
-    internal class ThrowException : Exception
+    private static void throw_exception (string msg)
     {
-      Symbol tag;
-      public object value;
+      throw new Exception (msg);
+    }
 
-      public ThrowException (Symbol tag, object value) : base ()
-       {
-         this.tag = tag;
-         this.value = value;
-       }
+    private static void throw_exception (string fmt, params object[] args)
+    {
+      throw new Exception (String.Format (fmt, args));
     }
-#endif
 
     internal class CatchTag : IEquatable<CatchTag>
     {
@@ -728,7 +729,7 @@ namespace System.Xml.Expression
       internal void ThrowBreak ()
       {
        if (catch_stack.Peek () != CatchTag.Break)
-         throw new Exception ("No outer loop to break");
+         throw_exception ("No outer loop to break");
        catch_count--;
       }
 
@@ -949,11 +950,11 @@ namespace System.Xml.Expression
          {
            Variable.Int intvari = vari as Variable.Int;
            if (intvari == null)
-             throw new Exception ("Variable type mismatch");
+             throw new Exception ("Variable type mismatch: " + name);
            if (range == null)
              range = intvari.Range;
            else if (! intvari.IsSubrange (range))
-             throw new Exception ("Variable range mismatch");
+             throw new Exception ("Variable range mismatch: " + name);
            if (desc == null)
              desc = vari.Description;
          }
@@ -971,11 +972,11 @@ namespace System.Xml.Expression
          {
            Variable.Str strvari = vari as Variable.Str;
            if (strvari == null)
-             throw new Exception ("Variable type mismatch");
+             throw new Exception ("Variable type mismatch: " + name);
            if (range == null)
              range = strvari.Range;
            else if (! strvari.IsSubrange (range))
-             throw new Exception ("Variable range mismatch");
+             throw new Exception ("Variable range mismatch: " + name);
            if (desc == null)
              desc = vari.Description;
          }
@@ -993,11 +994,11 @@ namespace System.Xml.Expression
          {
            Variable.Sym symvari = vari as Variable.Sym;
            if (symvari == null)
-             throw new Exception ("Variable type mismatch");
+             throw new Exception ("Variable type mismatch: " + name);
            if (range == null)
              range = symvari.Range;
            else if (! symvari.IsSubrange (range))
-             throw new Exception ("Variable range mismatch");
+             throw new Exception ("Variable range mismatch: " + name);
            if (desc == null)
              desc = vari.Description;
          }
@@ -1061,7 +1062,7 @@ namespace System.Xml.Expression
 
       internal void DebugWrite (bool head, string fmt, params string[] arg)
       {
-       if (debug_level > depth)
+       if (debug_depth > depth)
          {
            if (head)
              {
@@ -1685,8 +1686,8 @@ namespace System.Xml.Expression
              int nargs = args.Length;
              if (nargs < func.min_arg
                  || (func.max_arg >= 0 && nargs > func.max_arg))
-               throw new Exception ("Invalid number of arguments to: "
-                                    + func.name + " " + nargs);
+               throw_exception ("Invalid number of arguments to {0}: ",
+                                func.name, nargs);
            }
          this.func = func;
          this.vari = vari;
index e888cca..3e87235 100644 (file)
--- a/input.cs
+++ b/input.cs
@@ -2,23 +2,40 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Xml;
-using System.Xml.Expression;
 using M17N;
 using M17N.Core;
 using M17N.Input;
-using Xex = System.Xml.Expression.Xexpression;
+using Xex = System.Xml.Xexpression;
 
 public class Test
 {
   public static void Main(string[] args)
   {
-    //M17n.debug = true;
-    Xex.debug_level = 10;
-    MDatabase.ApplicationDir = "/usr/local/share/m17n-xml";
-    MInputMethod im = MInputMethod.Find ("zh", "py-b5");
-    MInputMethod.Context ic = new MInputMethod.Context (im);
-    MText str = args[0];
+    // M17n.debug = true;
+    // Xex.DebugDepth = 10;
+    int argc = 0;
+    if (args[0] == "xml")
+      {
+       MDatabase.ApplicationDir = "/usr/local/share/m17n-xml";
+       argc++;
+      }
+    else
+      MDatabase.ApplicationDir = "/usr/local/share/m17n";
+    MInputMethod im = MInputMethod.Find (args[argc], args[argc + 1]);
+    MText mt = new MText ();
+    MInputMethod.Session session = new MInputMethod.Session (im, mt, 0);
+
+    MText str = args[argc + 2];
     for (int i = 0; i < str.Length; i++)
-      ic.Filter (new MInputMethod.Key (str[i]));
+      {
+       MInputMethod.Key key = new MInputMethod.Key (str[i]);
+       session.HandleKey (key);
+       int pos = session.CurrentPos;
+       Console.WriteLine ("{0} -> \"{1}|{2}|{3}\"",
+                          str[i, i + 1],
+                          mt[0, pos],
+                          session.Preedit,
+                          mt[pos, mt.Length]);
+      }
   }
 }