mirror of https://github.com/mono/CppSharp.git
4 changed files with 386 additions and 367 deletions
@ -1,241 +1,242 @@ |
|||||||
using System; |
using Cxxi.Templates; |
||||||
|
using System; |
||||||
using System.Collections.Generic; |
using System.Collections.Generic; |
||||||
using System.IO; |
using System.IO; |
||||||
using System.Text.RegularExpressions; |
using System.Text.RegularExpressions; |
||||||
|
|
||||||
using Cxxi; |
namespace Cxxi |
||||||
using Cxxi.Templates; |
|
||||||
|
|
||||||
public partial class Generator |
|
||||||
{ |
{ |
||||||
public List<ModuleTransform> Transformations { get; set; } |
public partial class Generator |
||||||
|
|
||||||
Library Library; |
|
||||||
Options Options; |
|
||||||
|
|
||||||
public Generator(Library library, Options options) |
|
||||||
{ |
|
||||||
Transformations = new List<ModuleTransform>(); |
|
||||||
|
|
||||||
Library = library; |
|
||||||
Options = options; |
|
||||||
} |
|
||||||
|
|
||||||
public void Process() |
|
||||||
{ |
|
||||||
TransformModule(); |
|
||||||
ProcessModules(); |
|
||||||
} |
|
||||||
|
|
||||||
// Generates the binding code.
|
|
||||||
public void Generate() |
|
||||||
{ |
|
||||||
GenerateModules(); |
|
||||||
} |
|
||||||
|
|
||||||
int UniqueType = 0; |
|
||||||
|
|
||||||
void CleanupText(ref string debugText) |
|
||||||
{ |
{ |
||||||
// Strip off newlines from the debug text.
|
public List<ModuleTransform> Transformations { get; set; } |
||||||
if (String.IsNullOrWhiteSpace(debugText)) |
|
||||||
debugText = String.Empty; |
|
||||||
|
|
||||||
// TODO: Make this transformation in the output.
|
Library Library; |
||||||
debugText = Regex.Replace(debugText, " ( )+", " "); |
Options Options; |
||||||
debugText = Regex.Replace(debugText, "\n", ""); |
|
||||||
} |
|
||||||
|
|
||||||
void ProcessType(Declaration type) |
public Generator(Library library, Options options) |
||||||
{ |
{ |
||||||
// If after all the transformations the type still does
|
Transformations = new List<ModuleTransform>(); |
||||||
// not have a name, then generate one.
|
|
||||||
|
|
||||||
if (String.IsNullOrWhiteSpace(type.Name)) |
Library = library; |
||||||
type.Name = String.Format("UnnamedType{0}", UniqueType++); |
Options = options; |
||||||
|
} |
||||||
|
|
||||||
CleanupText(ref type.DebugText); |
public void Process() |
||||||
} |
{ |
||||||
|
TransformModule(); |
||||||
|
ProcessModules(); |
||||||
|
} |
||||||
|
|
||||||
void ProcessTypes<T>(List<T> types) where T : Declaration |
// Generates the binding code.
|
||||||
{ |
public void Generate() |
||||||
foreach (T type in types) |
{ |
||||||
ProcessType(type); |
GenerateModules(); |
||||||
} |
} |
||||||
|
|
||||||
void ProcessClasses(List<Class> Classes) |
int UniqueType = 0; |
||||||
{ |
|
||||||
ProcessTypes(Classes); |
|
||||||
|
|
||||||
foreach (var @class in Classes) |
void CleanupText(ref string debugText) |
||||||
ProcessTypes(@class.Fields); |
{ |
||||||
} |
// Strip off newlines from the debug text.
|
||||||
|
if (String.IsNullOrWhiteSpace(debugText)) |
||||||
|
debugText = String.Empty; |
||||||
|
|
||||||
void ProcessFunctions(List<Function> Functions) |
// TODO: Make this transformation in the output.
|
||||||
{ |
debugText = Regex.Replace(debugText, " ( )+", " "); |
||||||
ProcessTypes(Functions); |
debugText = Regex.Replace(debugText, "\n", ""); |
||||||
|
} |
||||||
|
|
||||||
foreach (var function in Functions) |
void ProcessType(Declaration type) |
||||||
{ |
{ |
||||||
if (function.ReturnType == null) |
// If after all the transformations the type still does
|
||||||
{ |
// not have a name, then generate one.
|
||||||
// Ignore and warn about unknown types.
|
|
||||||
function.Ignore = true; |
|
||||||
|
|
||||||
var s = "Function '{0}' was ignored due to unknown return type..."; |
|
||||||
Console.WriteLine( String.Format(s, function.Name) ); |
|
||||||
} |
|
||||||
|
|
||||||
ProcessTypes(function.Parameters); |
if (String.IsNullOrWhiteSpace(type.Name)) |
||||||
} |
type.Name = String.Format("UnnamedType{0}", UniqueType++); |
||||||
} |
|
||||||
|
|
||||||
void ProcessModules() |
CleanupText(ref type.DebugText); |
||||||
{ |
} |
||||||
if (String.IsNullOrEmpty(Library.Name)) |
|
||||||
Library.Name = ""; |
|
||||||
|
|
||||||
// Process everything in the global namespace for now.
|
void ProcessTypes<T>(List<T> types) where T : Declaration |
||||||
foreach (var module in Library.Modules) |
|
||||||
{ |
{ |
||||||
ProcessNamespace(module); |
foreach (T type in types) |
||||||
|
ProcessType(type); |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
void ProcessNamespace(Namespace @namespace) |
void ProcessClasses(List<Class> Classes) |
||||||
{ |
{ |
||||||
ProcessTypes(@namespace.Enums); |
ProcessTypes(Classes); |
||||||
ProcessFunctions(@namespace.Functions); |
|
||||||
ProcessClasses(@namespace.Classes); |
|
||||||
} |
|
||||||
|
|
||||||
void TransformModule() |
foreach (var @class in Classes) |
||||||
{ |
ProcessTypes(@class.Fields); |
||||||
if (String.IsNullOrEmpty(Library.Name)) |
} |
||||||
Library.Name = ""; |
|
||||||
|
|
||||||
// Process everything in the global namespace for now.
|
void ProcessFunctions(List<Function> Functions) |
||||||
foreach (var module in Library.Modules) |
|
||||||
{ |
{ |
||||||
foreach (Enumeration @enum in module.Enums) |
ProcessTypes(Functions); |
||||||
TransformEnum(@enum); |
|
||||||
|
|
||||||
foreach (Function function in module.Functions) |
foreach (var function in Functions) |
||||||
TransformFunction(function); |
{ |
||||||
|
if (function.ReturnType == null) |
||||||
|
{ |
||||||
|
// Ignore and warn about unknown types.
|
||||||
|
function.Ignore = true; |
||||||
|
|
||||||
foreach (Class @class in module.Classes) |
var s = "Function '{0}' was ignored due to unknown return type..."; |
||||||
TransformClass(@class); |
Console.WriteLine(String.Format(s, function.Name)); |
||||||
|
} |
||||||
|
|
||||||
|
ProcessTypes(function.Parameters); |
||||||
|
} |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
void TransformType(Declaration type) |
void ProcessModules() |
||||||
{ |
{ |
||||||
foreach (var transform in Transformations) |
if (String.IsNullOrEmpty(Library.Name)) |
||||||
transform.ProcessDeclaration(type); |
Library.Name = ""; |
||||||
} |
|
||||||
|
|
||||||
void TransformClass(Class @class) |
// Process everything in the global namespace for now.
|
||||||
{ |
foreach (var module in Library.Modules) |
||||||
TransformType(@class); |
{ |
||||||
|
ProcessNamespace(module); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
foreach (var field in @class.Fields) |
void ProcessNamespace(Namespace @namespace) |
||||||
TransformType(field); |
{ |
||||||
} |
ProcessTypes(@namespace.Enums); |
||||||
|
ProcessFunctions(@namespace.Functions); |
||||||
|
ProcessClasses(@namespace.Classes); |
||||||
|
} |
||||||
|
|
||||||
void TransformFunction(Function function) |
void TransformModule() |
||||||
{ |
{ |
||||||
TransformType(function); |
if (String.IsNullOrEmpty(Library.Name)) |
||||||
|
Library.Name = ""; |
||||||
|
|
||||||
foreach (var param in function.Parameters) |
// Process everything in the global namespace for now.
|
||||||
TransformType(param); |
foreach (var module in Library.Modules) |
||||||
} |
{ |
||||||
|
foreach (Enumeration @enum in module.Enums) |
||||||
|
TransformEnum(@enum); |
||||||
|
|
||||||
|
foreach (Function function in module.Functions) |
||||||
|
TransformFunction(function); |
||||||
|
|
||||||
void TransformEnum(Enumeration @enum) |
foreach (Class @class in module.Classes) |
||||||
{ |
TransformClass(@class); |
||||||
TransformType(@enum); |
} |
||||||
|
} |
||||||
|
|
||||||
foreach (var transform in Transformations) |
void TransformType(Declaration type) |
||||||
{ |
{ |
||||||
foreach (var item in @enum.Items) |
foreach (var transform in Transformations) |
||||||
transform.ProcessEnumItem(item); |
transform.ProcessDeclaration(type); |
||||||
} |
} |
||||||
|
|
||||||
// If the enumeration only has power of two values, assume it's
|
void TransformClass(Class @class) |
||||||
// a flags enum.
|
{ |
||||||
|
TransformType(@class); |
||||||
|
|
||||||
bool isFlags = true; |
foreach (var field in @class.Fields) |
||||||
bool hasBigRange = false; |
TransformType(field); |
||||||
|
} |
||||||
|
|
||||||
foreach (var item in @enum.Items) |
void TransformFunction(Function function) |
||||||
{ |
{ |
||||||
if (item.Name.Length >= 1 && Char.IsDigit(item.Name[0])) |
TransformType(function); |
||||||
item.Name = String.Format("_{0}", item.Name); |
|
||||||
|
|
||||||
long value = item.Value; |
foreach (var param in function.Parameters) |
||||||
if (value >= 4) |
TransformType(param); |
||||||
hasBigRange = true; |
|
||||||
if (value <= 1 || value.IsPowerOfTwo()) |
|
||||||
continue; |
|
||||||
isFlags = false; |
|
||||||
} |
} |
||||||
|
|
||||||
// Only apply this heuristic if there are enough values to have a
|
|
||||||
// reasonable chance that it really is a bitfield.
|
|
||||||
|
|
||||||
if (isFlags && hasBigRange) |
void TransformEnum(Enumeration @enum) |
||||||
{ |
{ |
||||||
@enum.Modifiers |= Enumeration.EnumModifiers.Flags; |
TransformType(@enum); |
||||||
} |
|
||||||
|
|
||||||
// If we still do not have a valid name, then try to guess one
|
foreach (var transform in Transformations) |
||||||
// based on the enum value names.
|
{ |
||||||
|
foreach (var item in @enum.Items) |
||||||
|
transform.ProcessEnumItem(item); |
||||||
|
} |
||||||
|
|
||||||
if (!String.IsNullOrWhiteSpace(@enum.Name)) |
// If the enumeration only has power of two values, assume it's
|
||||||
return; |
// a flags enum.
|
||||||
|
|
||||||
var names = new List<string>(); |
bool isFlags = true; |
||||||
|
bool hasBigRange = false; |
||||||
foreach (var item in @enum.Items) |
|
||||||
names.Add(item.Name); |
|
||||||
|
|
||||||
var prefix = names.ToArray().CommonPrefix(); |
foreach (var item in @enum.Items) |
||||||
|
{ |
||||||
|
if (item.Name.Length >= 1 && Char.IsDigit(item.Name[0])) |
||||||
|
item.Name = String.Format("_{0}", item.Name); |
||||||
|
|
||||||
|
long value = item.Value; |
||||||
|
if (value >= 4) |
||||||
|
hasBigRange = true; |
||||||
|
if (value <= 1 || value.IsPowerOfTwo()) |
||||||
|
continue; |
||||||
|
isFlags = false; |
||||||
|
} |
||||||
|
|
||||||
// Try a simple heuristic to make sure we end up with a valid name.
|
// Only apply this heuristic if there are enough values to have a
|
||||||
if (prefix.Length >= 3) |
// reasonable chance that it really is a bitfield.
|
||||||
{ |
|
||||||
prefix = prefix.Trim().Trim(new char[] { '_' }); |
if (isFlags && hasBigRange) |
||||||
@enum.Name = prefix; |
{ |
||||||
|
@enum.Modifiers |= Enumeration.EnumModifiers.Flags; |
||||||
|
} |
||||||
|
|
||||||
|
// If we still do not have a valid name, then try to guess one
|
||||||
|
// based on the enum value names.
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(@enum.Name)) |
||||||
|
return; |
||||||
|
|
||||||
|
var names = new List<string>(); |
||||||
|
|
||||||
|
foreach (var item in @enum.Items) |
||||||
|
names.Add(item.Name); |
||||||
|
|
||||||
|
var prefix = names.ToArray().CommonPrefix(); |
||||||
|
|
||||||
|
// Try a simple heuristic to make sure we end up with a valid name.
|
||||||
|
if (prefix.Length >= 3) |
||||||
|
{ |
||||||
|
prefix = prefix.Trim().Trim(new char[] { '_' }); |
||||||
|
@enum.Name = prefix; |
||||||
|
} |
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
void GenerateModules() |
void GenerateModules() |
||||||
{ |
|
||||||
// Process everything in the global namespace for now.
|
|
||||||
foreach (var module in Library.Modules) |
|
||||||
{ |
{ |
||||||
if (module.Ignore || !module.HasDeclarations) |
// Process everything in the global namespace for now.
|
||||||
continue; |
foreach (var module in Library.Modules) |
||||||
|
{ |
||||||
|
if (module.Ignore || !module.HasDeclarations) |
||||||
|
continue; |
||||||
|
|
||||||
// Generate the code from templates.
|
// Generate the code from templates.
|
||||||
var template = new CSharpModule(); |
var template = new CSharpModule(); |
||||||
template.Library = Library; |
template.Library = Library; |
||||||
template.Options = Options; |
template.Options = Options; |
||||||
template.Module = module; |
template.Module = module; |
||||||
|
|
||||||
if (!Directory.Exists(Options.OutputDir)) |
if (!Directory.Exists(Options.OutputDir)) |
||||||
Directory.CreateDirectory(Options.OutputDir); |
Directory.CreateDirectory(Options.OutputDir); |
||||||
|
|
||||||
var file = Path.GetFileNameWithoutExtension(module.FileName) + ".cs"; |
var file = Path.GetFileNameWithoutExtension(module.FileName) + ".cs"; |
||||||
var path = Path.Combine(Options.OutputDir, file); |
var path = Path.Combine(Options.OutputDir, file); |
||||||
|
|
||||||
// Normalize path.
|
// Normalize path.
|
||||||
path = Path.GetFullPath(path); |
path = Path.GetFullPath(path); |
||||||
|
|
||||||
string code = template.TransformText(); |
string code = template.TransformText(); |
||||||
|
|
||||||
Console.WriteLine(" Generated '" + file + "'."); |
Console.WriteLine(" Generated '" + file + "'."); |
||||||
File.WriteAllText(path, code); |
File.WriteAllText(path, code); |
||||||
|
} |
||||||
} |
} |
||||||
} |
} |
||||||
} |
} |
@ -1,262 +1,272 @@ |
|||||||
using Cxxi; |
using System; |
||||||
using System; |
|
||||||
using System.Globalization; |
using System.Globalization; |
||||||
using System.Text.RegularExpressions; |
using System.Text.RegularExpressions; |
||||||
|
|
||||||
/// <summary>
|
namespace Cxxi |
||||||
/// Used to massage the library types into something more .NET friendly.
|
|
||||||
/// </summary>
|
|
||||||
public interface LibraryTransform |
|
||||||
{ |
|
||||||
public void Transform(Generator g); |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Used to provide different types of code transformation on a module
|
|
||||||
/// declarations and types before the code generation process is started.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class ModuleTransform |
|
||||||
{ |
{ |
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes a declaration.
|
/// Used to massage the library types into something more .NET friendly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual bool ProcessDeclaration(Declaration declaration) |
public interface LibraryTransform |
||||||
{ |
{ |
||||||
return false; |
/// <summary>
|
||||||
|
/// Do transformations that should happen before processing here.
|
||||||
|
/// </summary>
|
||||||
|
void Preprocess(Generator g); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Do transformations that should happen after processing here.
|
||||||
|
/// </summary>
|
||||||
|
void Postprocess(Generator g); |
||||||
} |
} |
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes an enum item.
|
/// Used to provide different types of code transformation on a module
|
||||||
|
/// declarations and types before the code generation process is started.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual bool ProcessEnumItem(Enumeration.Item item) |
public abstract class ModuleTransform |
||||||
{ |
{ |
||||||
return false; |
/// <summary>
|
||||||
} |
/// Processes a declaration.
|
||||||
} |
/// </summary>
|
||||||
|
public virtual bool ProcessDeclaration(Declaration declaration) |
||||||
/// <summary>
|
{ |
||||||
/// Renames a declaration based on a regular expression pattern.
|
return false; |
||||||
/// </summary>
|
} |
||||||
public class RenameTransform : ModuleTransform |
|
||||||
{ |
|
||||||
public string Pattern; |
|
||||||
public string Replacement; |
|
||||||
|
|
||||||
public RenameTransform(string pattern, string replacement) |
/// <summary>
|
||||||
{ |
/// Processes an enum item.
|
||||||
Pattern = pattern; |
/// </summary>
|
||||||
Replacement = replacement; |
public virtual bool ProcessEnumItem(Enumeration.Item item) |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
} |
} |
||||||
|
|
||||||
public override bool ProcessDeclaration(Declaration type) |
/// <summary>
|
||||||
|
/// Renames a declaration based on a regular expression pattern.
|
||||||
|
/// </summary>
|
||||||
|
public class RenameTransform : ModuleTransform |
||||||
{ |
{ |
||||||
return Rename(ref type.Name); |
public string Pattern; |
||||||
} |
public string Replacement; |
||||||
|
|
||||||
public override bool ProcessEnumItem(Enumeration.Item item) |
public RenameTransform(string pattern, string replacement) |
||||||
{ |
{ |
||||||
return Rename(ref item.Name); |
Pattern = pattern; |
||||||
} |
Replacement = replacement; |
||||||
|
} |
||||||
|
|
||||||
bool Rename(ref string name) |
public override bool ProcessDeclaration(Declaration type) |
||||||
{ |
{ |
||||||
string replace = Regex.Replace(name, Pattern, Replacement); |
return Rename(ref type.Name); |
||||||
|
} |
||||||
|
|
||||||
if (!name.Equals(replace)) |
public override bool ProcessEnumItem(Enumeration.Item item) |
||||||
{ |
{ |
||||||
name = replace; |
return Rename(ref item.Name); |
||||||
return true; |
|
||||||
} |
} |
||||||
|
|
||||||
return false; |
bool Rename(ref string name) |
||||||
} |
{ |
||||||
} |
string replace = Regex.Replace(name, Pattern, Replacement); |
||||||
|
|
||||||
public partial class Generator |
if (!name.Equals(replace)) |
||||||
{ |
{ |
||||||
#region Transform Operations
|
name = replace; |
||||||
|
return true; |
||||||
public void RemovePrefix(string prefix) |
} |
||||||
{ |
|
||||||
Transformations.Add(new RenameTransform(prefix, String.Empty)); |
return false; |
||||||
|
} |
||||||
} |
} |
||||||
|
|
||||||
public void RemoveType(Declaration type) |
public partial class Generator |
||||||
{ |
{ |
||||||
|
#region Transform Operations
|
||||||
|
|
||||||
} |
public void RemovePrefix(string prefix) |
||||||
|
{ |
||||||
#endregion
|
Transformations.Add(new RenameTransform(prefix, String.Empty)); |
||||||
|
} |
||||||
#region Enum Helpers
|
|
||||||
|
|
||||||
public Enumeration FindEnum(string name) |
public void RemoveType(Declaration type) |
||||||
{ |
|
||||||
foreach (var module in Library.Modules) |
|
||||||
{ |
{ |
||||||
var @enum = module.FindEnum(name); |
|
||||||
if (@enum != null) |
|
||||||
return @enum; |
|
||||||
} |
} |
||||||
|
|
||||||
return null; |
#endregion
|
||||||
} |
|
||||||
|
|
||||||
public void IgnoreEnumWithMatchingItem(string Pattern) |
#region Enum Helpers
|
||||||
{ |
|
||||||
Enumeration @enum = GetEnumWithMatchingItem(Pattern); |
|
||||||
if (@enum != null) |
|
||||||
@enum.Ignore = true; |
|
||||||
} |
|
||||||
|
|
||||||
public void SetNameOfEnumWithMatchingItem(string Pattern, string Name) |
public Enumeration FindEnum(string name) |
||||||
{ |
{ |
||||||
Enumeration @enum = GetEnumWithMatchingItem(Pattern); |
foreach (var module in Library.Modules) |
||||||
if (@enum != null) |
{ |
||||||
@enum.Name = Name; |
var @enum = module.FindEnum(name); |
||||||
} |
if (@enum != null) |
||||||
|
return @enum; |
||||||
|
} |
||||||
|
|
||||||
public void SetNameOfEnumWithName(string enumName, string name) |
return null; |
||||||
{ |
} |
||||||
Enumeration @enum = FindEnum(enumName); |
|
||||||
if (@enum != null) |
|
||||||
@enum.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
public Enumeration GetEnumWithMatchingItem(string Pattern) |
public void IgnoreEnumWithMatchingItem(string Pattern) |
||||||
{ |
|
||||||
foreach (var module in Library.Modules) |
|
||||||
{ |
{ |
||||||
Enumeration @enum = module.FindEnumWithItem(Pattern); |
Enumeration @enum = GetEnumWithMatchingItem(Pattern); |
||||||
if (@enum == null) continue; |
if (@enum != null) |
||||||
return @enum; |
@enum.Ignore = true; |
||||||
} |
} |
||||||
|
|
||||||
return null; |
public void SetNameOfEnumWithMatchingItem(string Pattern, string Name) |
||||||
} |
{ |
||||||
|
Enumeration @enum = GetEnumWithMatchingItem(Pattern); |
||||||
|
if (@enum != null) |
||||||
|
@enum.Name = Name; |
||||||
|
} |
||||||
|
|
||||||
public Enumeration.Item GenerateEnumItemFromMacro(MacroDefine macro) |
public void SetNameOfEnumWithName(string enumName, string name) |
||||||
{ |
{ |
||||||
var item = new Enumeration.Item(); |
Enumeration @enum = FindEnum(enumName); |
||||||
item.Name = macro.Name; |
if (@enum != null) |
||||||
item.Expression = macro.Expression; |
@enum.Name = name; |
||||||
item.Value = ParseMacroExpression(macro.Expression); |
} |
||||||
|
|
||||||
return item; |
public Enumeration GetEnumWithMatchingItem(string Pattern) |
||||||
} |
{ |
||||||
|
foreach (var module in Library.Modules) |
||||||
|
{ |
||||||
|
Enumeration @enum = module.FindEnumWithItem(Pattern); |
||||||
|
if (@enum == null) continue; |
||||||
|
return @enum; |
||||||
|
} |
||||||
|
|
||||||
public Enumeration GenerateEnumFromMacros(string name, params string[] macros) |
return null; |
||||||
{ |
} |
||||||
Enumeration @enum = new Enumeration(); |
|
||||||
@enum.Name = name; |
public Enumeration.Item GenerateEnumItemFromMacro(MacroDefine macro) |
||||||
|
{ |
||||||
|
var item = new Enumeration.Item(); |
||||||
|
item.Name = macro.Name; |
||||||
|
item.Expression = macro.Expression; |
||||||
|
item.Value = ParseMacroExpression(macro.Expression); |
||||||
|
|
||||||
var pattern = String.Join("|", macros); |
return item; |
||||||
var regex = new Regex(pattern); |
} |
||||||
|
|
||||||
foreach (var module in Library.Modules) |
public Enumeration GenerateEnumFromMacros(string name, params string[] macros) |
||||||
{ |
{ |
||||||
foreach (var macro in module.Macros) |
Enumeration @enum = new Enumeration(); |
||||||
{ |
@enum.Name = name; |
||||||
var match = regex.Match(macro.Name); |
|
||||||
if (!match.Success) continue; |
|
||||||
|
|
||||||
var item = GenerateEnumItemFromMacro(macro); |
var pattern = String.Join("|", macros); |
||||||
@enum.AddItem(item); |
var regex = new Regex(pattern); |
||||||
} |
|
||||||
|
|
||||||
if (@enum.Items.Count > 0) |
foreach (var module in Library.Modules) |
||||||
{ |
{ |
||||||
module.Enums.Add(@enum); |
foreach (var macro in module.Macros) |
||||||
break; |
{ |
||||||
|
var match = regex.Match(macro.Name); |
||||||
|
if (!match.Success) continue; |
||||||
|
|
||||||
|
var item = GenerateEnumItemFromMacro(macro); |
||||||
|
@enum.AddItem(item); |
||||||
|
} |
||||||
|
|
||||||
|
if (@enum.Items.Count > 0) |
||||||
|
{ |
||||||
|
module.Enums.Add(@enum); |
||||||
|
break; |
||||||
|
} |
||||||
} |
} |
||||||
|
|
||||||
|
return @enum; |
||||||
} |
} |
||||||
|
|
||||||
return @enum; |
#endregion
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
#region Class Helpers
|
||||||
|
|
||||||
#region Class Helpers
|
public Class FindClass(string name) |
||||||
|
{ |
||||||
|
foreach (var module in Library.Modules) |
||||||
|
{ |
||||||
|
var @class = module.FindClass(name); |
||||||
|
if (@class != null) |
||||||
|
return @class; |
||||||
|
} |
||||||
|
|
||||||
public Class FindClass(string name) |
return null; |
||||||
{ |
} |
||||||
foreach (var module in Library.Modules) |
|
||||||
|
public void SetNameOfClassWithName(string className, string name) |
||||||
{ |
{ |
||||||
var @class = module.FindClass(name); |
Class @class = FindClass(className); |
||||||
if (@class != null) |
if (@class != null) |
||||||
return @class; |
@class.Name = name; |
||||||
} |
} |
||||||
|
|
||||||
return null; |
#endregion
|
||||||
} |
|
||||||
|
|
||||||
public void SetNameOfClassWithName(string className, string name) |
#region Function Helpers
|
||||||
{ |
|
||||||
Class @class = FindClass(className); |
|
||||||
if (@class != null) |
|
||||||
@class.Name = name; |
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
public Function FindFunction(string name) |
||||||
|
{ |
||||||
|
foreach (var module in Library.Modules) |
||||||
|
{ |
||||||
|
var function = module.FindFunction(name); |
||||||
|
if (function != null) |
||||||
|
return function; |
||||||
|
} |
||||||
|
|
||||||
#region Function Helpers
|
return null; |
||||||
|
} |
||||||
|
|
||||||
public Function FindFunction(string name) |
public void IgnoreFunctionWithName(string name) |
||||||
{ |
|
||||||
foreach (var module in Library.Modules) |
|
||||||
{ |
{ |
||||||
var function = module.FindFunction(name); |
Function function = FindFunction(name); |
||||||
if (function != null) |
if (function != null) |
||||||
return function; |
function.Ignore = true; |
||||||
} |
} |
||||||
|
|
||||||
return null; |
#endregion
|
||||||
} |
|
||||||
|
|
||||||
public void IgnoreFunctionWithName(string name) |
|
||||||
{ |
|
||||||
Function function = FindFunction(name); |
|
||||||
if (function != null) |
|
||||||
function.Ignore = true; |
|
||||||
} |
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Module Helpers
|
#region Module Helpers
|
||||||
|
|
||||||
public Module IgnoreModuleWithName(string Pattern) |
public Module IgnoreModuleWithName(string Pattern) |
||||||
{ |
{ |
||||||
Module module = Library.Modules.Find( |
Module module = Library.Modules.Find( |
||||||
m => Regex.Match(m.FilePath, Pattern).Success); |
m => Regex.Match(m.FilePath, Pattern).Success); |
||||||
|
|
||||||
if (module != null) |
if (module != null) |
||||||
module.Ignore = true; |
module.Ignore = true; |
||||||
|
|
||||||
return module; |
return module; |
||||||
} |
} |
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
static bool ParseToNumber(string num, out long val) |
static bool ParseToNumber(string num, out long val) |
||||||
{ |
|
||||||
if (num.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase)) |
|
||||||
{ |
{ |
||||||
num = num.Substring(2); |
if (num.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase)) |
||||||
|
{ |
||||||
|
num = num.Substring(2); |
||||||
|
|
||||||
return long.TryParse(num, NumberStyles.HexNumber, |
return long.TryParse(num, NumberStyles.HexNumber, |
||||||
CultureInfo.CurrentCulture, out val); |
CultureInfo.CurrentCulture, out val); |
||||||
|
} |
||||||
|
|
||||||
|
return long.TryParse(num, out val); |
||||||
} |
} |
||||||
|
|
||||||
return long.TryParse(num, out val); |
static long ParseMacroExpression(string Expression) |
||||||
} |
{ |
||||||
|
long val; |
||||||
|
if (ParseToNumber(Expression, out val)) |
||||||
|
return val; |
||||||
|
// TODO: Handle string expressions
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
static long ParseMacroExpression(string Expression) |
|
||||||
{ |
|
||||||
long val; |
|
||||||
if (ParseToNumber(Expression, out val)) |
|
||||||
return val; |
|
||||||
// TODO: Handle string expressions
|
|
||||||
return 0; |
|
||||||
} |
} |
||||||
|
|
||||||
} |
} |
Loading…
Reference in new issue