Commit | Line | Data |
38bf2a25 |
1 | #include "mop.h" |
2 | |
3 | static bool |
4 | find_method (const char *key, STRLEN keylen, SV *val, void *ud) |
5 | { |
6 | bool *found_method = (bool *)ud; |
7 | PERL_UNUSED_ARG(key); |
8 | PERL_UNUSED_ARG(keylen); |
9 | PERL_UNUSED_ARG(val); |
10 | *found_method = TRUE; |
11 | return FALSE; |
12 | } |
13 | |
14 | static bool |
15 | check_version (SV *klass, SV *required_version) |
16 | { |
17 | bool ret = 0; |
18 | |
19 | dSP; |
20 | ENTER; |
21 | SAVETMPS; |
22 | PUSHMARK(SP); |
23 | EXTEND(SP, 2); |
24 | PUSHs(klass); |
25 | PUSHs(required_version); |
26 | PUTBACK; |
27 | |
28 | call_method("VERSION", G_DISCARD|G_VOID|G_EVAL); |
29 | |
30 | SPAGAIN; |
31 | |
32 | if (!SvTRUE(ERRSV)) { |
33 | ret = 1; |
34 | } |
35 | |
36 | PUTBACK; |
37 | FREETMPS; |
38 | LEAVE; |
39 | |
40 | return ret; |
41 | } |
42 | |
43 | MODULE = Class::MOP PACKAGE = Class::MOP |
44 | |
45 | PROTOTYPES: DISABLE |
46 | |
47 | # use prototype here to be compatible with get_code_info from Sub::Identify |
48 | void |
49 | get_code_info(coderef) |
50 | SV *coderef |
51 | PROTOTYPE: $ |
52 | PREINIT: |
53 | char *pkg = NULL; |
54 | char *name = NULL; |
55 | PPCODE: |
56 | SvGETMAGIC(coderef); |
57 | if (mop_get_code_info(coderef, &pkg, &name)) { |
58 | EXTEND(SP, 2); |
59 | mPUSHs(newSVpv(pkg, 0)); |
60 | mPUSHs(newSVpv(name, 0)); |
61 | } |
62 | |
63 | void |
64 | is_class_loaded(klass, options=NULL) |
65 | SV *klass |
66 | HV *options |
67 | PREINIT: |
68 | HV *stash; |
69 | bool found_method = FALSE; |
70 | PPCODE: |
71 | SvGETMAGIC(klass); |
72 | if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */ |
73 | XSRETURN_NO; |
74 | } |
75 | |
76 | stash = gv_stashsv(klass, 0); |
77 | if (!stash) { |
78 | XSRETURN_NO; |
79 | } |
80 | |
81 | if (options && hv_exists_ent(options, KEY_FOR(_version), HASH_FOR(_version))) { |
82 | HE *required_version = hv_fetch_ent(options, KEY_FOR(_version), 0, HASH_FOR(_version)); |
83 | if (check_version (klass, HeVAL(required_version))) { |
84 | XSRETURN_YES; |
85 | } |
86 | |
87 | XSRETURN_NO; |
88 | } |
89 | |
90 | if (hv_exists_ent (stash, KEY_FOR(VERSION), HASH_FOR(VERSION))) { |
91 | HE *version = hv_fetch_ent(stash, KEY_FOR(VERSION), 0, HASH_FOR(VERSION)); |
92 | SV *version_sv; |
93 | if (version && HeVAL(version) && (version_sv = GvSV(HeVAL(version)))) { |
94 | if (SvROK(version_sv)) { |
95 | SV *version_sv_ref = SvRV(version_sv); |
96 | |
97 | if (SvOK(version_sv_ref)) { |
98 | XSRETURN_YES; |
99 | } |
100 | } |
101 | else if (SvOK(version_sv)) { |
102 | XSRETURN_YES; |
103 | } |
104 | } |
105 | } |
106 | |
107 | if (hv_exists_ent (stash, KEY_FOR(ISA), HASH_FOR(ISA))) { |
108 | HE *isa = hv_fetch_ent(stash, KEY_FOR(ISA), 0, HASH_FOR(ISA)); |
109 | if (isa && HeVAL(isa) && GvAV(HeVAL(isa)) && av_len(GvAV(HeVAL(isa))) != -1) { |
110 | XSRETURN_YES; |
111 | } |
112 | } |
113 | |
114 | mop_get_package_symbols(stash, TYPE_FILTER_CODE, find_method, &found_method); |
115 | if (found_method) { |
116 | XSRETURN_YES; |
117 | } |
118 | |
119 | XSRETURN_NO; |