You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
#include "casefile.h"
#include "case.h"
#include "error.h"
#include "misc.h"
+#include "mkfile.h"
#include "settings.h"
#include "var.h"
-#ifdef HAVE_VALGRIND_VALGRIND_H
-#include <valgrind/valgrind.h>
-#endif
-
#define IO_BUF_SIZE (8192 / sizeof (union value))
/* A casefile is a sequentially accessible array of immutable
struct ccase c; /* Current case. */
};
+/* Return the case number of the current case */
+unsigned long
+casereader_cnum(const struct casereader *r)
+{
+ return r->case_idx;
+}
+
/* Doubly linked list of all casefiles. */
static struct casefile *casefiles;
casefile_mode_reader (cf);
casefile_to_disk (cf);
+ flush_buffer (cf);
if (cf->fd != -1)
{
}
}
-/* Creates a temporary file and stores its name in *FILENAME and
- a file descriptor for it in *FD. Returns success. Caller is
- responsible for freeing *FILENAME. */
-static int
-make_temp_file (int *fd, char **filename)
-{
- const char *parent_dir;
-
- assert (filename != NULL);
- assert (fd != NULL);
-
- if (getenv ("TMPDIR") != NULL)
- parent_dir = getenv ("TMPDIR");
- else
- parent_dir = P_tmpdir;
-
- *filename = xmalloc (strlen (parent_dir) + 32);
- sprintf (*filename, "%s%cpsppXXXXXX", parent_dir, DIR_SEPARATOR);
- *fd = mkstemp (*filename);
- if (*fd < 0)
- {
- msg (FE, _("%s: Creating temporary file: %s."),
- *filename, strerror (errno));
- free (*filename);
- *filename = NULL;
- return 0;
- }
- return 1;
-}
/* If CF is currently stored in memory, writes it to disk. Readers, if any,
retain their current positions. */
cf->mode = READ;
reader = xmalloc (sizeof *reader);
- reader->cf = cf;
reader->next = cf->readers;
if (cf->readers != NULL)
reader->next->prev = reader;
- reader->prev = NULL;
cf->readers = reader;
+ reader->prev = NULL;
+ reader->cf = cf;
reader->case_idx = 0;
+ reader->destructive = 0;
reader->fd = -1;
reader->buffer = NULL;
reader->buffer_pos = 0;
}
/* Reads a copy of the next case from READER into C.
- Caller is responsible for destroying C. */
+ Caller is responsible for destroying C.
+ Returns true if successful, false at end of file. */
int
casereader_read (struct casereader *reader, struct ccase *c)
{
}
/* Reads the next case from READER into C and transfers ownership
- to the caller. Caller is responsible for destroying C. */
+ to the caller. Caller is responsible for destroying C.
+ Returns true if successful, false at end of file. */
int
casereader_read_xfer (struct casereader *reader, struct ccase *c)
{
}
}
+/* Reads the next case from READER into C and transfers ownership
+ to the caller. Caller is responsible for destroying C.
+ Assert-fails at end of file. */
+void
+casereader_read_xfer_assert (struct casereader *reader, struct ccase *c)
+{
+ bool success = casereader_read_xfer (reader, c);
+ assert (success);
+}
+
/* Destroys READER. */
void
casereader_destroy (struct casereader *reader)
return bytes_written;
}
+
/* Registers our exit handler with atexit() if it has not already
been registered. */
static void
}
}
+
+
/* atexit() handler that closes and deletes our temporary
files. */
static void
if (token != '.')
return lex_end_of_command ();
- for (pattern = 0; pattern < 5; pattern++)
+ for (pattern = 0; pattern < 6; pattern++)
{
const size_t *size;
static void
test_casefile (int pattern, size_t value_cnt, size_t case_cnt)
{
- int zero = 0;
struct casefile *cf;
struct casereader *r1, *r2;
struct ccase c;
rng = gsl_rng_alloc (gsl_rng_mt19937);
cf = casefile_create (value_cnt);
+ if (pattern == 5)
+ casefile_to_disk (cf);
for (i = 0; i < case_cnt; i++)
write_random_case (cf, i);
+ if (pattern == 5)
+ casefile_sleep (cf);
r1 = casefile_get_reader (cf);
r2 = casefile_get_reader (cf);
switch (pattern)
{
case 0:
+ case 5:
for (i = 0; i < case_cnt; i++)
{
read_and_verify_random_case (cf, r1, i);