add bindings
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
FileVersion = 1
|
||||
|
||||
[Project]
|
||||
Name = "MicroUI.Setup"
|
||||
StartupObject = "MicroUI.Setup.Program"
|
||||
|
||||
[Dependencies]
|
||||
corlib = "*"
|
||||
"Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/Rune/Cpp2Beef.git"}
|
||||
@@ -0,0 +1,8 @@
|
||||
FileVersion = 1
|
||||
|
||||
[Workspace]
|
||||
StartupProject = "MicroUI.Setup"
|
||||
|
||||
[Projects]
|
||||
"MicroUI.Setup" = {Path = "."}
|
||||
"Cpp2Beef.git" = {Git = "https://git.unicon-gmbh.de/Rune/Cpp2Beef.git"}
|
||||
@@ -0,0 +1,254 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Cpp2Beef;
|
||||
using LibClang;
|
||||
|
||||
namespace MicroUI.Setup;
|
||||
|
||||
class MicroUIGenerator : Cpp2BeefGenerator, this(Span<char8*> args)
|
||||
{
|
||||
protected override Span<char8*> Args => args;
|
||||
protected override Flags Flags => .None;
|
||||
|
||||
StreamWriter writer = new .()..Create("../src/MicroUI.bf")..Write("""
|
||||
// This file was generated by Cpp2Beef
|
||||
|
||||
using System;
|
||||
using System.Interop;
|
||||
|
||||
namespace MicroUI;
|
||||
|
||||
|
||||
""") ~ delete _;
|
||||
|
||||
protected override StreamWriter GetWriterForHeader(StringView header)
|
||||
{
|
||||
if (header.EndsWith("microui.h"))
|
||||
return writer;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override Block GetCursorBlock(CXCursor cursor)
|
||||
{
|
||||
if (cursor.kind == .FunctionDecl)
|
||||
return .CustomBlock("MicroUI");
|
||||
return base.GetCursorBlock(cursor);
|
||||
}
|
||||
|
||||
static int enumParentLen;
|
||||
protected override void HandleCursor(CXCursor cursor)
|
||||
{
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .MacroDefinition:
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
if (spelling == "MU_REAL")
|
||||
return;
|
||||
case .EnumDecl:
|
||||
BeginCursor(cursor);
|
||||
Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
{
|
||||
(Self self, int* parentLen) = *(.)client_data;
|
||||
var spelling = GetCursorSpelling!(cursor);
|
||||
Runtime.Assert(spelling.StartsWith("MU_"));
|
||||
spelling.RemoveFromStart(3);
|
||||
spelling = spelling[..<spelling.IndexOf('_')];
|
||||
*parentLen = spelling.Length + 4;
|
||||
self.str.Append("[CRepr] enum mu_");
|
||||
self.str.Append(spelling);
|
||||
return .Break;
|
||||
}, &(this, &enumParentLen));
|
||||
BeginBody!(cursor);
|
||||
Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
{
|
||||
Self self = (.)Internal.UnsafeCastToObject(client_data);
|
||||
self.HandleCursor(cursor);
|
||||
return .Continue;
|
||||
}, Internal.UnsafeCastToPtr(this));
|
||||
enumParentLen = 0;
|
||||
case .StructDecl:
|
||||
if (Clang.GetCursorSemanticParent(cursor).kind == .StructDecl)
|
||||
return;
|
||||
if (Clang.VisitChildren(cursor, (cursor, parent, client_data) =>
|
||||
{
|
||||
return .Break;
|
||||
}, null) == 0) return;
|
||||
BeginCursor(cursor);
|
||||
Record(cursor);
|
||||
return;
|
||||
case .FieldDecl:
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
if (spelling.EndsWith("_stack") || spelling.EndsWith("_list"))
|
||||
{
|
||||
BeginCursor(cursor);
|
||||
str.Append("[CRepr] ");
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("struct { public c_int idx; public c_char[MU_");
|
||||
for (let char in spelling)
|
||||
if (char.IsLetter)
|
||||
str.Append(char.ToUpper);
|
||||
str.Append("_SIZE] items; } ", spelling);
|
||||
str.Append(';');
|
||||
return;
|
||||
}
|
||||
default:
|
||||
}
|
||||
base.HandleCursor(cursor);
|
||||
}
|
||||
|
||||
protected override void GetNameInBindings(CXCursor cursor, String outString)
|
||||
{
|
||||
if (!cGetNameInBindings(cursor, outString))
|
||||
base.GetNameInBindings(cursor, outString);
|
||||
}
|
||||
|
||||
protected override void Type(CXType type, TypeParamMode paramMode = .None)
|
||||
{
|
||||
if (!cType(type, str, currentCursor))
|
||||
base.Type(type, paramMode);
|
||||
}
|
||||
|
||||
public static bool cGetNameInBindings(LibClang.CXCursor cursor, String outString)
|
||||
{
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .FunctionDecl:
|
||||
var spelling = GetCursorSpelling!(cursor);
|
||||
Runtime.Assert(spelling.StartsWith("mu_"));
|
||||
spelling.RemoveFromStart(3);
|
||||
UpperSnakeCase2PascalCase(spelling, outString);
|
||||
case .EnumConstantDecl:
|
||||
var spelling = GetCursorSpelling!(cursor);
|
||||
spelling.RemoveFromStart(enumParentLen);
|
||||
UpperSnakeCase2PascalCase(spelling, outString);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool cType(CXType type, String str, CXCursor cursor)
|
||||
{
|
||||
if (type.kind == .Int && cursor.kind == .FieldDecl || cursor.kind == .ParmDecl)
|
||||
{
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
switch (spelling)
|
||||
{
|
||||
case "key": str.Append("mu_KEY");
|
||||
case "type": str.Append("mu_COMMAND");
|
||||
case "colorid": str.Append("mu_COLOR");
|
||||
case "opt": str.Append("mu_OPT");
|
||||
case "icon": str.Append("mu_ICON");
|
||||
case "btn": str.Append("mu_MOUSE");
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (type.kind == .Int && cursor.kind == .FunctionDecl)
|
||||
{
|
||||
str.Append("mu_RES");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class MicroUIWrapperGenerator : Cpp2BeefGenerator, this(Span<char8*> args)
|
||||
{
|
||||
protected override Span<char8*> Args => args;
|
||||
protected override Flags Flags => .None;
|
||||
|
||||
StreamWriter writer = new .()..Create("../src/Wrapper.bf")..Write("""
|
||||
// This file was generated by Cpp2Beef
|
||||
|
||||
using System;
|
||||
using System.Interop;
|
||||
|
||||
namespace MicroUI;
|
||||
|
||||
extension MicroUIContext
|
||||
{
|
||||
|
||||
""") ~ delete _..Write("}\n");
|
||||
|
||||
protected override StreamWriter GetWriterForHeader(StringView header)
|
||||
{
|
||||
if (header.EndsWith("microui.h"))
|
||||
return writer;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override Block GetCursorBlock(CXCursor cursor)
|
||||
{
|
||||
return .NoBlock;
|
||||
}
|
||||
|
||||
protected override void GetNameInBindings(CXCursor cursor, String outString)
|
||||
{
|
||||
if (!MicroUIGenerator.cGetNameInBindings(cursor, outString))
|
||||
base.GetNameInBindings(cursor, outString);
|
||||
}
|
||||
|
||||
protected override void Type(CXType type, TypeParamMode paramMode = .None)
|
||||
{
|
||||
if (!MicroUIGenerator.cType(type, str, currentCursor))
|
||||
base.Type(type, paramMode);
|
||||
}
|
||||
|
||||
protected override void HandleCursor(CXCursor cursor)
|
||||
{
|
||||
if (cursor.kind != .FunctionDecl || GetCursorSpelling!(cursor) == "mu_init") return;
|
||||
Flush();
|
||||
Method_Parameters(cursor);
|
||||
StringView parameters = scope String(str);
|
||||
str.Clear();
|
||||
if (!parameters.StartsWith("mu_Context* ctx"))
|
||||
return;
|
||||
parameters.RemoveFromStart("mu_Context* ctx".Length);
|
||||
if (parameters.StartsWith(", "))
|
||||
parameters.RemoveFromStart(2);
|
||||
BeginCursor(cursor);
|
||||
AccessSpecifier(cursor);
|
||||
WriteTypeAndName(cursor, Clang.GetCursorResultType(cursor));
|
||||
str.Append('(');
|
||||
str.Append(parameters, ") => MicroUI.");
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Append("(&");
|
||||
|
||||
let numArgs = Clang.Cursor_GetNumArguments(cursor);
|
||||
for (let i < numArgs)
|
||||
{
|
||||
if (i > 0) str.Append(", ");
|
||||
str.Append(GetCursorSpelling!(Clang.Cursor_GetArgument(cursor, (.)i)));
|
||||
}
|
||||
if (Clang.Cursor_IsVariadic(cursor) != 0)
|
||||
{
|
||||
if (numArgs > 0) str.Append(", ");
|
||||
str.Append("...");
|
||||
}
|
||||
str.Append(");");
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
[CLink] static extern int32 system(char8*);
|
||||
|
||||
public static int Main(String[] args)
|
||||
{
|
||||
if (system("git -C .. submodule update") != 0)
|
||||
{
|
||||
Console.WriteLine("Failed to fetch microui, check your internet connection");
|
||||
return 1;
|
||||
}
|
||||
|
||||
scope MicroUIGenerator(char8*[?]("--language=c")).Generate("../microui/src/microui.h");
|
||||
scope MicroUIWrapperGenerator(char8*[?]("--language=c")).Generate("../microui/src/microui.h");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user