[vlc-commits] [Git][videolan/vlc][master] 5 commits: vlcrs-macros: rust-format module.rs code
François Cartegnie (@fcartegnie)
gitlab at videolan.org
Mon Sep 2 03:04:21 UTC 2024
François Cartegnie pushed to branch master at VideoLAN / VLC
Commits:
543b8897 by Alexandre Janniaux at 2024-09-02T02:50:05+00:00
vlcrs-macros: rust-format module.rs code
The module.rs file had a lot of additional intendation and other points
that were automatically changed when re-formatting. Apply those
formatting options to avoid it changing too much code each time it is
called.
- - - - -
d215c5cc by Alexandre Janniaux at 2024-09-02T02:50:05+00:00
module.rs: use separate variable for version
Using a separate variable for version allows matching the name of the C
define, ensuring grep would highlight both while making it clearer that
both needs to be updated. It also brings the benefit of removing the
null-character from the string itself as it can now be directly
concatenated when the code is generated, which ensures a future update
will not break the version by forgetting the null-character.
- - - - -
22250933 by Alexandre Janniaux at 2024-09-02T02:50:05+00:00
module_default: add test for version
Check that the version symbol is available and returns the correct
C-string value.
- - - - -
8e3b6a8a by Alexandre Janniaux at 2024-09-02T02:50:05+00:00
vlcrs-macros: add vlc_static_plugins #[cfg]
The vlc_static_plugins #[cfg] will be used to enforce suffixed
vlc_entry_* functions naming, just like it is done in the plugin system
when HAVE_DYNAMIC_PLUGINS is false, so that the modules generated from
the rust buildsystem can also be linked into a static bundle of plugins.
Features were considered in the first iteration of the design, since
they can allow crates using vlcrs-macros to require the static
entrypoint generator from the Cargo.toml file directly, but features are
supposed to be used additively and not behaviour-changing so that it
doesn't matter if a dependency is using the crate with extra-features
when it doesn't require so.
The additive design would have required to expose both the static_plugin
feature and the dynamic_plugin feature, while allowing both to be
enabled at the same time if needed, which meant generating two
entrypoints on module!{} call.
Note that #[cfg(vlc_static_plugins)] is checked at the compile time of
the module being built, and not the compile time of the vlcrs-macros
proc-macro crate since the cfg would not be forwarded to the crate
otherwise without a proper build.rs file. Both variant are thus
generated with proper #[cfg()] in the output of the module!{} macro.
- - - - -
57f26370 by Alexandre Janniaux at 2024-09-02T02:50:05+00:00
include: vlc_plugin: notice Rust file for plugin version
- - - - -
4 changed files:
- include/vlc_plugin.h
- src/rust/vlcrs-macros/Cargo.toml
- src/rust/vlcrs-macros/src/module.rs
- src/rust/vlcrs-macros/tests/module_default.rs
Changes:
=====================================
include/vlc_plugin.h
=====================================
@@ -217,7 +217,10 @@ enum vlc_config_subcat
};
/**
- * Current plugin ABI version
+ * Current plugin ABI version.
+ *
+ * \note This must be synchronized with the values from:
+ * - src/rust/vlcrs-macros/module.rs
*/
#define VLC_API_VERSION_STRING "4.0.6"
=====================================
src/rust/vlcrs-macros/Cargo.toml
=====================================
@@ -7,6 +7,9 @@ license.workspace = true
[lib]
proc-macro = true
+[lints.rust]
+unexpected_cfgs = { level = "warn", check-cfg = ['cfg(vlc_static_plugins)'] }
+
[dependencies]
vlcrs-plugin = { path = "../vlcrs-plugin" }
quote = "1.0"
=====================================
src/rust/vlcrs-macros/src/module.rs
=====================================
@@ -1,14 +1,16 @@
//! Module macros implementation
use proc_macro::TokenStream;
-use proc_macro2::TokenStream as TokenStream2;
+use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{quote, quote_spanned, ToTokens};
use syn::{
- braced, bracketed, parenthesized, parse::Parse, parse_macro_input,
- punctuated::Punctuated, spanned::Spanned, Attribute, Error, ExprRange,
- Ident, Lit, LitByteStr, LitInt, LitStr, MetaNameValue, RangeLimits, Token
+ braced, bracketed, parenthesized, parse::Parse, parse_macro_input, punctuated::Punctuated,
+ spanned::Spanned, Attribute, Error, ExprRange, Ident, Lit, LitByteStr, LitInt, LitStr,
+ MetaNameValue, RangeLimits, Token,
};
+const VLC_API_VERSION_STRING: &str = "4.0.6";
+
struct SectionInfo {
name: LitStr,
description: Option<LitStr>,
@@ -161,7 +163,7 @@ impl Parse for ModuleInfo {
}
"submodules" => {
input.parse::<Token![:]>()?;
-
+
let inner;
bracketed!(inner in input);
let parsed_submodules = inner.parse_terminated(SubmoduleInfo::parse)?;
@@ -710,8 +712,7 @@ fn generate_module_code(module_info: &ModuleInfo) -> TokenStream2 {
::std::convert::Into::<::std::ffi::c_double>::into(#default_)
}
};
- let item_type =
- quote! { ::vlcrs_plugin::ConfigModule::ITEM_FLOAT };
+ let item_type = quote! { ::vlcrs_plugin::ConfigModule::ITEM_FLOAT };
let range_type = Some(quote! { ::std::ffi::c_double });
(value, item_type, range_type)
@@ -722,8 +723,7 @@ fn generate_module_code(module_info: &ModuleInfo) -> TokenStream2 {
::std::convert::Into::<i64>::into(#default_)
}
};
- let item_type =
- quote! { ::vlcrs_plugin::ConfigModule::ITEM_BOOL };
+ let item_type = quote! { ::vlcrs_plugin::ConfigModule::ITEM_BOOL };
(value, item_type, None)
} else if param.type_ == "str" {
@@ -897,49 +897,66 @@ fn generate_module_code(module_info: &ModuleInfo) -> TokenStream2 {
let module_close_with_nul = tt_c_str!(type_.span() => module_close);
quote! {
- if unsafe {
- vlc_set(
- opaque,
- module as _,
- ::vlcrs_plugin::ModuleProperties::MODULE_CAPABILITY as _,
- #capability_with_nul,
- )
- } != 0 {
- return -1;
- }
- if unsafe {
- vlc_set(
- opaque,
- module as _,
- ::vlcrs_plugin::ModuleProperties::MODULE_SCORE as _,
- ::std::convert::Into::<i32>::into(#score),
- )
- } != 0 {
- return -1;
- }
+ if unsafe {
+ vlc_set(
+ opaque,
+ module as _,
+ ::vlcrs_plugin::ModuleProperties::MODULE_CAPABILITY as _,
+ #capability_with_nul,
+ )
+ } != 0 {
+ return -1;
+ }
+ if unsafe {
+ vlc_set(
+ opaque,
+ module as _,
+ ::vlcrs_plugin::ModuleProperties::MODULE_SCORE as _,
+ ::std::convert::Into::<i32>::into(#score),
+ )
+ } != 0 {
+ return -1;
+ }
+ if unsafe {
+ vlc_set(
+ opaque,
+ module as _,
+ ::vlcrs_plugin::ModuleProperties::MODULE_DESCRIPTION as _,
+ #description_with_nul,
+ )
+ } != 0
+ {
+ return -1;
+ }
+ #module_entry_help
+ #module_entry_shortname
+ #module_entry_shortcuts
+ if unsafe {
+ vlc_set(
+ opaque,
+ module as _,
+ ::vlcrs_plugin::ModuleProperties::MODULE_CB_OPEN as _,
+ #module_open_with_nul,
+ unsafe {
+ <#loader as ModuleProtocol<#type_>>::activate_function()
+ as *mut std::ffi::c_void
+ }
+ )
+ } != 0
+ {
+ return -1;
+ }
+
+ if <#loader as ModuleProtocol<#type_>>::deactivate_function() != None {
if unsafe {
vlc_set(
opaque,
module as _,
- ::vlcrs_plugin::ModuleProperties::MODULE_DESCRIPTION as _,
- #description_with_nul,
- )
- } != 0
- {
- return -1;
- }
- #module_entry_help
- #module_entry_shortname
- #module_entry_shortcuts
- if unsafe {
- vlc_set(
- opaque,
- module as _,
- ::vlcrs_plugin::ModuleProperties::MODULE_CB_OPEN as _,
- #module_open_with_nul,
+ ::vlcrs_plugin::ModuleProperties::MODULE_CB_CLOSE as _,
+ #module_close_with_nul,
unsafe {
- <#loader as ModuleProtocol<#type_>>::activate_function()
+ <#loader as ModuleProtocol<#type_>>::deactivate_function().unwrap()
as *mut std::ffi::c_void
}
)
@@ -947,28 +964,55 @@ fn generate_module_code(module_info: &ModuleInfo) -> TokenStream2 {
{
return -1;
}
+ }
- if <#loader as ModuleProtocol<#type_>>::deactivate_function() != None {
- if unsafe {
- vlc_set(
- opaque,
- module as _,
- ::vlcrs_plugin::ModuleProperties::MODULE_CB_CLOSE as _,
- #module_close_with_nul,
- unsafe {
- <#loader as ModuleProtocol<#type_>>::deactivate_function().unwrap()
- as *mut std::ffi::c_void
- }
- )
- } != 0
- {
- return -1;
- }
- }
+ #vlc_entry_config_subcategory
+ #vlc_entry_config_params
+ }
+}
+
+fn vlc_symbol(symbol_name: &str, module_name: Option<&str>) -> Ident {
+ if let Some(module_name) = module_name {
+ Ident::new(
+ &format!("{}__{}", symbol_name, module_name),
+ Span::call_site(),
+ )
+ } else {
+ Ident::new(symbol_name, Span::call_site())
+ }
+}
+
+fn vlc_entry_api_version(module_suffix: Option<&str>) -> TokenStream2 {
+ let symbol = vlc_symbol("vlc_entry_api_version", module_suffix);
+ quote! {
+ #[no_mangle]
+ #[doc(hidden)]
+ extern "C" fn #symbol() -> *const u8 {
+ concat!(#VLC_API_VERSION_STRING, "\0").as_ptr()
+ }
+ }
+}
- #vlc_entry_config_subcategory
- #vlc_entry_config_params
+fn vlc_entry_copyright(module_suffix: Option<&str>) -> TokenStream2 {
+ let symbol = vlc_symbol("vlc_entry_copyright", module_suffix);
+ quote! {
+ #[no_mangle]
+ #[doc(hidden)]
+ extern "C" fn #symbol() -> *const u8 {
+ ::vlcrs_plugin::VLC_COPYRIGHT_VIDEOLAN.as_ptr()
}
+ }
+}
+
+fn vlc_entry_license(module_suffix: Option<&str>) -> TokenStream2 {
+ let symbol = vlc_symbol("vlc_entry_license", module_suffix);
+ quote! {
+ #[no_mangle]
+ #[doc(hidden)]
+ extern "C" fn #symbol() -> *const u8 {
+ ::vlcrs_plugin::VLC_LICENSE_LGPL_2_1_PLUS.as_ptr()
+ }
+ }
}
pub fn module(input: TokenStream) -> TokenStream {
@@ -976,8 +1020,10 @@ pub fn module(input: TokenStream) -> TokenStream {
// TODO: Improve this with some kind environment variable passed by the build system
// like what is done for the C side.
- let name = format!("{}-rs", module_info.type_.to_string().to_lowercase());
+ let module_suffix = module_info.type_.to_string().to_lowercase();
+ let name = format!("{}-rs", module_suffix);
let name_len = name.len() + 1;
+ let module_suffix = module_suffix + "_rs";
let name_with_nul = tt_c_str!(module_info.type_.span() => name);
@@ -988,33 +1034,19 @@ pub fn module(input: TokenStream) -> TokenStream {
pub static vlc_module_name: &[u8; #name_len] = #name_with_nul;
};
- // Copied from #define VLC_API_VERSION_STRING in include/vlc_plugin.h
- let entry_api_version = quote! {
- #[no_mangle]
- #[doc(hidden)]
- extern "C" fn vlc_entry_api_version() -> *const u8 {
- b"4.0.6\0".as_ptr()
- }
- };
+ let entry_api_version = vlc_entry_api_version(None);
+ let entry_copyright = vlc_entry_copyright(None);
+ let entry_license = vlc_entry_license(None);
- let entry_copyright = quote! {
- #[no_mangle]
- #[doc(hidden)]
- extern "C" fn vlc_entry_copyright() -> *const u8 {
- ::vlcrs_plugin::VLC_COPYRIGHT_VIDEOLAN.as_ptr()
- }
- };
-
- let entry_license = quote! {
- #[no_mangle]
- #[doc(hidden)]
- extern "C" fn vlc_entry_license() -> *const u8 {
- ::vlcrs_plugin::VLC_LICENSE_LGPL_2_1_PLUS.as_ptr()
- }
- };
+ let entry_api_version_module_name = vlc_entry_api_version(Some(&module_suffix));
+ let entry_copyright_module_name = vlc_entry_copyright(Some(&module_suffix));
+ let entry_license_module_name = vlc_entry_license(Some(&module_suffix));
let type_params = module_info.params.as_ref().map(|params| {
- let struct_name = Ident::new(&format!("{}Args", module_info.type_), module_info.type_.span());
+ let struct_name = Ident::new(
+ &format!("{}Args", module_info.type_),
+ module_info.type_.span(),
+ );
let params_def = params.params.iter().map(|param| {
let rust_name = ¶m.name;
@@ -1065,51 +1097,80 @@ pub fn module(input: TokenStream) -> TokenStream {
}
});
- let module_entry = quote! {
- #[no_mangle]
- #[doc(hidden)]
- extern "C" fn vlc_entry(
- vlc_set: ::vlcrs_plugin::sys::vlc_set_cb,
- opaque: *mut ::std::ffi::c_void,
- ) -> i32 {
- use vlcrs_plugin::ModuleProtocol;
- let mut module: *mut ::vlcrs_plugin::module_t = ::std::ptr::null_mut();
- let mut config: *mut ::vlcrs_plugin::vlc_param = ::std::ptr::null_mut();
+ let vlc_entry = |module_suffix: Option<&str>| {
+ let symbol = vlc_symbol("vlc_entry", module_suffix);
+ quote! {
+ #[no_mangle]
+ #[doc(hidden)]
+ extern "C" fn #symbol(
+ vlc_set: ::vlcrs_plugin::sys::vlc_set_cb,
+ opaque: *mut ::std::ffi::c_void,
+ ) -> i32 {
+ use vlcrs_plugin::ModuleProtocol;
+ let mut module: *mut ::vlcrs_plugin::module_t = ::std::ptr::null_mut();
+ let mut config: *mut ::vlcrs_plugin::vlc_param = ::std::ptr::null_mut();
- if unsafe {
- vlc_set(
- opaque,
- ::std::ptr::null_mut(),
- ::vlcrs_plugin::ModuleProperties::MODULE_CREATE as _,
- &mut module as *mut *mut ::vlcrs_plugin::module_t,
- )
- } != 0
- {
- return -1;
- }
- if unsafe {
- vlc_set(
- opaque,
- module as _,
- ::vlcrs_plugin::ModuleProperties::MODULE_NAME as _,
- #name_with_nul,
- )
- } != 0
- {
- return -1;
+ if unsafe {
+ vlc_set(
+ opaque,
+ ::std::ptr::null_mut(),
+ ::vlcrs_plugin::ModuleProperties::MODULE_CREATE as _,
+ &mut module as *mut *mut ::vlcrs_plugin::module_t,
+ )
+ } != 0
+ {
+ return -1;
+ }
+ if unsafe {
+ vlc_set(
+ opaque,
+ module as _,
+ ::vlcrs_plugin::ModuleProperties::MODULE_NAME as _,
+ #name_with_nul,
+ )
+ } != 0
+ {
+ return -1;
+ }
+ #module_entry_configs
+ #submodules_entry
+ 0
}
- #module_entry_configs
- #submodules_entry
- 0
}
};
+ let module_entry_module_name = vlc_entry(Some(&module_suffix));
+ let module_entry = vlc_entry(None);
+
+ let cfg_static = quote!{ #[cfg(vlc_static_plugins)] };
+ let cfg_not_static = quote!{ #[cfg(not(vlc_static_plugins))] };
let expanded = quote! {
#type_params
+
+ #cfg_static
+ #entry_api_version_module_name
+
+ #cfg_static
+ #entry_license_module_name
+
+ #cfg_static
+ #entry_copyright_module_name
+
+ #cfg_static
+ #module_entry_module_name
+
+ #cfg_not_static
#entry_api_version
+
+ #cfg_not_static
#entry_license
+
+ #cfg_not_static
#entry_copyright
+
#module_name
+
+ #cfg_not_static
#module_entry
};
TokenStream::from(expanded)
=====================================
src/rust/vlcrs-macros/tests/module_default.rs
=====================================
@@ -12,7 +12,7 @@ use common::TestContext;
use vlcrs_macros::module;
-use std::ffi::c_int;
+use std::ffi::{c_int, CStr};
use vlcrs_plugin::{ModuleProtocol,vlc_activate};
unsafe extern "C"
@@ -71,6 +71,9 @@ module! {
#[test]
fn test_module_load_default_deactivate()
{
+ let version = unsafe{ CStr::from_ptr(vlc_entry_api_version() as *const i8) };
+ assert_eq!(version, c"4.0.6");
+
use vlcrs_plugin::ModuleProperties;
let mut context = TestContext::<vlc_activate> {
command_cursor: 0,
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0d6833886f88078b3728b5f380b16c5cb24b979d...57f263708180f36cb7ab32ea06f22425a5aa97cc
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/0d6833886f88078b3728b5f380b16c5cb24b979d...57f263708180f36cb7ab32ea06f22425a5aa97cc
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list