X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fcasefile.c;h=f43ec8faa4fb22d7e6a25f2ae536c9521b0a41fa;hb=5a33cc6d78fe87ff5e9bd32ea4af3f895e4ad2fc;hp=6d74e8e286ee3a8451b90db6951fb2f7599789b1;hpb=d5e5cf282cc56899913654a62c425e584acecfb2;p=pspp-builds.git diff --git a/src/casefile.c b/src/casefile.c index 6d74e8e2..f43ec8fa 100644 --- a/src/casefile.c +++ b/src/casefile.c @@ -14,8 +14,8 @@ 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 #include "casefile.h" @@ -30,13 +30,10 @@ #include "case.h" #include "error.h" #include "misc.h" +#include "mkfile.h" #include "settings.h" #include "var.h" -#ifdef HAVE_VALGRIND_VALGRIND_H -#include -#endif - #define IO_BUF_SIZE (8192 / sizeof (union value)) /* A casefile is a sequentially accessible array of immutable @@ -90,6 +87,13 @@ struct casereader 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; @@ -217,6 +221,7 @@ casefile_sleep (const struct casefile *cf_) casefile_mode_reader (cf); casefile_to_disk (cf); + flush_buffer (cf); if (cf->fd != -1) { @@ -331,35 +336,6 @@ flush_buffer (struct casefile *cf) } } -/* 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. */ @@ -437,13 +413,14 @@ casefile_get_reader (const struct casefile *cf_) 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; @@ -554,7 +531,8 @@ casereader_get_casefile (const struct casereader *reader) } /* 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) { @@ -591,7 +569,8 @@ 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) { @@ -613,6 +592,16 @@ 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) @@ -717,6 +706,7 @@ full_write (int fd, const void *buffer_, size_t size) return bytes_written; } + /* Registers our exit handler with atexit() if it has not already been registered. */ static void @@ -730,6 +720,8 @@ register_atexit (void) } } + + /* atexit() handler that closes and deletes our temporary files. */ static void @@ -776,7 +768,7 @@ cmd_debug_casefile (void) if (token != '.') return lex_end_of_command (); - for (pattern = 0; pattern < 5; pattern++) + for (pattern = 0; pattern < 6; pattern++) { const size_t *size; @@ -796,7 +788,6 @@ cmd_debug_casefile (void) 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; @@ -805,13 +796,18 @@ test_casefile (int pattern, size_t value_cnt, size_t case_cnt) 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);