summaryrefslogtreecommitdiff
path: root/codegen/command
diff options
context:
space:
mode:
Diffstat (limited to 'codegen/command')
-rw-r--r--codegen/command/functions.rs62
-rw-r--r--codegen/command/globals.rs15
-rw-r--r--codegen/command/mod.rs2
3 files changed, 79 insertions, 0 deletions
diff --git a/codegen/command/functions.rs b/codegen/command/functions.rs
new file mode 100644
index 0000000..6d1a3d3
--- /dev/null
+++ b/codegen/command/functions.rs
@@ -0,0 +1,62 @@
+use std::error::Error;
+use std::str::FromStr;
+
+use opengl_registry::command::Command;
+use proc_macro2::{LexError, TokenStream};
+use quote::{format_ident, quote};
+
+use crate::codegen::formatting::{clean_param_name, fix_type};
+
+pub fn create_command_functions(
+ commands: &[Command],
+) -> Result<Vec<TokenStream>, Box<dyn Error>>
+{
+ commands.iter().map(|command| {
+ let command_name_str = command.prototype().name();
+
+ let command_name = format_ident!("{}", command.prototype().name());
+
+ let command_name_prefixless = format_ident!("{}", command.prototype()
+ .name()
+ .strip_prefix("gl")
+ .unwrap_or_else(|| command.prototype().name()));
+
+ let command_args = command
+ .parameters()
+ .iter()
+ .map(|param| {
+ let param_name = format_ident!("{}", clean_param_name(param.name()));
+
+ let param_type = TokenStream::from_str(&fix_type(param.get_type()))?;
+
+ Ok::<_, LexError>(quote! { #param_name: #param_type })
+ }).collect::<Result<Vec<_>, _>>()?;
+
+ let command_return_type = TokenStream::from_str(&fix_type(command.prototype().return_type()))?;
+
+ let command_arg_types = command
+ .parameters()
+ .iter()
+ .map(|param| TokenStream::from_str(&fix_type(param.get_type())))
+ .collect::<Result<Vec<_>, _>>()?;
+
+ let command_arg_names = command
+ .parameters()
+ .iter()
+ .map(|param| format_ident!("{}", clean_param_name(param.name())))
+ .collect::<Vec<_>>();
+
+ Ok(quote! {
+ #[doc = #command_name_str]
+ #[allow(non_snake_case, clippy::too_many_arguments)]
+ pub unsafe fn #command_name_prefixless(#(#command_args),*) -> #command_return_type {
+ type GLFunc =
+ unsafe extern "C" fn(#(#command_arg_types),*) -> #command_return_type;
+
+ let gl_func = std::mem::transmute::<_, GLFunc>(functions::#command_name);
+
+ gl_func(#(#command_arg_names),*)
+ }
+ })
+ }).collect()
+}
diff --git a/codegen/command/globals.rs b/codegen/command/globals.rs
new file mode 100644
index 0000000..e522e68
--- /dev/null
+++ b/codegen/command/globals.rs
@@ -0,0 +1,15 @@
+use opengl_registry::command::Command;
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+
+pub fn create_command_globals(commands: &[Command]) -> Vec<TokenStream>
+{
+ commands.iter().map(|command| {
+ let command_name = format_ident!("{}", command.prototype().name());
+
+ quote! {
+ #[allow(non_upper_case_globals)]
+ pub static mut #command_name: unsafe extern "C" fn() = function_not_loaded;
+ }
+ }).collect()
+}
diff --git a/codegen/command/mod.rs b/codegen/command/mod.rs
new file mode 100644
index 0000000..7559bc1
--- /dev/null
+++ b/codegen/command/mod.rs
@@ -0,0 +1,2 @@
+pub mod functions;
+pub mod globals;