mirror of
https://github.com/icewind1991/ivory.git
synced 2026-06-03 18:54:07 +02:00
cleanup
This commit is contained in:
parent
99bdad5ec0
commit
aa1e5d7dca
14 changed files with 86 additions and 85 deletions
|
|
@ -15,7 +15,7 @@ fn hello_other(other: String) {
|
|||
|
||||
#[ivory_export]
|
||||
fn hello_world() {
|
||||
printf("Hello world, Rust2!");
|
||||
printf("Hello world, Rust!");
|
||||
}
|
||||
|
||||
ivory_module!({
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ authors = ["Robin Appelman <robin@icewind.nl>"]
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.50"
|
||||
ivory = { path = "../../ivory", version = "0.1.0" }
|
||||
|
||||
[lib]
|
||||
|
|
|
|||
|
|
@ -5,5 +5,5 @@
|
|||
- build with `cargo build`
|
||||
- run php with the module and call the defined method
|
||||
```bash
|
||||
php -d extension=target/debug/libhelloworld.so -r 'helloworld();'`
|
||||
php -d extension=../../target/debug/libhelloworld.so -r 'helloworld();'`
|
||||
```
|
||||
|
|
@ -8,7 +8,7 @@ fn hello_other(other: String) {
|
|||
|
||||
#[ivory_export]
|
||||
fn hello_world() {
|
||||
printf("Hello world, Rust2!");
|
||||
printf("Hello world, Rust!");
|
||||
}
|
||||
|
||||
ivory_module!({
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ repository = "https://github.com/rethinkphp/php-rs"
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.50"
|
||||
ivory-macro = { version = "0.1", path = "macro" }
|
||||
ivory-sys = { version = "7.3", path = "sys" }
|
||||
|
||||
|
|
|
|||
|
|
@ -4,22 +4,26 @@ extern crate proc_macro;
|
|||
|
||||
use proc_macro2::{Span, TokenStream, TokenTree};
|
||||
use quote::quote;
|
||||
use syn::{AttributeArgs, Expr, FieldValue, FnArg, Ident, Item, ItemFn, LitStr, parse2, parse_macro_input, Pat, Type};
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{
|
||||
parse2, parse_macro_input, AttributeArgs, Expr, FieldValue, FnArg, Ident, Item, ItemFn, LitStr,
|
||||
Pat, Type,
|
||||
};
|
||||
|
||||
/// See the [crate documentation](index.html) for details
|
||||
#[proc_macro_attribute]
|
||||
pub fn ivory_export(attr: proc_macro::TokenStream, input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
pub fn ivory_export(
|
||||
attr: proc_macro::TokenStream,
|
||||
input: proc_macro::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
let input: TokenStream = input.into();
|
||||
let item = syn::parse2::<Item>(input).unwrap();
|
||||
let _attr = parse_macro_input!(attr as AttributeArgs);
|
||||
|
||||
let output = match item {
|
||||
Item::Fn(item_fn) => {
|
||||
export_fn(item_fn).into()
|
||||
}
|
||||
_ => unimplemented!()
|
||||
Item::Fn(item_fn) => export_fn(item_fn).into(),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
|
||||
// panic!("{}", output);
|
||||
|
|
@ -38,9 +42,7 @@ fn export_fn(item: ItemFn) -> TokenStream {
|
|||
unimplemented!("generics are not supported for exported functions");
|
||||
}
|
||||
|
||||
let args: Vec<(String, Type, bool, Span)> = decl.inputs.into_iter()
|
||||
.map(get_arg_info)
|
||||
.collect();
|
||||
let args: Vec<(String, Type, bool, Span)> = decl.inputs.into_iter().map(get_arg_info).collect();
|
||||
let arg_count = args.len() as u32;
|
||||
|
||||
let arg_defs = args.iter().map(|(name, _type, is_ref, _)| {
|
||||
|
|
@ -77,7 +79,7 @@ fn export_fn(item: ItemFn) -> TokenStream {
|
|||
}
|
||||
|
||||
const #meta_name: ::ivory::zend::FunctionMeta = ::ivory::zend::FunctionMeta{
|
||||
name: {concat!(#name_str, "\0").as_ptr() as *const ::libc::c_char},
|
||||
name: {concat!(#name_str, "\0").as_ptr() as *const ::std::os::raw::c_char},
|
||||
func: #name,
|
||||
args: &[ #(#arg_defs),*]
|
||||
};
|
||||
|
|
@ -89,14 +91,17 @@ fn get_arg_info(arg: FnArg) -> (String, Type, bool, Span) {
|
|||
FnArg::Captured(cap) => {
|
||||
let arg_type = cap.ty;
|
||||
match cap.pat {
|
||||
Pat::Ident(ident_pat) => {
|
||||
(ident_pat.ident.to_string(), arg_type, ident_pat.by_ref.is_some(), ident_pat.span())
|
||||
},
|
||||
Pat::Ident(ident_pat) => (
|
||||
ident_pat.ident.to_string(),
|
||||
arg_type,
|
||||
ident_pat.by_ref.is_some(),
|
||||
ident_pat.span(),
|
||||
),
|
||||
Pat::Ref(_ref_pat) => unimplemented!(),
|
||||
_ => panic!()
|
||||
_ => panic!(),
|
||||
}
|
||||
},
|
||||
_ => panic!("only normal function arguments are supported")
|
||||
}
|
||||
_ => panic!("only normal function arguments are supported"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,10 +114,8 @@ pub fn ivory_module(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||
let mut tokens = input.into_iter();
|
||||
let token = tokens.next().unwrap();
|
||||
let group = match token {
|
||||
TokenTree::Group(group) => {
|
||||
group
|
||||
}
|
||||
_ => panic!("macro input must be a group")
|
||||
TokenTree::Group(group) => group,
|
||||
_ => panic!("macro input must be a group"),
|
||||
};
|
||||
|
||||
let fields = group.stream();
|
||||
|
|
@ -161,8 +164,9 @@ pub fn ivory_module(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||
}
|
||||
|
||||
fn into_c_str(input: TokenStream) -> TokenStream {
|
||||
let tokens: Vec<TokenTree> = input.into_iter().map(|token| {
|
||||
match token.clone() {
|
||||
let tokens: Vec<TokenTree> = input
|
||||
.into_iter()
|
||||
.map(|token| match token.clone() {
|
||||
TokenTree::Literal(_lit) => {
|
||||
let mut tokens = TokenStream::new();
|
||||
tokens.extend(vec![token.clone()]);
|
||||
|
|
@ -170,7 +174,7 @@ fn into_c_str(input: TokenStream) -> TokenStream {
|
|||
Ok(lit_str) => {
|
||||
let val = lit_str.value();
|
||||
let tokens = quote! {
|
||||
{ concat!(#val, "\0").as_ptr() as *const ::libc::c_char }
|
||||
{ concat!(#val, "\0").as_ptr() as *const ::std::os::raw::c_char }
|
||||
};
|
||||
if let Some(tree) = tokens.into_iter().next() {
|
||||
tree
|
||||
|
|
@ -178,12 +182,12 @@ fn into_c_str(input: TokenStream) -> TokenStream {
|
|||
panic!();
|
||||
}
|
||||
}
|
||||
Err(_) => token
|
||||
Err(_) => token,
|
||||
}
|
||||
}
|
||||
_ => token
|
||||
}
|
||||
}).collect();
|
||||
_ => token,
|
||||
})
|
||||
.collect();
|
||||
let mut output = TokenStream::new();
|
||||
output.extend(tokens.into_iter());
|
||||
output
|
||||
|
|
@ -193,31 +197,29 @@ fn get_function_names(struct_def: TokenStream) -> Vec<String> {
|
|||
let expr: Expr = parse2(struct_def).unwrap();
|
||||
let expr = get_field_expr(expr, "functions").unwrap();
|
||||
match expr {
|
||||
Expr::Reference(ref_expr) => {
|
||||
match *ref_expr.expr {
|
||||
Expr::Array(arr) => {
|
||||
arr.elems.into_iter().map(|element: Expr| {
|
||||
Expr::Reference(ref_expr) => match *ref_expr.expr {
|
||||
Expr::Array(arr) => arr
|
||||
.elems
|
||||
.into_iter()
|
||||
.map(|element: Expr| {
|
||||
let tokens: TokenStream = quote!(#element);
|
||||
let tree = tokens.into_iter().next().unwrap();
|
||||
match tree {
|
||||
TokenTree::Ident(ident) => {
|
||||
ident.to_string()
|
||||
TokenTree::Ident(ident) => ident.to_string(),
|
||||
_ => panic!(),
|
||||
}
|
||||
_ => panic!()
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
_ => panic!()
|
||||
}
|
||||
}
|
||||
_ => panic!()
|
||||
})
|
||||
.collect(),
|
||||
_ => panic!(),
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_field_expr(expr: Expr, field_name: &str) -> Option<Expr> {
|
||||
let fields: Punctuated<FieldValue, syn::token::Comma> = match expr {
|
||||
Expr::Struct(expr) => expr.fields,
|
||||
_ => panic!("invalid struct")
|
||||
_ => panic!("invalid struct"),
|
||||
};
|
||||
for field in fields {
|
||||
if let syn::Member::Named(ident) = &field.member {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
use std::ffi::CString;
|
||||
use std::intrinsics::transmute;
|
||||
|
||||
use libc::*;
|
||||
|
||||
use ivory_sys::zend_error;
|
||||
|
||||
extern "C" {
|
||||
pub fn php_printf(format: *const c_char, ...) -> size_t;
|
||||
}
|
||||
use ivory_sys::{php_printf, zend_error};
|
||||
|
||||
pub fn printf<T: Into<Vec<u8>>>(string: T) {
|
||||
let cstr = CString::new(string).unwrap();
|
||||
unsafe { php_printf(cstr.as_ptr()); }
|
||||
unsafe {
|
||||
php_printf(cstr.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
|
|
@ -41,5 +37,7 @@ impl From<ErrorLevel> for i32 {
|
|||
|
||||
pub fn error<T: Into<Vec<u8>>>(level: ErrorLevel, message: T) {
|
||||
let cstr = CString::new(message).unwrap();
|
||||
unsafe { zend_error(level.into(), cstr.as_ptr()); }
|
||||
unsafe {
|
||||
zend_error(level.into(), cstr.as_ptr());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
use libc::*;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
|
||||
extern "C" {
|
||||
pub fn php_info_print_table_start();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#[macro_export]
|
||||
macro_rules! c_str {
|
||||
($s:expr) => {{
|
||||
concat!($s, "\0").as_ptr() as *const ::libc::c_char
|
||||
concat!($s, "\0").as_ptr() as *const ::std::os::raw::c_char
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use std;
|
||||
|
||||
use libc::*;
|
||||
use std::os::raw::{c_char, c_uchar};
|
||||
|
||||
use crate::zend::HandlerFunc;
|
||||
|
||||
|
|
@ -33,7 +32,6 @@ impl ArgInfo {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[repr(C)]
|
||||
pub struct Function {
|
||||
fname: *const c_char,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use std;
|
||||
use std::mem;
|
||||
use std::os::raw::{c_char, c_int, c_uchar, c_uint, c_ushort, c_void};
|
||||
|
||||
use libc::*;
|
||||
|
||||
use crate::zend::function::{Function, ArgInfo};
|
||||
use crate::zend::function::{ArgInfo, Function};
|
||||
use crate::zend::{ExecuteData, ZVal};
|
||||
|
||||
pub(crate) type StartupFunc = extern "C" fn(type_: c_int, module_number: c_int) -> c_int;
|
||||
|
|
@ -34,7 +33,7 @@ pub struct ModuleInternal {
|
|||
request_shutdown_func: Option<ShutdownFunc>,
|
||||
info_func: Option<InfoFunc>,
|
||||
version: *const c_char,
|
||||
globals_size: size_t,
|
||||
globals_size: usize,
|
||||
globals_ptr: *const c_void,
|
||||
globals_ctor: Option<GlobalsCtorFunc>,
|
||||
globals_dtor: Option<GlobalsDtorFunc>,
|
||||
|
|
@ -97,7 +96,7 @@ impl ModuleInternal {
|
|||
pub struct FunctionMeta {
|
||||
pub name: *const c_char,
|
||||
pub func: HandlerFunc,
|
||||
pub args: &'static [ArgInfo]
|
||||
pub args: &'static [ArgInfo],
|
||||
}
|
||||
|
||||
impl FunctionMeta {
|
||||
|
|
@ -114,5 +113,5 @@ pub struct PhpModule {
|
|||
pub name: *const c_char,
|
||||
pub version: *const c_char,
|
||||
pub functions: &'static [HandlerFunc],
|
||||
pub info: &'static [(&'static str, &'static str)]
|
||||
pub info: &'static [(&'static str, &'static str)],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
# ivory-sys
|
||||
|
||||
Bindings to php.
|
||||
|
||||
## PHP version
|
||||
|
||||
While building, it will grab the source for the php version specified in `Cargo.toml`.
|
||||
Thus changing the version number of the crate also changes the version of php which it's compiled against
|
||||
|
||||
## Credits
|
||||
|
||||
This crate is taken almost entirely from [php-sys](https://github.com/hjr3/php-rpm/tree/master/php-sys), all credit goes to it's authors
|
||||
|
|
@ -26,7 +26,11 @@ fn run_command_or_fail(dir: String, cmd: &str, args: &[&str]) {
|
|||
args.join(" "),
|
||||
dir
|
||||
);
|
||||
let ret = Command::new(cmd).current_dir(dir).args(args).env("CC", "clang").status();
|
||||
let ret = Command::new(cmd)
|
||||
.current_dir(dir)
|
||||
.args(args)
|
||||
.env("CC", "clang")
|
||||
.status();
|
||||
match ret.map(|status| (status.success(), status.code())) {
|
||||
Ok((true, _)) => return,
|
||||
Ok((false, Some(c))) => panic!("Command failed with error code {}", c),
|
||||
|
|
@ -69,14 +73,7 @@ fn main() {
|
|||
|
||||
if !exists("php-src/LICENSE") {
|
||||
println_stderr!("Setting up PHP {}", php_version);
|
||||
run_command_or_fail(
|
||||
"/".to_string(),
|
||||
"mkdir",
|
||||
&[
|
||||
"-p",
|
||||
&target("")
|
||||
],
|
||||
);
|
||||
run_command_or_fail("/".to_string(), "mkdir", &["-p", &target("")]);
|
||||
run_command_or_fail(
|
||||
target(""),
|
||||
"git",
|
||||
|
|
@ -159,6 +156,7 @@ fn main() {
|
|||
.whitelist_function("php_printf")
|
||||
.whitelist_type("zval")
|
||||
.whitelist_type("zend_execute_data")
|
||||
.whitelist_type("zend_module_entry")
|
||||
.derive_default(false)
|
||||
.header("wrapper.h")
|
||||
.generate()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,5 @@
|
|||
#define PHP_RS_WRAPPER_H
|
||||
#include <Zend/zend.h>
|
||||
#include <Zend/zend_compile.h>
|
||||
//#include <main/php.h>
|
||||
//#include <sapi/embed/php_embed.h>
|
||||
#include <main/php.h>
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue