2009-02-22 10:43:35 +00:00
|
|
|
|
#region --- License ---
|
|
|
|
|
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
|
|
|
|
* See license.txt for license info
|
|
|
|
|
*/
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2013-11-17 20:27:09 +00:00
|
|
|
|
using System.Linq;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
|
|
|
|
|
namespace Bind.Structures
|
|
|
|
|
{
|
2010-10-13 21:41:06 +00:00
|
|
|
|
class Function : Delegate, IEquatable<Function>, IComparable<Function>
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2009-02-28 19:29:34 +00:00
|
|
|
|
#region Fields
|
|
|
|
|
|
|
|
|
|
Delegate wrapped_delegate;
|
|
|
|
|
|
|
|
|
|
#endregion
|
2014-03-31 15:09:30 +00:00
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
|
#region --- Constructors ---
|
|
|
|
|
|
|
|
|
|
public Function(Delegate d)
|
|
|
|
|
: base(d)
|
|
|
|
|
{
|
2013-10-26 23:30:45 +00:00
|
|
|
|
TrimmedName = Name = d.Name;
|
2009-03-21 21:44:07 +00:00
|
|
|
|
Body = new FunctionBody();
|
2009-02-28 19:29:34 +00:00
|
|
|
|
WrappedDelegate = d;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-03-21 21:44:07 +00:00
|
|
|
|
public Function(Function f)
|
2009-10-27 22:37:05 +00:00
|
|
|
|
: this(f.WrappedDelegate)
|
2009-03-21 21:44:07 +00:00
|
|
|
|
{
|
2009-10-27 22:37:05 +00:00
|
|
|
|
Parameters = new ParameterCollection(f.Parameters);
|
|
|
|
|
ReturnType = new Type(f.ReturnType);
|
2013-10-26 23:30:45 +00:00
|
|
|
|
TrimmedName = f.TrimmedName;
|
2013-12-08 15:20:04 +00:00
|
|
|
|
Obsolete = f.Obsolete;
|
2013-12-15 21:01:45 +00:00
|
|
|
|
CLSCompliant = f.CLSCompliant;
|
2014-03-31 15:09:30 +00:00
|
|
|
|
Documentation = f.Documentation;
|
2009-10-27 22:37:05 +00:00
|
|
|
|
Body.AddRange(f.Body);
|
2009-03-21 21:44:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2009-03-25 17:55:37 +00:00
|
|
|
|
#region public Delegate WrappedDelegate
|
|
|
|
|
|
2009-02-28 19:29:34 +00:00
|
|
|
|
public Delegate WrappedDelegate
|
|
|
|
|
{
|
|
|
|
|
get { return wrapped_delegate; }
|
|
|
|
|
set { wrapped_delegate = value; }
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-25 17:55:37 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2009-02-28 19:29:34 +00:00
|
|
|
|
#region public void TurnVoidPointersToIntPtr()
|
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
|
public void TurnVoidPointersToIntPtr()
|
|
|
|
|
{
|
2009-08-25 15:59:57 +00:00
|
|
|
|
foreach (Parameter p in Parameters)
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2009-07-15 22:33:26 +00:00
|
|
|
|
if (p.Pointer != 0 && p.CurrentType == "void")
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
|
|
|
|
p.CurrentType = "IntPtr";
|
2009-07-15 22:33:26 +00:00
|
|
|
|
p.Pointer = 0;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-28 19:29:34 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
|
#region public override bool Unsafe
|
|
|
|
|
|
|
|
|
|
public override bool Unsafe
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return base.Unsafe;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public FunctionBody Body
|
|
|
|
|
|
|
|
|
|
FunctionBody _body;
|
|
|
|
|
|
|
|
|
|
public FunctionBody Body
|
|
|
|
|
{
|
|
|
|
|
get { return _body; }
|
|
|
|
|
set { _body = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public string TrimmedName
|
|
|
|
|
|
2013-10-26 23:30:45 +00:00
|
|
|
|
public string TrimmedName { get; set; }
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2014-03-31 15:09:30 +00:00
|
|
|
|
#region Documentation
|
|
|
|
|
|
|
|
|
|
public Documentation Documentation { get; set; }
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2013-11-01 08:17:34 +00:00
|
|
|
|
#region ToString
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
2013-11-03 19:34:18 +00:00
|
|
|
|
return String.Format("{0} {1}{2}",
|
2013-11-01 08:17:34 +00:00
|
|
|
|
ReturnType,
|
|
|
|
|
TrimmedName,
|
|
|
|
|
Parameters);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region IEquatable<Function> Members
|
|
|
|
|
|
|
|
|
|
public bool Equals(Function other)
|
|
|
|
|
{
|
2013-11-01 08:17:34 +00:00
|
|
|
|
bool result =
|
2009-08-25 15:59:57 +00:00
|
|
|
|
!String.IsNullOrEmpty(TrimmedName) && !String.IsNullOrEmpty(other.TrimmedName) &&
|
2013-11-01 08:17:34 +00:00
|
|
|
|
TrimmedName.Equals(other.TrimmedName) &&
|
|
|
|
|
Parameters.Equals(other.Parameters);
|
|
|
|
|
return result;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2009-05-30 15:28:52 +00:00
|
|
|
|
#region IComparable<Function> Members
|
|
|
|
|
|
|
|
|
|
public int CompareTo(Function other)
|
|
|
|
|
{
|
2009-08-11 14:06:40 +00:00
|
|
|
|
int ret = Name.CompareTo(other.Name);
|
|
|
|
|
if (ret == 0)
|
2009-11-17 09:26:05 +00:00
|
|
|
|
ret = Parameters.CompareTo(other.Parameters);
|
2009-08-11 14:06:40 +00:00
|
|
|
|
if (ret == 0)
|
2009-11-17 09:26:05 +00:00
|
|
|
|
ret = ReturnType.CompareTo(other.ReturnType);
|
2009-08-11 14:06:40 +00:00
|
|
|
|
return ret;
|
2009-05-30 15:28:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region class FunctionBody : List<string>
|
|
|
|
|
|
|
|
|
|
public class FunctionBody : List<string>
|
|
|
|
|
{
|
|
|
|
|
public FunctionBody()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public FunctionBody(FunctionBody fb)
|
|
|
|
|
{
|
|
|
|
|
foreach (string s in fb)
|
|
|
|
|
{
|
2009-08-25 15:59:57 +00:00
|
|
|
|
Add(s);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string indent = "";
|
|
|
|
|
|
|
|
|
|
public void Indent()
|
|
|
|
|
{
|
|
|
|
|
indent += " ";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Unindent()
|
|
|
|
|
{
|
2013-11-01 08:17:34 +00:00
|
|
|
|
if (indent.Length > 4)
|
2009-02-22 10:43:35 +00:00
|
|
|
|
indent = indent.Substring(4);
|
2013-11-01 08:17:34 +00:00
|
|
|
|
else
|
|
|
|
|
indent = String.Empty;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
new public void Add(string s)
|
|
|
|
|
{
|
2013-11-01 08:17:34 +00:00
|
|
|
|
base.Add(indent + s.TrimEnd('\r', '\n'));
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
new public void AddRange(IEnumerable<string> collection)
|
|
|
|
|
{
|
|
|
|
|
foreach (string t in collection)
|
|
|
|
|
{
|
2009-08-25 15:59:57 +00:00
|
|
|
|
Add(t);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
2009-08-25 15:59:57 +00:00
|
|
|
|
if (Count == 0)
|
2009-02-22 10:43:35 +00:00
|
|
|
|
return String.Empty;
|
|
|
|
|
|
2009-08-25 15:59:57 +00:00
|
|
|
|
StringBuilder sb = new StringBuilder(Count);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
|
|
sb.AppendLine("{");
|
|
|
|
|
foreach (string s in this)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(" " + s);
|
|
|
|
|
}
|
|
|
|
|
sb.Append("}");
|
|
|
|
|
|
|
|
|
|
return sb.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2009-05-29 15:57:01 +00:00
|
|
|
|
#region class FunctionCollection : SortedDictionary<string, List<Function>>
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
2009-05-29 15:57:01 +00:00
|
|
|
|
class FunctionCollection : SortedDictionary<string, List<Function>>
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
|
|
|
|
Regex unsignedFunctions = new Regex(@".+(u[dfisb]v?)", RegexOptions.Compiled);
|
|
|
|
|
|
2013-11-01 08:17:34 +00:00
|
|
|
|
void Add(Function f)
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2009-08-25 15:59:57 +00:00
|
|
|
|
if (!ContainsKey(f.Extension))
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2009-08-25 15:59:57 +00:00
|
|
|
|
Add(f.Extension, new List<Function>());
|
2009-02-22 10:43:35 +00:00
|
|
|
|
this[f.Extension].Add(f);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
this[f.Extension].Add(f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddRange(IEnumerable<Function> functions)
|
|
|
|
|
{
|
|
|
|
|
foreach (Function f in functions)
|
|
|
|
|
{
|
2013-11-01 08:17:34 +00:00
|
|
|
|
AddChecked(f);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2009-03-08 19:19:52 +00:00
|
|
|
|
/// Adds the function to the collection, if a function with the same name and parameters doesn't already exist.
|
2009-02-22 10:43:35 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="f">The Function to add.</param>
|
|
|
|
|
public void AddChecked(Function f)
|
|
|
|
|
{
|
2010-10-13 21:41:06 +00:00
|
|
|
|
if (ContainsKey(f.Extension))
|
2009-02-22 10:43:35 +00:00
|
|
|
|
{
|
2013-11-11 09:01:15 +00:00
|
|
|
|
var list = this[f.Extension];
|
|
|
|
|
int index = list.IndexOf(f);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
if (index == -1)
|
|
|
|
|
{
|
2010-10-13 21:41:06 +00:00
|
|
|
|
Add(f);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
2009-03-08 22:00:13 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2013-11-11 09:01:15 +00:00
|
|
|
|
Function existing = list[index];
|
2013-11-17 20:27:09 +00:00
|
|
|
|
bool replace = existing.Parameters.HasUnsignedParameters &&
|
|
|
|
|
!unsignedFunctions.IsMatch(existing.Name) && unsignedFunctions.IsMatch(f.Name);
|
|
|
|
|
replace |= !existing.Parameters.HasUnsignedParameters &&
|
|
|
|
|
unsignedFunctions.IsMatch(existing.Name) && !unsignedFunctions.IsMatch(f.Name);
|
|
|
|
|
replace |=
|
|
|
|
|
(from p_old in existing.Parameters
|
|
|
|
|
join p_new in f.Parameters on p_old.Name equals p_new.Name
|
|
|
|
|
where p_new.ElementCount == 0 && p_old.ElementCount != 0
|
|
|
|
|
select true)
|
|
|
|
|
.Count() != 0;
|
|
|
|
|
if (replace)
|
2009-03-08 22:00:13 +00:00
|
|
|
|
{
|
2013-11-11 09:01:15 +00:00
|
|
|
|
list[index] = f;
|
2009-03-08 22:00:13 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2010-10-13 21:41:06 +00:00
|
|
|
|
Add(f);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|