From 28babf307eed425322821b5ec8da4f8c8de52634 Mon Sep 17 00:00:00 2001
From: Aleric Inglewood
Date: Sat, 24 May 2014 02:36:12 +0200
Subject: Fix looking up line number and colum when there is no exact match.

When a compile error reports a colum/error that is not an exact
match in the positionMap dictionary, the last position in the
map with a line number and position before the reported error
should be returned.

The old code had the following problems:
1) It returns l,c - which are line and column of the C# file, not LSL.
2) It doesn't set l to 'line' when the map has an entry with 'line'.
3) It sorts the map without taking columns into account, which may
   result in a random order of the columns. With my mono implementation
   the columns were reversed in order.

For example, if the map contains the following lines:

99,5,49,10
100,30,50,10
100,40,1,0
101,5,51,10

and a translation of 100,35 was requested,
then the old code would compare '100' with the keys in
the first column - setting l to that key while it is
smaller. Hence, l is set to 99.
Then it finds the key 100 and doesn't update l.
Because of the reversed sort order, it first compares
the column 35 with 40, finding that it is smaller
and therefore it stops; returning 99,1 instead of finding
the correct 100,30 entry and returning 50,10.

This patch causes 50,10 to be returned.

The remaining problems after this patch are:
1) The sorting might not be necessary at all.
2) The is code duplication (I fixed both instances,
   but really there should be no code duplication
   imho).
---
 .../ScriptEngine/Shared/CodeTools/Compiler.cs      | 29 ++++++----------
 OpenSim/Tools/Compiler/Program.cs                  | 39 +++++++++-------------
 2 files changed, 27 insertions(+), 41 deletions(-)

diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 1efe798..0b41bc6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -729,7 +729,8 @@ namespace SecondLife
             public int Compare(KeyValuePair<int, int> a,
                     KeyValuePair<int, int> b)
             {
-                return a.Key.CompareTo(b.Key);
+                int kc = a.Key.CompareTo(b.Key);
+                return (kc != 0) ? kc : a.Value.CompareTo(b.Value);
             }
         }
 
@@ -751,27 +752,19 @@ namespace SecondLife
 
             sorted.Sort(new kvpSorter());
 
-            int l = 1;
-            int c = 1;
+            int l = sorted[0].Key;
+            int c = sorted[0].Value;
 
             foreach (KeyValuePair<int, int> cspos in sorted)
             {
-                if (cspos.Key >= line)
-                {
-                    if (cspos.Key > line)
-                        return new KeyValuePair<int, int>(l, c);
-                    if (cspos.Value > col)
-                        return new KeyValuePair<int, int>(l, c);
-                    c = cspos.Value;
-                    if (c == 0)
-                        c++;
-                }
-                else
-                {
-                    l = cspos.Key;
-                }
+                if (cspos.Key >= line &&
+                    !(cspos.Key == line && cspos.Value <= col))
+                  break;
+                l = cspos.Key;
+                c = cspos.Value;
             }
-            return new KeyValuePair<int, int>(l, c);
+            positionMap.TryGetValue(new KeyValuePair<int, int>(l, c), out ret);
+            return ret;
         }
 
         string ReplaceTypes(string message)
diff --git a/OpenSim/Tools/Compiler/Program.cs b/OpenSim/Tools/Compiler/Program.cs
index 6c59c31..b9c960b 100644
--- a/OpenSim/Tools/Compiler/Program.cs
+++ b/OpenSim/Tools/Compiler/Program.cs
@@ -255,12 +255,13 @@ namespace OpenSim.Tools.LSL.Compiler
             return FindErrorPosition(line, col, null);
         }
 
-        private class kvpSorter : IComparer<KeyValuePair<int,int>>
+        private class kvpSorter : IComparer<KeyValuePair<int, int>>
         {
-            public int Compare(KeyValuePair<int,int> a,
-                               KeyValuePair<int,int> b)
+            public int Compare(KeyValuePair<int, int> a,
+                    KeyValuePair<int, int> b)
             {
-                return a.Key.CompareTo(b.Key);
+                int kc = a.Key.CompareTo(b.Key);
+                return (kc != 0) ? kc : a.Value.CompareTo(b.Value);
             }
         }
 
@@ -277,32 +278,24 @@ namespace OpenSim.Tools.LSL.Compiler
                     out ret))
                 return ret;
 
-            List<KeyValuePair<int,int>> sorted =
-                    new List<KeyValuePair<int,int>>(positionMap.Keys);
+            List<KeyValuePair<int, int>> sorted =
+                    new List<KeyValuePair<int, int>>(positionMap.Keys);
 
             sorted.Sort(new kvpSorter());
 
-            int l = 1;
-            int c = 1;
+            int l = sorted[0].Key;
+            int c = sorted[0].Value;
 
             foreach (KeyValuePair<int, int> cspos in sorted)
             {
-                if (cspos.Key >= line)
-                {
-                    if (cspos.Key > line)
-                        return new KeyValuePair<int, int>(l, c);
-                    if (cspos.Value > col)
-                        return new KeyValuePair<int, int>(l, c);
-                    c = cspos.Value;
-                    if (c == 0)
-                        c++;
-                }
-                else
-                {
-                    l = cspos.Key;
-                }
+                if (cspos.Key >= line &&
+                    !(cspos.Key == line && cspos.Value <= col))
+                  break;
+                l = cspos.Key;
+                c = cspos.Value;
             }
-            return new KeyValuePair<int, int>(l, c);
+            positionMap.TryGetValue(new KeyValuePair<int, int>(l, c), out ret);
+            return ret;
         }
     }
 }
-- 
cgit v1.1