summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGisle Aas <gisle@aas.no>1998-06-30 15:34:07 +0200
committerGurusamy Sarathy <gsar@cpan.org>1998-07-04 02:53:26 +0000
commit57079c468e190b483eeed1dc905fcaa88d70475e (patch)
tree142f286d1dd853167dbad2277eb85f422a634489
parent0a528a3542746230f4fc096636f17a8e901151fc (diff)
downloadperl-57079c468e190b483eeed1dc905fcaa88d70475e.tar.gz
applied patch with tweaks to prose
Subject: [PATCH] Simplified AVHV support Message-ID: <m3k95z86og.fsf@furu.g.aas.no> p4raw-id: //depot/perl@1286
-rw-r--r--ObjXSub.h14
-rw-r--r--av.c196
-rw-r--r--embed.h7
-rw-r--r--global.sym7
-rw-r--r--objpp.h14
-rw-r--r--pod/perldiag.pod17
-rw-r--r--pp.c4
-rw-r--r--proto.h7
-rwxr-xr-xt/op/avhv.t5
9 files changed, 42 insertions, 229 deletions
diff --git a/ObjXSub.h b/ObjXSub.h
index b0890a0afe..6cb2baaf8e 100644
--- a/ObjXSub.h
+++ b/ObjXSub.h
@@ -715,30 +715,16 @@
#define av_undef pPerl->Perl_av_undef
#undef av_unshift
#define av_unshift pPerl->Perl_av_unshift
-#undef avhv_delete
-#define avhv_delete pPerl->Perl_avhv_delete
-#undef avhv_delete_ent
-#define avhv_delete_ent pPerl->Perl_avhv_delete_ent
-#undef avhv_exists
-#define avhv_exists pPerl->Perl_avhv_exists
#undef avhv_exists_ent
#define avhv_exists_ent pPerl->Perl_avhv_exists_ent
-#undef avhv_fetch
-#define avhv_fetch pPerl->Perl_avhv_fetch
#undef avhv_fetch_ent
#define avhv_fetch_ent pPerl->Perl_avhv_fetch_ent
#undef avhv_iternext
#define avhv_iternext pPerl->Perl_avhv_iternext
-#undef avhv_iternextsv
-#define avhv_iternextsv pPerl->Perl_avhv_iternextsv
#undef avhv_iterval
#define avhv_iterval pPerl->Perl_avhv_iterval
#undef avhv_keys
#define avhv_keys pPerl->Perl_avhv_keys
-#undef avhv_store
-#define avhv_store pPerl->Perl_avhv_store
-#undef avhv_store_ent
-#define avhv_store_ent pPerl->Perl_avhv_store_ent
#undef bind_match
#define bind_match pPerl->Perl_bind_match
#undef block_end
diff --git a/av.c b/av.c
index 6e41c2e571..2e460536ed 100644
--- a/av.c
+++ b/av.c
@@ -590,14 +590,25 @@ av_fill(register AV *av, I32 fill)
(void)av_store(av,fill,&sv_undef);
}
-
+
+/* AVHV: Support for treating arrays as if they were hashes. The
+ * first element of the array should be a hash reference that maps
+ * hash keys to array indices.
+ */
+
+static I32
+avhv_index_sv(SV* sv)
+{
+ I32 index = SvIV(sv);
+ if (index < 1)
+ croak("Bad index while coercing array into hash");
+ return index;
+}
+
HV*
avhv_keys(AV *av)
{
- SV **keysp;
- HV *keys = Nullhv;
-
- keysp = av_fetch(av, 0, FALSE);
+ SV **keysp = av_fetch(av, 0, FALSE);
if (keysp) {
SV *sv = *keysp;
if (SvGMAGICAL(sv))
@@ -605,34 +616,10 @@ avhv_keys(AV *av)
if (SvROK(sv)) {
sv = SvRV(sv);
if (SvTYPE(sv) == SVt_PVHV)
- keys = (HV*)sv;
+ return (HV*)sv;
}
}
- if (!keys)
- croak("Can't coerce array into hash");
- return keys;
-}
-
-SV**
-avhv_fetch(AV *av, char *key, U32 klen, I32 lval)
-{
- SV **indsvp;
- HV *keys = avhv_keys(av);
- I32 ind;
-
- indsvp = hv_fetch(keys, key, klen, FALSE);
- if (indsvp) {
- ind = SvIV(*indsvp);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- } else {
- if (!lval)
- return 0;
-
- ind = AvFILL(av) + 1;
- hv_store(keys, key, klen, newSViv(ind), 0);
- }
- return av_fetch(av, ind, lval);
+ croak("Can't coerce array into hash");
}
SV**
@@ -641,59 +628,11 @@ avhv_fetch_ent(AV *av, SV *keysv, I32 lval, U32 hash)
SV **indsvp;
HV *keys = avhv_keys(av);
HE *he;
- I32 ind;
-
- he = hv_fetch_ent(keys, keysv, FALSE, hash);
- if (he) {
- ind = SvIV(HeVAL(he));
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- } else {
- if (!lval)
- return 0;
-
- ind = AvFILL(av) + 1;
- hv_store_ent(keys, keysv, newSViv(ind), 0);
- }
- return av_fetch(av, ind, lval);
-}
-
-SV**
-avhv_store(AV *av, char *key, U32 klen, SV *val, U32 hash)
-{
- SV **indsvp;
- HV *keys = avhv_keys(av);
- I32 ind;
-
- indsvp = hv_fetch(keys, key, klen, FALSE);
- if (indsvp) {
- ind = SvIV(*indsvp);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- } else {
- ind = AvFILL(av) + 1;
- hv_store(keys, key, klen, newSViv(ind), hash);
- }
- return av_store(av, ind, val);
-}
-
-SV**
-avhv_store_ent(AV *av, SV *keysv, SV *val, U32 hash)
-{
- HV *keys = avhv_keys(av);
- HE *he;
- I32 ind;
he = hv_fetch_ent(keys, keysv, FALSE, hash);
- if (he) {
- ind = SvIV(HeVAL(he));
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- } else {
- ind = AvFILL(av) + 1;
- hv_store_ent(keys, keysv, newSViv(ind), hash);
- }
- return av_store(av, ind, val);
+ if (!he)
+ croak("No such array field");
+ return av_fetch(av, avhv_index_sv(HeVAL(he)), lval);
}
bool
@@ -703,69 +642,6 @@ avhv_exists_ent(AV *av, SV *keysv, U32 hash)
return hv_exists_ent(keys, keysv, hash);
}
-bool
-avhv_exists(AV *av, char *key, U32 klen)
-{
- HV *keys = avhv_keys(av);
- return hv_exists(keys, key, klen);
-}
-
-/* avhv_delete leaks. Caller can re-index and compress if so desired. */
-SV *
-avhv_delete(AV *av, char *key, U32 klen, I32 flags)
-{
- HV *keys = avhv_keys(av);
- SV *sv;
- SV **svp;
- I32 ind;
-
- sv = hv_delete(keys, key, klen, 0);
- if (!sv)
- return Nullsv;
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- svp = av_fetch(av, ind, FALSE);
- if (!svp)
- return Nullsv;
- if (flags & G_DISCARD) {
- sv = Nullsv;
- SvREFCNT_dec(*svp);
- } else {
- sv = sv_2mortal(*svp);
- }
- *svp = &sv_undef;
- return sv;
-}
-
-/* avhv_delete_ent leaks. Caller can re-index and compress if so desired. */
-SV *
-avhv_delete_ent(AV *av, SV *keysv, I32 flags, U32 hash)
-{
- HV *keys = avhv_keys(av);
- SV *sv;
- SV **svp;
- I32 ind;
-
- sv = hv_delete_ent(keys, keysv, 0, hash);
- if (!sv)
- return Nullsv;
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- svp = av_fetch(av, ind, FALSE);
- if (!svp)
- return Nullsv;
- if (flags & G_DISCARD) {
- sv = Nullsv;
- SvREFCNT_dec(*svp);
- } else {
- sv = sv_2mortal(*svp);
- }
- *svp = &sv_undef;
- return sv;
-}
-
HE *
avhv_iternext(AV *av)
{
@@ -776,32 +652,6 @@ avhv_iternext(AV *av)
SV *
avhv_iterval(AV *av, register HE *entry)
{
- HV *keys = avhv_keys(av);
- SV *sv;
- I32 ind;
-
- sv = hv_iterval(keys, entry);
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- return *av_fetch(av, ind, TRUE);
-}
-
-SV *
-avhv_iternextsv(AV *av, char **key, I32 *retlen)
-{
- HV *keys = avhv_keys(av);
- HE *he;
- SV *sv;
- I32 ind;
-
- he = hv_iternext(keys);
- if (!he)
- return Nullsv;
- *key = hv_iterkey(he, retlen);
- sv = hv_iterval(keys, he);
- ind = SvIV(sv);
- if (ind < 1)
- croak("Bad index while coercing array into hash");
- return *av_fetch(av, ind, TRUE);
+ SV *sv = hv_iterval(avhv_keys(av), entry);
+ return *av_fetch(av, avhv_index_sv(sv), TRUE);
}
diff --git a/embed.h b/embed.h
index 53607f1ed6..01813c94a8 100644
--- a/embed.h
+++ b/embed.h
@@ -46,18 +46,11 @@
#define av_store Perl_av_store
#define av_undef Perl_av_undef
#define av_unshift Perl_av_unshift
-#define avhv_delete Perl_avhv_delete
-#define avhv_delete_ent Perl_avhv_delete_ent
-#define avhv_exists Perl_avhv_exists
#define avhv_exists_ent Perl_avhv_exists_ent
-#define avhv_fetch Perl_avhv_fetch
#define avhv_fetch_ent Perl_avhv_fetch_ent
#define avhv_iternext Perl_avhv_iternext
-#define avhv_iternextsv Perl_avhv_iternextsv
#define avhv_iterval Perl_avhv_iterval
#define avhv_keys Perl_avhv_keys
-#define avhv_store Perl_avhv_store
-#define avhv_store_ent Perl_avhv_store_ent
#define band_amg Perl_band_amg
#define bind_match Perl_bind_match
#define block_end Perl_block_end
diff --git a/global.sym b/global.sym
index 61bba976e4..44c8dbcc3b 100644
--- a/global.sym
+++ b/global.sym
@@ -181,18 +181,11 @@ av_shift
av_store
av_undef
av_unshift
-avhv_delete
-avhv_delete_ent
-avhv_exists
avhv_exists_ent
-avhv_fetch
avhv_fetch_ent
avhv_iternext
-avhv_iternextsv
avhv_iterval
avhv_keys
-avhv_store
-avhv_store_ent
bind_match
block_end
block_gimme
diff --git a/objpp.h b/objpp.h
index 94837c7c03..ba12c25760 100644
--- a/objpp.h
+++ b/objpp.h
@@ -51,28 +51,14 @@
#define av_unshift CPerlObj::Perl_av_unshift
#undef avhv_keys
#define avhv_keys CPerlObj::Perl_avhv_keys
-#undef avhv_fetch
-#define avhv_fetch CPerlObj::Perl_avhv_fetch
#undef avhv_fetch_ent
#define avhv_fetch_ent CPerlObj::Perl_avhv_fetch_ent
-#undef avhv_store
-#define avhv_store CPerlObj::Perl_avhv_store
-#undef avhv_store_ent
-#define avhv_store_ent CPerlObj::Perl_avhv_store_ent
#undef avhv_exists_ent
#define avhv_exists_ent CPerlObj::Perl_avhv_exists_ent
-#undef avhv_exists
-#define avhv_exists CPerlObj::Perl_avhv_exists
-#undef avhv_delete
-#define avhv_delete CPerlObj::Perl_avhv_delete
-#undef avhv_delete_ent
-#define avhv_delete_ent CPerlObj::Perl_avhv_delete_ent
#undef avhv_iternext
#define avhv_iternext CPerlObj::Perl_avhv_iternext
#undef avhv_iterval
#define avhv_iterval CPerlObj::Perl_avhv_iterval
-#undef avhv_iternextsv
-#define avhv_iternextsv CPerlObj::Perl_avhv_iternextsv
#undef bad_type
#define bad_type CPerlObj::bad_type
#undef bind_match
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 468e0a341f..3851bacfd0 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -321,6 +321,11 @@ system malloc().
(F) A field name of a typed variable was looked up in the %FIELDS
hash, but the index found was not legal, i.e. less than 1.
+=item Bad index while coercing array into hash
+
+(F) The index looked up in the hash found as 0'th element of the array
+is not legal. Index values must be at 1 or greater.
+
=item Bad name after %s::
(F) You started to name a symbol by using a package prefix, and then didn't
@@ -497,6 +502,12 @@ but then $foo no longer contains a glob.
(F) Certain types of SVs, in particular real symbol table entries
(typeglobs), can't be forced to stop being what they are.
+=item Can't coerce array into hash
+
+(F) You used an array where a hash was expected, but the array has no
+information on how to map from keys to array indices. You can do that
+only with arrays that have a hash reference at index 0.
+
=item Can't create pipe mailbox
(P) An error peculiar to VMS. The process is suffering from exhausted quotas
@@ -1606,6 +1617,12 @@ your system.
(F) The argument to B<-I> must follow the B<-I> immediately with no
intervening space.
+=item No such array field
+
+(F) You tried to access an array as a hash, but the field name used is
+not defined. The hash at index 0 should map all valid field names to
+array indices for that to work.
+
=item No such field "%s" in variable %s of type %s
(F) You tried to access a field of a typed variable where the type
diff --git a/pp.c b/pp.c
index 55ab5d1cdd..a927b3ddc0 100644
--- a/pp.c
+++ b/pp.c
@@ -2358,8 +2358,6 @@ PP(pp_delete)
while (++MARK <= SP) {
if (hvtype == SVt_PVHV)
sv = hv_delete_ent(hv, *MARK, discard, 0);
- else if (hvtype == SVt_PVAV)
- sv = avhv_delete_ent((AV*)hv, *MARK, discard, 0);
else
DIE("Not a HASH reference");
*MARK = sv ? sv : &sv_undef;
@@ -2377,8 +2375,6 @@ PP(pp_delete)
hv = (HV*)POPs;
if (SvTYPE(hv) == SVt_PVHV)
sv = hv_delete_ent(hv, keysv, discard, 0);
- else if (SvTYPE(hv) == SVt_PVAV)
- sv = avhv_delete_ent((AV*)hv, keysv, discard, 0);
else
DIE("Not a HASH reference");
if (!sv)
diff --git a/proto.h b/proto.h
index 0479480c55..5bbde48039 100644
--- a/proto.h
+++ b/proto.h
@@ -21,18 +21,11 @@ VIRTUAL OP* append_elem _((I32 optype, OP* head, OP* tail));
VIRTUAL OP* append_list _((I32 optype, LISTOP* first, LISTOP* last));
VIRTUAL I32 apply _((I32 type, SV** mark, SV** sp));
VIRTUAL void assertref _((OP* o));
-VIRTUAL SV* avhv_delete _((AV *ar, char* key, U32 klen, I32 flags));
-VIRTUAL SV* avhv_delete_ent _((AV *ar, SV* keysv, I32 flags, U32 hash));
-VIRTUAL bool avhv_exists _((AV *ar, char* key, U32 klen));
VIRTUAL bool avhv_exists_ent _((AV *ar, SV* keysv, U32 hash));
-VIRTUAL SV** avhv_fetch _((AV *ar, char* key, U32 klen, I32 lval));
VIRTUAL SV** avhv_fetch_ent _((AV *ar, SV* keysv, I32 lval, U32 hash));
VIRTUAL HE* avhv_iternext _((AV *ar));
-VIRTUAL SV * avhv_iternextsv _((AV *ar, char** key, I32* retlen));
VIRTUAL SV* avhv_iterval _((AV *ar, HE* entry));
VIRTUAL HV* avhv_keys _((AV *ar));
-VIRTUAL SV** avhv_store _((AV *ar, char* key, U32 klen, SV* val, U32 hash));
-VIRTUAL SV** avhv_store_ent _((AV *av, SV *keysv, SV *val, U32 hash));
VIRTUAL void av_clear _((AV* ar));
VIRTUAL void av_extend _((AV* ar, I32 key));
VIRTUAL AV* av_fake _((I32 size, SV** svp));
diff --git a/t/op/avhv.t b/t/op/avhv.t
index 84d3f270fb..e01201e845 100755
--- a/t/op/avhv.t
+++ b/t/op/avhv.t
@@ -32,12 +32,11 @@ $a->[0] = $sch;
$a->{'abc'} = 'ABC';
$a->{'def'} = 'DEF';
$a->{'jkl'} = 'JKL';
-$a->{'a'} = 'A'; #should extend schema
@keys = keys %$a;
@values = values %$a;
-if ($#keys == 3 && $#values == 3) {print "ok 1\n";} else {print "not ok 1\n";}
+if ($#keys == 2 && $#values == 2) {print "ok 1\n";} else {print "not ok 1\n";}
$i = 0; # stop -w complaints
@@ -48,7 +47,7 @@ while (($key,$value) = each %$a) {
}
}
-if ($i == 4) {print "ok 2\n";} else {print "not ok 2\n";}
+if ($i == 3) {print "ok 2\n";} else {print "not ok 2\n";}
# quick check with tied array
tie @fake, 'Tie::StdArray';