Added casereader_clone function.
authorJohn Darrington <john@darrington.wattle.id.au>
Mon, 25 Sep 2006 09:35:15 +0000 (09:35 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Mon, 25 Sep 2006 09:35:15 +0000 (09:35 +0000)
Introduced casenum_t type to enumerate and count cases.

27 files changed:
po/de.po
po/pspp.pot
src/data/ChangeLog
src/data/casefile-private.h
src/data/casefile.c
src/data/casefile.h
src/data/fastfile.c
src/data/procedure.c
src/data/transformations.h
src/language/control/do-if.c
src/language/control/loop.c
src/language/data-io/data-list.c
src/language/data-io/get.c
src/language/data-io/inpt-pgm.c
src/language/data-io/print-space.c
src/language/data-io/print.c
src/language/stats/autorecode.c
src/language/stats/descriptives.c
src/language/stats/regression.q
src/language/tests/casefile-test.c
src/language/xforms/compute.c
src/language/xforms/count.c
src/language/xforms/recode.c
src/language/xforms/sample.c
src/language/xforms/select-if.c
src/ui/flexifile.c
tests/xforms/casefile.sh

index 145f70c62767d5f5c8fa7b2a43d98c7b7561ea53..e9998f076cfe2c3f717db6dae256b168c6e0b4ae 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PSPP 0.4.2\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2006-07-30 14:13+0800\n"
+"POT-Creation-Date: 2006-09-25 16:28+0800\n"
 "PO-Revision-Date: 2006-05-26 17:49+0800\n"
 "Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
 "Language-Team: German <pspp-dev@gnu.org>\n"
@@ -268,32 +268,32 @@ msgid ""
 "system-missing, zero, or negative.  These case(s) were ignored."
 msgstr ""
 
-#: src/data/fastfile.c:499
+#: src/data/fastfile.c:536
 #, c-format
 msgid "%s: Removing temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:623
+#: src/data/fastfile.c:660
 #, c-format
 msgid "Error writing temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:651
+#: src/data/fastfile.c:688
 #, c-format
 msgid "%s: Opening temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:695
+#: src/data/fastfile.c:732
 #, c-format
 msgid "%s: Seeking temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:717
+#: src/data/fastfile.c:754
 #, c-format
 msgid "%s: Reading temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:720
+#: src/data/fastfile.c:757
 #, c-format
 msgid "%s: Temporary file ended unexpectedly."
 msgstr ""
@@ -1163,24 +1163,24 @@ msgid ""
 msgstr ""
 
 #: src/language/data-io/data-list.c:403 src/language/data-io/data-list.c:503
-#: src/language/data-io/print.c:368 src/language/dictionary/split-file.c:84
+#: src/language/data-io/print.c:370 src/language/dictionary/split-file.c:84
 #: src/language/dictionary/sys-file-info.c:144
 #: src/language/dictionary/sys-file-info.c:378
 #: src/language/stats/descriptives.c:894
 msgid "Variable"
 msgstr ""
 
-#: src/language/data-io/data-list.c:404 src/language/data-io/print.c:369
+#: src/language/data-io/data-list.c:404 src/language/data-io/print.c:371
 msgid "Record"
 msgstr ""
 
-#: src/language/data-io/data-list.c:405 src/language/data-io/print.c:370
+#: src/language/data-io/data-list.c:405 src/language/data-io/print.c:372
 #: src/ui/gui/var-sheet.c:78
 msgid "Columns"
 msgstr "Spalten"
 
 #: src/language/data-io/data-list.c:406 src/language/data-io/data-list.c:504
-#: src/language/data-io/print.c:371
+#: src/language/data-io/print.c:373
 msgid "Format"
 msgstr ""
 
@@ -1416,7 +1416,7 @@ msgstr ""
 msgid "COLUMN subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:385
+#: src/language/data-io/inpt-pgm.c:384
 msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
@@ -1678,19 +1678,19 @@ msgid ""
 "Data fields must be listed in order of increasing record number."
 msgstr ""
 
-#: src/language/data-io/print.c:246
+#: src/language/data-io/print.c:248
 #, c-format
 msgid "Output calls for %d records but %d specified on RECORDS subcommand."
 msgstr ""
 
-#: src/language/data-io/print.c:400
+#: src/language/data-io/print.c:402
 #, c-format
 msgid "Writing %d record to %s."
 msgid_plural "Writing %d records to %s."
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/language/data-io/print.c:404
+#: src/language/data-io/print.c:406
 #, c-format
 msgid "Writing %d record."
 msgid_plural "Writing %d records."
@@ -1727,7 +1727,7 @@ msgid "No matching variables found between the source and target files."
 msgstr ""
 
 #: src/language/dictionary/formats.c:92
-msgid "`(' expected after variable list"
+msgid "`(' expected after variable list."
 msgstr ""
 
 #: src/language/dictionary/formats.c:102 src/language/dictionary/numeric.c:71
@@ -4222,7 +4222,7 @@ msgstr "Alle Datei"
 msgid "Save Data As"
 msgstr "Speichern unter"
 
-#: src/ui/gui/menu-actions.c:582
+#: src/ui/gui/menu-actions.c:500
 msgid "Font Selection"
 msgstr "Schriftwahlung"
 
@@ -4250,11 +4250,11 @@ msgstr "Falshe Spannweitebeschreibung"
 msgid "Sorry. The help system hasn't yet been implemented."
 msgstr "Es gibt noch nicht kein Helpsysteme. Schade!"
 
-#: src/ui/gui/psppire-data-store.c:731
+#: src/ui/gui/psppire-data-store.c:733
 msgid "var"
 msgstr ""
 
-#: src/ui/gui/psppire-data-store.c:812 src/ui/gui/psppire-var-store.c:518
+#: src/ui/gui/psppire-data-store.c:814 src/ui/gui/psppire-var-store.c:518
 #: src/ui/gui/psppire-var-store.c:528 src/ui/gui/psppire-var-store.c:538
 #: src/ui/gui/psppire-var-store.c:735
 #, c-format
index 34ae5e4078ec78079cbbab1c4681d4f92aa04703..74ece980f9bcfcbef3f092e2eff8305d2fb9aec3 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2006-07-30 14:13+0800\n"
+"POT-Creation-Date: 2006-09-25 16:28+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -267,32 +267,32 @@ msgid ""
 "system-missing, zero, or negative.  These case(s) were ignored."
 msgstr ""
 
-#: src/data/fastfile.c:499
+#: src/data/fastfile.c:536
 #, c-format
 msgid "%s: Removing temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:623
+#: src/data/fastfile.c:660
 #, c-format
 msgid "Error writing temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:651
+#: src/data/fastfile.c:688
 #, c-format
 msgid "%s: Opening temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:695
+#: src/data/fastfile.c:732
 #, c-format
 msgid "%s: Seeking temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:717
+#: src/data/fastfile.c:754
 #, c-format
 msgid "%s: Reading temporary file: %s."
 msgstr ""
 
-#: src/data/fastfile.c:720
+#: src/data/fastfile.c:757
 #, c-format
 msgid "%s: Temporary file ended unexpectedly."
 msgstr ""
@@ -1162,24 +1162,24 @@ msgid ""
 msgstr ""
 
 #: src/language/data-io/data-list.c:403 src/language/data-io/data-list.c:503
-#: src/language/data-io/print.c:368 src/language/dictionary/split-file.c:84
+#: src/language/data-io/print.c:370 src/language/dictionary/split-file.c:84
 #: src/language/dictionary/sys-file-info.c:144
 #: src/language/dictionary/sys-file-info.c:378
 #: src/language/stats/descriptives.c:894
 msgid "Variable"
 msgstr ""
 
-#: src/language/data-io/data-list.c:404 src/language/data-io/print.c:369
+#: src/language/data-io/data-list.c:404 src/language/data-io/print.c:371
 msgid "Record"
 msgstr ""
 
-#: src/language/data-io/data-list.c:405 src/language/data-io/print.c:370
+#: src/language/data-io/data-list.c:405 src/language/data-io/print.c:372
 #: src/ui/gui/var-sheet.c:78
 msgid "Columns"
 msgstr ""
 
 #: src/language/data-io/data-list.c:406 src/language/data-io/data-list.c:504
-#: src/language/data-io/print.c:371
+#: src/language/data-io/print.c:373
 msgid "Format"
 msgstr ""
 
@@ -1415,7 +1415,7 @@ msgstr ""
 msgid "COLUMN subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:385
+#: src/language/data-io/inpt-pgm.c:384
 msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
@@ -1677,19 +1677,19 @@ msgid ""
 "Data fields must be listed in order of increasing record number."
 msgstr ""
 
-#: src/language/data-io/print.c:246
+#: src/language/data-io/print.c:248
 #, c-format
 msgid "Output calls for %d records but %d specified on RECORDS subcommand."
 msgstr ""
 
-#: src/language/data-io/print.c:400
+#: src/language/data-io/print.c:402
 #, c-format
 msgid "Writing %d record to %s."
 msgid_plural "Writing %d records to %s."
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/language/data-io/print.c:404
+#: src/language/data-io/print.c:406
 #, c-format
 msgid "Writing %d record."
 msgid_plural "Writing %d records."
@@ -1726,7 +1726,7 @@ msgid "No matching variables found between the source and target files."
 msgstr ""
 
 #: src/language/dictionary/formats.c:92
-msgid "`(' expected after variable list"
+msgid "`(' expected after variable list."
 msgstr ""
 
 #: src/language/dictionary/formats.c:102 src/language/dictionary/numeric.c:71
@@ -4221,7 +4221,7 @@ msgstr ""
 msgid "Save Data As"
 msgstr ""
 
-#: src/ui/gui/menu-actions.c:582
+#: src/ui/gui/menu-actions.c:500
 msgid "Font Selection"
 msgstr ""
 
@@ -4249,11 +4249,11 @@ msgstr ""
 msgid "Sorry. The help system hasn't yet been implemented."
 msgstr ""
 
-#: src/ui/gui/psppire-data-store.c:731
+#: src/ui/gui/psppire-data-store.c:733
 msgid "var"
 msgstr ""
 
-#: src/ui/gui/psppire-data-store.c:812 src/ui/gui/psppire-var-store.c:518
+#: src/ui/gui/psppire-data-store.c:814 src/ui/gui/psppire-var-store.c:518
 #: src/ui/gui/psppire-var-store.c:528 src/ui/gui/psppire-var-store.c:538
 #: src/ui/gui/psppire-var-store.c:735
 #, c-format
index 3086444287fc0de8346f67808656a37a51ac4be0..795b40254816351226341ff764e7a04a7b9d4522 100644 (file)
@@ -1,3 +1,10 @@
+Mon Sep 25 17:11:46 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile-private.h casefile.c casefile.h fastfile.c: Created new
+       casereader method casereader_clone.   
+       
+       * procedure.c pransformations.h: Introduced new type casenum_t
+
 Thu Sep 21 07:00:30 2006  Ben Pfaff  <blp@gnu.org>
 
        * variable.c: (width_to_bytes) Rephrase code for clarify.
index 6e35300be7b5e37e068f01bb8469573cd635054e..c59027658e3b6b4416038d2aa785fba14dd28489 100644 (file)
@@ -65,6 +65,8 @@ struct class_casereader
   unsigned long (*cnum) (const struct casereader *);
 
   void (*destroy) (struct casereader * r);
+
+  struct casereader * (*clone) (const struct casereader *);
 };
 
 
