/// <summary> /// Add a known type to the list. Args is (.net type/cpp type) /// </summary> /// <param name="typeName"></param> public static void AddMethod(string typeName, string methodName, string cppMethodName, Tuple <string, string>[] args = null, string[] includeFiles = null) { var kt = new KnownTypeInfo() { Name = typeName }; var ourArgs = new KnownTypeInfo.MechodArg[0]; if (args != null) { ourArgs = (from t in args select new KnownTypeInfo.MechodArg() { Type = t.Item1, CPPType = t.Item2 }).ToArray(); } var incfiles = includeFiles; if (incfiles == null) { incfiles = new string[0]; } kt.Methods = new KnownTypeInfo.MethodInfo[] { new KnownTypeInfo.MethodInfo() { Name = methodName, CPPName = cppMethodName, Arguments = ourArgs, IncludeFiles = incfiles } }; gSetTypes.Add(kt); }
/// <summary> /// Merge a type in with another type we already have. /// </summary> /// <param name="kt"></param> private void Merge(KnownTypeInfo kt) { Init(); var already = (from k in _knownTypes where k.Name == kt.Name select k).FirstOrDefault(); if (already == null) { _knownTypes.Add(kt); } else { List <KnownTypeInfo.MethodInfo> methods = new List <KnownTypeInfo.MethodInfo>(already.Methods); methods.AddRange(kt.Methods); already.Methods = methods.ToArray(); } }
/// <summary> /// Parse a stream from a file (or whatever) for function definitions and add them. Don't supersede ones that are already there, but /// allow duplicates. /// </summary> /// <param name="stringReader"></param> internal void Parse(TextReader stringReader) { /// /// Get the "good" lines /// var goodLines = from l in ReadLinesAsIterator(stringReader) let ltrm = l.Trim() where !ltrm.StartsWith("#") && !string.IsNullOrWhiteSpace(ltrm) select ltrm; /// /// Is the format good enough that we can split things up? /// Regex funcFinder = new Regex("(?<class>[^\\s]+)\\s+(?<netfunc>[^\\s\\(]+)\\s*\\((?<netargs>[^\\)]+)\\)\\s*=>\\s*(?<cppfunc>[^\\s\\(]+)\\s*\\((?<cppargs>[^\\)]+)\\)"); string[] includfiles = new string[0]; foreach (var line in goodLines) { if (line.StartsWith("include:")) { var files = from l in line.Substring(8).Split(' ') let lstuff = l.Trim() where !string.IsNullOrWhiteSpace(lstuff) select l; includfiles = files.ToArray(); continue; } var m = funcFinder.Match(line); if (!m.Success) { throw new InvalidDataException("Unable to interpret line '" + line + "'"); } var netargs = ParseArgumentListTokens(m.Groups["netargs"].Value); var cppargs = ParseArgumentListTokens(m.Groups["cppargs"].Value); if (cppargs.Length != netargs.Length) { throw new InvalidDataException("Arguments for cpp and net are not the same in line '" + line + "'"); } /// /// Finally, ready to create the mapping! /// var kt = new KnownTypeInfo() { Name = m.Groups["class"].Value, Methods = new KnownTypeInfo.MethodInfo[] { new KnownTypeInfo.MethodInfo() { Name = m.Groups["netfunc"].Value, CPPName = m.Groups["cppfunc"].Value, Arguments = (from a in netargs.Zip(cppargs, (n, c) => new KnownTypeInfo.MechodArg() { CPPType = c, Type = n }) select a).ToArray(), IncludeFiles = includfiles } } }; Merge(kt); } }
/// <summary> /// Merge a type in with another type we already have. /// </summary> /// <param name="kt"></param> private void Merge(KnownTypeInfo kt) { Init(); var already = (from k in _knownTypes where k.Name == kt.Name select k).FirstOrDefault(); if (already == null) { _knownTypes.Add(kt); } else { List<KnownTypeInfo.MethodInfo> methods = new List<KnownTypeInfo.MethodInfo>(already.Methods); methods.AddRange(kt.Methods); already.Methods = methods.ToArray(); } }
/// <summary> /// Parse a stream from a file (or whatever) for function definitions and add them. Don't supersede ones that are already there, but /// allow duplicates. /// </summary> /// <param name="stringReader"></param> internal void Parse(TextReader stringReader) { /// /// Get the "good" lines /// var goodLines = from l in ReadLinesAsIterator(stringReader) let ltrm = l.Trim() where !ltrm.StartsWith("#") && !string.IsNullOrWhiteSpace(ltrm) select ltrm; /// /// Is the format good enough that we can split things up? /// Regex funcFinder = new Regex("(?<class>[^\\s]+)\\s+(?<netfunc>[^\\s\\(]+)\\s*\\((?<netargs>[^\\)]+)\\)\\s*=>\\s*(?<cppfunc>[^\\s\\(]+)\\s*\\((?<cppargs>[^\\)]+)\\)"); string[] includfiles = new string[0]; foreach (var line in goodLines) { if (line.StartsWith("include:")) { var files = from l in line.Substring(8).Split(' ') let lstuff = l.Trim() where !string.IsNullOrWhiteSpace(lstuff) select l; includfiles = files.ToArray(); continue; } var m = funcFinder.Match(line); if (!m.Success) throw new InvalidDataException("Unable to interpret line '" + line + "'"); var netargs = ParseArgumentListTokens(m.Groups["netargs"].Value); var cppargs = ParseArgumentListTokens(m.Groups["cppargs"].Value); if (cppargs.Length != netargs.Length) { throw new InvalidDataException("Arguments for cpp and net are not the same in line '" + line + "'"); } /// /// Finally, ready to create the mapping! /// var kt = new KnownTypeInfo() { Name = m.Groups["class"].Value, Methods = new KnownTypeInfo.MethodInfo[] {new KnownTypeInfo.MethodInfo() { Name = m.Groups["netfunc"].Value, CPPName = m.Groups["cppfunc"].Value, Arguments = (from a in netargs.Zip(cppargs, (n, c) => new KnownTypeInfo.MechodArg() { CPPType = c, Type = n}) select a).ToArray(), IncludeFiles = includfiles } } }; Merge(kt); } }
/// <summary> /// Add a known type to the list. Args is (.net type/cpp type) /// </summary> /// <param name="typeName"></param> public static void AddMethod(string typeName, string methodName, string cppMethodName, Tuple<string, string>[] args = null, string[] includeFiles = null) { var kt = new KnownTypeInfo() { Name = typeName }; var ourArgs = new KnownTypeInfo.MechodArg[0]; if (args != null) ourArgs = (from t in args select new KnownTypeInfo.MechodArg() { Type = t.Item1, CPPType = t.Item2 }).ToArray(); var incfiles = includeFiles; if (incfiles == null) { incfiles = new string[0]; } kt.Methods = new KnownTypeInfo.MethodInfo[] { new KnownTypeInfo.MethodInfo() { Name = methodName, CPPName = cppMethodName, Arguments = ourArgs, IncludeFiles = incfiles } }; gSetTypes.Add(kt); }