mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-22 13:44:59 -07:00
167 lines
6.1 KiB
Odin
167 lines
6.1 KiB
Odin
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");
|
|
}
|
|
}
|