index 95e0388c4e8733ed74b6a3e89ebd780a0dbbe771..f0e700d530a131b3ec5560916d37a7100df2aba5 100644 (file)
@@ -157,7 +157,10 @@ casereader_read_xfer (struct casereader *ffr, struct ccase *c)
   if ( ! read_case ) return false;
 
   if ( ffr->destructive && casefile_in_core (cf) )
+    {
+      case_nullify (c);
     case_move (c, read_case);
+    }
   else
     case_clone (c, read_case);
 
@@ -173,6 +176,16 @@ casereader_destroy (struct casereader *r)
   r->class->destroy(r);
 }
 
+/* Creates a copy of R and returns it */
+struct casereader *
+casereader_clone(const struct casereader *r)
+{
+  /* Would we ever want to clone a destructive reader ?? */
+  assert ( ! r->destructive ) ;
+
+  return r->class->clone (r);
+}
+
 /* Destroys casefile CF. */
 void
 casefile_destroy(struct casefile *cf)
index 1bddb2d24a19769224ad42ee8a85db56a8744538..9c985001e93dec76752b87a744e992f576218723 100644 (file)
@@ -30,6 +30,7 @@ struct casereader;
 struct casefile;
 
 
+/* Casereader functions */
 
 struct casefile *casereader_get_casefile (const struct casereader *r);
 
