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"
 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"
 "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 ""
 
 "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 ""
 
 #, 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 ""
 
 #, 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 ""
 
 #, 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 ""
 
 #, 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 ""
 
 #, 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 ""
 #, 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
 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/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 ""
 
 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/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 ""
 
 msgid "Format"
 msgstr ""
 
@@ -1416,7 +1416,7 @@ msgstr ""
 msgid "COLUMN subcommand multiply specified."
 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 ""
 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 ""
 
 "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 ""
 
 #, 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] ""
 
 #, 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."
 #, 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
 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
 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"
 
 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"
 
 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!"
 
 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 ""
 
 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
 #: 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"
 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"
 "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 ""
 
 "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 ""
 
 #, 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 ""
 
 #, 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 ""
 
 #, 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 ""
 
 #, 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 ""
 
 #, 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 ""
 #, 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
 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/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 ""
 
 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/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 ""
 
 msgid "Format"
 msgstr ""
 
@@ -1415,7 +1415,7 @@ msgstr ""
 msgid "COLUMN subcommand multiply specified."
 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 ""
 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 ""
 
 "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 ""
 
 #, 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] ""
 
 #, 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."
 #, 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
 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
 msgstr ""
 
 #: src/language/dictionary/formats.c:102 src/language/dictionary/numeric.c:71
@@ -4221,7 +4221,7 @@ msgstr ""
 msgid "Save Data As"
 msgstr ""
 
 msgid "Save Data As"
 msgstr ""
 
-#: src/ui/gui/menu-actions.c:582
+#: src/ui/gui/menu-actions.c:500
 msgid "Font Selection"
 msgstr ""
 
 msgid "Font Selection"
 msgstr ""
 
@@ -4249,11 +4249,11 @@ msgstr ""
 msgid "Sorry. The help system hasn't yet been implemented."
 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 ""
 
 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
 #: 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.
 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);
   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) )
   if ( ! read_case ) return false;
 
   if ( ffr->destructive && casefile_in_core (cf) )
+    {
+      case_nullify (c);
     case_move (c, read_case);
     case_move (c, read_case);
+    }
   else
     case_clone (c, read_case);
 
   else
     case_clone (c, read_case);
 
@@ -173,6 +176,16 @@ casereader_destroy (struct casereader *r)
   r->class->destroy(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)
 /* Destroys casefile CF. */
 void
 casefile_destroy(struct casefile *cf)
index 1bddb2d24a19769224ad42ee8a85db56a8744538..9c985001e93dec76752b87a744e992f576218723 100644 (file)
@@ -30,6 +30,7 @@ struct casereader;
 struct casefile;
 
 
 struct casefile;
 
 
+/* Casereader functions */
 
 struct casefile *casereader_get_casefile (const struct casereader *r);
 
 
 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);
 
 
 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);
 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);
 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);
 
 
 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.
 
           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().
 
           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;
 }
 
   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)
 /* 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_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_,
    *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) 
 {
   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_,
 /* 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_;
   
 {
   struct variable *filter_var = filter_var_;
index 196f65dce980e6f2ce2f8f38b7fb9042634e1b75..cc552a103ec44464b8d3d5ec21a162af97c79f9d 100644 (file)
@@ -23,6 +23,8 @@
 #include <stdbool.h>
 #include <stddef.h>
 
 #include <stdbool.h>
 #include <stddef.h>
 
+typedef unsigned long casenum_t ;
+
 /* trns_proc_func return values. */
 enum trns_result 
   {
 /* trns_proc_func return values. */
 enum trns_result 
   {
@@ -35,7 +37,7 @@ enum trns_result
 
 struct ccase;
 typedef void trns_finalize_func (void *);
 
 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. */
 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 
    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;
 {
   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 
 
 /* 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_;
 
 {
   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
 
 /* 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_;
 
 {
   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
 
 /* 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_;
 
 {
   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
 
 /* 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_;
 
 {
   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
 
 /* 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;
 {
   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
 
 /* 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);
 {
   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
 
 /* 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_;
 
 {
   struct input_program_pgm *inp = inp_;
 
@@ -370,7 +370,7 @@ cmd_reread (void)
 
 /* Executes a REREAD transformation. */
 static int
 
 /* 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_;
 
 {
   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,
 /* 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;
 }
 {
   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,
 /* 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;
 {
   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
 
 /* 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;
 {
   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
 
 /* 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;
 {
   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,
 */
 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;
 {
   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
   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;
 {
   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
   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;
 {
   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 <stdarg.h>
 #include <language/command.h>
 #include <language/lexer/lexer.h>
+#include <libpspp/assertion.h>
 
 #include "xalloc.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 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
 static void fail_test (const char *message, ...);
 
 int
@@ -63,7 +67,7 @@ cmd_debug_casefile (void)
   if (token != '.')
     return lex_end_of_command ();
     
   if (token != '.')
     return lex_end_of_command ();
     
-  for (pattern = 0; pattern < 6; pattern++) 
+  for (pattern = 0; pattern < 7; pattern++) 
     {
       const size_t *size;
 
     {
       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;
       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.");
     }
   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);
 }
 
   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, ...) 
 {
 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
 
 /* 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_;
 
 {
   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
 /* 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_;
 
 {
   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
 
 /* 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_;
 
 {
   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
 /* 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_;
 
 {
   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,
 /* 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;
 {
   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
 
 /* 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;
 {
   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,
 /* 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;
 {
   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,
 /* 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
 {
   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;
 }
 
   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)
 {
 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_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
 diff -b $TEMPDIR/casefile.out - <<EOF
 Casefile tests succeeded.
 EOF
-
-if [ $? -ne 0 ] ; then no_result ; fi
-
-
 if [ $? -ne 0 ] ; then fail ; fi
 
 
 if [ $? -ne 0 ] ; then fail ; fi
 
 
-
 pass;
 pass;