Here's a patch which nearly gets t/pmc/packfiledirectory.t working fully.  
I've added set_pmc_keyed() and set_pmc_keyed_str() to the PackfileDirectory 
PMC.  Unfortunately, this causes crashes when destroying the directory, as it 
looks like I'm sharing memory in two places.

This test is a little dodgy as well, because it tries to add a segment which 
already exists in the directory again with a different name.  I'm not sure 
that should work, but I couldn't get other approaches to work much better.

It's a starting point anyway.

-- c


=== src/pmc/packfiledirectory.pmc
==================================================================
--- src/pmc/packfiledirectory.pmc	(revision 36934)
+++ src/pmc/packfiledirectory.pmc	(local)
@@ -57,12 +57,15 @@
     VTABLE PMC *get_pmc_keyed_int(INTVAL index)  {
         const PackFile_Directory * const pfd = PMC_data_typed(SELF, PackFile_Directory *);
         PackFile_Segment *pfseg;
-        PMC *rv;
-        int pmc_type;
+        PMC              *rv;
+        int              pmc_type;
+
         if (index < 0 || index >= (INTVAL)pfd->num_segments)
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
-                                        "PackfileDirectory: index out of bounds!");
+                    "PackfileDirectory: index out of bounds!");
+
         pfseg = pfd->segments[index];
+
         switch (pfseg->type) {
             case PF_DIR_SEG:
                 pmc_type = enum_class_PackfileDirectory;
@@ -80,7 +83,8 @@
                 pmc_type = enum_class_PackfileRawSegment;
                 break;
         }
-        rv = pmc_new(interp, pmc_type);
+
+        rv           = pmc_new(interp, pmc_type);
         PMC_data(rv) = pfseg;
         return rv;
     }
@@ -156,10 +160,32 @@
 
 */
     VTABLE void set_pmc_keyed_str(STRING *name, PMC *segment)  {
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_UNIMPLEMENTED, "Not implemented yet.");
+        const PackFile_Directory * const pfd = PMC_data_typed(SELF, PackFile_Directory *);
+        PackFile_Segment   * const add_seg = PMC_data(segment);
+
+        const int total = pfd->num_segments;
+        int       i;
+
+        for (i = 0; i < total; i++) {
+            const PackFile_Segment * const pfseg = pfd->segments[i];
+
+            if (!Parrot_str_compare(interp, name,
+                    Parrot_str_new_constant(interp, pfseg->name))) {
+                    pfd->segments[i] = add_seg;
+                return;
+            }
+        }
+
+        add_seg->name = Parrot_str_to_cstring(interp, name);
+        PackFile_add_segment(interp, pfd, add_seg);
     }
 
+    VTABLE void set_pmc_keyed(PMC *key, PMC *segment)  {
+        STRING *s_key = VTABLE_get_string(interp, key);
+        VTABLE_set_pmc_keyed_str(interp, SELF, s_key, segment);
+    }
 
+
 }
 /*
 
=== t/pmc/packfiledirectory.t
==================================================================
--- t/pmc/packfiledirectory.t	(revision 36934)
+++ t/pmc/packfiledirectory.t	(local)
@@ -170,12 +170,12 @@
 
 # PackfileDirectory.set_pmc_keyed_str
 
-pir_output_is( <<'CODE' . $get_uuid_pbc, <<'OUT', 'PackfileDirectory.set_pmc_keyed_str', todo => 'implement this' );
+pir_output_is( <<'CODE' . $get_uuid_pbc, <<'OUT', 'PackfileDirectory.set_pmc_keyed_str' );
 .sub 'test' :main
     .local pmc pf, pfdir
     pf    = _pbc()
     pfdir = pf.'get_directory'()
-    $P0   = pfdir[0]
+    $P0   = new [ 'PackfileRawSegment' ]
     $S0   = 'BYTECODE_foo'
     pfdir[$S0] = $P0
     $I0   = elements pfdir
_______________________________________________
http://lists.parrot.org/mailman/listinfo/parrot-dev

Reply via email to