@@ -41,6 +42,11 @@ bool casereader_read_xfer (struct casereader *r, struct ccase *c);
 
 void casereader_destroy (struct casereader *r);
 
+struct casereader *casereader_clone(const struct casereader *r);
+
+
+/* Casefile functions */
+
 void casefile_destroy (struct casefile *cf);
 
 bool casefile_error (const struct casefile *cf);
@@ -50,9 +56,8 @@ unsigned long casefile_get_case_cnt (const struct casefile *cf);
 size_t casefile_get_value_cnt (const struct casefile *cf);
 
 struct casereader *casefile_get_reader (const struct casefile *cf);
-struct casereader *casefile_get_destructive_reader (struct casefile *cf);
-
 
+struct casereader *casefile_get_destructive_reader (struct casefile *cf);
 
 bool casefile_append (struct casefile *cf, const struct ccase *c);
 
index 9cdba1567648b002c7848b057ba431be88464ff4..c789012b2339780dc2488bb95273297a978a09d5 100644 (file)
@@ -86,8 +86,7 @@
           also read with casereaders in this phase, but the
           ability to create new casereaders is curtailed.
 
-          In this phase, casereaders could still be cloned (once
-          we eventually implement cloning).
+          In this phase, casereaders could still be cloned.
 
           To transition from phase 1 or 2 to phase 3 and create a
           casereader, call casefile_get_destructive_reader().
@@ -287,6 +286,44 @@ fastfile_get_reader (const struct casefile *cf_)
   return reader;
 }
 
+
+/* Creates a copy of the casereader CR, and returns it */
+static struct casereader *
+fastfilereader_clone (const struct casereader *cr)
+{
+  const struct fastfilereader *ffr = (const struct fastfilereader *) cr ;
+  struct fastfilereader *new_ffr = xzalloc (sizeof *new_ffr);
+
+  struct casereader *new_reader = (struct casereader *) new_ffr;
+
+  struct casefile *cf =  casereader_get_casefile (cr);
+  struct fastfile *ff = (struct fastfile *) cf;
+
+  assert (!cf->being_destroyed);
+
+  /* Flush the buffer to disk if it's not empty. */
+  if (ff->mode == WRITE && ff->storage == DISK)
+    flush_buffer (ff);
+
+  ff->mode = READ;
+
+  casereader_register (cf, new_reader, &class_reader);
+
+  new_ffr->case_idx = ffr->case_idx ;
+  new_reader->destructive = cr->destructive;
+  new_ffr->fd = ffr->fd ;
+  new_ffr->buffer = ffr->buffer ;
+  new_ffr->buffer_pos = ffr->buffer_pos;
+
+  if (ff->storage == DISK)
+    reader_open_file (new_ffr);
+
+  return new_reader;
+}
+
+
+
+
 /* Returns the number of `union value's in a case for CF. */
 static size_t
 fastfile_get_value_cnt (const struct casefile *cf)
@@ -748,4 +785,5 @@ static const struct class_casereader class_reader =
     fastfilereader_get_next_case,
     fastfilereader_cnum,
     fastfilereader_destroy,
+    fastfilereader_clone,
   };
index 5649a173a223446a6d27b0d659d39fb8a455889b..a779771ca427d1e55befa6d51b955fe1b1bb98ce 100644 (file)
@@ -875,7 +875,7 @@ add_case_limit_trns (void)
    *CASES_REMAINING. */
 static int
 case_limit_trns_proc (void *cases_remaining_,
-                      struct ccase *c UNUSED, int case_nr UNUSED) 
+                      struct ccase *c UNUSED, casenum_t case_nr UNUSED) 
 {
   size_t *cases_remaining = cases_remaining_;
   if (*cases_remaining > 0) 
@@ -914,7 +914,7 @@ add_filter_trns (void)
 /* FILTER transformation. */
 static int
 filter_trns_proc (void *filter_var_,
-                  struct ccase *c UNUSED, int case_nr UNUSED) 
+                  struct ccase *c UNUSED, casenum_t case_nr UNUSED) 
   
 {
   struct variable *filter_var = filter_var_;
index 196f65dce980e6f2ce2f8f38b7fb9042634e1b75..cc552a103ec44464b8d3d5ec21a162af97c79f9d 100644 (file)
@@ -23,6 +23,8 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+typedef unsigned long casenum_t ;
+
 /* trns_proc_func return values. */
 enum trns_result 
   {
@@ -35,7 +37,7 @@ enum trns_result
 
 struct ccase;
 typedef void trns_finalize_func (void *);
-typedef int trns_proc_func (void *, struct ccase *, int);
+typedef int trns_proc_func (void *, struct ccase *, casenum_t);
 typedef bool trns_free_func (void *);
 \f
 /* Transformation chains. */
index 47fceee6781bbb3d158b6073ea24cfa210132315..a0bbf79381434b101a20ab0b1991a44cb434cf89 100644 (file)
@@ -238,7 +238,7 @@ do_if_finalize_func (void *do_if_ UNUSED)
    Checks each clause and jumps to the appropriate
    transformation. */
 static int 
-do_if_trns_proc (void *do_if_, struct ccase *c, int case_num UNUSED)
+do_if_trns_proc (void *do_if_, struct ccase *c, casenum_t case_num UNUSED)
 {
   struct do_if_trns *do_if = do_if_;
   struct clause *clause;
@@ -277,7 +277,7 @@ do_if_trns_free (void *do_if_)
 
 /* Breaks out of a DO IF construct. */
 static int 
-break_trns_proc (void *do_if_, struct ccase *c UNUSED, int case_num UNUSED)
+break_trns_proc (void *do_if_, struct ccase *c UNUSED, casenum_t case_num UNUSED)
 {
   struct do_if_trns *do_if = do_if_;
 
index f31486f605f7bd7680257bf4dd0710738374b02a..242c936a159dc5b651b719b08cd85620ff2d5607 100644 (file)
@@ -273,7 +273,7 @@ loop_trns_finalize (void *do_if_ UNUSED)
 
 /* Sets up LOOP for the first pass. */
 static int
-loop_trns_proc (void *loop_, struct ccase *c, int case_num)
+loop_trns_proc (void *loop_, struct ccase *c, casenum_t case_num)
 {
   struct loop_trns *loop = loop_;
 
@@ -325,7 +325,7 @@ loop_trns_free (void *loop_)
 
 /* Finishes a pass through the loop and starts the next. */
 static int
-end_loop_trns_proc (void *loop_, struct ccase *c, int case_num UNUSED)
+end_loop_trns_proc (void *loop_, struct ccase *c, casenum_t case_num UNUSED)
 {
   struct loop_trns *loop = loop_;
 
@@ -363,7 +363,7 @@ end_loop_trns_proc (void *loop_, struct ccase *c, int case_num UNUSED)
 
 /* Executes BREAK. */
 static int
-break_trns_proc (void *loop_, struct ccase *c UNUSED, int case_num UNUSED)
+break_trns_proc (void *loop_, struct ccase *c UNUSED, casenum_t case_num UNUSED)
 {
   struct loop_trns *loop = loop_;
 
index e86c91b386e2753e3a1430bee2d04082f5ef6982..39bd743efb3e3dec479b7c6c47a20aebe3cb7652 100644 (file)
@@ -771,7 +771,7 @@ data_list_trns_free (void *dls_)
 
 /* Handle DATA LIST transformation DLS, parsing data into C. */
 static int
-data_list_trns_proc (void *dls_, struct ccase *c, int case_num UNUSED)
+data_list_trns_proc (void *dls_, struct ccase *c, casenum_t case_num UNUSED)
 {
   struct data_list_pgm *dls = dls_;
   int retval;
index 789d259e6cbb1a3a197788ff92ed64b7d3f439e8..2bb463113c4fcff8d4b49d0dd7aba8818512c3bd 100644 (file)
@@ -542,7 +542,7 @@ parse_output_trns (enum writer_type writer_type)
 
 /* Writes case C to the system file specified on XSAVE or XEXPORT. */
 static int
-output_trns_proc (void *trns_, struct ccase *c, int case_num UNUSED)
+output_trns_proc (void *trns_, struct ccase *c, casenum_t case_num UNUSED)
 {
   struct output_trns *t = trns_;
   case_writer_write_case (t->aw, c);
index c5d6cfe7d4862a07d128f3178ae3124905204a54..11b633195b0e4f3715ee1ad5c1d7e2f0f016d02e 100644 (file)
@@ -297,7 +297,7 @@ cmd_end_case (void)
 
 /* Sends the current case as the source's output. */
 int
-end_case_trns_proc (void *inp_, struct ccase *c, int case_nr UNUSED)
+end_case_trns_proc (void *inp_, struct ccase *c, casenum_t case_nr UNUSED)
 {
   struct input_program_pgm *inp = inp_;
 
@@ -370,7 +370,7 @@ cmd_reread (void)
 
 /* Executes a REREAD transformation. */
 static int
-reread_trns_proc (void *t_, struct ccase *c, int case_num)
+reread_trns_proc (void *t_, struct ccase *c, casenum_t case_num)
 {
   struct reread_trns *t = t_;
 
@@ -416,7 +416,7 @@ cmd_end_file (void)
 /* Executes an END FILE transformation. */
 static int
 end_file_trns_proc (void *trns_ UNUSED, struct ccase *c UNUSED,
-                    int case_num UNUSED)
+                    casenum_t case_num UNUSED)
 {
   return TRNS_END_FILE;
 }
index 1388f2971294660be67ae8d5a88f6deff5d37488..7eddf99dd855f80405428b5b27542651fc905cde 100644 (file)
@@ -103,7 +103,7 @@ cmd_print_space (void)
 /* Executes a PRINT SPACE transformation. */
 static int
 print_space_trns_proc (void *t_, struct ccase *c,
-                       int case_num UNUSED)
+                       casenum_t case_num UNUSED)
 {
   struct print_space_trns *trns = t_;
   int n;
index 64e1e13f63016366011dd3be89c28f5b535777e2..87f20675097c055d4aad8d1cd81e3075a2d67d6f 100644 (file)
@@ -416,7 +416,7 @@ static void flush_records (struct print_trns *,
 
 /* Performs the transformation inside print_trns T on case C. */
 static int
-print_trns_proc (void *trns_, struct ccase *c, int case_num UNUSED)
+print_trns_proc (void *trns_, struct ccase *c, casenum_t case_num UNUSED)
 {
   struct print_trns *trns = trns_;
   struct prt_out_spec *spec;
index 4d3513eea4925e09f0c506b2bd57514ce1ef2a53..f967dd3aca217d29a7594d861707bb6b82dd47f0 100644 (file)
@@ -272,7 +272,7 @@ recode (const struct autorecode_pgm *arc)
 
 /* Executes an AUTORECODE transformation. */
 static int
-autorecode_trns_proc (void *trns_, struct ccase *c, int case_idx UNUSED)
+autorecode_trns_proc (void *trns_, struct ccase *c, casenum_t case_idx UNUSED)
 {
   struct autorecode_trns *trns = trns_;
   size_t i;
index eaf9bb7fcc0034b77c9d2f6b8f3ee177af60262e..a513bc09ef1436d565fc6bbf2ca4508bdce9eac4 100644 (file)
@@ -576,7 +576,7 @@ dump_z_table (struct dsc_proc *dsc)
 */
 static int
 descriptives_trns_proc (void *trns_, struct ccase * c,
-                        int case_idx UNUSED)
+                        casenum_t case_idx UNUSED)
 {
   struct dsc_trns *t = trns_;
   struct dsc_z_score *z;
index 3706760a38ed9689b64b4d0afaedd7a05908fb0a..83d781448218e7a3d0910e0ba58c1b262df15e5a 100644 (file)
@@ -544,7 +544,8 @@ regression_trns_free (void *t_)
   Gets the predicted values.
  */
 static int
-regression_trns_pred_proc (void *t_, struct ccase *c, int case_idx UNUSED)
+regression_trns_pred_proc (void *t_, struct ccase *c, 
+                          casenum_t case_idx UNUSED)
 {
   size_t i;
   size_t n_vals;
@@ -582,7 +583,8 @@ regression_trns_pred_proc (void *t_, struct ccase *c, int case_idx UNUSED)
   Gets the residuals.
  */
 static int
-regression_trns_resid_proc (void *t_, struct ccase *c, int case_idx UNUSED)
+regression_trns_resid_proc (void *t_, struct ccase *c, 
+                           casenum_t case_idx UNUSED)
 {
   size_t i;
   size_t n_vals;
index a90cbfb7e7a1dc4f5b26d622478e40d8b94ee522..a1927ddb98dc3009820ed3b5200ca7a416997c44 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdarg.h>
 #include <language/command.h>
 #include <language/lexer/lexer.h>
+#include <libpspp/assertion.h>
 
 #include "xalloc.h"
 
@@ -38,6 +39,9 @@ static void write_random_case (struct casefile *cf, size_t case_idx);
 static void read_and_verify_random_case (struct casefile *cf,
                                          struct casereader *reader,
                                          size_t case_idx);
+static void test_casereader_clone (struct casereader *reader1, size_t case_cnt);
+                                
+
 static void fail_test (const char *message, ...);
 
 int
@@ -63,7 +67,7 @@ cmd_debug_casefile (void)
   if (token != '.')
     return lex_end_of_command ();
     
-  for (pattern = 0; pattern < 6; pattern++) 
+  for (pattern = 0; pattern < 7; pattern++) 
     {
       const size_t *size;
 
@@ -129,6 +133,12 @@ test_casefile (int pattern, size_t value_cnt, size_t case_cnt)
       for (; j < case_cnt; j++) 
         read_and_verify_random_case (cf, r2, j);
       break;
+    case 6:
+      test_casereader_clone (r1, case_cnt);
+      test_casereader_clone (r2, case_cnt);
+      break;
+    default:
+      NOT_REACHED ();
     }
   if (casereader_read (r1, &c))
     fail_test ("Casereader 1 not at end of file.");
@@ -204,6 +214,60 @@ read_and_verify_random_case (struct casefile *cf,
   case_destroy (&expected_case);
 }
 
+static void
+test_casereader_clone (struct casereader *reader1, size_t case_cnt)
+{
+  size_t i;
+  size_t cases = 0;
+  struct ccase c1;
+  struct ccase c2;
+  struct casefile *src = casereader_get_casefile (reader1);
+  struct casereader *clone = NULL;
+
+  size_t value_cnt = casefile_get_value_cnt (src);
+
+  struct casefile *newfile = fastfile_create (value_cnt);
+  struct casereader *newreader;
+
+
+  /* Read a 3rd of the cases */
+  for ( i = 0 ; i < case_cnt / 3 ; ++i ) 
+    casereader_read (reader1, &c1);
+
+  clone = casereader_clone (reader1);
+
+  /* Copy all the cases into a new file */
+  while( casereader_read (reader1, &c1))
+    { 
+      casefile_append (newfile, &c1);
+      cases ++;
+    }
+
+  newreader = casefile_get_reader (newfile);
+
+  /* Make sure that the new file's are identical to those returned from 
+     the cloned reader */
+  while( casereader_read (clone, &c1))
+    { 
+      const union value *v1;
+      const union value *v2;
+      cases --;
+
+      if ( ! casereader_read_xfer (newreader, &c2) ) 
+       break;
+      
+      v1 = case_data_all (&c1) ;
+      v2 = case_data_all (&c2) ;
+
+      if ( 0 != memcmp (v1, v2, value_cnt * MAX_SHORT_STRING))
+       fail_test ("Cloned reader read different value at case %ld", cases);
+    }
+
+  if ( cases > 0 ) 
+    fail_test ("Cloned reader reads different number of cases.");
+
+}
+
 static void
 fail_test (const char *message, ...) 
 {
index 0bc6e4d3fd231581fcc9448792f89d494cd964f7..5c13d2f23a7a3970139a1259eead41e75cd741a0 100644 (file)
@@ -110,7 +110,7 @@ cmd_compute (void)
 
 /* Handle COMPUTE or IF with numeric target variable. */
 static int
-compute_num (void *compute_, struct ccase *c, int case_num)
+compute_num (void *compute_, struct ccase *c, casenum_t case_num)
 {
   struct compute_trns *compute = compute_;
 
@@ -125,7 +125,7 @@ compute_num (void *compute_, struct ccase *c, int case_num)
 /* Handle COMPUTE or IF with numeric vector element target
    variable. */
 static int
-compute_num_vec (void *compute_, struct ccase *c, int case_num)
+compute_num_vec (void *compute_, struct ccase *c, casenum_t case_num)
 {
   struct compute_trns *compute = compute_;
 
@@ -157,7 +157,7 @@ compute_num_vec (void *compute_, struct ccase *c, int case_num)
 
 /* Handle COMPUTE or IF with string target variable. */
 static int
-compute_str (void *compute_, struct ccase *c, int case_num)
+compute_str (void *compute_, struct ccase *c, casenum_t case_num)
 {
   struct compute_trns *compute = compute_;
 
@@ -172,7 +172,7 @@ compute_str (void *compute_, struct ccase *c, int case_num)
 /* Handle COMPUTE or IF with string vector element target
    variable. */
 static int
-compute_str_vec (void *compute_, struct ccase *c, int case_num)
+compute_str_vec (void *compute_, struct ccase *c, casenum_t case_num)
 {
   struct compute_trns *compute = compute_;
 
index 38e3e955775513d340b9b01f8bfc3db95f8e7429..8f6c8f627243c93584ce7b850cee2770ff600115 100644 (file)
@@ -325,7 +325,7 @@ count_string (struct criteria *crit, struct ccase *c)
 /* Performs the COUNT transformation T on case C. */
 static int
 count_trns_proc (void *trns_, struct ccase *c,
-                 int case_num UNUSED)
+                 casenum_t case_num UNUSED)
 {
   struct count_trns *trns = trns_;
   struct dst_var *dv;
index 03fd0bc3dd0fc6132e781b452f16473d5069a910..05cd3d1c04f36449d278ee4a96d99990b61ad8eb 100644 (file)
@@ -622,7 +622,7 @@ find_src_string (struct recode_trns *trns, const char *value, int width)
 
 /* Performs RECODE transformation. */
 static int
-recode_trns_proc (void *trns_, struct ccase *c, int case_idx UNUSED)
+recode_trns_proc (void *trns_, struct ccase *c, casenum_t case_idx UNUSED)
 {
   struct recode_trns *trns = trns_;
   size_t i;
index 41b47f869d34bceecfa24f1299a6f9d6cd4674c9..8b0650d51e4502639a1e0192355692092d49eaef 100644 (file)
@@ -119,7 +119,7 @@ cmd_sample (void)
 /* Executes a SAMPLE transformation. */
 static int
 sample_trns_proc (void *t_, struct ccase *c UNUSED,
-                  int case_num UNUSED)
+                  casenum_t case_num UNUSED)
 {
   struct sample_trns *t = t_;
   double U;
index e6dc9b4bb0b291c4c21a2f4b5a4a035b3b7e2f30..7acb3ec09aafa2017ef16175b79fd622f1d89046 100644 (file)
@@ -73,7 +73,7 @@ cmd_select_if (void)
 /* Performs the SELECT IF transformation T on case C. */
 static int
 select_if_proc (void *t_, struct ccase *c,
-                int case_num)
+                casenum_t case_num)
 {
   struct select_if_trns *t = t_;
   return (expr_evaluate_num (t->e, c, case_num) == 1.0
index 756f67a10b2f07c8f056fe2632d4a4953e4d1c1d..9ed760b254a7def3c016aa946380fa07e9413552 100644 (file)
@@ -212,6 +212,24 @@ flexifile_get_reader (const struct casefile *cf_)
   return reader;
 }
 
+
+static struct casereader *
+flexifilereader_clone (const struct casereader *cr)
+{
+  const struct flexifilereader *ffr = (const struct flexifilereader *) cr;
+  struct flexifilereader *new_ffr = xzalloc (sizeof *new_ffr);
+  struct casereader *new_reader = (struct casereader *) new_ffr;
+  struct casefile *cf = casereader_get_casefile (cr);
+
+  casereader_register (cf, new_reader, CLASS_CASEREADER(&class_reader));
+
+  new_ffr->case_idx = ffr->case_idx ;
+  new_ffr->destructive = ffr->destructive ;
+
+  return new_reader;
+}
+
+
 static bool
 flexifile_in_core(const struct casefile *cf UNUSED)
 {
@@ -268,7 +286,8 @@ static const struct class_flexifilereader class_reader =
     {
       flexifilereader_get_next_case,
       0,  /* cnum */
-      flexifilereader_destroy
+      flexifilereader_destroy,
+      flexifilereader_clone
     }
   };
 
index 46e97eab76e86ca332b664a0b3b7d80605bbfbb9..c354857240b1b1bf7094304bcff2c370b99e5d0f 100755 (executable)
@@ -66,12 +66,7 @@ perl -pi -e 's/^\s*$//g' $TEMPDIR/casefile.out
 diff -b $TEMPDIR/casefile.out - <<EOF
 Casefile tests succeeded.
 EOF
-
-if [ $? -ne 0 ] ; then no_result ; fi
-
-
 if [ $? -ne 0 ] ; then fail ; fi
 
 
-
 pass;