Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ authors = [
"Xenira <[email protected]>",
"David Cole <[email protected]>",
]
edition = "2021"
edition = "2024"
categories = ["api-bindings"]
exclude = ["/.github", "/.crates"]
autotests = false
Expand Down
32 changes: 21 additions & 11 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{
str::FromStr,
};

use anyhow::{anyhow, bail, Context, Error, Result};
use anyhow::{Context, Error, Result, anyhow, bail};
use bindgen::RustTarget;
use impl_::Provider;

Expand Down Expand Up @@ -332,17 +332,25 @@ impl TryFrom<u32> for ApiVersion {

fn try_from(version: u32) -> Result<Self, Self::Error> {
match version {
x if ((ApiVersion::Php80 as u32)..(ApiVersion::Php81 as u32)).contains(&x) => Ok(ApiVersion::Php80),
x if ((ApiVersion::Php81 as u32)..(ApiVersion::Php82 as u32)).contains(&x) => Ok(ApiVersion::Php81),
x if ((ApiVersion::Php82 as u32)..(ApiVersion::Php83 as u32)).contains(&x) => Ok(ApiVersion::Php82),
x if ((ApiVersion::Php83 as u32)..(ApiVersion::Php84 as u32)).contains(&x) => Ok(ApiVersion::Php83),
x if ((ApiVersion::Php80 as u32)..(ApiVersion::Php81 as u32)).contains(&x) => {
Ok(ApiVersion::Php80)
}
x if ((ApiVersion::Php81 as u32)..(ApiVersion::Php82 as u32)).contains(&x) => {
Ok(ApiVersion::Php81)
}
x if ((ApiVersion::Php82 as u32)..(ApiVersion::Php83 as u32)).contains(&x) => {
Ok(ApiVersion::Php82)
}
x if ((ApiVersion::Php83 as u32)..(ApiVersion::Php84 as u32)).contains(&x) => {
Ok(ApiVersion::Php83)
}
x if (ApiVersion::Php84 as u32) == x => Ok(ApiVersion::Php84),
version => Err(anyhow!(
"The current version of PHP is not supported. Current PHP API version: {}, requires a version between {} and {}",
version,
ApiVersion::min() as u32,
ApiVersion::max() as u32
))
"The current version of PHP is not supported. Current PHP API version: {}, requires a version between {} and {}",
version,
ApiVersion::min() as u32,
ApiVersion::max() as u32
)),
}
}
}
Expand All @@ -367,7 +375,9 @@ fn check_php_version(info: &PHPInfo) -> Result<()> {
);

if version == ApiVersion::Php80 {
println!("cargo:warning=PHP 8.0 is EOL and is no longer supported. Please upgrade to a supported version of PHP. See https://www.php.net/supported-versions.php for information on version support timelines.");
println!(
"cargo:warning=PHP 8.0 is EOL and is no longer supported. Please upgrade to a supported version of PHP. See https://www.php.net/supported-versions.php for information on version support timelines."
);
}

