Skip to content
Open
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
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ repository.workspace = true
rust-version.workspace = true
version.workspace = true

[lints]
workspace = true

[package.metadata.docs.rs]
# Show documentation for private items
rustdoc-args = ["--document-private-items"]
Expand Down Expand Up @@ -195,7 +198,6 @@ clap = { version = "4.6.7", features = ["derive"] }
diff = "0.1.13"
php-ast = "0.26.0"
php-rs-parser = "0.26.0"
proc-macro2 = "1.0.107"
regex = "1.13.1"
rsphp-build-tools = { version = "0.1.2", path = "./crates/build-tools" }
rsphp-macros-c = { version = "0.1.2", path = "./crates/macros-c" }
Expand All @@ -209,7 +211,6 @@ walkdir = "2.5.0"
[dependencies]
bstr = { workspace = true, optional = true }
rsphp-macros-c = { workspace = true }
rsphp-macros-rs = { workspace = true }
rsphp-sys = { workspace = true }

[features]
Expand Down
14 changes: 9 additions & 5 deletions crates/macros-c/src/zend_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,15 @@ macro_rules! ZVAL_EMPTY_ARRAY {
#[macro_export]
macro_rules! ZEND_HASH_ELEMENT_SIZE {
($ht:expr) => {
std::mem::size_of::<rsphp_sys::zval>()
+ ((!$crate::HT_FLAGS!($ht) & rsphp_sys::HASH_FLAG_PACKED) as usize)
* ((std::mem::size_of::<rsphp_sys::Bucket>()
- std::mem::size_of::<rsphp_sys::zval>())
/ (rsphp_sys::HASH_FLAG_PACKED as usize))
#[expect(clippy::integer_division, reason = "Matches C version")]
// Need a block so that attribute can be applied
{
std::mem::size_of::<rsphp_sys::zval>()
+ ((!$crate::HT_FLAGS!($ht) & rsphp_sys::HASH_FLAG_PACKED) as usize)
* ((std::mem::size_of::<rsphp_sys::Bucket>()
- std::mem::size_of::<rsphp_sys::zval>())
/ (rsphp_sys::HASH_FLAG_PACKED as usize))
}
};
}

Expand Down
2 changes: 1 addition & 1 deletion crates/sys/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# rsphp-sys

FFI bindings for PHP's ABIC, see the main [rsphp] README for more information.
FFI bindings for PHP's ABI, see the main [rsphp] README for more information.

[rsphp]: https://github.com/DanielEScherzer/rsphp
17 changes: 17 additions & 0 deletions src/extensions/hash_table_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,29 @@ use rsphp_sys::{
};
use std::ptr::NonNull;

/// Extension trait for [`rsphp_sys::HashTable`].
pub trait HashTableExt {
/// Does the table contain a value with the given string key?
///
/// Wrapper around [`rsphp_sys::zend_hash_exists()`].
fn contains(&self, key: &mut zend_string) -> bool;

/// Insert the given value to the next numerical index, and return the
/// resulting pointer.
///
/// Wrapper around [`rsphp_sys::zend_hash_next_index_insert()`].
fn next_index_insert<T>(&mut self, value: T) -> *mut zval
where
T: Into<PHPValue>;

/// Try to find the value in the table with the given string key.
///
/// Wrapper around [`rsphp_sys::zend_hash_find()`].
fn find(&self, key: &mut zend_string) -> Option<NonNull<zval>>;

/// Check the number of elements currently in the table.
///
/// This is equivalent to [`rsphp_sys::zend_hash_num_elements()`].
fn num_elements(&self) -> u32;
}

Expand Down
6 changes: 3 additions & 3 deletions src/extensions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod hash_table_ext;
pub use hash_table_ext::HashTableExt;

mod zend_attribute_ext;
pub use zend_attribute_ext::ZendAttributeExt;
pub use zend_attribute_ext::{ZendAttributeArgIter, ZendAttributeExt};

mod zend_arg_info_ext;
pub use zend_arg_info_ext::ZendArgInfoExt;
Expand All @@ -14,7 +14,7 @@ mod zend_class_constant_ext;
pub use zend_class_constant_ext::ZendClassConstantExt;

mod zend_class_entry_ext;
pub use zend_class_entry_ext::ZendClassEntryExt;
pub use zend_class_entry_ext::{ZendClassEntryExt, ZendClassEntryTraitNamesIter};

mod zend_constant_ext;
pub use zend_constant_ext::ZendConstantExt;
Expand All @@ -38,7 +38,7 @@ mod zend_type_ext;
pub use zend_type_ext::ZendTypeExt;

mod zend_type_list_ext;
pub use zend_type_list_ext::ZendTypeListExt;
pub use zend_type_list_ext::{ZendTypeListExt, ZendTypeListIter};

mod zval_ext;
pub use zval_ext::ZvalExt;
21 changes: 21 additions & 0 deletions src/extensions/zend_arg_info_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,31 @@ use rsphp_sys::{
zend_arg_info,
};

/// Extension trait for [`rsphp_sys::zend_arg_info`].
pub trait ZendArgInfoExt {
/// Get the "send" mode for the argument.
///
/// The result should be one of
/// - [`rsphp_sys::ZEND_SEND_BY_VAL`]
/// - [`rsphp_sys::ZEND_SEND_BY_REF`]
/// - [`rsphp_sys::ZEND_SEND_PREFER_REF`]
///
/// This is equivalent to [`rsphp_macros_c::ZEND_ARG_SEND_MODE!()`].
fn send_mode(&self) -> u8;

/// Check if an argument is marked as variadic.
///
/// This is equivalent to [`rsphp_macros_c::ZEND_ARG_IS_VARIADIC!()`].
fn is_variadic(&self) -> bool;

/// Check if an argument is marked as promoted.
///
/// This is equivalent to [`rsphp_macros_c::ZEND_ARG_IS_PROMOTED!()`].
fn is_promoted(&self) -> bool;

/// Check if an argument is marked as having a tentative type.
///
/// This is equivalent to [`rsphp_macros_c::ZEND_ARG_TYPE_IS_TENTATIVE!()`].
fn is_tentative(&self) -> bool;
}

Expand Down
13 changes: 13 additions & 0 deletions src/extensions/zend_attribute_ext.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
//! Extension trait for [`rsphp_sys::zend_attribute`].
use rsphp_sys::{zend_attribute, zend_attribute_arg};
use std::fmt;
use std::ops::Range;

/// Extension trait for [`rsphp_sys::zend_attribute`].
pub trait ZendAttributeExt {
/// Get an iterator over the arguments of the attribute.
fn args(&self) -> ZendAttributeArgIter<'_>;
}

Expand Down Expand Up @@ -41,3 +44,13 @@ impl Iterator for ZendAttributeArgIter<'_> {
self.range.size_hint()
}
}

