diff --git a/.gitmodules b/.gitmodules index ec11c84..6a011bd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "netcdf-src/source"] path = netcdf-src/source - url = https://github.com/gigainfosystems/netcdf-c + url = https://github.com/mulimoen/netcdf-c diff --git a/netcdf-src/source b/netcdf-src/source index 3fabcf3..cbf1282 160000 --- a/netcdf-src/source +++ b/netcdf-src/source @@ -1 +1 @@ -Subproject commit 3fabcf34b18bcba578ef7ad13a20ac0320680267 +Subproject commit cbf128203297f5a990f37b8c28f45455292d5e7b diff --git a/netcdf-sys/build.rs b/netcdf-sys/build.rs index 9d3e264..35a1e36 100644 --- a/netcdf-sys/build.rs +++ b/netcdf-sys/build.rs @@ -284,6 +284,7 @@ fn main() { Version::new(4, 8, 1), Version::new(4, 9, 0), Version::new(4, 9, 1), + Version::new(4, 9, 2), ]; if !versions.contains(&metaheader.version) { @@ -305,6 +306,10 @@ fn main() { "cargo:rustc-cfg=feature=\"{}.{}.{}\"", version.major, version.minor, version.patch ); + println!( + "cargo:version_\"{}.{}.{}\"=1", + version.major, version.minor, version.patch + ); } } metaheader.emit_feature_flags(); diff --git a/netcdf-sys/src/functions.rs b/netcdf-sys/src/functions.rs index 0e80e21..65086bf 100644 --- a/netcdf-sys/src/functions.rs +++ b/netcdf-sys/src/functions.rs @@ -1728,6 +1728,11 @@ mod netcdf_2 { #[cfg(feature = "4.6.2")] pub fn nc_initialize() -> c_int; pub fn nc_finalize() -> c_int; + + #[cfg(feature = "4.9.2")] + pub fn nc_rc_get(key: *const c_char) -> *mut c_char; + #[cfg(feature = "4.9.2")] + pub fn nc_rc_set(key: *const c_char, value: *const c_char) -> c_int; } } pub use netcdf_2::*; diff --git a/netcdf/Cargo.toml b/netcdf/Cargo.toml index 8f32b43..91ebbaa 100644 --- a/netcdf/Cargo.toml +++ b/netcdf/Cargo.toml @@ -23,6 +23,7 @@ static = ["netcdf-sys/static"] ndarray = { version = "0.15", optional = true } netcdf-sys = { workspace = true } bitflags = "2.4.2" +libc = "0.2.154" [dev-dependencies] clap = { version = "4.5.1", features = ["derive"] } diff --git a/netcdf/build.rs b/netcdf/build.rs index 1d174dc..6b0d9be 100644 --- a/netcdf/build.rs +++ b/netcdf/build.rs @@ -2,4 +2,9 @@ fn main() { if std::env::var("DEP_NETCDF_HAS_MMAP").is_ok() { println!("cargo:rustc-cfg=feature=\"has-mmap\""); } + for (env, _value) in std::env::vars() { + if let Some(version) = env.strip_prefix("DEP_NETCDF_VERSION_") { + println!("cargo:rustc-cfg=feature={version}"); + } + } } diff --git a/netcdf/src/lib.rs b/netcdf/src/lib.rs index ae9df16..4f51e48 100644 --- a/netcdf/src/lib.rs +++ b/netcdf/src/lib.rs @@ -110,6 +110,8 @@ pub(crate) mod error; pub(crate) mod extent; pub(crate) mod file; pub(crate) mod group; +#[cfg(feature = "4.9.2")] +pub mod rc; pub mod types; pub(crate) mod variable; diff --git a/netcdf/src/rc.rs b/netcdf/src/rc.rs new file mode 100644 index 0000000..e0be69f --- /dev/null +++ b/netcdf/src/rc.rs @@ -0,0 +1,42 @@ +use std::ffi::{c_char, CStr, CString}; +use std::ops::Deref; +use std::ptr::NonNull; + +pub fn set(key: &str, value: &str) -> crate::error::Result<()> { + let key = CString::new(key)?; + let value = CString::new(value)?; + crate::error::checked(crate::with_lock(|| unsafe { + netcdf_sys::nc_rc_set(key.as_ptr(), value.as_ptr()) + })) +} + +#[derive(Debug)] +pub struct OwnedString { + inner: NonNull, +} + +impl Deref for OwnedString { + type Target = CStr; + fn deref(&self) -> &Self::Target { + unsafe { CStr::from_ptr(self.inner.as_ptr()) } + } +} + +impl Drop for OwnedString { + fn drop(&mut self) { + unsafe { + libc::free(self.inner.as_ptr().cast()); + } + } +} + +pub fn get(key: &str) -> Option { + let key = if let Ok(key) = CString::new(key) { + key + } else { + return None; + }; + let _lock = netcdf_sys::libnetcdf_lock.lock().unwrap(); + let value = unsafe { netcdf_sys::nc_rc_get(key.as_ptr()) }; + NonNull::new(value).map(|inner| OwnedString { inner }) +}