From 4419a829ffcf2280a03ba5f407679595ae7e5788 Mon Sep 17 00:00:00 2001 From: handa Date: Thu, 11 Jun 2009 12:54:17 +0000 Subject: [PATCH] *** empty log message *** --- MText.cs | 259 +++++++++++++++++++++++++++++++++++++++++++++++--------------- Makefile | 7 +- 2 files changed, 201 insertions(+), 65 deletions(-) diff --git a/MText.cs b/MText.cs index fe03bfb..52d1943 100644 --- a/MText.cs +++ b/MText.cs @@ -71,7 +71,7 @@ namespace M17N.Core public static bool HasFlags (MSymbol key, Flags flags) { - return ((key.flags & flags) == flags); + return ((key.flags & flags) != Flags.None); } public override string ToString () @@ -663,6 +663,14 @@ namespace M17N.Core MProperty.Flags.RearSensitive) ; } } + public bool isAnySensitive + { + get { return MProperty.HasFlags (Key, + (MProperty.Flags.Sensitive + | MProperty.Flags.RearSensitive + | MProperty.Flags.FrontSensitive)) ; } + } + private void update_from_to () { if (Parent == null) @@ -927,6 +935,30 @@ namespace M17N.Core return copy; } + public MInterval Copy (MText mt, int start, int end, + bool first, bool last) + { + MInterval copy = Copy (mt, start, end); + MInterval head = find_head (start); + MInterval tail = find_tail (end); + + if (! head.Stack.IsEmpty + && (isAnySensitive && head.From < start + || isFrontSensitive && ! first)) + { + head = copy.find_head (0); + head.Stack.Clear (); + } + if (! tail.Stack.IsEmpty + && (isAnySensitive && end < head.To + || isRearSensitive && ! last)) + { + tail = copy.find_tail (copy.Length); + tail.Stack.Clear (); + } + return copy; + } + // this-. ==> this-. // right newright-. // right @@ -934,7 +966,7 @@ namespace M17N.Core { MInterval interval = new MInterval (Key, mtext, To - pos, Stack); - M17n.DebugPrint ("divide-right({0}) at ", pos); DumpOne (false, true); + M17n.DebugPrint ("divide-right({0}) at {1}\n", pos, this); To = pos; if (Right != null) { @@ -954,7 +986,7 @@ namespace M17N.Core { MInterval interval = new MInterval (Key, mtext, pos - From, Stack); - M17n.DebugPrint ("divide-left({0}) at ", pos); DumpOne (false, true); + M17n.DebugPrint ("divide-left({0}) at {1}\n", pos, this); From = pos; if (Left != null) { @@ -1005,9 +1037,20 @@ namespace M17N.Core MInterval i = interval.find_head (start); len = 0; - while (i != null && mergeable (i)) + if (Stack.IsEmpty + && (isFrontSensitive + || ((isSensitive || isRearSensitive) && i.From < start))) { - M17n.DebugPrint (" grafting "); i.DumpOne (false, false); + M17n.DebugPrint (" grafting {0}", i); + if (i.To < end) + len = i.To - start; + else + len = end - start; + i = i.Next; + } + while (i != null && i.From < end && mergeable (i)) + { + M17n.DebugPrint (" grafting {0}", i); len += i.To - i.From; if (i.From < start) len -= start - i.From; @@ -1020,7 +1063,7 @@ namespace M17N.Core } } - M17n.DebugPrint (" grafted {0} in ", len); DumpOne (false, true); + M17n.DebugPrint (" grafted {0} in {1}\n", len, this); if (len > 0) enlarge (len); return len; @@ -1039,9 +1082,20 @@ namespace M17N.Core MInterval i = interval.find_tail (end); len = 0; - while (i != null && mergeable (i)) + if (Stack.IsEmpty + && (isRearSensitive + || ((isSensitive || isFrontSensitive) && end < i.To))) { - M17n.DebugPrint (" grafting "); i.DumpOne (false, false); + M17n.DebugPrint (" grafting {0}", i); + if (i.From <= start) + len = end - start; + else + len = end - i.From; + i = i.Prev; + } + while (i != null && i.To <= start && mergeable (i)) + { + M17n.DebugPrint (" grafting {0}", i); len += i.To - i.From; if (end < i.To) len -= i.To - end; @@ -1054,7 +1108,7 @@ namespace M17N.Core } } - M17n.DebugPrint (" grafted {0} in ", len); DumpOne (false, true); + M17n.DebugPrint (" grafted {0} in {1}\n", len, this); if (len > 0) enlarge (len); return len; @@ -1064,8 +1118,8 @@ namespace M17N.Core { update_from_to (); - M17n.DebugPrint ("insert({0} to {1}) at {2} in ", start, end, pos); - DumpOne (false, false); + M17n.DebugPrint ("insert({0} to {1}) at {2} in {3}", + start, end, pos, this); if (pos < From) Left.Insert (pos, interval, start, end); @@ -1087,17 +1141,28 @@ namespace M17N.Core enlarge (end - start); return; } - if (prev != null) + bool front_grafted = false, rear_grafted = false; + int grafted; + if (prev != null + && (grafted = prev.graft_forward (interval, start, end)) > 0) { - start += prev.graft_forward (interval, start, end); + start += grafted; if (start == end) return; + front_grafted = true; + } + if ((grafted = graft_backward (interval, start, end)) > 0) + { + end -= grafted; + if (start == end) + return; + rear_grafted = true; } - if ((end -= graft_backward (interval, start, end)) == start) - return; if (interval != null) - interval = interval.Copy (mtext, start, end); + interval = interval.Copy (mtext, start, end, + front_grafted || prev == null, + rear_grafted); else interval = new MInterval (Key, mtext, end - start, null); @@ -1122,22 +1187,36 @@ namespace M17N.Core } else if (pos < To) { - if (isSensitive) - Stack.Clear (); - else if (! Stack.IsEmpty && (isFrontSticky || isRearSticky)) + if (! Stack.IsEmpty) { - enlarge (end - start); - return; + if (isSensitive || isFrontSensitive || isRearSensitive) + Stack.Clear (); + else if (isFrontSticky || isRearSticky) + { + enlarge (end - start); + return; + } + } + bool front_grafted = false, rear_grafted = false; + int grafted; + if ((grafted = graft_forward (interval, start, end)) > 0) + { + start += grafted; + if (start == end) + return; + front_grafted = true; + pos += grafted; + } + if ((grafted = graft_backward (interval, start, end)) > 0) + { + end -= grafted; + if (start == end) + return; + rear_grafted = true; } - int len = graft_forward (interval, start, end); - start += len; - if (start == end) - return; - if ((end -= graft_backward (interval, start, end)) == start) - return; - pos += len; if (interval != null) - interval = interval.Copy (mtext, start, end); + interval = interval.Copy (mtext, start, end, + front_grafted, rear_grafted); else interval = new MInterval (Key, mtext, end - start, null); @@ -1160,23 +1239,32 @@ namespace M17N.Core enlarge (end - start); return; } - if (next != null) + if (next != null && isFrontSticky && ! next.Stack.IsEmpty) { - if (isFrontSticky && ! next.Stack.IsEmpty) - { - next.enlarge (end - start); - return; - } - end -= next.graft_backward (interval, start, end); + next.enlarge (end - start); + return; + } + bool front_grafted = false, rear_grafted = false; + int grafted; + if (next != null + && (grafted = next.graft_backward (interval, start, end)) > 0) + { + end -= grafted; if (start == end) return; + rear_grafted = true; + } + if ((grafted = graft_forward (interval, start, end)) > 0) + { + start += grafted; + if (start == end) + return; + front_grafted = true; } - - if ((start += graft_forward (interval, start, end)) == end) - return; - if (interval != null) - interval = interval.Copy (mtext, start, end); + interval = interval.Copy (mtext, start, end, + front_grafted, + rear_grafted || next == null); else interval = new MInterval (Key, mtext, end - start, null); @@ -1241,31 +1329,53 @@ namespace M17N.Core public void Delete (int start, int end) { update_from_to (); - M17n.DebugPrint ("delete({0} {1}) from ", start, end); DumpOne (false, true); + M17n.DebugPrint ("delete({0} {1}) from {2}\n", start, end, this); + + bool front_checked = false; + bool rear_checked = false; + if (start < From) { if (end <= From) { + if (end == From && isFrontSensitive) + Stack.Clear (); Left.Delete (start, end); return; } + if (isSensitive || isFrontSensitive) + Stack.Clear (); Left.Delete (start, From); To -= From - start; end -= From - start; From = start; + front_checked = true; } if (end > To) { if (start >= To) { + if (start == To && isRearSensitive) + Stack.Clear (); Right.Delete (start, end); return; } + if (isSensitive || isRearSensitive) + Stack.Clear (); Right.Delete (To, end); end = To; + rear_checked = true; } if (start == From && end == To) { + if (! front_checked + && start > 0 + && isRearSensitive) + Prev.Stack.Clear (); + if (! rear_checked + && end < mtext.Length + && isFrontSensitive) + Next.Stack.Clear (); if (Right == null) { vacate_node (Left); @@ -1289,6 +1399,8 @@ namespace M17N.Core { int len = end - start; + if (isAnySensitive) + Stack.Clear (); for (MInterval i = this; i != null; i = i.Parent) i.Length -= len; } @@ -1297,7 +1409,7 @@ namespace M17N.Core public void Push (int start, int end, MProperty prop) { update_from_to (); - M17n.DebugPrint ("push({0} {1}) at ", start, end); DumpOne (false, true); + M17n.DebugPrint ("push({0} {1}) at {2}\n", start, end, this); if (start < From) { if (end <= From) @@ -1319,6 +1431,8 @@ namespace M17N.Core end = To; } + if (! Stack.IsEmpty && isAnySensitive) + Stack.Clear (); if (start > From) divide_left (start); if (end < To) @@ -1331,8 +1445,7 @@ namespace M17N.Core /// that the intervals are mergeable in advance. private static void combine (MInterval head, MInterval tail) { - M17n.DebugPrint ("combining "); head.DumpOne (true, false); - M17n.DebugPrint (" through "); tail.DumpOne (true, false); + M17n.DebugPrint ("combining {0} through {1}", head, tail); head.update_from_to (); tail.update_from_to (); @@ -1344,7 +1457,7 @@ namespace M17N.Core for (root = head; root.To + root.RightLength < to; root = root.Parent); - M17n.DebugPrint (" common root is "); root.DumpOne (false, true); + M17n.DebugPrint (" with common root {0}\n", root); if (from < root.From) { @@ -1352,7 +1465,7 @@ namespace M17N.Core while (true) { - M17n.DebugPrint ("merging "); prev.DumpOne (false, true); + M17n.DebugPrint ("merging {0}\n", prev); prev.vacate_node (prev.Left, root); if (prev == head) break; @@ -1369,7 +1482,7 @@ namespace M17N.Core while (true) { - M17n.DebugPrint ("merging "); next.DumpOne (false, true); + M17n.DebugPrint ("merging {0}\n", next); next.vacate_node (next.Right, root); if (next == tail) break; @@ -1380,7 +1493,6 @@ namespace M17N.Core } root.update_from_to (); } - M17n.DebugPrint ("combining done\n"); } public void MergeAfterChange (int start, int end) @@ -1388,19 +1500,23 @@ namespace M17N.Core update_from_to (); MInterval head = find_head (start), i = head; - MInterval tail = find_tail (end).Next; + MInterval tail = start < end ? find_tail (end) : head; + + if (tail.To < Length) + tail = tail.Next; if (start == head.From && start > 0) { - i = head.Prev; - if (! head.mergeable (i)) - i = head; + MInterval prev = head.Prev; + if (head.mergeable (prev)) + head = prev; } + M17n.DebugPrint ("merge between {0} and {1}\n", head, tail); while (i != tail) { MInterval next = i.Next; - if (next == null || ! i.mergeable (next)) + if (! i.mergeable (next)) { if (head != i) combine (head, i); @@ -1408,12 +1524,14 @@ namespace M17N.Core } i = next; } + if (head != i) + combine (head, i); } public void Pop (int start, int end) { update_from_to (); - M17n.DebugPrint ("pop({0} {1}) at ", start, end); DumpOne (false, true); + M17n.DebugPrint ("pop({0} {1}) at {2}\n", start, end, this); if (start < From) { if (end <= From) @@ -1437,11 +1555,16 @@ namespace M17N.Core if (! Stack.IsEmpty) { - if (start > From) - divide_left (start); - if (end < To) - divide_right (end); - Stack.Pop (); + if (isAnySensitive) + Stack.Clear (); + else + { + if (start > From) + divide_left (start); + if (end < To) + divide_right (end); + Stack.Pop (); + } } } @@ -1469,9 +1592,21 @@ namespace M17N.Core Pop (head.From, tail.To); } - private void DumpOne (bool with_prop, bool newline) + public override string ToString () { - DumpOne (with_prop, newline, false); + string str = String.Format ("#{0}({1} {2} {3} [", ID, Length, From, To); + bool first = true; + foreach (MPlist p in Stack) + { + if (first) + { + str += ((MProperty) p.Val).Val; + first = false; + } + else + str += " " + ((MProperty) p.Val).Val; + } + return (str + "])"); } private void DumpOne (bool with_prop, bool newline, bool force) diff --git a/Makefile b/Makefile index 8b94700..7ae3864 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,11 @@ CS=gmcs2 M17N_SRC = M17N.cs CORE_SRC = MSymbol.cs MPlist.cs MText.cs MDatabase.cs -TEST_PROG = symbol.exe plist.exe mtext.exe textprop.exe database.exe \ - rearsticky.exe frontsticky.exe sensitive.exe +EXAMPLE = symbol.exe plist.exe mtext.exe textprop.exe database.exe +TEST = rearsticky.exe frontsticky.exe \ + sensitive.exe frontsensitive.exe rearsensitive.exe -all: ${TEST_PROG} +all: ${EXAMPLE} ${TEST} M17N.dll: ${M17N_SRC} $(CS) /out:$@ /t:library ${M17N_SRC} -- 1.7.10.4