Revert change #22520 (optimise away my $foo = undef and similar
[p5sagit/p5-mst-13.2.git] / universal.c
CommitLineData
d6376244 1/* universal.c
2 *
b5f8cc5c 3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
241d1a3b 4 * 2005, 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/*
12 * "The roots of those mountains must be roots indeed; there must be
13 * great secrets buried there which have not been discovered since the
14 * beginning." --Gandalf, relating Gollum's story
15 */
16
166f8a29 17/* This file contains the code that implements the functions in Perl's
18 * UNIVERSAL package, such as UNIVERSAL->can().
19 */
20
6d4a7be2 21#include "EXTERN.h"
864dbfa3 22#define PERL_IN_UNIVERSAL_C
6d4a7be2 23#include "perl.h"
6d4a7be2 24
39f7a870 25#ifdef USE_PERLIO
26#include "perliol.h" /* For the PERLIO_F_XXX */
27#endif
28
6d4a7be2 29/*
30 * Contributed by Graham Barr <Graham.Barr@tiuk.ti.com>
31 * The main guts of traverse_isa was actually copied from gv_fetchmeth
32 */
33
76e3520e 34STATIC SV *
301daebc 35S_isa_lookup(pTHX_ HV *stash, const char *name, HV* name_stash,
36 int len, int level)
6d4a7be2 37{
38 AV* av;
39 GV* gv;
40 GV** gvp;
41 HV* hv = Nullhv;
46e4b22b 42 SV* subgen = Nullsv;
bfcb3514 43 const char *hvname;
6d4a7be2 44
301daebc 45 /* A stash/class can go by many names (ie. User == main::User), so
46 we compare the stash itself just in case */
47 if (name_stash && (stash == name_stash))
48 return &PL_sv_yes;
6d4a7be2 49
bfcb3514 50 hvname = HvNAME_get(stash);
51
52 if (strEQ(hvname, name))
3280af22 53 return &PL_sv_yes;
6d4a7be2 54
a1d407e8 55 if (strEQ(name, "UNIVERSAL"))
56 return &PL_sv_yes;
57
6d4a7be2 58 if (level > 100)
46e4b22b 59 Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'",
bfcb3514 60 hvname);
6d4a7be2 61
62 gvp = (GV**)hv_fetch(stash, "::ISA::CACHE::", 14, FALSE);
63
46e4b22b 64 if (gvp && (gv = *gvp) != (GV*)&PL_sv_undef && (subgen = GvSV(gv))
65 && (hv = GvHV(gv)))
66 {
eb160463 67 if (SvIV(subgen) == (IV)PL_sub_generation) {
46e4b22b 68 SV* sv;
7452cf6a 69 SV** const svp = (SV**)hv_fetch(hv, name, len, FALSE);
46e4b22b 70 if (svp && (sv = *svp) != (SV*)&PL_sv_undef) {
71 DEBUG_o( Perl_deb(aTHX_ "Using cached ISA %s for package %s\n",
bfcb3514 72 name, hvname) );
46e4b22b 73 return sv;
74 }
75 }
76 else {
77 DEBUG_o( Perl_deb(aTHX_ "ISA Cache in package %s is stale\n",
bfcb3514 78 hvname) );
46e4b22b 79 hv_clear(hv);
80 sv_setiv(subgen, PL_sub_generation);
81 }
6d4a7be2 82 }
83
84 gvp = (GV**)hv_fetch(stash,"ISA",3,FALSE);
46e4b22b 85
3280af22 86 if (gvp && (gv = *gvp) != (GV*)&PL_sv_undef && (av = GvAV(gv))) {
46e4b22b 87 if (!hv || !subgen) {
6d4a7be2 88 gvp = (GV**)hv_fetch(stash, "::ISA::CACHE::", 14, TRUE);
89
90 gv = *gvp;
91
92 if (SvTYPE(gv) != SVt_PVGV)
93 gv_init(gv, stash, "::ISA::CACHE::", 14, TRUE);
94
46e4b22b 95 if (!hv)
96 hv = GvHVn(gv);
97 if (!subgen) {
98 subgen = newSViv(PL_sub_generation);
99 GvSV(gv) = subgen;
100 }
6d4a7be2 101 }
46e4b22b 102 if (hv) {
6d4a7be2 103 SV** svp = AvARRAY(av);
93965878 104 /* NOTE: No support for tied ISA */
105 I32 items = AvFILLp(av) + 1;
6d4a7be2 106 while (items--) {
c4420975 107 SV* const sv = *svp++;
108 HV* const basestash = gv_stashsv(sv, FALSE);
6d4a7be2 109 if (!basestash) {
599cee73 110 if (ckWARN(WARN_MISC))
9014280d 111 Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
bfcb3514 112 "Can't locate package %"SVf" for @%s::ISA",
113 sv, hvname);
6d4a7be2 114 continue;
115 }
301daebc 116 if (&PL_sv_yes == isa_lookup(basestash, name, name_stash,
117 len, level + 1)) {
3280af22 118 (void)hv_store(hv,name,len,&PL_sv_yes,0);
119 return &PL_sv_yes;
6d4a7be2 120 }
121 }
3280af22 122 (void)hv_store(hv,name,len,&PL_sv_no,0);
6d4a7be2 123 }
124 }
a1d407e8 125 return &PL_sv_no;
6d4a7be2 126}
127
954c1994 128/*
ccfc67b7 129=head1 SV Manipulation Functions
130
954c1994 131=for apidoc sv_derived_from
132
133Returns a boolean indicating whether the SV is derived from the specified
134class. This is the function that implements C<UNIVERSAL::isa>. It works
135for class names as well as for objects.
136
137=cut
138*/
139
55497cff 140bool
864dbfa3 141Perl_sv_derived_from(pTHX_ SV *sv, const char *name)
55497cff 142{
a3b680e6 143 const char *type = Nullch;
144 HV *stash = Nullhv;
301daebc 145 HV *name_stash;
46e4b22b 146
5b295bef 147 SvGETMAGIC(sv);
55497cff 148
149 if (SvROK(sv)) {
150 sv = SvRV(sv);
151 type = sv_reftype(sv,0);
46e4b22b 152 if (SvOBJECT(sv))
55497cff 153 stash = SvSTASH(sv);
154 }
155 else {
156 stash = gv_stashsv(sv, FALSE);
157 }
46e4b22b 158
301daebc 159 name_stash = gv_stashpv(name, FALSE);
160
55497cff 161 return (type && strEQ(type,name)) ||
301daebc 162 (stash && isa_lookup(stash, name, name_stash, strlen(name), 0)
163 == &PL_sv_yes)
55497cff 164 ? TRUE
165 : FALSE ;
55497cff 166}
167
1b026014 168#include "XSUB.h"
169
27da23d5 170PERL_XS_EXPORT_C void XS_UNIVERSAL_isa(pTHX_ CV *cv);
171PERL_XS_EXPORT_C void XS_UNIVERSAL_can(pTHX_ CV *cv);
172PERL_XS_EXPORT_C void XS_UNIVERSAL_VERSION(pTHX_ CV *cv);
439cb1c4 173XS(XS_version_new);
174XS(XS_version_stringify);
175XS(XS_version_numify);
9137345a 176XS(XS_version_normal);
439cb1c4 177XS(XS_version_vcmp);
178XS(XS_version_boolean);
2dfd8427 179#ifdef HASATTRIBUTE_NORETURN
180XS(XS_version_noop) __attribute__noreturn__;
181#else
439cb1c4 182XS(XS_version_noop);
2dfd8427 183#endif
c8d69e4a 184XS(XS_version_is_alpha);
137d6fc0 185XS(XS_version_qv);
8800c35a 186XS(XS_utf8_is_utf8);
1b026014 187XS(XS_utf8_valid);
188XS(XS_utf8_encode);
189XS(XS_utf8_decode);
190XS(XS_utf8_upgrade);
191XS(XS_utf8_downgrade);
192XS(XS_utf8_unicode_to_native);
193XS(XS_utf8_native_to_unicode);
29569577 194XS(XS_Internals_SvREADONLY);
195XS(XS_Internals_SvREFCNT);
f044d0d1 196XS(XS_Internals_hv_clear_placehold);
39f7a870 197XS(XS_PerlIO_get_layers);
39cff0d9 198XS(XS_Regexp_DESTROY);
9a7034eb 199XS(XS_Internals_hash_seed);
008fb0c0 200XS(XS_Internals_rehash_seed);
05619474 201XS(XS_Internals_HvREHASH);
4a818d86 202XS(XS_utf8_SWASHGET_heavy);
0cb96387 203
204void
205Perl_boot_core_UNIVERSAL(pTHX)
206{
e1ec3a88 207 const char file[] = __FILE__;
0cb96387 208
209 newXS("UNIVERSAL::isa", XS_UNIVERSAL_isa, file);
210 newXS("UNIVERSAL::can", XS_UNIVERSAL_can, file);
211 newXS("UNIVERSAL::VERSION", XS_UNIVERSAL_VERSION, file);
439cb1c4 212 {
ad63d80f 213 /* register the overloading (type 'A') magic */
214 PL_amagic_generation++;
439cb1c4 215 /* Make it findable via fetchmethod */
be2ebcad 216 newXS("version::()", XS_version_noop, file);
439cb1c4 217 newXS("version::new", XS_version_new, file);
218 newXS("version::(\"\"", XS_version_stringify, file);
219 newXS("version::stringify", XS_version_stringify, file);
220 newXS("version::(0+", XS_version_numify, file);
221 newXS("version::numify", XS_version_numify, file);
9137345a 222 newXS("version::normal", XS_version_normal, file);
439cb1c4 223 newXS("version::(cmp", XS_version_vcmp, file);
224 newXS("version::(<=>", XS_version_vcmp, file);
225 newXS("version::vcmp", XS_version_vcmp, file);
226 newXS("version::(bool", XS_version_boolean, file);
227 newXS("version::boolean", XS_version_boolean, file);
228 newXS("version::(nomethod", XS_version_noop, file);
229 newXS("version::noop", XS_version_noop, file);
c8d69e4a 230 newXS("version::is_alpha", XS_version_is_alpha, file);
137d6fc0 231 newXS("version::qv", XS_version_qv, file);
439cb1c4 232 }
8800c35a 233 newXS("utf8::is_utf8", XS_utf8_is_utf8, file);
1b026014 234 newXS("utf8::valid", XS_utf8_valid, file);
235 newXS("utf8::encode", XS_utf8_encode, file);
236 newXS("utf8::decode", XS_utf8_decode, file);
237 newXS("utf8::upgrade", XS_utf8_upgrade, file);
238 newXS("utf8::downgrade", XS_utf8_downgrade, file);
239 newXS("utf8::native_to_unicode", XS_utf8_native_to_unicode, file);
240 newXS("utf8::unicode_to_native", XS_utf8_unicode_to_native, file);
29569577 241 newXSproto("Internals::SvREADONLY",XS_Internals_SvREADONLY, file, "\\[$%@];$");
242 newXSproto("Internals::SvREFCNT",XS_Internals_SvREFCNT, file, "\\[$%@];$");
dfd4ef2f 243 newXSproto("Internals::hv_clear_placeholders",
f044d0d1 244 XS_Internals_hv_clear_placehold, file, "\\%");
9d569fce 245 newXSproto("PerlIO::get_layers",
246 XS_PerlIO_get_layers, file, "*;@");
39cff0d9 247 newXS("Regexp::DESTROY", XS_Regexp_DESTROY, file);
9a7034eb 248 newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
008fb0c0 249 newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
05619474 250 newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
4a818d86 251 newXS("utf8::SWASHGET_heavy", XS_utf8_SWASHGET_heavy, file);
0cb96387 252}
253
55497cff 254
6d4a7be2 255XS(XS_UNIVERSAL_isa)
256{
257 dXSARGS;
6d4a7be2 258
259 if (items != 2)
cea2e8a9 260 Perl_croak(aTHX_ "Usage: UNIVERSAL::isa(reference, kind)");
c4420975 261 else {
262 SV * const sv = ST(0);
263 const char *name;
6d4a7be2 264
c4420975 265 SvGETMAGIC(sv);
d3f7f2b2 266
c4420975 267 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
268 || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
269 XSRETURN_UNDEF;
f8f70380 270
c4420975 271 name = SvPV_nolen_const(ST(1));
6d4a7be2 272
c4420975 273 ST(0) = boolSV(sv_derived_from(sv, name));
274 XSRETURN(1);
275 }
6d4a7be2 276}
277
6d4a7be2 278XS(XS_UNIVERSAL_can)
279{
280 dXSARGS;
281 SV *sv;
6867be6d 282 const char *name;
6d4a7be2 283 SV *rv;
6f08146e 284 HV *pkg = NULL;
6d4a7be2 285
286 if (items != 2)
cea2e8a9 287 Perl_croak(aTHX_ "Usage: UNIVERSAL::can(object-ref, method)");
6d4a7be2 288
289 sv = ST(0);
f8f70380 290
5b295bef 291 SvGETMAGIC(sv);
d3f7f2b2 292
253ecd6d 293 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
294 || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
f8f70380 295 XSRETURN_UNDEF;
296
0510663f 297 name = SvPV_nolen_const(ST(1));
3280af22 298 rv = &PL_sv_undef;
6d4a7be2 299
46e4b22b 300 if (SvROK(sv)) {
6f08146e 301 sv = (SV*)SvRV(sv);
46e4b22b 302 if (SvOBJECT(sv))
6f08146e 303 pkg = SvSTASH(sv);
304 }
305 else {
306 pkg = gv_stashsv(sv, FALSE);
307 }
308
309 if (pkg) {
c4420975 310 GV * const gv = gv_fetchmethod_autoload(pkg, name, FALSE);
dc848c6f 311 if (gv && isGV(gv))
312 rv = sv_2mortal(newRV((SV*)GvCV(gv)));
6d4a7be2 313 }
314
315 ST(0) = rv;
316 XSRETURN(1);
317}
318
6d4a7be2 319XS(XS_UNIVERSAL_VERSION)
320{
321 dXSARGS;
322 HV *pkg;
323 GV **gvp;
324 GV *gv;
325 SV *sv;
e1ec3a88 326 const char *undef;
6d4a7be2 327
1571675a 328 if (SvROK(ST(0))) {
6d4a7be2 329 sv = (SV*)SvRV(ST(0));
1571675a 330 if (!SvOBJECT(sv))
cea2e8a9 331 Perl_croak(aTHX_ "Cannot find version of an unblessed reference");
6d4a7be2 332 pkg = SvSTASH(sv);
333 }
334 else {
335 pkg = gv_stashsv(ST(0), FALSE);
336 }
337
338 gvp = pkg ? (GV**)hv_fetch(pkg,"VERSION",7,FALSE) : Null(GV**);
339
0008872a 340 if (gvp && isGV(gv = *gvp) && (sv = GvSV(gv)) && SvOK(sv)) {
c4420975 341 SV * const nsv = sv_newmortal();
6d4a7be2 342 sv_setsv(nsv, sv);
343 sv = nsv;
137d6fc0 344 if ( !sv_derived_from(sv, "version"))
345 upg_version(sv);
6d4a7be2 346 undef = Nullch;
347 }
348 else {
3280af22 349 sv = (SV*)&PL_sv_undef;
6d4a7be2 350 undef = "(undef)";
351 }
352
1571675a 353 if (items > 1) {
1571675a 354 SV *req = ST(1);
355
62658f4d 356 if (undef) {
bfcb3514 357 if (pkg) {
c4420975 358 const char * const name = HvNAME_get(pkg);
a3b680e6 359 Perl_croak(aTHX_
bfcb3514 360 "%s does not define $%s::VERSION--version check failed",
361 name, name);
362 } else {
a3b680e6 363 Perl_croak(aTHX_
364 "%s defines neither package nor VERSION--version check failed",
0510663f 365 SvPVx_nolen_const(ST(0)) );
62658f4d 366 }
367 }
ad63d80f 368
137d6fc0 369 if ( !sv_derived_from(req, "version")) {
370 /* req may very well be R/O, so create a new object */
c4420975 371 SV * const nsv = sv_newmortal();
137d6fc0 372 sv_setsv(nsv, req);
373 req = nsv;
374 upg_version(req);
375 }
1571675a 376
137d6fc0 377 if ( vcmp( req, sv ) > 0 )
b9381830 378 Perl_croak(aTHX_ "%s version %"SVf" (%"SVf") required--"
bfcb3514 379 "this is only version %"SVf" (%"SVf")", HvNAME_get(pkg),
b9381830 380 vnumify(req),vnormal(req),vnumify(sv),vnormal(sv));
2d8e6c8d 381 }
6d4a7be2 382
2b140d5b 383 if ( SvOK(sv) && sv_derived_from(sv, "version") ) {
b38a9dc5 384 ST(0) = vnumify(sv);
13f8f398 385 } else {
386 ST(0) = sv;
b38a9dc5 387 }
6d4a7be2 388
389 XSRETURN(1);
390}
391
439cb1c4 392XS(XS_version_new)
393{
394 dXSARGS;
129318bd 395 if (items > 3)
439cb1c4 396 Perl_croak(aTHX_ "Usage: version::new(class, version)");
397 SP -= items;
398 {
137d6fc0 399 SV *vs = ST(1);
400 SV *rv;
c4420975 401 const char * const classname =
402 sv_isobject(ST(0)) /* get the class if called as an object method */
403 ? HvNAME(SvSTASH(SvRV(ST(0))))
404 : (char *)SvPV_nolen(ST(0));
9137345a 405
406 if ( items == 1 ) {
407 /* no parameter provided */
408 if ( sv_isobject(ST(0)) ) {
409 /* copy existing object */
410 vs = ST(0);
411 }
412 else {
413 /* create empty object */
414 vs = sv_newmortal();
1946a074 415 sv_setpvn(vs,"",0);
9137345a 416 }
417 }
418 else if ( items == 3 ) {
419 vs = sv_newmortal();
cfd0369c 420 Perl_sv_setpvf(aTHX_ vs,"v%s",SvPV_nolen_const(ST(2)));
129318bd 421 }
439cb1c4 422
137d6fc0 423 rv = new_version(vs);
0723351e 424 if ( strcmp(classname,"version") != 0 ) /* inherited new() */
425 sv_bless(rv, gv_stashpv(classname,TRUE));
137d6fc0 426
427 PUSHs(sv_2mortal(rv));
439cb1c4 428 PUTBACK;
429 return;
430 }
431}
432
433XS(XS_version_stringify)
434{
41be1fbd 435 dXSARGS;
436 if (items < 1)
437 Perl_croak(aTHX_ "Usage: version::stringify(lobj, ...)");
438 SP -= items;
439 {
7452cf6a 440 SV * lobj;
41be1fbd 441
442 if (sv_derived_from(ST(0), "version")) {
9137345a 443 lobj = SvRV(ST(0));
41be1fbd 444 }
445 else
446 Perl_croak(aTHX_ "lobj is not of type version");
447
137d6fc0 448 PUSHs(sv_2mortal(vstringify(lobj)));
41be1fbd 449
450 PUTBACK;
451 return;
452 }
439cb1c4 453}
454
455XS(XS_version_numify)
456{
41be1fbd 457 dXSARGS;
458 if (items < 1)
459 Perl_croak(aTHX_ "Usage: version::numify(lobj, ...)");
460 SP -= items;
461 {
7452cf6a 462 SV * lobj;
41be1fbd 463
464 if (sv_derived_from(ST(0), "version")) {
9137345a 465 lobj = SvRV(ST(0));
41be1fbd 466 }
467 else
468 Perl_croak(aTHX_ "lobj is not of type version");
469
137d6fc0 470 PUSHs(sv_2mortal(vnumify(lobj)));
41be1fbd 471
472 PUTBACK;
473 return;
474 }
439cb1c4 475}
476
9137345a 477XS(XS_version_normal)
478{
479 dXSARGS;
480 if (items < 1)
481 Perl_croak(aTHX_ "Usage: version::normal(lobj, ...)");
482 SP -= items;
483 {
7452cf6a 484 SV * lobj;
9137345a 485
486 if (sv_derived_from(ST(0), "version")) {
487 lobj = SvRV(ST(0));
488 }
489 else
490 Perl_croak(aTHX_ "lobj is not of type version");
491
492 PUSHs(sv_2mortal(vnormal(lobj)));
493
494 PUTBACK;
495 return;
496 }
497}
498
439cb1c4 499XS(XS_version_vcmp)
500{
41be1fbd 501 dXSARGS;
502 if (items < 1)
503 Perl_croak(aTHX_ "Usage: version::vcmp(lobj, ...)");
504 SP -= items;
505 {
7452cf6a 506 SV * lobj;
41be1fbd 507
508 if (sv_derived_from(ST(0), "version")) {
9137345a 509 lobj = SvRV(ST(0));
41be1fbd 510 }
511 else
512 Perl_croak(aTHX_ "lobj is not of type version");
513
514 {
515 SV *rs;
516 SV *rvs;
517 SV * robj = ST(1);
7452cf6a 518 const IV swap = (IV)SvIV(ST(2));
41be1fbd 519
520 if ( ! sv_derived_from(robj, "version") )
521 {
522 robj = new_version(robj);
523 }
524 rvs = SvRV(robj);
525
526 if ( swap )
527 {
528 rs = newSViv(vcmp(rvs,lobj));
529 }
530 else
531 {
532 rs = newSViv(vcmp(lobj,rvs));
533 }
534
137d6fc0 535 PUSHs(sv_2mortal(rs));
41be1fbd 536 }
537
538 PUTBACK;
539 return;
540 }
439cb1c4 541}
542
543XS(XS_version_boolean)
544{
41be1fbd 545 dXSARGS;
546 if (items < 1)
547 Perl_croak(aTHX_ "Usage: version::boolean(lobj, ...)");
548 SP -= items;
c4420975 549 if (sv_derived_from(ST(0), "version")) {
550 SV * const lobj = SvRV(ST(0));
551 SV * const rs = newSViv( vcmp(lobj,new_version(newSVpvn("0",1))) );
552 PUSHs(sv_2mortal(rs));
553 PUTBACK;
554 return;
555 }
556 else
557 Perl_croak(aTHX_ "lobj is not of type version");
439cb1c4 558}
559
560XS(XS_version_noop)
561{
2dfd8427 562 dXSARGS;
563 if (items < 1)
564 Perl_croak(aTHX_ "Usage: version::noop(lobj, ...)");
565 if (sv_derived_from(ST(0), "version"))
566 Perl_croak(aTHX_ "operation not supported with version object");
567 else
568 Perl_croak(aTHX_ "lobj is not of type version");
569#ifndef HASATTRIBUTE_NORETURN
570 XSRETURN_EMPTY;
571#endif
439cb1c4 572}
573
c8d69e4a 574XS(XS_version_is_alpha)
575{
576 dXSARGS;
577 if (items != 1)
578 Perl_croak(aTHX_ "Usage: version::is_alpha(lobj)");
579 SP -= items;
c4420975 580 if (sv_derived_from(ST(0), "version")) {
581 SV * const lobj = ST(0);
582 if ( hv_exists((HV*)SvRV(lobj), "alpha", 5 ) )
583 XSRETURN_YES;
584 else
585 XSRETURN_NO;
c8d69e4a 586 PUTBACK;
587 return;
588 }
c4420975 589 else
590 Perl_croak(aTHX_ "lobj is not of type version");
c8d69e4a 591}
592
137d6fc0 593XS(XS_version_qv)
594{
595 dXSARGS;
596 if (items != 1)
597 Perl_croak(aTHX_ "Usage: version::qv(ver)");
598 SP -= items;
599 {
600 SV * ver = ST(0);
c4420975 601 if ( !SvVOK(ver) ) { /* only need to do with if not already v-string */
602 SV * const vs = sv_newmortal();
137d6fc0 603 char *version;
604 if ( SvNOK(ver) ) /* may get too much accuracy */
605 {
606 char tbuf[64];
86c11942 607 const STRLEN len = my_sprintf(tbuf,"%.9"NVgf, SvNVX(ver));
608 version = savepvn(tbuf, len);
137d6fc0 609 }
610 else
611 {
2e0de35c 612 version = savesvpv(ver);
137d6fc0 613 }
614 (void)scan_version(version,vs,TRUE);
615 Safefree(version);
616
617 PUSHs(vs);
618 }
619 else
620 {
621 PUSHs(sv_2mortal(new_version(ver)));
622 }
623
624 PUTBACK;
625 return;
626 }
627}
628
8800c35a 629XS(XS_utf8_is_utf8)
630{
41be1fbd 631 dXSARGS;
632 if (items != 1)
633 Perl_croak(aTHX_ "Usage: utf8::is_utf8(sv)");
c4420975 634 else {
635 const SV * const sv = ST(0);
636 if (SvUTF8(sv))
637 XSRETURN_YES;
638 else
639 XSRETURN_NO;
41be1fbd 640 }
641 XSRETURN_EMPTY;
8800c35a 642}
643
1b026014 644XS(XS_utf8_valid)
645{
41be1fbd 646 dXSARGS;
647 if (items != 1)
648 Perl_croak(aTHX_ "Usage: utf8::valid(sv)");
c4420975 649 else {
650 SV * const sv = ST(0);
651 STRLEN len;
652 const char * const s = SvPV_const(sv,len);
653 if (!SvUTF8(sv) || is_utf8_string((const U8*)s,len))
654 XSRETURN_YES;
655 else
656 XSRETURN_NO;
657 }
41be1fbd 658 XSRETURN_EMPTY;
1b026014 659}
660
661XS(XS_utf8_encode)
662{
663 dXSARGS;
664 if (items != 1)
665 Perl_croak(aTHX_ "Usage: utf8::encode(sv)");
c4420975 666 sv_utf8_encode(ST(0));
1b026014 667 XSRETURN_EMPTY;
668}
669
670XS(XS_utf8_decode)
671{
672 dXSARGS;
673 if (items != 1)
674 Perl_croak(aTHX_ "Usage: utf8::decode(sv)");
c4420975 675 else {
676 SV * const sv = ST(0);
6867be6d 677 const bool RETVAL = sv_utf8_decode(sv);
1b026014 678 ST(0) = boolSV(RETVAL);
679 sv_2mortal(ST(0));
680 }
681 XSRETURN(1);
682}
683
684XS(XS_utf8_upgrade)
685{
686 dXSARGS;
687 if (items != 1)
688 Perl_croak(aTHX_ "Usage: utf8::upgrade(sv)");
c4420975 689 else {
690 SV * const sv = ST(0);
1b026014 691 STRLEN RETVAL;
692 dXSTARG;
693
694 RETVAL = sv_utf8_upgrade(sv);
695 XSprePUSH; PUSHi((IV)RETVAL);
696 }
697 XSRETURN(1);
698}
699
700XS(XS_utf8_downgrade)
701{
702 dXSARGS;
703 if (items < 1 || items > 2)
704 Perl_croak(aTHX_ "Usage: utf8::downgrade(sv, failok=0)");
c4420975 705 else {
706 SV * const sv = ST(0);
6867be6d 707 const bool failok = (items < 2) ? 0 : (int)SvIV(ST(1));
708 const bool RETVAL = sv_utf8_downgrade(sv, failok);
1b026014 709
1b026014 710 ST(0) = boolSV(RETVAL);
711 sv_2mortal(ST(0));
712 }
713 XSRETURN(1);
714}
715
716XS(XS_utf8_native_to_unicode)
717{
718 dXSARGS;
6867be6d 719 const UV uv = SvUV(ST(0));
b7953727 720
721 if (items > 1)
722 Perl_croak(aTHX_ "Usage: utf8::native_to_unicode(sv)");
723
1b026014 724 ST(0) = sv_2mortal(newSViv(NATIVE_TO_UNI(uv)));
725 XSRETURN(1);
726}
727
728XS(XS_utf8_unicode_to_native)
729{
730 dXSARGS;
6867be6d 731 const UV uv = SvUV(ST(0));
b7953727 732
733 if (items > 1)
734 Perl_croak(aTHX_ "Usage: utf8::unicode_to_native(sv)");
735
1b026014 736 ST(0) = sv_2mortal(newSViv(UNI_TO_NATIVE(uv)));
737 XSRETURN(1);
738}
739
14a976d6 740XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */
29569577 741{
742 dXSARGS;
c4420975 743 SV * const sv = SvRV(ST(0));
6867be6d 744
29569577 745 if (items == 1) {
746 if (SvREADONLY(sv))
747 XSRETURN_YES;
748 else
749 XSRETURN_NO;
750 }
751 else if (items == 2) {
752 if (SvTRUE(ST(1))) {
753 SvREADONLY_on(sv);
754 XSRETURN_YES;
755 }
756 else {
14a976d6 757 /* I hope you really know what you are doing. */
29569577 758 SvREADONLY_off(sv);
759 XSRETURN_NO;
760 }
761 }
14a976d6 762 XSRETURN_UNDEF; /* Can't happen. */
29569577 763}
764
14a976d6 765XS(XS_Internals_SvREFCNT) /* This is dangerous stuff. */
29569577 766{
767 dXSARGS;
c4420975 768 SV * const sv = SvRV(ST(0));
6867be6d 769
29569577 770 if (items == 1)
14a976d6 771 XSRETURN_IV(SvREFCNT(sv) - 1); /* Minus the ref created for us. */
29569577 772 else if (items == 2) {
14a976d6 773 /* I hope you really know what you are doing. */
29569577 774 SvREFCNT(sv) = SvIV(ST(1));
775 XSRETURN_IV(SvREFCNT(sv));
776 }
14a976d6 777 XSRETURN_UNDEF; /* Can't happen. */
29569577 778}
779
f044d0d1 780XS(XS_Internals_hv_clear_placehold)
dfd4ef2f 781{
782 dXSARGS;
6867be6d 783
3540d4ce 784 if (items != 1)
785 Perl_croak(aTHX_ "Usage: UNIVERSAL::hv_clear_placeholders(hv)");
c4420975 786 else {
787 HV * const hv = (HV *) SvRV(ST(0));
788 hv_clear_placeholders(hv);
789 XSRETURN(0);
790 }
dfd4ef2f 791}
39f7a870 792
39cff0d9 793XS(XS_Regexp_DESTROY)
794{
53c1dcc0 795 PERL_UNUSED_ARG(cv);
39cff0d9 796}
797
39f7a870 798XS(XS_PerlIO_get_layers)
799{
800 dXSARGS;
801 if (items < 1 || items % 2 == 0)
802 Perl_croak(aTHX_ "Usage: PerlIO_get_layers(filehandle[,args])");
5fef3b4a 803#ifdef USE_PERLIO
39f7a870 804 {
805 SV * sv;
806 GV * gv;
807 IO * io;
808 bool input = TRUE;
809 bool details = FALSE;
810
811 if (items > 1) {
c4420975 812 SV * const *svp;
39f7a870 813 for (svp = MARK + 2; svp <= SP; svp += 2) {
c4420975 814 SV * const * const varp = svp;
815 SV * const * const valp = svp + 1;
39f7a870 816 STRLEN klen;
c4420975 817 const char * const key = SvPV_const(*varp, klen);
39f7a870 818
819 switch (*key) {
820 case 'i':
821 if (klen == 5 && memEQ(key, "input", 5)) {
822 input = SvTRUE(*valp);
823 break;
824 }
825 goto fail;
826 case 'o':
827 if (klen == 6 && memEQ(key, "output", 6)) {
828 input = !SvTRUE(*valp);
829 break;
830 }
831 goto fail;
832 case 'd':
833 if (klen == 7 && memEQ(key, "details", 7)) {
834 details = SvTRUE(*valp);
835 break;
836 }
837 goto fail;
838 default:
839 fail:
840 Perl_croak(aTHX_
841 "get_layers: unknown argument '%s'",
842 key);
843 }
844 }
845
846 SP -= (items - 1);
847 }
848
849 sv = POPs;
850 gv = (GV*)sv;
851
852 if (!isGV(sv)) {
853 if (SvROK(sv) && isGV(SvRV(sv)))
854 gv = (GV*)SvRV(sv);
671d49be 855 else if (SvPOKp(sv))
7a5fd60d 856 gv = gv_fetchsv(sv, FALSE, SVt_PVIO);
39f7a870 857 }
858
859 if (gv && (io = GvIO(gv))) {
860 dTARGET;
c4420975 861 AV* const av = PerlIO_get_layers(aTHX_ input ?
39f7a870 862 IoIFP(io) : IoOFP(io));
863 I32 i;
c4420975 864 const I32 last = av_len(av);
39f7a870 865 I32 nitem = 0;
866
867 for (i = last; i >= 0; i -= 3) {
c4420975 868 SV * const * const namsvp = av_fetch(av, i - 2, FALSE);
869 SV * const * const argsvp = av_fetch(av, i - 1, FALSE);
870 SV * const * const flgsvp = av_fetch(av, i, FALSE);
39f7a870 871
c4420975 872 const bool namok = namsvp && *namsvp && SvPOK(*namsvp);
873 const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
874 const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
39f7a870 875
876 if (details) {
ec3bab8e 877 XPUSHs(namok
878 ? newSVpvn(SvPVX_const(*namsvp), SvCUR(*namsvp))
879 : &PL_sv_undef);
880 XPUSHs(argok
881 ? newSVpvn(SvPVX_const(*argsvp), SvCUR(*argsvp))
882 : &PL_sv_undef);
39f7a870 883 if (flgok)
884 XPUSHi(SvIVX(*flgsvp));
885 else
886 XPUSHs(&PL_sv_undef);
887 nitem += 3;
888 }
889 else {
890 if (namok && argok)
891 XPUSHs(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
892 *namsvp, *argsvp));
893 else if (namok)
894 XPUSHs(Perl_newSVpvf(aTHX_ "%"SVf, *namsvp));
895 else
896 XPUSHs(&PL_sv_undef);
897 nitem++;
898 if (flgok) {
c4420975 899 const IV flags = SvIVX(*flgsvp);
39f7a870 900
901 if (flags & PERLIO_F_UTF8) {
902 XPUSHs(newSVpvn("utf8", 4));
903 nitem++;
904 }
905 }
906 }
907 }
908
909 SvREFCNT_dec(av);
910
911 XSRETURN(nitem);
912 }
913 }
5fef3b4a 914#endif
39f7a870 915
916 XSRETURN(0);
917}
918
9a7034eb 919XS(XS_Internals_hash_seed)
c910b28a 920{
c85d3f85 921 /* Using dXSARGS would also have dITEM and dSP,
922 * which define 2 unused local variables. */
557b887a 923 dAXMARK;
53c1dcc0 924 PERL_UNUSED_ARG(cv);
ad73156c 925 PERL_UNUSED_VAR(mark);
81eaca17 926 XSRETURN_UV(PERL_HASH_SEED);
c910b28a 927}
928
008fb0c0 929XS(XS_Internals_rehash_seed)
8e90d776 930{
931 /* Using dXSARGS would also have dITEM and dSP,
932 * which define 2 unused local variables. */
557b887a 933 dAXMARK;
53c1dcc0 934 PERL_UNUSED_ARG(cv);
ad73156c 935 PERL_UNUSED_VAR(mark);
008fb0c0 936 XSRETURN_UV(PL_rehash_seed);
8e90d776 937}
938
05619474 939XS(XS_Internals_HvREHASH) /* Subject to change */
940{
941 dXSARGS;
942 if (SvROK(ST(0))) {
c4420975 943 const HV * const hv = (HV *) SvRV(ST(0));
05619474 944 if (items == 1 && SvTYPE(hv) == SVt_PVHV) {
945 if (HvREHASH(hv))
946 XSRETURN_YES;
947 else
948 XSRETURN_NO;
949 }
950 }
951 Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
952}
241d1a3b 953
4a818d86 954XS(XS_utf8_SWASHGET_heavy)
955{
956 dXSARGS;
957 if (items != 4) {
958 Perl_croak(aTHX_
959 "Usage: utf8::SWASHGET_heavy($self, $start, $len, DEBUG)");
960 }
961 {
962 SV* self = ST(0);
963 const I32 i_start = (I32)SvIV(ST(1));
964 const I32 i_len = (I32)SvIV(ST(2));
965 const I32 debug = (I32)SvIV(ST(3));
966 U32 start = (U32)i_start;
967 U32 len = (U32)i_len;
968
969 HV *hv;
970 SV **listsvp, **typesvp, **bitssvp, **nonesvp, **extssvp, *swatch;
971 U8 *l, *lend, *x, *xend, *s, *nextline;
972 STRLEN lcur, xcur, scur;
973 U8* typestr;
974 int typeto;
975 U32 bits, none, end, octets;
976
977 if (SvROK(self) && SvTYPE(SvRV(self))==SVt_PVHV)
978 hv = (HV*)SvRV(self);
979 else
980 Perl_croak(aTHX_ "hv is not a hash reference");
981
982 if (i_start < 0)
983 Perl_croak(aTHX_ "SWASHGET negative start");
984 if (i_len < 0)
985 Perl_croak(aTHX_ "SWASHGET negative len");
986
987 listsvp = hv_fetch(hv, "LIST", 4, FALSE);
988 typesvp = hv_fetch(hv, "TYPE", 4, FALSE);
989 bitssvp = hv_fetch(hv, "BITS", 4, FALSE);
990 nonesvp = hv_fetch(hv, "NONE", 4, FALSE);
991 extssvp = hv_fetch(hv, "EXTRAS", 6, FALSE);
8fe4d5b2 992 typestr = (U8*)SvPV_nolen(*typesvp);
4a818d86 993 typeto = typestr[0] == 'T' && typestr[1] == 'o';
994 bits = (U32)SvUV(*bitssvp);
995 none = (U32)SvUV(*nonesvp);
996 end = start + len;
997 octets = bits >> 3; /* if bits == 1, then octets == 0 */
998
999 if (bits != 1 && bits != 8 && bits != 16 && bits != 32) {
1000 Perl_croak(aTHX_ "SWASHGET unknown bits %"UVuf, (UV)bits);
1001 }
1002 if (debug) {
1003 char* selfstr = SvPV_nolen(self);
1004 PerlIO_printf(Perl_error_log, "SWASHGET ");
1005 PerlIO_printf(Perl_error_log, "%s %"UVuf" %"UVuf" ",
1006 selfstr, (UV)start, (UV)len);
1007 PerlIO_printf(Perl_error_log, "[%s/%"UVuf"/%"UVuf"]\n",
1008 typestr, (UV)bits, (UV)none);
1009 }
1010
1011 /* initialize $swatch */
1012 swatch = newSVpvn("",0);
1013 scur = octets ? (len * octets) : (len + 7) / 8;
1014 SvGROW(swatch, scur + 1);
1015 s = (U8*)SvPVX(swatch);
1016 if (octets && none) {
1017 const U8* e = s + scur;
1018 while (s < e) {
1019 if (bits == 8)
1020 *s++ = (U8)(none & 0xff);
1021 else if (bits == 16) {
1022 *s++ = (U8)((none >> 8) & 0xff);
1023 *s++ = (U8)( none & 0xff);
1024 }
1025 else if (bits == 32) {
1026 *s++ = (U8)((none >> 24) & 0xff);
1027 *s++ = (U8)((none >> 16) & 0xff);
1028 *s++ = (U8)((none >> 8) & 0xff);
1029 *s++ = (U8)( none & 0xff);
1030 }
1031 }
1032 *s = '\0';
1033 }
1034 else {
1035 (void)memzero((U8*)s, scur + 1);
1036 }
1037 SvCUR_set(swatch, scur);
1038 s = (U8*)SvPVX(swatch);
1039
1040 /* read $self->{LIST} */
1041 l = (U8*)SvPV(*listsvp, lcur);
1042 lend = l + lcur;
1043 while (l < lend) {
1044 U32 min, max, val, key;
1045 STRLEN numlen;
1046 I32 flags = PERL_SCAN_SILENT_ILLDIGIT | PERL_SCAN_DISALLOW_PREFIX;
1047
1048 nextline = (U8*)memchr(l, '\n', lend - l);
1049
1050 numlen = lend - l;
8fe4d5b2 1051 min = (U32)grok_hex((char *)l, &numlen, &flags, NULL);
4a818d86 1052 if (numlen)
1053 l += numlen;
1054 else if (nextline) {
1055 l = nextline + 1; /* 1 is length of "\n" */
1056 continue;
1057 }
1058 else {
1059 l = lend; /* to the end of LIST, at which no \n */
1060 break;
1061 }
1062
1063 if (isBLANK(*l)) {
1064 ++l;
1065 flags = PERL_SCAN_SILENT_ILLDIGIT | PERL_SCAN_DISALLOW_PREFIX;
1066 numlen = lend - l;
8fe4d5b2 1067 max = (U32)grok_hex((char *)l, &numlen, &flags, NULL);
4a818d86 1068 if (numlen)
1069 l += numlen;
1070 else
1071 max = min;
1072
1073 if (octets) {
1074 if (isBLANK(*l)) {
1075 ++l;
1076 flags = PERL_SCAN_SILENT_ILLDIGIT |
1077 PERL_SCAN_DISALLOW_PREFIX;
1078 numlen = lend - l;
8fe4d5b2 1079 val = (U32)grok_hex((char *)l, &numlen, &flags, NULL);
4a818d86 1080 if (numlen)
1081 l += numlen;
1082 else
1083 val = 0;
1084 }
1085 else {
1086 val = 0;
1087 if (typeto) {
1088 Perl_croak(aTHX_ "%s: illegal mapping '%s'",
1089 typestr, l);
1090 }
1091 }
1092 }
1093 }
1094 else {
1095 max = min;
1096 if (octets) {
1097 val = 0;
1098 if (typeto) {
1099 Perl_croak(aTHX_ "%s: illegal mapping '%s'",
1100 typestr, l);
1101 }
1102 }
1103 }
1104
1105 if (nextline)
1106 l = nextline + 1;
1107 else
1108 l = lend;
1109
1110 if (max < start)
1111 continue;
1112
1113 if (octets) {
1114 if (debug) {
1115 PerlIO_printf(Perl_error_log,
1116 "%"UVuf" %"UVuf" %"UVuf"\n",
1117 (UV)min, (UV)max, (UV)val);
1118 }
1119 if (min < start) {
1120 if (!none || val < none) {
1121 val += start - min;
1122 }
1123 min = start;
1124 }
1125 for (key = min; key <= max; key++) {
1126 U32 offset;
1127 if (key >= end)
1128 goto go_out_list;
1129 if (debug) {
1130 PerlIO_printf(Perl_error_log,
1131 "%"UVuf" => %"UVuf"\n",
1132 (UV)key, (UV)val);
1133 }
1134
1135 /* offset must be non-negative (start <= min <= key < end) */
1136 offset = (key - start) * octets;
1137 if (bits == 8)
1138 s[offset] = (U8)(val & 0xff);
1139 else if (bits == 16) {
1140 s[offset ] = (U8)((val >> 8) & 0xff);
1141 s[offset + 1] = (U8)( val & 0xff);
1142 }
1143 else if (bits == 32) {
1144 s[offset ] = (U8)((val >> 24) & 0xff);
1145 s[offset + 1] = (U8)((val >> 16) & 0xff);
1146 s[offset + 2] = (U8)((val >> 8) & 0xff);
1147 s[offset + 3] = (U8)( val & 0xff);
1148 }
1149
1150 if (!none || val < none)
1151 ++val;
1152 }
1153 }
1154 else {
1155 if (min < start)
1156 min = start;
1157 for (key = min; key <= max; key++) {
1158 U32 offset = key - start;
1159 if (key >= end)
1160 goto go_out_list;
1161 if (debug) {
1162 PerlIO_printf(Perl_error_log,
1163 "%"UVuf" => 1\n", (UV)key);
1164 }
1165 s[offset >> 3] |= 1 << (offset & 7);
1166 }
1167 }
1168 }
1169 go_out_list:
1170
1171 /* read $self->{EXTRAS} */
1172 x = (U8*)SvPV(*extssvp, xcur);
1173 xend = x + xcur;
1174 while (x < xend) {
1175 STRLEN namelen;
1176 U8 *namestr;
1177 SV** othersvp;
1178 U32 otherbits;
1179
1180 U8 opc = *x++;
1181 if (opc == '\n')
1182 continue;
1183
1184 nextline = (U8*)memchr(x, '\n', xend - x);
1185
1186 if (opc != '-' && opc != '+' && opc != '!' && opc != '&') {
1187 if (nextline) {
1188 x = nextline + 1;
1189 continue;
1190 }
1191 else {
1192 x = xend;
1193 break;
1194 }
1195 }
1196
1197 namestr = x;
1198
1199 if (nextline) {
1200 namelen = nextline - namestr;
1201 x = nextline + 1;
1202 }
1203 else {
1204 namelen = xend - namestr;
1205 x = xend;
1206 }
1207
1208 if (debug) {
1209 U8* tmpstr;
1210 Newx(tmpstr, namelen + 1, U8);
1211 Move(namestr, tmpstr, namelen, U8);
1212 tmpstr[namelen] = '\0';
1213 PerlIO_printf(Perl_error_log,
1214 "INDIRECT %c %s\n", opc, tmpstr);
1215 Safefree(tmpstr);
1216 }
1217
1218 {
1219 HV* otherhv;
1220 SV **otherbitssvp;
1221
8fe4d5b2 1222 othersvp = hv_fetch(hv, (char *)namestr, namelen, FALSE);
4a818d86 1223 if (*othersvp && SvROK(*othersvp) &&
1224 SvTYPE(SvRV(*othersvp))==SVt_PVHV)
1225 otherhv = (HV*)SvRV(*othersvp);
1226 else
1227 Perl_croak(aTHX_ "otherhv is not a hash reference");
1228
1229 otherbitssvp = hv_fetch(otherhv, "BITS", 4, FALSE);
1230 otherbits = (U32)SvUV(*otherbitssvp);
1231 if (bits < otherbits)
1232 Perl_croak(aTHX_ "SWASHGET size mismatch");
1233 }
1234
1235 {
1236 dSP;
1237 ENTER;
1238 SAVETMPS;
1239 PUSHMARK(SP);
1240 EXTEND(SP,3);
1241 PUSHs(*othersvp);
1242 PUSHs(sv_2mortal(newSViv(start)));
1243 PUSHs(sv_2mortal(newSViv(len)));
1244 PUTBACK;
1245 if (call_method("SWASHGET", G_SCALAR)) {
1246 U8 *s, *o;
1247 STRLEN slen, olen;
1248 SV* tmpsv = *PL_stack_sp--;
1249 o = (U8*)SvPV(tmpsv, olen);
1250
1251 if (!olen)
1252 Perl_croak(aTHX_ "SWASHGET didn't return valid swatch");
8fe4d5b2 1253 s = (U8*)SvPV(swatch, slen);
4a818d86 1254 if (bits == 1 && otherbits == 1) {
1255 if (slen != olen)
1256 Perl_croak(aTHX_ "SWASHGET length mismatch");
1257
1258 switch (opc) {
1259 case '+':
1260 while (slen--)
1261 *s++ |= *o++;
1262 break;
1263 case '!':
1264 while (slen--)
1265 *s++ |= ~*o++;
1266 break;
1267 case '-':
1268 while (slen--)
1269 *s++ &= ~*o++;
1270 break;
1271 case '&':
1272 while (slen--)
1273 *s++ &= *o++;
1274 break;
1275 default:
1276 break;
1277 }
1278 }
1279 else {
1280 U32 otheroctets = otherbits / 8;
1281 U32 offset = 0;
1282 U8* send = s + slen;
1283
1284 while (s < send) {
1285 U32 val = 0;
1286
1287 if (otherbits == 1) {
1288 val = (o[offset >> 3] >> (offset & 7)) & 1;
1289 ++offset;
1290 }
1291 else {
1292 U32 vlen = otheroctets;
1293 val = *o++;
1294 while (--vlen) {
1295 val <<= 8;
1296 val |= *o++;
1297 }
1298 }
1299
1300 if (opc == '+' && val)
1301 val = 1;
1302 else if (opc == '!' && !val)
1303 val = 1;
1304 else if (opc == '-' && val)
1305 val = 0;
1306 else if (opc == '&' && !val)
1307 val = 0;
1308 else {
1309 s += octets;
1310 continue;
1311 }
1312
1313 if (bits == 8)
1314 *s++ = (U8)( val & 0xff);
1315 else if (bits == 16) {
1316 *s++ = (U8)((val >> 8) & 0xff);
1317 *s++ = (U8)( val & 0xff);
1318 }
1319 else if (bits == 32) {
1320 *s++ = (U8)((val >> 24) & 0xff);
1321 *s++ = (U8)((val >> 16) & 0xff);
1322 *s++ = (U8)((val >> 8) & 0xff);
1323 *s++ = (U8)( val & 0xff);
1324 }
1325 }
1326 }
1327 }
1328 FREETMPS;
1329 LEAVE;
1330 }
1331 }
1332
1333 if (debug) {
1334 U8* s = (U8*)SvPVX(swatch);
1335 PerlIO_printf(Perl_error_log, "CELLS ");
1336 if (bits == 1) {
1337 U32 key;
1338 for (key = 0; key < len; key++) {
1339 int val = (s[key >> 3] >> (key & 7)) & 1;
1340 PerlIO_printf(Perl_error_log, val ? "1 " : "0 ");
1341 }
1342 }
1343 else {
1344 U8* send = s + len * octets;
1345 while (s < send) {
1346 U32 vlen = octets;
1347 U32 val = *s++;
1348 while (--vlen) {
1349 val <<= 8;
1350 val |= *s++;
1351 }
1352 PerlIO_printf(Perl_error_log, "%"UVuf" ", (UV)val);
1353 }
1354 }
1355 PerlIO_printf(Perl_error_log, "\n");
1356 }
1357
1358 ST(0) = swatch;
1359 sv_2mortal(ST(0));
1360 }
1361 XSRETURN(1);
1362}
1363
1364
241d1a3b 1365/*
1366 * Local variables:
1367 * c-indentation-style: bsd
1368 * c-basic-offset: 4
1369 * indent-tabs-mode: t
1370 * End:
1371 *
37442d52 1372 * ex: set ts=8 sts=4 sw=4 noet:
1373 */