diff -Naur YAML-Syck-1.07/Changes YAML-Syck-1.08/Changes
--- YAML-Syck-1.07/Changes Sat Apr 25 05:39:18 2009
+++ YAML-Syck-1.08/Changes Sun May 3 08:28:05 2009
@@ -1,3 +1,6 @@
+* Dump() no longer leaves hash iterators in an improper state
+ Contributed by: Laurent Dami
+
[Changes for 1.07 (JSON::Syck 0.30) - 2009-04-25]
* Added the missing Loadfile function to JSON::Syck.
diff -Naur YAML-Syck-1.07/perl_syck.h YAML-Syck-1.08/perl_syck.h
--- YAML-Syck-1.07/perl_syck.h Sun Jun 8 19:53:09 2008
+++ YAML-Syck-1.08/perl_syck.h Sun May 3 08:03:57 2009
@@ -703,19 +703,15 @@
break;
}
case SVt_PVHV: {
- I32 len, i;
-#ifdef HAS_RESTRICTED_HASHES
- len = HvTOTALKEYS((HV*)sv);
-#else
- len = HvKEYS((HV*)sv);
-#endif
hv_iterinit((HV*)sv);
- for (i = 0; i < len; i++) {
+ HE *he;
+ while (he =
#ifdef HV_ITERNEXT_WANTPLACEHOLDERS
- HE *he = hv_iternext_flags((HV*)sv, HV_ITERNEXT_WANTPLACEHOLDERS);
+ hv_iternext_flags((HV*)sv, HV_ITERNEXT_WANTPLACEHOLDERS)
#else
- HE *he = hv_iternext((HV*)sv);
+ hv_iternext((HV*)sv)
#endif
+ ) {
SV *val = hv_iterval((HV*)sv, he);
PERL_SYCK_MARK_EMITTER( e, val );
}
@@ -929,30 +925,27 @@
e->indent = PERL_SYCK_INDENT_LEVEL;
*tag = '\0';
-#ifdef HAS_RESTRICTED_HASHES
- len = HvTOTALKEYS((HV*)sv);
-#else
- len = HvKEYS((HV*)sv);
-#endif
hv_iterinit((HV*)sv);
-
if (e->sort_keys) {
AV *av = (AV*)sv_2mortal((SV*)newAV());
- for (i = 0; i < len; i++) {
+ HE *he;
+ while (he =
#ifdef HAS_RESTRICTED_HASHES
- HE *he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS);
+ hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS)
#else
- HE *he = hv_iternext(hv);
+ hv_iternext(hv)
#endif
+ ) {
SV *key = hv_iterkeysv(he);
av_store(av, AvFILLp(av)+1, key); /* av_push(), really */
}
- STORE_HASH_SORT;
- for (i = 0; i < len; i++) {
+ STORE_HASH_SORT(av);
+
+ SV *key;
+ while ((key = av_shift(av)) != &PL_sv_undef) {
#ifdef HAS_RESTRICTED_HASHES
int placeholders = (int)HvPLACEHOLDERS_get(hv);
#endif
- SV *key = av_shift(av);
HE *he = hv_fetch_ent(hv, key, 0, 0);
SV *val = HeVAL(he);
if (val == NULL) { val = &PL_sv_undef; }
@@ -961,12 +954,14 @@
}
}
else {
- for (i = 0; i < len; i++) {
+ HE *he;
+ while (he =
#ifdef HV_ITERNEXT_WANTPLACEHOLDERS
- HE *he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS);
+ hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS)
#else
- HE *he = hv_iternext(hv);
+ hv_iternext(hv)
#endif
+ ) {
SV *key = hv_iterkeysv(he);
SV *val = hv_iterval(hv, he);
syck_emit_item( e, (st_data_t)key );
diff -Naur YAML-Syck-1.07/ppport_sort.h YAML-Syck-1.08/ppport_sort.h
--- YAML-Syck-1.07/ppport_sort.h Sat Oct 20 10:47:56 2007
+++ YAML-Syck-1.08/ppport_sort.h Sun May 3 08:05:28 2009
@@ -6,25 +6,25 @@
#if defined(USE_ITHREADS)
-#define STORE_HASH_SORT \
+#define STORE_HASH_SORT(arg) \
ENTER; { \
PerlInterpreter *orig_perl = PERL_GET_CONTEXT; \
SAVESPTR(orig_perl); \
PERL_SET_CONTEXT(aTHX); \
- qsort((char *) AvARRAY(av), len, sizeof(SV *), sortcmp); \
+ qsort((char *) AvARRAY(arg), av_len(arg)+1, sizeof(SV *), sortcmp); \
} LEAVE;
#else /* ! USE_ITHREADS */
-#define STORE_HASH_SORT \
- qsort((char *) AvARRAY(av), len, sizeof(SV *), sortcmp);
+#define STORE_HASH_SORT(arg) \
+ qsort((char *) AvARRAY(arg), av_len(arg)+1, sizeof(SV *), sortcmp);
#endif /* USE_ITHREADS */
#else /* PATCHLEVEL > 6 */
-#define STORE_HASH_SORT \
- sortsv(AvARRAY(av), len, Perl_sv_cmp);
+#define STORE_HASH_SORT(arg) \
+ sortsv(AvARRAY(arg), av_len(arg)+1, Perl_sv_cmp);
#endif /* PATCHLEVEL <= 6 */
diff -Naur YAML-Syck-1.07/t/5-iterhash.t YAML-Syck-1.08/t/5-iterhash.t
--- YAML-Syck-1.07/t/5-iterhash.t Thu Jan 1 01:00:00 1970
+++ YAML-Syck-1.08/t/5-iterhash.t Sun May 3 06:14:03 2009
@@ -0,0 +1,24 @@
+use t::TestYAML tests => 3;
+
+my $hash = {foo => 1, subhash => {bar => 2, buz => 3, bobo => 4}};
+
+is (Dump($hash), <<"", "dumped text");
+---
+foo: 1
+subhash:
+ bar: 2
+ bobo: 4
+ buz: 3
+
+
+my $count = 0;
+while (my ($k, $v) = each %$hash) {
+ $count ++;
+}
+is ($count, 2, "iterator on main hash");
+
+$count = 0;
+while (my ($k, $v) = each %{$hash->{subhash}}) {
+ $count ++;
+}
+is ($count, 3, "iterator on subhash");