add code
This commit is contained in:
353
Setup/src/Program.bf
Normal file
353
Setup/src/Program.bf
Normal file
@@ -0,0 +1,353 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Cpp2Beef;
|
||||
using LibClang;
|
||||
|
||||
namespace SDL3.Setup;
|
||||
|
||||
class SDL3Generator : Cpp2BeefGenerator, this(Span<char8*> args)
|
||||
{
|
||||
protected override Span<char8*> Args => args;
|
||||
protected override Flags Flags => .None;
|
||||
|
||||
private BumpAllocator alloc = new .() ~ delete _;
|
||||
|
||||
append Dictionary<String, StreamWriter> writers = .(16);
|
||||
protected override StreamWriter GetWriterForHeader(StringView header)
|
||||
{
|
||||
String filename = Path.GetFileNameWithoutExtension(header, ..scope .(64));
|
||||
if (!filename.StartsWith("SDL_") || filename == "SDL_begin_code") return null;
|
||||
if (writers.TryAdd(filename, let keyPtr, let valuePtr))
|
||||
{
|
||||
*keyPtr = new:alloc .(filename);
|
||||
*valuePtr = new:alloc .()..Create(scope $"../src/{filename}.bf")..Write("""
|
||||
// This file was generated by Cpp2Beef
|
||||
|
||||
using System;
|
||||
using System.Interop;
|
||||
using static SDL3.SDL;
|
||||
|
||||
namespace SDL3;
|
||||
|
||||
|
||||
""");
|
||||
}
|
||||
return *valuePtr;
|
||||
}
|
||||
|
||||
protected override Block GetCursorBlock(CXCursor cursor)
|
||||
{
|
||||
if (Path.GetFileName(GetFilePath!(fileInfo.file), ..scope .(128)).StartsWith("SDL_test"))
|
||||
return .CustomBlock("SDLTest");
|
||||
return .CustomBlock("SDL");
|
||||
}
|
||||
|
||||
protected override void HandleCursor(CXCursor cursor)
|
||||
{
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .MacroDefinition:
|
||||
if (Clang.Cursor_IsMacroFunctionLike(cursor) != 0 && GetFilePath!(fileInfo.file).EndsWith("SDL_version.h"))
|
||||
{
|
||||
BeginCursor(cursor);
|
||||
let tokens = ScopeTokenize!(cursor, unit);
|
||||
WriteCustomAttributes(cursor);
|
||||
str.Append("public static ");
|
||||
if (GetCursorSpelling!(cursor) == "SDL_VERSION_ATLEAST")
|
||||
str.Append("bool ");
|
||||
else
|
||||
str.Append("c_int ");
|
||||
GetNameInBindings(cursor, str);
|
||||
bool inArgs = true;
|
||||
for (let token in tokens[1...])
|
||||
{
|
||||
if (inArgs)
|
||||
{
|
||||
let spelling = GetTokenSpelling!(token);
|
||||
if (spelling == ")")
|
||||
{
|
||||
inArgs = false;
|
||||
str.Append(") => ");
|
||||
continue;
|
||||
}
|
||||
if (Clang.GetTokenKind(token) == .Identifier)
|
||||
str.Append("c_int ");
|
||||
str.Append(spelling);
|
||||
if (spelling == ",")
|
||||
str.Append(' ');
|
||||
}
|
||||
else
|
||||
WriteToken(token);
|
||||
}
|
||||
str.Append(';');
|
||||
return;
|
||||
}
|
||||
|
||||
let spelling = GetCursorSpelling!(cursor);
|
||||
if (spelling.StartsWith("SDL_PRI") || spelling.StartsWith("VK_DEFINE_"))
|
||||
return;
|
||||
switch (spelling)
|
||||
{
|
||||
case "FONT_LINE_HEIGHT":
|
||||
BeginCursor(cursor);
|
||||
str.Append("public static c_int FONT_LINE_HEIGHT => (FONT_CHARACTER_SIZE + 2);");
|
||||
return;
|
||||
case "PFN_xrGetInstanceProcAddr":
|
||||
BeginCursor(cursor);
|
||||
str.Append("public typealias PFN_xrGetInstanceProcAddr = SDL.FunctionPointer;");
|
||||
return;
|
||||
case "main", "SDL_SIZE_MAX", "SDL_FUNCTION", "SDL_FILE", "SDL_ASSERT_FILE", "SDL_LINE", "SDL_SCOPED_CAPABILITY", "SDL_NO_THREAD_SAFETY_ANALYSIS":
|
||||
return;
|
||||
}
|
||||
case .TypedefDecl:
|
||||
String prefix = scope .(64);
|
||||
var spelling = GetCursorSpelling!(cursor);
|
||||
|
||||
if (spelling == "SDL_Keycode")
|
||||
prefix.Set("SDLK_");
|
||||
else
|
||||
{
|
||||
if (!spelling.StartsWith("SDL_")) fallthrough;
|
||||
spelling.RemoveFromStart(4);
|
||||
|
||||
/*if (GetTypeSpelling!(Clang.GetTypedefDeclUnderlyingType(cursor)) != "Uint32")
|
||||
fallthrough;*/
|
||||
|
||||
if (spelling == "TrayEntryFlags")
|
||||
spelling = "Trayentry";
|
||||
else if (spelling == "MouseButtonFlags")
|
||||
spelling = "Button";
|
||||
else if (spelling.EndsWith("Flags"))
|
||||
spelling.RemoveFromEnd(5);
|
||||
else if (spelling.EndsWith("Flag"))
|
||||
spelling.RemoveFromEnd(4);
|
||||
/*else if (spelling.EndsWith("ID"))
|
||||
spelling.RemoveFromEnd(2);*/
|
||||
else if (spelling == "BlendMode")
|
||||
spelling = "Blendmode";
|
||||
else if (spelling == "GLContextResetNotification")
|
||||
spelling = "GlContextReset";
|
||||
else if (spelling == "GLProfile")
|
||||
spelling = "GlContextProfile";
|
||||
else if (spelling == "Keycode")
|
||||
spelling = "K";
|
||||
else if (spelling != "GPUShaderFormat")
|
||||
fallthrough;
|
||||
if (spelling.StartsWith("GL"))
|
||||
{
|
||||
spelling = scope:: String(spelling);
|
||||
spelling[1] = 'l';
|
||||
}
|
||||
|
||||
prefix.Append("SDL");
|
||||
if (spelling.StartsWith("GPU"))
|
||||
{
|
||||
prefix.Append("_GPU_");
|
||||
for (let c in spelling[3...])
|
||||
prefix.Append(c.ToUpper);
|
||||
prefix.Append('_');
|
||||
}
|
||||
else
|
||||
{
|
||||
for (let c in spelling)
|
||||
{
|
||||
if (c.IsUpper) prefix.Append('_');
|
||||
prefix.Append(c.ToUpper);
|
||||
}
|
||||
prefix.Append('_');
|
||||
}
|
||||
}
|
||||
|
||||
BeginCursor(cursor);
|
||||
if (spelling == "Button") str.Append("[AllowDuplicates] ");
|
||||
AccessSpecifier(cursor);
|
||||
str.Append("enum ");
|
||||
GetNameInBindings(cursor, str);
|
||||
str.Append(" : ");
|
||||
Type(Clang.GetTypedefDeclUnderlyingType(cursor));
|
||||
void FixCurly()
|
||||
{
|
||||
if (fileInfo.queuedTokens.HasFlag(.LSquirly))
|
||||
str.Append("\n{");
|
||||
if (fileInfo.queuedTokens.HasFlag(.RSquirly))
|
||||
str.Append("\n}");
|
||||
else
|
||||
str.Append("\n\t");
|
||||
fileInfo.queuedTokens = .None;
|
||||
}
|
||||
bool isSDL_GLContextFlag = spelling == "GlContext";
|
||||
{
|
||||
BeginBody!(cursor);
|
||||
for (let macro in this.[Friend]unitMacros)
|
||||
{
|
||||
let macroCursor = macro.value;
|
||||
if (Clang.Cursor_IsMacroFunctionLike(macroCursor) != 0)
|
||||
continue;
|
||||
if (Clang.GetFileLocation(Clang.GetCursorLocation(macroCursor), ..?, ?, ?, ?) != fileInfo.file)
|
||||
continue;
|
||||
var macroSpelling = GetCursorSpelling!(macroCursor);
|
||||
if (!macroSpelling.StartsWith(prefix))
|
||||
continue;
|
||||
if (isSDL_GLContextFlag)
|
||||
{
|
||||
if (!macroSpelling.EndsWith("_FLAG"))
|
||||
continue;
|
||||
macroSpelling.RemoveFromEnd(5);
|
||||
}
|
||||
macroSpelling.RemoveFromStart(prefix.Length);
|
||||
BeginCursor(macroCursor);
|
||||
FixCurly();
|
||||
if (macroSpelling[0].IsDigit) str.Append('_');
|
||||
UpperSnakeCase2PascalCase(macroSpelling, str);
|
||||
let tokens = ScopeTokenize!(macroCursor, unit);
|
||||
AllWhiteSpaceBetween(Clang.GetRangeEnd(Clang.GetTokenExtent(unit, tokens[0])), Clang.GetRangeStart(Clang.GetTokenExtent(unit, tokens[1])));
|
||||
str.Append("= ");
|
||||
WriteTokens(tokens[1...], Clang.GetNullLocation(), .Punctuation);
|
||||
str.Append(',');
|
||||
@macro.Remove();
|
||||
WriteComments(Clang.GetCursorLocation(macroCursor));
|
||||
}
|
||||
}
|
||||
FixCurly();
|
||||
return;
|
||||
default:
|
||||
}
|
||||
base.HandleCursor(cursor);
|
||||
}
|
||||
|
||||
protected override void GetNameInBindings(CXCursor cursor, String outString)
|
||||
{
|
||||
bool RemovePrefix(ref StringView view)
|
||||
{
|
||||
if (view.StartsWith("SDLTest_")) view.RemoveFromStart(8);
|
||||
else if (view.StartsWith("SDL_")) view.RemoveFromStart(4);
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
var spelling = GetCursorSpelling!(cursor);
|
||||
if (!RemovePrefix(ref spelling))
|
||||
{
|
||||
if (cursor.kind == .MacroDefinition)
|
||||
switch (spelling)
|
||||
{
|
||||
case "NULL": outString.Append("null"); return;
|
||||
case "TRUE": outString.Append("true"); return;
|
||||
case "FALSE": outString.Append("false"); return;
|
||||
}
|
||||
base.GetNameInBindings(cursor, outString);
|
||||
return;
|
||||
}
|
||||
switch (cursor.kind)
|
||||
{
|
||||
case .EnumConstantDecl:
|
||||
var parentSpelling = GetCursorSpelling!(Clang.GetCursorSemanticParent(cursor));
|
||||
if (parentSpelling == "SDL_GPUTextureFormat")
|
||||
{
|
||||
spelling.RemoveFromStart("GPU_TEXTUREFORMAT_".Length);
|
||||
outString.Append(spelling);
|
||||
break;
|
||||
}
|
||||
|
||||
StringView name = UpperSnakeCase2PascalCase(spelling, ..scope .(spelling.Length));
|
||||
switch (parentSpelling)
|
||||
{
|
||||
case "SDL_AudioFormat": parentSpelling = "Audio";
|
||||
case "SDL_AssertState": parentSpelling = "Assertion";
|
||||
case "SDL_GamepadBindingType": parentSpelling = "GamepadBindtype";
|
||||
case "SDL_RendererLogicalPresentation": parentSpelling = "LogicalPresentation";
|
||||
default:
|
||||
RemovePrefix(ref parentSpelling);
|
||||
}
|
||||
for (let c in parentSpelling)
|
||||
{
|
||||
if (name[0].ToLower == c.ToLower)
|
||||
name.RemoveFromStart(1);
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (name[0].IsDigit)
|
||||
outString.Append('_');
|
||||
outString.Append(name);
|
||||
default:
|
||||
outString.Append(spelling);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void WriteToken(CXToken token)
|
||||
{
|
||||
var spelling = GetTokenSpelling!(token);
|
||||
switch (spelling)
|
||||
{
|
||||
case "size_t": str.Append("c_size"); return;
|
||||
case "SDL_BUTTON_LEFT": str.Append("Left"); return;
|
||||
case "SDL_BUTTON_MIDDLE": str.Append("Middle"); return;
|
||||
case "SDL_BUTTON_RIGHT": str.Append("Right"); return;
|
||||
case "SDL_BUTTON_X1": str.Append("X1"); return;
|
||||
case "SDL_BUTTON_X2": str.Append("X2"); return;
|
||||
}
|
||||
if (!spelling.StartsWith("SDL_") || !spelling.EndsWith("ID"))
|
||||
{
|
||||
base.WriteToken(token);
|
||||
return;
|
||||
}
|
||||
spelling.RemoveFromStart(4);
|
||||
str.Append("SDL.");
|
||||
str.Append(spelling);
|
||||
}
|
||||
|
||||
protected override bool IsOutParam(CXCursor arg, CXCursor method)
|
||||
{
|
||||
let comment = Clang.Cursor_GetParsedComment(method);
|
||||
let spelling = GetCursorSpelling!(arg);
|
||||
for (let i < Clang.Comment_GetNumChildren(comment))
|
||||
{
|
||||
let param = Clang.Comment_GetChild(comment, i);
|
||||
if (Clang.Comment_GetKind(param) != .ParamCommand ||
|
||||
ScopeCXString!(Clang.ParamCommandComment_GetParamName(param)) != spelling) continue;
|
||||
let paragraph = Clang.BlockCommandComment_GetParagraph(param);
|
||||
if (Clang.Comment_GetNumChildren(paragraph) == 0) continue;
|
||||
let paragraphChild = Clang.Comment_GetChild(paragraph, 0);
|
||||
if (Clang.Comment_GetKind(paragraphChild) != .Text) continue;
|
||||
StringView paragraphText = ScopeCXString!(Clang.TextComment_GetText(paragraphChild))..TrimStart();
|
||||
if (paragraphText.StartsWith("a pointer filled in") || paragraphText.StartsWith("a pointer to receive")) return true;
|
||||
else break;
|
||||
}
|
||||
return base.IsOutParam(arg, method);
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
[CLink] static extern int32 system(char8*);
|
||||
|
||||
public static int Main(String[] args)
|
||||
{
|
||||
//Runtime.Assert(system("git -C .. submodule update") == 0, "Failed to fetch SDL3, check your internet connection");
|
||||
|
||||
{
|
||||
StreamWriter all = scope .()..Create("SDL3_all.h");
|
||||
for (let file in Directory.EnumerateFiles("../SDL/include/SDL3"))
|
||||
{
|
||||
let filename = file.GetFileName(..scope .(64));
|
||||
if (filename == "SDL_oldnames.h" || filename == "SDL_egl.h" || filename == "SDL_intrin.h" || filename == "SDL_endian.h" ||
|
||||
filename == "SDL_platform_defines.h" || filename == "SDL_begin_code.h" || filename == "SDL_close_code.h" || filename.StartsWith("SDL_opengl"))
|
||||
continue;
|
||||
all.Write("#include <SDL3/");
|
||||
all.Write(filename);
|
||||
all.Write(">\n");
|
||||
}
|
||||
}
|
||||
|
||||
SDL3Generator generator = scope .(char8*[?]("--language=c", "-I../SDL/include",
|
||||
"-DSDL_oldnames_h_", "-DSDL_platform_defines_h_", "-DSDL_endian_h_",
|
||||
"-DCrcUint32=Uint32", "-DCrcUint8=Uint8",
|
||||
"-DSDL_SLOW_MEMCPY", "-DSDL_SLOW_MEMMOVE", "-DSDL_SLOW_MEMSET", "-DSDL_DISABLE_ALLOCA", "-DSDL_DISABLE_ANALYZE_MACROS"));
|
||||
generator.Generate("SDL3_all.h", null);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user