Improve and restructure t/op/pat.t and split out some unicode related tests into...
[p5sagit/p5-mst-13.2.git] / xsutils.c
CommitLineData
d6376244 1/* xsutils.c
2 *
1129b882 3 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
371fce9b 4 * by Larry Wall and others
d6376244 5 *
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
8 *
9 */
10
d31a8517 11/*
4ac71550 12 * 'Perilous to us all are the devices of an art deeper than we possess
13 * ourselves.' --Gandalf
14 *
15 * [p.597 of _The Lord of the Rings_, III/xi: "The Palantír"]
d31a8517 16 */
17
18
09bef843 19#include "EXTERN.h"
20#define PERL_IN_XSUTILS_C
21#include "perl.h"
22
23/*
24 * Contributed by Spider Boardman (spider.boardman@orb.nashua.nh.us).
25 */
26
349fd7b7 27/* package attributes; */
27da23d5 28PERL_XS_EXPORT_C void XS_attributes_reftype(pTHX_ CV *cv);
29PERL_XS_EXPORT_C void XS_attributes__modify_attrs(pTHX_ CV *cv);
30PERL_XS_EXPORT_C void XS_attributes__guess_stash(pTHX_ CV *cv);
31PERL_XS_EXPORT_C void XS_attributes__fetch_attrs(pTHX_ CV *cv);
32PERL_XS_EXPORT_C void XS_attributes_bootstrap(pTHX_ CV *cv);
349fd7b7 33
34
35/*
36 * Note that only ${pkg}::bootstrap definitions should go here.
37 * This helps keep down the start-up time, which is especially
38 * relevant for users who don't invoke any features which are
39 * (partially) implemented here.
40 *
41 * The various bootstrap definitions can take care of doing
42 * package-specific newXS() calls. Since the layout of the
6a34af38 43 * bundled *.pm files is in a version-specific directory,
349fd7b7 44 * version checks in these bootstrap calls are optional.
45 */
46
a4c98449 47static const char file[] = __FILE__;
48
349fd7b7 49void
50Perl_boot_core_xsutils(pTHX)
51{
349fd7b7 52 newXS("attributes::bootstrap", XS_attributes_bootstrap, file);
53}
54
349fd7b7 55#include "XSUB.h"
56
57static int
acfe0abc 58modify_SV_attributes(pTHX_ SV *sv, SV **retlist, SV **attrlist, int numattrs)
09bef843 59{
97aff369 60 dVAR;
09bef843 61 SV *attr;
09bef843 62 int nret;
63
64 for (nret = 0 ; numattrs && (attr = *attrlist++); numattrs--) {
4373e329 65 STRLEN len;
cfd0369c 66 const char *name = SvPV_const(attr, len);
4373e329 67 const bool negated = (*name == '-');
68
69 if (negated) {
09bef843 70 name++;
71 len--;
72 }
73 switch (SvTYPE(sv)) {
74 case SVt_PVCV:
75 switch ((int)len) {
76 case 6:
8cad210e 77 switch (name[3]) {
09bef843 78#ifdef CVf_LVALUE
d5adc3a1 79 case 'l':
8cad210e 80 if (memEQ(name, "lvalue", 6)) {
09bef843 81 if (negated)
ea726b52 82 CvFLAGS(MUTABLE_CV(sv)) &= ~CVf_LVALUE;
09bef843 83 else
ea726b52 84 CvFLAGS(MUTABLE_CV(sv)) |= CVf_LVALUE;
09bef843 85 continue;
86 }
8cad210e 87 break;
d5adc3a1 88#endif
8cad210e 89 case 'k':
8cad210e 90 if (memEQ(name, "locked", 6)) {
09bef843 91 if (negated)
ea726b52 92 CvFLAGS(MUTABLE_CV(sv)) &= ~CVf_LOCKED;
09bef843 93 else
ea726b52 94 CvFLAGS(MUTABLE_CV(sv)) |= CVf_LOCKED;
09bef843 95 continue;
96 }
97 break;
8cad210e 98 case 'h':
99 if (memEQ(name, "method", 6)) {
09bef843 100 if (negated)
ea726b52 101 CvFLAGS(MUTABLE_CV(sv)) &= ~CVf_METHOD;
09bef843 102 else
ea726b52 103 CvFLAGS(MUTABLE_CV(sv)) |= CVf_METHOD;
09bef843 104 continue;
105 }
106 break;
107 }
108 break;
109 }
110 break;
111 default:
0256094b 112 switch ((int)len) {
95f0a2f1 113 case 6:
8cad210e 114 switch (name[5]) {
115 case 'd':
116 if (memEQ(name, "share", 5)) {
13c1b207 117 if (negated)
118 Perl_croak(aTHX_ "A variable may not be unshared");
119 SvSHARE(sv);
120 continue;
121 }
122 break;
8cad210e 123 case 'e':
124 if (memEQ(name, "uniqu", 5)) {
6e592b3a 125 if (isGV_with_GP(sv)) {
44f8325f 126 if (negated) {
95f0a2f1 127 GvUNIQUE_off(sv);
44f8325f 128 } else {
95f0a2f1 129 GvUNIQUE_on(sv);
44f8325f 130 }
95f0a2f1 131 }
132 /* Hope this came from toke.c if not a GV. */
0256094b 133 continue;
134 }
135 }
136 }
09bef843 137 break;
138 }
139 /* anything recognized had a 'continue' above */
140 *retlist++ = attr;
141 nret++;
142 }
143
144 return nret;
145}
146
147
09bef843 148
149/* package attributes; */
150
151XS(XS_attributes_bootstrap)
152{
97aff369 153 dVAR;
09bef843 154 dXSARGS;
09bef843 155
592f5969 156 if( items > 1 )
afa74d42 157 croak_xs_usage(cv, "$module");
b7953727 158
09bef843 159 newXS("attributes::_modify_attrs", XS_attributes__modify_attrs, file);
160 newXSproto("attributes::_guess_stash", XS_attributes__guess_stash, file, "$");
161 newXSproto("attributes::_fetch_attrs", XS_attributes__fetch_attrs, file, "$");
162 newXSproto("attributes::reftype", XS_attributes_reftype, file, "$");
163
164 XSRETURN(0);
165}
166
167XS(XS_attributes__modify_attrs)
168{
97aff369 169 dVAR;
09bef843 170 dXSARGS;
171 SV *rv, *sv;
172
173 if (items < 1) {
174usage:
afa74d42 175 croak_xs_usage(cv, "@attributes");
09bef843 176 }
177
178 rv = ST(0);
179 if (!(SvOK(rv) && SvROK(rv)))
180 goto usage;
181 sv = SvRV(rv);
182 if (items > 1)
acfe0abc 183 XSRETURN(modify_SV_attributes(aTHX_ sv, &ST(0), &ST(1), items-1));
09bef843 184
185 XSRETURN(0);
186}
187
188XS(XS_attributes__fetch_attrs)
189{
97aff369 190 dVAR;
09bef843 191 dXSARGS;
192 SV *rv, *sv;
193 cv_flags_t cvflags;
194
195 if (items != 1) {
196usage:
afa74d42 197 croak_xs_usage(cv, "$reference");
09bef843 198 }
199
200 rv = ST(0);
201 SP -= items;
202 if (!(SvOK(rv) && SvROK(rv)))
203 goto usage;
204 sv = SvRV(rv);
205
206 switch (SvTYPE(sv)) {
207 case SVt_PVCV:
ea726b52 208 cvflags = CvFLAGS((const CV *)sv);
09bef843 209 if (cvflags & CVf_LOCKED)
84bafc02 210 XPUSHs(newSVpvs_flags("locked", SVs_TEMP));
09bef843 211#ifdef CVf_LVALUE
212 if (cvflags & CVf_LVALUE)
84bafc02 213 XPUSHs(newSVpvs_flags("lvalue", SVs_TEMP));
09bef843 214#endif
215 if (cvflags & CVf_METHOD)
84bafc02 216 XPUSHs(newSVpvs_flags("method", SVs_TEMP));
ea726b52 217 if (GvUNIQUE(CvGV((const CV *)sv)))
84bafc02 218 XPUSHs(newSVpvs_flags("unique", SVs_TEMP));
95f0a2f1 219 break;
220 case SVt_PVGV:
6e592b3a 221 if (isGV_with_GP(sv) && GvUNIQUE(sv))
84bafc02 222 XPUSHs(newSVpvs_flags("unique", SVs_TEMP));
09bef843 223 break;
224 default:
225 break;
226 }
227
228 PUTBACK;
229}
230
231XS(XS_attributes__guess_stash)
232{
97aff369 233 dVAR;
09bef843 234 dXSARGS;
235 SV *rv, *sv;
d277572a 236 dXSTARG;
09bef843 237
238 if (items != 1) {
239usage:
afa74d42 240 croak_xs_usage(cv, "$reference");
09bef843 241 }
242
243 rv = ST(0);
244 ST(0) = TARG;
245 if (!(SvOK(rv) && SvROK(rv)))
246 goto usage;
247 sv = SvRV(rv);
248
249 if (SvOBJECT(sv))
7423f6db 250 sv_setpvn(TARG, HvNAME_get(SvSTASH(sv)), HvNAMELEN_get(SvSTASH(sv)));
09bef843 251#if 0 /* this was probably a bad idea */
252 else if (SvPADMY(sv))
253 sv_setsv(TARG, &PL_sv_no); /* unblessed lexical */
254#endif
255 else {
5c284bb0 256 const HV *stash = NULL;
09bef843 257 switch (SvTYPE(sv)) {
258 case SVt_PVCV:
6676db26 259 if (CvGV(sv) && isGV(CvGV(sv)) && GvSTASH(CvGV(sv)))
09bef843 260 stash = GvSTASH(CvGV(sv));
6676db26 261 else if (/* !CvANON(sv) && */ CvSTASH(sv))
09bef843 262 stash = CvSTASH(sv);
263 break;
09bef843 264 case SVt_PVGV:
159b6efe 265 if (isGV_with_GP(sv) && GvGP(sv) && GvESTASH(MUTABLE_GV(sv)))
266 stash = GvESTASH(MUTABLE_GV(sv));
09bef843 267 break;
268 default:
269 break;
270 }
271 if (stash)
7423f6db 272 sv_setpvn(TARG, HvNAME_get(stash), HvNAMELEN_get(stash));
09bef843 273 }
274
09bef843 275 SvSETMAGIC(TARG);
09bef843 276 XSRETURN(1);
277}
278
279XS(XS_attributes_reftype)
280{
97aff369 281 dVAR;
09bef843 282 dXSARGS;
283 SV *rv, *sv;
d277572a 284 dXSTARG;
09bef843 285
286 if (items != 1) {
287usage:
afa74d42 288 croak_xs_usage(cv, "$reference");
09bef843 289 }
290
291 rv = ST(0);
292 ST(0) = TARG;
5b295bef 293 SvGETMAGIC(rv);
121e869f 294 if (!(SvOK(rv) && SvROK(rv)))
09bef843 295 goto usage;
296 sv = SvRV(rv);
297 sv_setpv(TARG, sv_reftype(sv, 0));
09bef843 298 SvSETMAGIC(TARG);
09bef843 299
300 XSRETURN(1);
301}
302
66610fdd 303/*
304 * Local variables:
305 * c-indentation-style: bsd
306 * c-basic-offset: 4
307 * indent-tabs-mode: t
308 * End:
309 *
37442d52 310 * ex: set ts=8 sts=4 sw=4 noet:
311 */