impl fmt::Debug for ZendAttributeArgIter<'_> {
#[expect(clippy::pointer_format, reason = "No better options")]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ZendAttributeArgIter")
.field("raw", &format!("{:p}", std::ptr::from_ref(self.raw)))
.field("range", &self.range)
.finish()
}
}
4 changes: 4 additions & 0 deletions src/extensions/zend_class_constant_ext.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
//! Extension trait for [`rsphp_sys::zend_class_constant`].
use rsphp_sys::zend_class_constant;

/// Extension trait for [`rsphp_sys::zend_class_constant`].
pub trait ZendClassConstantExt {
/// Get the flags of the constant.
///
/// This is equivalent to [`rsphp_macros_c::ZEND_CLASS_CONST_FLAGS!()`].
fn get_flags(&self) -> u32;
}

Expand Down
17 changes: 17 additions & 0 deletions src/extensions/zend_class_entry_ext.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
//! Extension trait for [`rsphp_sys::zend_class_entry`].
use rsphp_sys::{instanceof_function, zend_class_entry, zend_class_name};
use std::fmt;
use std::ops::Range;

/// Extension trait for [`rsphp_sys::zend_class_entry`].
pub trait ZendClassEntryExt {
/// Get an iterator over the names of the traits used by this class entry.
fn get_trait_names(&self) -> ZendClassEntryTraitNamesIter<'_>;

/// Check if this class is an instance of some other class.
///
/// Wrapper around [`rsphp_sys::instanceof_function()`].
fn instance_of(&self, other: &zend_class_entry) -> bool;
}

