mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-31 20:00:09 +00:00
sync with main
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
package bindgen
|
||||
|
||||
import "core:os"
|
||||
import "core:fmt"
|
||||
|
||||
export_defines :: proc(data : ^GeneratorData) {
|
||||
for node in data.nodes.defines {
|
||||
defineName := clean_define_name(node.name, data.options);
|
||||
|
||||
// @fixme fprint of float numbers are pretty badly handled,
|
||||
// just has a 10^-3 precision.
|
||||
fcat(data.handle, defineName, " :: ", node.value, ";\n");
|
||||
}
|
||||
fcat(data.handle, "\n");
|
||||
}
|
||||
|
||||
export_typedefs :: proc(data : ^GeneratorData) {
|
||||
for node in data.nodes.typedefs {
|
||||
name := clean_pseudo_type_name(node.name, data.options);
|
||||
type := clean_type(data, node.type, "", true);
|
||||
if name == type do continue;
|
||||
fcat(data.handle, name, " :: ", type, ";\n");
|
||||
}
|
||||
fcat(data.handle, "\n");
|
||||
}
|
||||
|
||||
export_enums :: proc(data : ^GeneratorData) {
|
||||
for node in data.nodes.enumDefinitions {
|
||||
enumName := clean_pseudo_type_name(node.name, data.options);
|
||||
|
||||
if data.options.mode == "jai" {
|
||||
consideredFlags := false;
|
||||
for postfix in data.options.enumConsideredFlagsPostfixes {
|
||||
if ends_with(node.name, postfix) {
|
||||
consideredFlags = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if consideredFlags {
|
||||
fcat(data.handle, enumName, " :: enum_flags u32 {");
|
||||
} else {
|
||||
fcat(data.handle, enumName, " :: enum s32 {");
|
||||
}
|
||||
} else {
|
||||
fcat(data.handle, enumName, " :: enum i32 {");
|
||||
}
|
||||
|
||||
postfixes : [dynamic]string;
|
||||
enumName, postfixes = clean_enum_name_for_prefix_removal(enumName, data.options);
|
||||
|
||||
// Changing the case of postfixes to the enum value one,
|
||||
// so that they can be removed.
|
||||
enumValueCase := find_case(node.members[0].name);
|
||||
for postfix, i in postfixes {
|
||||
postfixes[i] = change_case(postfix, enumValueCase);
|
||||
}
|
||||
|
||||
// And changing the case of enumName to the enum value one
|
||||
enumName = change_case(enumName, enumValueCase);
|
||||
|
||||
// Merging enum value postfixes with postfixes that have been removed from the enum name.
|
||||
for postfix in data.options.enumValuePostfixes {
|
||||
append(&postfixes, postfix);
|
||||
}
|
||||
|
||||
export_enum_members(data, node.members, enumName, postfixes[:]);
|
||||
fcat(data.handle, data.options.mode == "jai" ? "}\n" : "};\n");
|
||||
fcat(data.handle, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
export_structs :: proc(data : ^GeneratorData) {
|
||||
for node in data.nodes.structDefinitions {
|
||||
structName := clean_pseudo_type_name(node.name, data.options);
|
||||
fcat(data.handle, structName, " :: struct {");
|
||||
export_struct_or_union_members(data, node.members);
|
||||
fcat(data.handle, data.options.mode == "jai" ? "}\n" : "};\n");
|
||||
fcat(data.handle, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
export_unions :: proc(data : ^GeneratorData) {
|
||||
for node in data.nodes.unionDefinitions {
|
||||
unionName := clean_pseudo_type_name(node.name, data.options);
|
||||
fcat(data.handle, unionName, data.options.mode == "jai" ? " :: union {" : " :: struct #raw_union {");
|
||||
export_struct_or_union_members(data, node.members);
|
||||
fcat(data.handle, data.options.mode == "jai" ? "}\n" : "};\n");
|
||||
fcat(data.handle, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
export_functions :: proc(data : ^GeneratorData) {
|
||||
for node in data.nodes.functionDeclarations {
|
||||
functionName := clean_function_name(node.name, data.options);
|
||||
if data.options.mode == "jai" {
|
||||
fcat(data.handle, functionName, " :: (");
|
||||
} else {
|
||||
fcat(data.handle, " @(link_name=\"", node.name, "\")\n");
|
||||
fcat(data.handle, " ", functionName, " :: proc(");
|
||||
}
|
||||
parameters := clean_function_parameters(data, node.parameters, data.options.mode == "jai" ? "" : " ");
|
||||
fcat(data.handle, parameters, ")");
|
||||
returnType := clean_type(data, node.returnType);
|
||||
if len(returnType) > 0 {
|
||||
fcat(data.handle, " -> ", returnType);
|
||||
}
|
||||
if data.options.mode == "jai" {
|
||||
fcat(data.handle, " #foreign ", data.foreignLibrary, " \"", node.name ,"\";\n");
|
||||
} else {
|
||||
fcat(data.handle, " ---;\n");
|
||||
}
|
||||
fcat(data.handle, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
export_enum_members :: proc(data : ^GeneratorData, members : [dynamic]EnumMember, enumName : string, postfixes : []string) {
|
||||
if (len(members) > 0) {
|
||||
fcat(data.handle, "\n");
|
||||
}
|
||||
|
||||
cleanedMembers : [dynamic]EnumMember;
|
||||
for member in members {
|
||||
cleanedMember : EnumMember;
|
||||
cleanedMember.hasValue = member.hasValue;
|
||||
cleanedMember.value = member.value;
|
||||
cleanedMember.name = clean_enum_value_name(member.name, enumName, postfixes, data.options);
|
||||
|
||||
if len(cleanedMember.name) == 0 {
|
||||
// print_warning("Enum member ", member.name, " resolves to an empty name. Ignoring it.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensuring that we don't collide with an other enum member.
|
||||
foundCopy := false;
|
||||
for existingCleanedMember in cleanedMembers {
|
||||
if cleanedMember.name == existingCleanedMember.name &&
|
||||
cleanedMember.hasValue == existingCleanedMember.hasValue &&
|
||||
cleanedMember.value == existingCleanedMember.value {
|
||||
print_warning("Enum member ", member.name, " is duplicated once cleaned. Keeping only one copy.");
|
||||
foundCopy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if foundCopy do continue;
|
||||
|
||||
fcat(data.handle, " ", cleanedMember.name);
|
||||
if member.hasValue {
|
||||
fcat(data.handle, data.options.mode == "jai" ? " :: " : " = ", member.value);
|
||||
}
|
||||
fcat(data.handle, data.options.mode == "jai" ? ";\n" : ",\n");
|
||||
|
||||
append(&cleanedMembers, cleanedMember);
|
||||
}
|
||||
}
|
||||
|
||||
export_struct_or_union_members :: proc(data : ^GeneratorData, members : [dynamic]StructOrUnionMember) {
|
||||
if (len(members) > 0) {
|
||||
fcat(data.handle, "\n");
|
||||
}
|
||||
for member in members {
|
||||
type := clean_type(data, member.type, " ");
|
||||
name := clean_variable_name(member.name, data.options);
|
||||
fcat(data.handle, " ", name, " : ", type, data.options.mode == "jai" ? ";\n" : ",\n");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user