diff options
author | Nicholas Clark <nick@ccl4.org> | 2006-04-01 21:17:46 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2006-04-01 21:17:46 +0000 |
commit | 5b9c067131ee63b4afa00d1d71c771377deb6ff9 (patch) | |
tree | f0d23e7597d8b97766a275feb1effc1c8360e3bb /hv.c | |
parent | def9038f0e6b68e6331316ef6cd457a2bf75dab6 (diff) | |
download | perl-5b9c067131ee63b4afa00d1d71c771377deb6ff9.tar.gz |
Automatically set HINT_LOCALIZE_HH whenever %^H is modified.
p4raw-id: //depot/perl@27666
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 33 |
1 files changed, 33 insertions, 0 deletions
@@ -1491,6 +1491,39 @@ Perl_newHVhv(pTHX_ HV *ohv) return hv; } +/* A rather specialised version of newHVhv for copying %^H, ensuring all the + magic stays on it. */ +HV * +Perl_hv_copy_hints_hv(pTHX_ HV *const ohv) +{ + HV * const hv = newHV(); + STRLEN hv_fill; + + if (ohv && (hv_fill = HvFILL(ohv))) { + STRLEN hv_max = HvMAX(ohv); + HE *entry; + const I32 riter = HvRITER_get(ohv); + HE * const eiter = HvEITER_get(ohv); + + while (hv_max && hv_max + 1 >= hv_fill * 2) + hv_max = hv_max / 2; + HvMAX(hv) = hv_max; + + hv_iterinit(ohv); + while ((entry = hv_iternext_flags(ohv, 0))) { + SV *const sv = newSVsv(HeVAL(entry)); + sv_magic(sv, NULL, PERL_MAGIC_hintselem, + (char *)newSVhek (HeKEY_hek(entry)), HEf_SVKEY); + hv_store_flags(hv, HeKEY(entry), HeKLEN(entry), + sv, HeHASH(entry), HeKFLAGS(entry)); + } + HvRITER_set(ohv, riter); + HvEITER_set(ohv, eiter); + } + hv_magic(hv, NULL, PERL_MAGIC_hints); + return hv; +} + void Perl_hv_free_ent(pTHX_ HV *hv, register HE *entry) { |