Fix llListFindList() returning no match when there is a match with a script constant component in the source list.
Adds regression test for this case. Based on http://opensimulator.org/mantis/view.php?id=6156 Thanks SignpostMarv.0.7.4-extended
parent
176b1c85c0
commit
eefd39a0d5
|
@ -5436,27 +5436,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
/// Returns the index of the first occurrence of test
|
/// Returns the index of the first occurrence of test
|
||||||
/// in src.
|
/// in src.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="src">Source list</param>
|
||||||
|
/// <param name="test">List to search for</param>
|
||||||
|
/// <returns>
|
||||||
|
/// The index number of the point in src where test was found if it was found.
|
||||||
|
/// Otherwise returns -1
|
||||||
|
/// </returns>
|
||||||
public LSL_Integer llListFindList(LSL_List src, LSL_List test)
|
public LSL_Integer llListFindList(LSL_List src, LSL_List test)
|
||||||
{
|
{
|
||||||
|
|
||||||
int index = -1;
|
int index = -1;
|
||||||
int length = src.Length - test.Length + 1;
|
int length = src.Length - test.Length + 1;
|
||||||
|
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
// If either list is empty, do not match
|
// If either list is empty, do not match
|
||||||
|
|
||||||
if (src.Length != 0 && test.Length != 0)
|
if (src.Length != 0 && test.Length != 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
if (src.Data[i].Equals(test.Data[0]))
|
// Why this piece of insanity? This is because most script constants are C# value types (e.g. int)
|
||||||
|
// rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code
|
||||||
|
// and so the comparison fails even if the LSL_Integer conceptually has the same value.
|
||||||
|
// Therefore, here we test Equals on both the source and destination objects.
|
||||||
|
// However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)).
|
||||||
|
if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i]))
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
for (j = 1; j < test.Length; j++)
|
for (j = 1; j < test.Length; j++)
|
||||||
if (!src.Data[i+j].Equals(test.Data[j]))
|
if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j])))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (j == test.Length)
|
if (j == test.Length)
|
||||||
{
|
{
|
||||||
index = i;
|
index = i;
|
||||||
|
@ -5467,7 +5476,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_String llGetObjectName()
|
public LSL_String llGetObjectName()
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Region.ScriptEngine.Shared;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Region.ScriptEngine.Shared.Api;
|
||||||
|
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
|
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||||
|
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||||
|
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
|
||||||
|
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Shared.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class LSL_ApiListTests
|
||||||
|
{
|
||||||
|
private LSL_Api m_lslApi;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
IConfigSource initConfigSource = new IniConfigSource();
|
||||||
|
IConfig config = initConfigSource.AddConfig("XEngine");
|
||||||
|
config.Set("Enabled", "true");
|
||||||
|
|
||||||
|
Scene scene = new SceneHelpers().SetupScene();
|
||||||
|
SceneObjectPart part = SceneHelpers.AddSceneObject(scene).RootPart;
|
||||||
|
|
||||||
|
XEngine.XEngine engine = new XEngine.XEngine();
|
||||||
|
engine.Initialise(initConfigSource);
|
||||||
|
engine.AddRegion(scene);
|
||||||
|
|
||||||
|
m_lslApi = new LSL_Api();
|
||||||
|
m_lslApi.Initialize(engine, part, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestllListFindList()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
|
||||||
|
LSL_List src = new LSL_List(new LSL_Integer(1), new LSL_Integer(2), new LSL_Integer(3));
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test for a single item that should be found
|
||||||
|
int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_Integer(4)));
|
||||||
|
Assert.That(result, Is.EqualTo(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test for a single item that should be found
|
||||||
|
int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_Integer(2)));
|
||||||
|
Assert.That(result, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test for a constant that should be found
|
||||||
|
int result = m_lslApi.llListFindList(src, new LSL_List(ScriptBaseClass.AGENT));
|
||||||
|
Assert.That(result, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test for a list that should be found
|
||||||
|
int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_Integer(2), new LSL_Integer(3)));
|
||||||
|
Assert.That(result, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test for a single item not in the list
|
||||||
|
int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_Integer(4)));
|
||||||
|
Assert.That(result, Is.EqualTo(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test for something that should not be cast
|
||||||
|
int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_String("4")));
|
||||||
|
Assert.That(result, Is.EqualTo(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test for a list not in the list
|
||||||
|
int result
|
||||||
|
= m_lslApi.llListFindList(
|
||||||
|
src, new LSL_List(new LSL_Integer(2), new LSL_Integer(3), new LSL_Integer(4)));
|
||||||
|
Assert.That(result, Is.EqualTo(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
LSL_List srcWithConstants
|
||||||
|
= new LSL_List(new LSL_Integer(3), ScriptBaseClass.AGENT, ScriptBaseClass.OS_NPC_LAND_AT_TARGET);
|
||||||
|
|
||||||
|
// Test for constants that appears in the source list that should be found
|
||||||
|
int result
|
||||||
|
= m_lslApi.llListFindList(srcWithConstants, new LSL_List(new LSL_Integer(1), new LSL_Integer(2)));
|
||||||
|
|
||||||
|
Assert.That(result, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue