X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fdata-writer.c;h=2c8f38a73e470be66cf5f8b0c1a61a4c0b3d4326;hb=e7d0a9f16192ceeff9243f0ede8e399ee1ef0d44;hp=57a5b9f71abc29422006c11c88b8c885cf66f76a;hpb=a19b858e0ac3c69e4a28c0ca6d8674427268a863;p=pspp-builds.git diff --git a/src/language/data-io/data-writer.c b/src/language/data-io/data-writer.c index 57a5b9f7..2c8f38a7 100644 --- a/src/language/data-io/data-writer.c +++ b/src/language/data-io/data-writer.c @@ -1,5 +1,5 @@ /* PSPP - computes sample statistics. - Copyright (C) 1997-2004 Free Software Foundation, Inc. + Copyright (C) 1997-2004, 2006 Free Software Foundation, Inc. Written by Ben Pfaff . This program is free software; you can redistribute it and/or @@ -18,16 +18,22 @@ 02110-1301, USA. */ #include + #include + #include #include #include + +#include +#include #include +#include #include -#include -#include #include +#include "minmax.h" + #include "gettext.h" #define _(msgid) gettext (msgid) @@ -35,8 +41,7 @@ struct dfm_writer { struct file_handle *fh; /* File handle. */ - struct file_ext file; /* Associated file. */ - char *bounce; /* Bounce buffer for fixed-size fields. */ + FILE *file; /* Associated file. */ }; /* Opens a file handle for writing as a data file. */ @@ -54,22 +59,13 @@ dfm_open_writer (struct file_handle *fh) w = *aux = xmalloc (sizeof *w); w->fh = fh; - w->file.file = NULL; - w->bounce = NULL; - - w->file.filename = xstrdup (fh_get_filename (w->fh)); - w->file.mode = "wb"; - w->file.file = NULL; - w->file.sequence_no = NULL; - w->file.param = NULL; - w->file.postopen = NULL; - w->file.preclose = NULL; - - if (!fn_open_ext (&w->file)) + w->file = fn_open (fh_get_file_name (w->fh), "wb"); + + if (w->file == NULL) { msg (ME, _("An error occurred while opening \"%s\" for writing " "as a data file: %s."), - fh_get_filename (w->fh), strerror (errno)); + fh_get_file_name (w->fh), strerror (errno)); goto error; } @@ -84,33 +80,48 @@ dfm_open_writer (struct file_handle *fh) bool dfm_write_error (const struct dfm_writer *writer) { - return ferror (writer->file.file); + return ferror (writer->file); } -/* Writes record REC having length LEN to the file corresponding to - HANDLE. REC is not null-terminated. Returns nonzero on success, - zero on failure. */ -int +/* Writes record REC (which need not be null-terminated) having + length LEN to the file corresponding to HANDLE. Adds any + needed formatting, such as a trailing new-line. Returns true + on success, false on failure. */ +bool dfm_put_record (struct dfm_writer *w, const char *rec, size_t len) { assert (w != NULL); if (dfm_write_error (w)) - return 0; - - if (fh_get_mode (w->fh) == FH_MODE_BINARY - && len < fh_get_record_width (w->fh)) + return false; + + switch (fh_get_mode (w->fh)) { - size_t rec_width = fh_get_record_width (w->fh); - if (w->bounce == NULL) - w->bounce = xmalloc (rec_width); - memcpy (w->bounce, rec, len); - memset (&w->bounce[len], 0, rec_width - len); - rec = w->bounce; - len = rec_width; + case FH_MODE_TEXT: + fwrite (rec, len, 1, w->file); + putc ('\n', w->file); + break; + + case FH_MODE_BINARY: + { + size_t record_width = fh_get_record_width (w->fh); + size_t write_bytes = MIN (len, record_width); + size_t pad_bytes = record_width - write_bytes; + fwrite (rec, write_bytes, 1, w->file); + while (pad_bytes > 0) + { + static const char spaces[32] = " "; + size_t chunk = MIN (pad_bytes, sizeof spaces); + fwrite (spaces, chunk, 1, w->file); + pad_bytes -= chunk; + } + } + break; + + default: + NOT_REACHED (); } - fwrite (rec, len, 1, w->file.file); return !dfm_write_error (w); } @@ -118,29 +129,28 @@ dfm_put_record (struct dfm_writer *w, const char *rec, size_t len) bool dfm_close_writer (struct dfm_writer *w) { + char *file_name; bool ok; if (w == NULL) return true; + file_name = xstrdup (fh_get_name (w->fh)); if (fh_close (w->fh, "data file", "ws")) - return true; + { + free (file_name); + return true; + } ok = true; - if (w->file.file != NULL) + if (w->file != NULL) { - ok = !dfm_write_error (w); - if (!fn_close_ext (&w->file)) - ok = false; + ok = !dfm_write_error (w) && !fn_close (file_name, w->file); if (!ok) - msg (ME, _("I/O error occurred writing data file \"%s\"."), - fh_get_filename (w->fh)); - - free (w->file.filename); - w->file.filename = NULL; + msg (ME, _("I/O error occurred writing data file \"%s\"."), file_name); } - free (w->bounce); free (w); + free (file_name); return ok; }