[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 = &param.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