106_scan_allpackage/
106_scan_allpackage.rs1#[cfg(perlapi_ver26)]
2use std::env;
3
4#[cfg(perlapi_ver26)]
5use libperl_rs::*;
6
7#[cfg(perlapi_ver26)]
8mod eg;
9#[cfg(perlapi_ver26)]
10use eg::{op0::*,sv0::*,cv0::*,gv0::*};
11
12#[cfg(perlapi_ver26)]
13pub struct Walker<'a> {
14 pub perl: &'a Perl,
15 pub cv: *const libperl_sys::cv,
16}
17
18#[cfg(perlapi_ver26)]
19impl<'a> Walker<'a> {
20 pub fn walk(&'a self, o: *const op, level: isize) {
21 if o.is_null() {return}
22 for kid in sibling_iter(o) {
23 self.walk(kid, level+1);
24 }
25 print!("{}", " ".repeat(level as usize));
26 let ox = op_extract(&self.perl, self.cv, o);
27 println!("{:?} {:?}", op_name(o), ox);
28 }
29}
30
31#[cfg(perlapi_ver26)]
32fn my_test() {
33 let mut perl = Perl::new();
34 perl.parse_env_args(env::args(), env::vars());
35
36 let mut seen = Seen::new();
37 seen.insert("main".to_string(), true); stash_subs(&perl, "", &mut seen);
39}
40
41#[cfg(perlapi_ver26)]
42type Seen = std::collections::HashMap<String, bool>;
43
44#[cfg(perlapi_ver26)]
45fn stash_subs(perl: &Perl, pack: &str, seen: &mut Seen) {
46 println!("pack = {}", pack);
47
48 if seen.contains_key(pack) {return};
49 seen.insert(pack.to_string(), true);
50
51 let stash = perl.gv_stashpv(pack, 0);
52 if stash.is_null() {return}
53
54 let emitter = |name: &String, cv: *const libperl_sys::cv| {
55 let walker = Walker {perl: &perl, cv};
56 println!("sub {:?} file {:?}", name, CvFILE(cv));
57 walker.walk(CvROOT(cv), 0);
58 println!("");
59 };
60
61 for (name, item) in eg::hv_iter0::HvIter::new(&perl, stash) {
63
64 if let Some(Sv::CODE(cv)) = SvRV(item).map(|sv| sv_extract(sv)) {
66 emitter(&name, cv)
67 }
68 else if let Sv::GLOB {gv, ..} = sv_extract(item) {
70 let cv = GvCV(gv);
71 if let Some(_file) = CvFILE(cv) {
72 emitter(&name, cv);
73 }
74 if name.ends_with("::") {
75 println!("package name = {}", name);
76 if let Some(pure) = name.get(..name.len() - 2) {
77 if !seen.contains_key(pure) {
78 let mut fullpack = String::from(pack);
80 fullpack.push_str("::");
81 fullpack.push_str(pure);
82 stash_subs(perl, fullpack.as_str(), seen);
83 }
84 }
85 }
86 }
87 }
88
89 }
93
94#[cfg(not(perlapi_ver26))]
95fn my_test() {
96 println!("Requires perl >= 5.26");
97}
98
99fn main() {
100 my_test();
101}