Expand Down Expand Up @@ -59,3 +66,13 @@ impl Iterator for ZendClassEntryTraitNamesIter<'_> {
self.range.size_hint()
}
}

impl fmt::Debug for ZendClassEntryTraitNamesIter<'_> {
#[expect(clippy::pointer_format, reason = "No better options")]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ZendClassEntryTraitNamesIter")
.field("raw", &format!("{:p}", std::ptr::from_ref(self.raw)))
.field("range", &self.range)
.finish()
}
}
8 changes: 8 additions & 0 deletions src/extensions/zend_constant_ext.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
//! Extension trait for [`rsphp_sys::zend_constant`].
use rsphp_sys::zend_constant;

/// Extension trait for [`rsphp_sys::zend_constant`].
pub trait ZendConstantExt {
/// Get the flags of the constant.
///
/// This is equivalent to [`rsphp_macros_c::ZEND_CONSTANT_FLAGS!()`].
fn get_flags(&self) -> u32;

/// Get the module number of the constant.
///
/// This is equivalent to [`rsphp_macros_c::ZEND_CONSTANT_MODULE_NUMBER!()`].
fn get_module_number(&self) -> u32;
}

Expand Down
10 changes: 10 additions & 0 deletions src/extensions/zend_extension_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@
use rsphp_sys::zend_extension;
use std::ffi::CStr;

/// Extension trait for [`rsphp_sys::zend_extension`].
pub trait ZendExtensionExt {
/// Get the name of the extension.
fn get_name(&self) -> &str;

/// Get the version of the extension, if set.
fn get_version(&self) -> Option<&str>;

/// Get the author of the extension, if set.
fn get_author(&self) -> Option<&str>;

/// Get the URL of the extension, if set.
fn get_url(&self) -> Option<&str>;

/// Get the copyright information of the extension, if set.
fn get_copyright(&self) -> Option<&str>;
}

Expand Down
10 changes: 10 additions & 0 deletions src/extensions/zend_function_ext.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
//! Extension trait for [`rsphp_sys::zend_function`].
use rsphp_sys::{_zend_function__common, zend_function};

/// Extension trait for [`rsphp_sys::zend_function`].
pub trait ZendFunctionExt {
/// Get the type of the function.
///
/// The result should be one of
/// - [`rsphp_sys::ZEND_INTERNAL_FUNCTION`]
/// - [`rsphp_sys::ZEND_USER_FUNCTION`]
/// - [`rsphp_sys::ZEND_EVAL_CODE`]
fn get_type(&self) -> u8;

/// Safe access for the common information shared by internal and userland
/// functions.
fn get_common(&self) -> &_zend_function__common;
}

Expand Down
4 changes: 4 additions & 0 deletions src/extensions/zend_module_dep_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
use rsphp_sys::zend_module_dep;
use std::ffi::CStr;

/// Extension trait for [`rsphp_sys::zend_module_dep`].
pub trait ZendModuleDepExt {
/// Get the relationship constraint of the dependency, if set.
fn get_relation(&self) -> Option<&str>;

/// Get the version for the relationship constraint of the dependency, if set.
fn get_version(&self) -> Option<&str>;
}

Expand Down
4 changes: 4 additions & 0 deletions src/extensions/zend_module_entry_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
use rsphp_sys::zend_module_entry;
use std::ffi::CStr;

/// Extension trait for [`rsphp_sys::zend_module_entry`].
pub trait ZendModuleEntryExt {
/// Get the name of the module entry.
fn get_name(&self) -> &str;

/// Get the version of the module entry, if set.
fn get_version(&self) -> Option<&str>;
}

Expand Down
4 changes: 4 additions & 0 deletions src/extensions/zend_string_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
use rsphp_macros_c::{ZSTR_LEN, ZSTR_VAL};
use rsphp_sys::zend_string;

/// Extension trait for [`rsphp_sys::zend_string`].
pub trait ZendStringExt {
/// Read the string as a slice.
fn as_slice(&self) -> &[u8];

#[cfg(feature = "bstr")]
/// Read the string as a [`bstr::BStr`].
fn as_bstr(&self) -> &bstr::BStr {
bstr::BStr::new(self.as_slice())
}
Expand Down
Loading
Loading