for supported_version in version.supported_apis() {
Expand Down
5 changes: 3 additions & 2 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ keywords = ["php", "ffi", "zend"]
version = "0.1.13"
authors = [
"Xenira <[email protected]>",
"David Cole <[email protected]>"
"David Cole <[email protected]>",
"Pierre Tondereau <[email protected]>",
]
edition = "2018"
edition = "2024"
categories = ["api-bindings", "command-line-interface"]

[dependencies]
Expand Down
28 changes: 15 additions & 13 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#[cfg(not(windows))]
mod ext;

use anyhow::{bail, Context, Result as AResult};
use cargo_metadata::{camino::Utf8PathBuf, CrateType, Target};
use anyhow::{Context, Result as AResult, bail};
use cargo_metadata::{CrateType, Target, camino::Utf8PathBuf};
use clap::Parser;
use dialoguer::{Confirm, Select};

Expand All @@ -27,7 +27,7 @@ macro_rules! stub_symbols {
(@INTERNAL; $s: ident) => {
#[allow(non_upper_case_globals)]
#[allow(missing_docs)]
#[no_mangle]
#[unsafe(no_mangle)]
pub static mut $s: *mut () = ::std::ptr::null_mut();
};
}
Expand Down Expand Up @@ -221,9 +221,9 @@ impl Install {
ext_dir.push(ext_name);
}

std::fs::copy(&ext_path, &ext_dir).with_context(|| {
"Failed to copy extension from target directory to extension directory"
})?;
std::fs::copy(&ext_path, &ext_dir).with_context(
|| "Failed to copy extension from target directory to extension directory",
)?;

if let Some(php_ini) = php_ini {
let mut file = OpenOptions::new()
Expand Down Expand Up @@ -408,15 +408,17 @@ impl Stubs {
let result = ext.describe();

// Ensure extension and CLI `ext-php-rs` versions are compatible.
let cli_version = semver::VersionReq::from_str(ext_php_rs::VERSION).with_context(|| {
"Failed to parse `ext-php-rs` version that `cargo php` was compiled with"
})?;
let ext_version = semver::Version::from_str(result.version).with_context(|| {
"Failed to parse `ext-php-rs` version that your extension was compiled with"
})?;
let cli_version = semver::VersionReq::from_str(ext_php_rs::VERSION).with_context(
|| "Failed to parse `ext-php-rs` version that `cargo php` was compiled with",
)?;
let ext_version = semver::Version::from_str(result.version).with_context(
|| "Failed to parse `ext-php-rs` version that your extension was compiled with",
)?;

if !cli_version.matches(&ext_version) {
bail!("Extension was compiled with an incompatible version of `ext-php-rs` - Extension: {ext_version}, CLI: {cli_version}");
bail!(
"Extension was compiled with an incompatible version of `ext-php-rs` - Extension: {ext_version}, CLI: {cli_version}"
);
}

let stubs = result
Expand Down
5 changes: 3 additions & 2 deletions crates/macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ license = "MIT OR Apache-2.0"
version = "0.11.4"
authors = [
"Xenira <[email protected]>",
"David Cole <[email protected]>"
"David Cole <[email protected]>",
"Pierre Tondereau <[email protected]>",
]
edition = "2021"
edition = "2024"

[lib]
proc-macro = true
Expand Down
4 changes: 2 additions & 2 deletions crates/macros/src/enum_.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::convert::TryFrom;

use darling::{util::Flag, FromAttributes};
use darling::{FromAttributes, util::Flag};
use itertools::Itertools;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use quote::{ToTokens, quote};
use syn::{Fields, Ident, ItemEnum, Lit};

use crate::{
Expand Down
4 changes: 2 additions & 2 deletions crates/macros/src/extern_.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{
punctuated::Punctuated, spanned::Spanned as _, token::Unsafe, ForeignItemFn, ItemForeignMod,
ReturnType, Signature, Token,
ForeignItemFn, ItemForeignMod, ReturnType, Signature, Token, punctuated::Punctuated,
spanned::Spanned as _, token::Unsafe,
};

use crate::prelude::*;
Expand Down
33 changes: 31 additions & 2 deletions crates/macros/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,19 @@ impl<'a> Function<'a> {
let required_arg_names: Vec<_> = required.iter().map(|arg| arg.name).collect();
let not_required_arg_names: Vec<_> = not_required.iter().map(|arg| arg.name).collect();

let variadic_bindings = self.args.typed.iter().filter_map(|arg| {
if arg.variadic {
let name = arg.name;
let variadic_name = format_ident!("__variadic_{}", name);
let clean_ty = arg.clean_ty();
Some(quote! {
let #variadic_name = #name.variadic_vals::<#clean_ty>();
})
} else {
None
}
});

let arg_accessors = self.args.typed.iter().map(|arg| {
arg.accessor(|e| {
quote! {
Expand All @@ -237,6 +250,7 @@ impl<'a> Function<'a> {
if parse.is_err() {
return;
}
#(#variadic_bindings)*

#ident(#({#arg_accessors}),*)
},
Expand Down Expand Up @@ -277,6 +291,7 @@ impl<'a> Function<'a> {
if parse_result.is_err() {
return;
}
#(#variadic_bindings)*

#call
}
Expand Down Expand Up @@ -332,6 +347,18 @@ impl<'a> Function<'a> {
.iter()
.map(TypedArg::arg_declaration)
.collect::<Vec<_>>();
let variadic_bindings = self.args.typed.iter().filter_map(|arg| {
if arg.variadic {
let name = arg.name;
let variadic_name = format_ident!("__variadic_{}", name);
let clean_ty = arg.clean_ty();
Some(quote! {
let #variadic_name = #name.variadic_vals::<#clean_ty>();
})
} else {
None
}
});
let arg_accessors = self.args.typed.iter().map(|arg| {
arg.accessor(
|e| quote! { return ::ext_php_rs::class::ConstructorResult::Exception(#e); },
Expand Down Expand Up @@ -359,6 +386,7 @@ impl<'a> Function<'a> {
if parse.is_err() {
return ::ext_php_rs::class::ConstructorResult::ArgError;
}
#(#variadic_bindings)*
#class::#ident(#({#arg_accessors}),*).into()
}
inner
Expand Down Expand Up @@ -535,7 +563,7 @@ impl TypedArg<'_> {
let mut ty = self.ty.clone();
ty.drop_lifetimes();

// Variadic arguments are passed as slices, so we need to extract the
// Variadic arguments are passed as &[&Zval], so we need to extract the
// inner type.
if self.variadic {
let Type::Reference(reference) = &ty else {
Expand Down Expand Up @@ -599,8 +627,9 @@ impl TypedArg<'_> {
#name.val().unwrap_or(#default.into())
}
} else if self.variadic {
let variadic_name = format_ident!("__variadic_{}", name);
quote! {
&#name.variadic_vals()
#variadic_name.as_slice()
}
} else if self.nullable {
// Originally I thought we could just use the below case for `null` options, as
Expand Down
2 changes: 1 addition & 1 deletion crates/macros/src/impl_.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use darling::util::Flag;
use darling::FromAttributes;
use darling::util::Flag;
use proc_macro2::TokenStream;
use quote::quote;
use std::collections::{HashMap, HashSet};
Expand Down
6 changes: 3 additions & 3 deletions crates/macros/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ pub fn parser(input: ItemFn) -> Result<TokenStream> {

Ok(quote! {
#[doc(hidden)]
#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn get_module() -> *mut ::ext_php_rs::zend::ModuleEntry {
static __EXT_PHP_RS_MODULE_STARTUP: ::ext_php_rs::internal::ModuleStartupMutex =
::ext_php_rs::internal::MODULE_STARTUP_INIT;

extern "C" fn ext_php_rs_startup(ty: i32, mod_num: i32) -> i32 {
let a = #startup;
let a = unsafe { #startup };
let b = __EXT_PHP_RS_MODULE_STARTUP
.lock()
.take()
Expand Down Expand Up @@ -64,7 +64,7 @@ pub fn parser(input: ItemFn) -> Result<TokenStream> {
}

#[cfg(debug_assertions)]
#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn ext_php_rs_describe_module() -> ::ext_php_rs::describe::Description {
use ::ext_php_rs::describe::*;

Expand Down
2 changes: 1 addition & 1 deletion crates/macros/src/parsing.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use convert_case::{Case, Casing};
use darling::FromMeta;
use quote::{quote, ToTokens};
use quote::{ToTokens, quote};

const MAGIC_METHOD: [&str; 17] = [
"__construct",
Expand Down
4 changes: 2 additions & 2 deletions crates/macros/src/zval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use darling::ToTokens;
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{
punctuated::Punctuated, token::Where, DataEnum, DataStruct, DeriveInput, GenericParam,
Generics, Ident, ImplGenerics, Lifetime, LifetimeParam, TypeGenerics, Variant, WhereClause,
DataEnum, DataStruct, DeriveInput, GenericParam, Generics, Ident, ImplGenerics, Lifetime,
LifetimeParam, TypeGenerics, Variant, WhereClause, punctuated::Punctuated, token::Where,
};

use crate::prelude::*;
Expand Down
22 changes: 13 additions & 9 deletions src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use cfg_if::cfg_if;
use crate::ffi::{_efree, _emalloc, _estrdup};
use std::{
alloc::Layout,
ffi::{c_char, c_void, CString},
ffi::{CString, c_char, c_void},
};

/// Uses the PHP memory allocator to allocate request-bound memory.
Expand Down Expand Up @@ -52,16 +52,20 @@ pub unsafe fn efree(ptr: *mut u8) {
cfg_if! {
if #[cfg(php_debug)] {
#[allow(clippy::used_underscore_items)]
_efree(
ptr.cast::<c_void>(),
std::ptr::null_mut(),
0,
std::ptr::null_mut(),
0,
);
unsafe {
_efree(
ptr.cast::<c_void>(),
std::ptr::null_mut(),
0,
std::ptr::null_mut(),
0,
);
}
} else {
#[allow(clippy::used_underscore_items)]
_efree(ptr.cast::<c_void>());
unsafe {
_efree(ptr.cast::<c_void>());
}
}
}
}
Expand Down
8 changes: 2 additions & 6 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{ffi::CString, ptr};

use crate::{
convert::{FromZvalMut, IntoZvalDyn},
describe::{abi, Parameter},
describe::{Parameter, abi},
error::{Error, Result},
ffi::{
_zend_expected_type, _zend_expected_type_Z_EXPECTED_ARRAY,
Expand Down Expand Up @@ -189,11 +189,7 @@ impl From<Arg<'_>> for _zend_expected_type {
_ => unreachable!(),
};

if arg.allow_null {
type_id + 1
} else {
type_id
}
if arg.allow_null { type_id + 1 } else { type_id }
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<T: ZBoxable> ZBox<T> {
/// Caller must ensure that `ptr` is non-null, well-aligned and pointing to
/// a `T`.
pub unsafe fn from_raw(ptr: *mut T) -> Self {
Self(NonNull::new_unchecked(ptr))
Self(unsafe { NonNull::new_unchecked(ptr) })
}

/// Returns the pointer contained by the box, dropping the box in the
Expand Down
Loading
Loading