110_call_method/
110_call_method.rs

1#[cfg(all(perl_useithreads,perlapi_ver26))]
2use std::env;
3#[cfg(all(perl_useithreads,perlapi_ver26))]
4use libperl_rs::*;
5#[cfg(all(perl_useithreads,perlapi_ver26))]
6use libperl_sys::*;
7#[cfg(all(perl_useithreads,perlapi_ver26))]
8use std::convert::TryInto;
9
10#[cfg(all(perl_useithreads,perlapi_ver26))]
11mod eg;
12#[cfg(all(perl_useithreads,perlapi_ver26))]
13use eg::sv0::*;
14
15#[cfg(all(perl_useithreads,perlapi_ver26))]
16fn my_test() {
17    
18    let mut args = env::args().skip(1);
19    let inc_path = args.next().expect("Include path is required");
20    let class_name = args.next().expect("Class name is required");
21    let method_name = args.next().expect("Method name is required");
22    let method_args: Vec<String> = args.collect();
23    
24    let mut perl = Perl::new();
25    perl.parse(&[
26        "",
27        format!("-I{}", inc_path).as_str(),
28        format!("-M{}", class_name).as_str(),
29        "-e0",
30    ], &[]);
31    
32    match call_list_method(&mut perl, class_name, method_name, method_args) {
33        Ok(ary) => {
34            for item in ary {
35                println!("{:?}", item);
36            }
37        }
38        Err(e) => {
39            println!("ERROR: {:?}", e);
40        }
41    }
42}
43
44#[cfg(all(perl_useithreads,perlapi_ver26))]
45fn call_list_method(perl: &mut Perl, class_name: String, method_name: String, args: Vec<String>) -> Result<Vec<Sv>,String>
46{
47
48    let my_perl = perl.my_perl();
49
50    // dSP
51    let mut sp = my_perl.Istack_sp;
52
53    // ENTER
54    unsafe_perl_api!{Perl_push_scope(perl.my_perl)};
55
56    // SAVETMPS
57    unsafe_perl_api!{Perl_savetmps(perl.my_perl)};
58
59    // PUSHMARK(SP)
60    perl.pushmark(sp);
61    
62    // (... argument pushing ...)
63    // EXTEND(SP, 1+method_args.len())
64    sp = unsafe_perl_api!{Perl_stack_grow(perl.my_perl, sp, sp, (1 + args.len()).try_into().unwrap())};
65    
66    for s in [&[class_name], args.as_slice()].concat() {
67        sp_push!(sp, perl.str2svpv_mortal(s.as_str()));
68    }
69
70    // PUTBACK
71    my_perl.Istack_sp = sp;
72
73    // call_method
74    let cnt = unsafe_perl_api!{Perl_call_method(perl.my_perl, method_name.as_ptr() as *const i8, (G_METHOD_NAMED | G_LIST) as i32)};
75    
76    // SPAGAIN
77    // sp = my_perl.Istack_sp;
78    // (PUTBACK)
79
80    let res = stack_extract(&perl, cnt);
81
82    // FREETMPS
83    perl.free_tmps();
84    // LEAVE
85    unsafe_perl_api!{Perl_pop_scope(perl.my_perl)};
86    
87    Ok(res)
88}
89
90#[cfg(all(perl_useithreads,perlapi_ver26))]
91fn stack_extract(perl: &Perl, count: perl_stack_size_t) -> Vec<Sv> {
92    let mut res = Vec::new();
93
94    let mut src = unsafe {(*(perl.my_perl)).Istack_base.add(1)};
95
96    for _i in 0..count {
97        let sv = unsafe {*src};
98        res.push(sv_extract(sv));
99        src = unsafe {src.add(1)}
100    }
101    
102    res
103}
104
105#[cfg(not(all(perl_useithreads,perlapi_ver26)))]
106fn my_test() {
107}
108
109fn main() {
110    my_test()
111}