Convert xsutils.c and lib/attributes.pm to a regular XS extension.
[p5sagit/p5-mst-13.2.git] / ext / attributes / attributes.xs
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"
09bef843 20#include "perl.h"
48462a74 21#include "XSUB.h"
09bef843 22
23/*
24 * Contributed by Spider Boardman (spider.boardman@orb.nashua.nh.us).
25 */
26
349fd7b7 27static int
acfe0abc 28modify_SV_attributes(pTHX_ SV *sv, SV **retlist, SV **attrlist, int numattrs)
09bef843 29{
97aff369 30 dVAR;
09bef843 31 SV *attr;
09bef843 32 int nret;
33
34 for (nret = 0 ; numattrs && (attr = *attrlist++); numattrs--) {
4373e329 35 STRLEN len;
cfd0369c 36 const char *name = SvPV_const(attr, len);
4373e329 37 const bool negated = (*name == '-');
38
39 if (negated) {
09bef843 40 name++;
41 len--;
42 }
43 switch (SvTYPE(sv)) {
44 case SVt_PVCV:
45 switch ((int)len) {
46 case 6:
8cad210e 47 switch (name[3]) {
d5adc3a1 48 case 'l':
8cad210e 49 if (memEQ(name, "lvalue", 6)) {
09bef843 50 if (negated)
ea726b52 51 CvFLAGS(MUTABLE_CV(sv)) &= ~CVf_LVALUE;
09bef843 52 else
ea726b52 53 CvFLAGS(MUTABLE_CV(sv)) |= CVf_LVALUE;
09bef843 54 continue;
55 }
8cad210e 56 break;
57 case 'k':
8cad210e 58 if (memEQ(name, "locked", 6)) {
09bef843 59 if (negated)
ea726b52 60 CvFLAGS(MUTABLE_CV(sv)) &= ~CVf_LOCKED;
09bef843 61 else
ea726b52 62 CvFLAGS(MUTABLE_CV(sv)) |= CVf_LOCKED;
09bef843 63 continue;
64 }
65 break;
8cad210e 66 case 'h':
67 if (memEQ(name, "method", 6)) {
09bef843 68 if (negated)
ea726b52 69 CvFLAGS(MUTABLE_CV(sv)) &= ~CVf_METHOD;
09bef843 70 else
ea726b52 71 CvFLAGS(MUTABLE_CV(sv)) |= CVf_METHOD;
09bef843 72 continue;
73 }
74 break;
75 }
76 break;
77 }
78 break;
79 default:
0256094b 80 switch ((int)len) {
95f0a2f1 81 case 6:
8cad210e 82 switch (name[5]) {
83 case 'd':
84 if (memEQ(name, "share", 5)) {
13c1b207 85 if (negated)
86 Perl_croak(aTHX_ "A variable may not be unshared");
87 SvSHARE(sv);
88 continue;
89 }
90 break;
8cad210e 91 case 'e':
92 if (memEQ(name, "uniqu", 5)) {
6e592b3a 93 if (isGV_with_GP(sv)) {
44f8325f 94 if (negated) {
95f0a2f1 95 GvUNIQUE_off(sv);
44f8325f 96 } else {
95f0a2f1 97 GvUNIQUE_on(sv);
44f8325f 98 }
95f0a2f1 99 }
100 /* Hope this came from toke.c if not a GV. */
0256094b 101 continue;
102 }
103 }
104 }
09bef843 105 break;
106 }
107 /* anything recognized had a 'continue' above */
108 *retlist++ = attr;
109 nret++;
110 }
111
112 return nret;
113}
114
48462a74 115MODULE = attributes PACKAGE = attributes
09bef843 116
48462a74 117void
118_modify_attrs(...)
119 PREINIT:
09bef843 120 SV *rv, *sv;
48462a74 121 PPCODE:
09bef843 122
123 if (items < 1) {
124usage:
afa74d42 125 croak_xs_usage(cv, "@attributes");
09bef843 126 }
127
128 rv = ST(0);
129 if (!(SvOK(rv) && SvROK(rv)))
130 goto usage;
131 sv = SvRV(rv);
132 if (items > 1)
acfe0abc 133 XSRETURN(modify_SV_attributes(aTHX_ sv, &ST(0), &ST(1), items-1));
09bef843 134
135 XSRETURN(0);
09bef843 136
48462a74 137void
138_fetch_attrs(...)
139 PREINIT:
09bef843 140 SV *rv, *sv;
141 cv_flags_t cvflags;
48462a74 142 PPCODE:
09bef843 143 if (items != 1) {
144usage:
afa74d42 145 croak_xs_usage(cv, "$reference");
09bef843 146 }
147
148 rv = ST(0);
09bef843 149 if (!(SvOK(rv) && SvROK(rv)))
150 goto usage;
151 sv = SvRV(rv);
152
153 switch (SvTYPE(sv)) {
154 case SVt_PVCV:
ea726b52 155 cvflags = CvFLAGS((const CV *)sv);
09bef843 156 if (cvflags & CVf_LOCKED)
84bafc02 157 XPUSHs(newSVpvs_flags("locked", SVs_TEMP));
09bef843 158 if (cvflags & CVf_LVALUE)
84bafc02 159 XPUSHs(newSVpvs_flags("lvalue", SVs_TEMP));
09bef843 160 if (cvflags & CVf_METHOD)
84bafc02 161 XPUSHs(newSVpvs_flags("method", SVs_TEMP));
ea726b52 162 if (GvUNIQUE(CvGV((const CV *)sv)))
84bafc02 163 XPUSHs(newSVpvs_flags("unique", SVs_TEMP));
95f0a2f1 164 break;
165 case SVt_PVGV:
6e592b3a 166 if (isGV_with_GP(sv) && GvUNIQUE(sv))
84bafc02 167 XPUSHs(newSVpvs_flags("unique", SVs_TEMP));
09bef843 168 break;
169 default:
170 break;
171 }
172
173 PUTBACK;
09bef843 174
48462a74 175void
176_guess_stash(...)
177 PREINIT:
09bef843 178 SV *rv, *sv;
d277572a 179 dXSTARG;
48462a74 180 PPCODE:
09bef843 181 if (items != 1) {
182usage:
afa74d42 183 croak_xs_usage(cv, "$reference");
09bef843 184 }
185
186 rv = ST(0);
187 ST(0) = TARG;
188 if (!(SvOK(rv) && SvROK(rv)))
189 goto usage;
190 sv = SvRV(rv);
191
192 if (SvOBJECT(sv))
7423f6db 193 sv_setpvn(TARG, HvNAME_get(SvSTASH(sv)), HvNAMELEN_get(SvSTASH(sv)));
09bef843 194#if 0 /* this was probably a bad idea */
195 else if (SvPADMY(sv))
196 sv_setsv(TARG, &PL_sv_no); /* unblessed lexical */
197#endif
198 else {
5c284bb0 199 const HV *stash = NULL;
09bef843 200 switch (SvTYPE(sv)) {
201 case SVt_PVCV:
6676db26 202 if (CvGV(sv) && isGV(CvGV(sv)) && GvSTASH(CvGV(sv)))
09bef843 203 stash = GvSTASH(CvGV(sv));
6676db26 204 else if (/* !CvANON(sv) && */ CvSTASH(sv))
09bef843 205 stash = CvSTASH(sv);
206 break;
09bef843 207 case SVt_PVGV:
159b6efe 208 if (isGV_with_GP(sv) && GvGP(sv) && GvESTASH(MUTABLE_GV(sv)))
209 stash = GvESTASH(MUTABLE_GV(sv));
09bef843 210 break;
211 default:
212 break;
213 }
214 if (stash)
7423f6db 215 sv_setpvn(TARG, HvNAME_get(stash), HvNAMELEN_get(stash));
09bef843 216 }
217
09bef843 218 SvSETMAGIC(TARG);
09bef843 219 XSRETURN(1);
09bef843 220
48462a74 221void
222reftype(...)
223 PREINIT:
09bef843 224 SV *rv, *sv;
d277572a 225 dXSTARG;
48462a74 226 PPCODE:
09bef843 227 if (items != 1) {
228usage:
afa74d42 229 croak_xs_usage(cv, "$reference");
09bef843 230 }
231
232 rv = ST(0);
233 ST(0) = TARG;
5b295bef 234 SvGETMAGIC(rv);
121e869f 235 if (!(SvOK(rv) && SvROK(rv)))
09bef843 236 goto usage;
237 sv = SvRV(rv);
238 sv_setpv(TARG, sv_reftype(sv, 0));
09bef843 239 SvSETMAGIC(TARG);
09bef843 240
241 XSRETURN(1);
66610fdd 242/*
243 * Local variables:
244 * c-indentation-style: bsd
245 * c-basic-offset: 4
246 * indent-tabs-mode: t
247 * End:
248 *
37442d52 249 * ex: set ts=8 sts=4 sw=4 noet:
48462a74 250 */