[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pspp-cvs] pspp/src libpspp/taint.h libpspp/taint.c data/s... [simpler-p
From: |
Ben Pfaff |
Subject: |
[Pspp-cvs] pspp/src libpspp/taint.h libpspp/taint.c data/s... [simpler-proc] |
Date: |
Mon, 07 May 2007 04:38:39 +0000 |
CVSROOT: /cvsroot/pspp
Module name: pspp
Branch: simpler-proc
Changes by: Ben Pfaff <blp> 07/05/07 04:38:39
Modified files:
src/libpspp : taint.h taint.c
src/data : sys-file-reader.c casewriter.h casewriter.c
casewriter-private.h casereader.c
casereader-private.h automake.mk
Added files:
src/data : casewriter-translator.c
Log message:
Continue cleanup.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/src/libpspp/taint.h?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/libpspp/taint.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/sys-file-reader.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.32.2.2&r2=1.32.2.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casewriter.h?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.3&r2=1.1.2.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casewriter.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.4&r2=1.1.2.5
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casewriter-private.h?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.2&r2=1.1.2.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casereader.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.6&r2=1.1.2.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casereader-private.h?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.2&r2=1.1.2.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/automake.mk?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.15.2.3&r2=1.15.2.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casewriter-translator.c?cvsroot=pspp&only_with_tag=simpler-proc&rev=1.1.2.1
Patches:
Index: libpspp/taint.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/libpspp/Attic/taint.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- libpspp/taint.h 4 May 2007 03:48:48 -0000 1.1.2.1
+++ libpspp/taint.h 7 May 2007 04:38:39 -0000 1.1.2.2
@@ -124,9 +124,9 @@
void taint_propagate (const struct taint *from, const struct taint *to);
bool taint_is_tainted (const struct taint *);
-void taint_set_taint (struct taint *);
+void taint_set_taint (const struct taint *);
bool taint_has_tainted_successor (const struct taint *);
-void taint_reset_successor_taint (struct taint *);
+void taint_reset_successor_taint (const struct taint *);
#endif /* libpspp/taint.h */
Index: libpspp/taint.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/libpspp/Attic/taint.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- libpspp/taint.c 4 May 2007 03:48:48 -0000 1.1.2.1
+++ libpspp/taint.c 7 May 2007 04:38:39 -0000 1.1.2.2
@@ -160,8 +160,9 @@
/* Marks TAINT tainted and propagates the taint to all of its
successors. */
void
-taint_set_taint (struct taint *taint)
+taint_set_taint (const struct taint *taint_)
{
+ struct taint *taint = (struct taint *) taint_;
if (!taint->tainted)
recursively_set_taint (taint);
}
@@ -180,8 +181,10 @@
/* Attempts to reset the successor-taint on TAINT. This is
successful only if TAINT currently has no tainted successor. */
void
-taint_reset_successor_taint (struct taint *taint)
+taint_reset_successor_taint (const struct taint *taint_)
{
+ struct taint *taint = (struct taint *) taint_;
+
if (taint->tainted_successor)
{
size_t i;
Index: data/sys-file-reader.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/sys-file-reader.c,v
retrieving revision 1.32.2.2
retrieving revision 1.32.2.3
diff -u -b -r1.32.2.2 -r1.32.2.3
--- data/sys-file-reader.c 4 May 2007 03:48:47 -0000 1.32.2.2
+++ data/sys-file-reader.c 7 May 2007 04:38:39 -0000 1.32.2.3
@@ -1100,7 +1100,7 @@
/* Reads one case from READER's file into C. Returns true only
if successful. */
static bool
-sys_file_casereader_read (struct casereader *reader UNUSED, void *r_,
+sys_file_casereader_read (struct casereader *reader, void *r_,
struct ccase *c)
{
struct sfm_reader *r = r_;
Index: data/casewriter.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casewriter.h,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -b -r1.1.2.3 -r1.1.2.4
--- data/casewriter.h 4 May 2007 03:48:47 -0000 1.1.2.3
+++ data/casewriter.h 7 May 2007 04:38:39 -0000 1.1.2.4
@@ -26,20 +26,20 @@
struct casewriter;
-struct casewriter *mem_writer_create (size_t value_cnt);
-struct casewriter *tmpfile_writer_create (size_t value_cnt);
-struct casewriter *autopaging_writer_create (size_t value_cnt);
-
-struct casewriter *casewriter_rename (struct casewriter *);
-
void casewriter_write (struct casewriter *, struct ccase *);
bool casewriter_destroy (struct casewriter *);
+struct casereader *casewriter_make_reader (struct casewriter *);
+
+struct casewriter *casewriter_rename (struct casewriter *);
+
bool casewriter_error (const struct casewriter *);
void casewriter_force_error (struct casewriter *);
const struct taint *casewriter_get_taint (const struct casewriter *);
-struct casereader *casewriter_make_reader (struct casewriter *);
+struct casewriter *mem_writer_create (size_t value_cnt);
+struct casewriter *tmpfile_writer_create (size_t value_cnt);
+struct casewriter *autopaging_writer_create (size_t value_cnt);
struct casewriter *
casewriter_create_translator (struct casewriter *,
Index: data/casewriter.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casewriter.c,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -b -r1.1.2.4 -r1.1.2.5
--- data/casewriter.c 6 May 2007 22:48:27 -0000 1.1.2.4
+++ data/casewriter.c 7 May 2007 04:38:39 -0000 1.1.2.5
@@ -34,25 +34,68 @@
#include "xalloc.h"
+/* A casewriter. */
struct casewriter
{
struct taint *taint;
casenumber case_cnt;
const struct casewriter_class *class;
- void *private;
+ void *aux;
};
-struct casewriter *
-casewriter_create (const struct casewriter_class *class, void *private)
+static struct casewriter *create_casewriter_window (size_t value_cnt,
+ casenumber max_in_core);
+
+/* Writes case C to WRITER. */
+void
+casewriter_write (struct casewriter *writer, struct ccase *c)
{
- struct casewriter *writer = xmalloc (sizeof *writer);
- writer->taint = taint_create ();
- writer->case_cnt = 0;
- writer->class = class;
- writer->private = private;
- return writer;
+ writer->class->write (writer, writer->aux, c);
}
+/* Destroys WRITER.
+ Returns true if successful, false if an I/O error was
+ encountered on WRITER or on some object on which WRITER has a
+ dependency. */
+bool
+casewriter_destroy (struct casewriter *writer)
+{
+ bool ok = true;
+ if (writer != NULL)
+ {
+ writer->class->destroy (writer, writer->aux);
+ ok = taint_destroy (writer->taint);
+ free (writer);
+ }
+ return ok;
+}
+
+/* Destroys WRITER and in its place returns a casereader that can
+ be used to read back the data written to WRITER. WRITER must
+ not be used again after calling this function, even as an
+ argument to casewriter_destroy.
+
+ Not all casewriters implement this function. Behavior is
+ undefined if it is called on one that does not.
+
+ If an I/O error was encountered on WRITER or on some object on
+ which WRITER has a dependency, then the error will be
+ propagated to the new casereader. */
+struct casereader *
+casewriter_make_reader (struct casewriter *writer)
+{
+ struct casereader *reader;
+ reader = writer->class->convert_to_reader (writer, writer->aux);
+ taint_propagate (writer->taint, casereader_get_taint (reader));
+ taint_destroy (writer->taint);
+ free (writer);
+ return reader;
+}
+
+/* Returns a copy of WRITER, which is itself destroyed.
+ Useful for taking over ownership of a casewriter, to enforce
+ preventing the original owner from accessing the casewriter
+ again. */
struct casewriter *
casewriter_rename (struct casewriter *writer)
{
@@ -61,86 +104,109 @@
return new;
}
-void
-casewriter_write (struct casewriter *writer, struct ccase *c)
-{
- writer->class->write (writer, writer->private, c);
-}
-
+/* Returns true if an I/O error or another hard error has
+ occurred on WRITER, a clone of WRITER, or on some object on
+ which WRITER's data has a dependency, false otherwise. */
bool
casewriter_error (const struct casewriter *writer)
{
return taint_is_tainted (writer->taint);
}
+/* Marks WRITER as having encountered an error.
+
+ Ordinarily, this function should be called by the
+ implementation of a casewriter, not by the casewriter's
+ client. Instead, casewriter clients should usually ensure
+ that a casewriter's error state is correct by using
+ taint_propagate to propagate to the casewriter's taint
+ structure, which may be obtained via casewriter_get_taint. */
void
casewriter_force_error (struct casewriter *writer)
{
taint_set_taint (writer->taint);
}
+/* Returns WRITER's associate taint object, for use with
+ taint_propagate and other taint functions. */
const struct taint *
casewriter_get_taint (const struct casewriter *writer)
{
return writer->taint;
}
-bool
-casewriter_destroy (struct casewriter *writer)
+/* Creates and returns a new casewriter with the given CLASS and
+ auxiliary data AUX. */
+struct casewriter *
+casewriter_create (const struct casewriter_class *class, void *aux)
{
- bool ok = true;
- if (writer != NULL)
- {
- writer->class->destroy (writer, writer->private);
- ok = taint_destroy (writer->taint);
- free (writer);
- }
- return ok;
+ struct casewriter *writer = xmalloc (sizeof *writer);
+ writer->taint = taint_create ();
+ writer->case_cnt = 0;
+ writer->class = class;
+ writer->aux = aux;
+ return writer;
}
-struct casereader *
-casewriter_make_reader (struct casewriter *writer)
-{
- struct casereader *reader;
- reader = writer->class->convert_to_reader (writer, writer->private);
- taint_propagate (writer->taint, casereader_get_taint (reader));
- taint_destroy (writer->taint);
- free (writer);
- return reader;
-}
+/* Returns a casewriter for cases with VALUE_CNT struct values
+ per case. The cases written to the casewriter will be kept in
+ memory, unless the amount of memory used grows too large, in
+ which case they will be written to disk.
-static const struct casewriter_class casewriter_window_class;
-static const struct buffered_reader_class casereader_window_class;
+ A casewriter created with this function may be passed to
+ casewriter_make_reader.
-static struct casewriter *
-create_casewriter_window (size_t value_cnt, casenumber max_in_core_cases)
+ This is usually the right kind of casewriter to use. */
+struct casewriter *
+autopaging_writer_create (size_t value_cnt)
{
- struct casewindow *window = casewindow_create (value_cnt, max_in_core_cases);
- struct casewriter *writer = casewriter_create (&casewriter_window_class,
- window);
- taint_propagate (casewindow_get_taint (window),
- casewriter_get_taint (writer));
- return writer;
+ return create_casewriter_window (value_cnt, get_workspace_cases (value_cnt));
}
+/* Returns a casewriter for cases with VALUE_CNT struct values
+ per case. The cases written to the casewriter will be kept in
+ memory.
+
+ A casewriter created with this function may be passed to
+ casewriter_make_reader. */
struct casewriter *
mem_writer_create (size_t value_cnt)
{
return create_casewriter_window (value_cnt, CASENUMBER_MAX);
}
+/* Returns a casewriter for cases with VALUE_CNT struct values
+ per case. The cases written to the casewriter will be written
+ to disk.
+
+ A casewriter created with this function may be passed to
+ casewriter_make_reader. */
struct casewriter *
tmpfile_writer_create (size_t value_cnt)
{
return create_casewriter_window (value_cnt, 0);
}
-struct casewriter *
-autopaging_writer_create (size_t value_cnt)
+static const struct casewriter_class casewriter_window_class;
+static const struct buffered_reader_class casereader_window_class;
+
+/* Creates and returns a new casewriter based on a casewindow.
+ Each of the casewriter's cases are composed of VALUE_CNT
+ struct values. The casewriter's cases will be maintained in
+ memory until MAX_IN_CORE_CASES have been written, at which
+ point they will be written to disk. */
+static struct casewriter *
+create_casewriter_window (size_t value_cnt, casenumber max_in_core_cases)
{
- return create_casewriter_window (value_cnt, get_workspace_cases (value_cnt));
+ struct casewindow *window = casewindow_create (value_cnt, max_in_core_cases);
+ struct casewriter *writer = casewriter_create (&casewriter_window_class,
+ window);
+ taint_propagate (casewindow_get_taint (window),
+ casewriter_get_taint (writer));
+ return writer;
}
+/* Writes case C to casewindow writer WINDOW. */
static void
casewriter_window_write (struct casewriter *writer UNUSED, void *window_,
struct ccase *c)
@@ -149,6 +215,7 @@
casewindow_push_head (window, c);
}
+/* Destroys casewindow writer WINDOW. */
static void
casewriter_window_destroy (struct casewriter *writer UNUSED, void *window_)
{
@@ -156,6 +223,8 @@
casewindow_destroy (window);
}
+/* Converts casewindow writer WINDOW to a casereader and returns
+ the casereader. */
static struct casereader *
casewriter_window_convert_to_reader (struct casewriter *writer UNUSED,
void *window_)
@@ -167,16 +236,20 @@
&casereader_window_class, window);
}
+/* Reads the case at the given 0-based OFFSET from the front of
+ WINDOW into C. Returns true if successful, false if
+ OFFSET is beyond the end of file or upon I/O error. */
static bool
-casereader_window_read (void *window_, casenumber case_idx, struct ccase *c)
+casereader_window_read (void *window_, casenumber offset, struct ccase *c)
{
struct casewindow *window = window_;
- if (case_idx >= casewindow_get_case_cnt (window))
+ if (offset >= casewindow_get_case_cnt (window))
return false;
else
- return casewindow_get_case (window, case_idx, c);
+ return casewindow_get_case (window, offset, c);
}
+/* Destroys casewindow reader WINDOW. */
static void
casereader_window_destroy (void *window_)
{
@@ -184,6 +257,7 @@
casewindow_destroy (window);
}
+/* Discards CASE_CNT cases from the front of WINDOW. */
static void
casereader_window_advance (void *window_, casenumber case_cnt)
{
@@ -191,6 +265,7 @@
casewindow_pop_tail (window, case_cnt);
}
+/* Class for casewindow writer. */
static const struct casewriter_class casewriter_window_class =
{
casewriter_window_write,
@@ -198,6 +273,7 @@
casewriter_window_convert_to_reader,
};
+/* Class for casewindow reader. */
static const struct buffered_reader_class casereader_window_class =
{
casereader_window_read,
@@ -205,60 +281,3 @@
casereader_window_advance,
};
-struct casewriter_translator
- {
- struct casewriter *subwriter;
-
- void (*translate) (const struct ccase *input, struct ccase *output,
- void *aux);
- bool (*destroy) (void *aux);
- void *aux;
- };
-
-static struct casewriter_class casewriter_translator_class;
-
-struct casewriter *
-casewriter_create_translator (struct casewriter *subwriter,
- void (*translate) (const struct ccase *input,
- struct ccase *output,
- void *aux),
- bool (*destroy) (void *aux),
- void *aux)
-{
- struct casewriter_translator *ct = xmalloc (sizeof *ct);
- struct casewriter *writer;
- ct->subwriter = casewriter_rename (subwriter);
- ct->translate = translate;
- ct->destroy = destroy;
- ct->aux = aux;
- writer = casewriter_create (&casewriter_translator_class, ct);
- taint_propagate (casewriter_get_taint (ct->subwriter),
- casewriter_get_taint (writer));
- return writer;
-}
-
-static void
-casewriter_translator_write (struct casewriter *writer UNUSED,
- void *ct_, struct ccase *c)
-{
- struct casewriter_translator *ct = ct_;
- struct ccase tmp;
-
- ct->translate (c, &tmp, ct->aux);
- casewriter_write (ct->subwriter, &tmp);
-}
-
-static void
-casewriter_translator_destroy (struct casewriter *writer UNUSED, void *ct_)
-{
- struct casewriter_translator *ct = ct_;
- casewriter_destroy (ct->subwriter);
- ct->destroy (ct->aux);
- free (ct);
-}
-
-static struct casewriter_class casewriter_translator_class =
- {
- casewriter_translator_write,
- casewriter_translator_destroy,
- };
Index: data/casewriter-private.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casewriter-private.h,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -b -r1.1.2.2 -r1.1.2.3
--- data/casewriter-private.h 4 May 2007 03:48:47 -0000 1.1.2.2
+++ data/casewriter-private.h 7 May 2007 04:38:39 -0000 1.1.2.3
@@ -23,12 +23,38 @@
struct casewriter_class
{
- /* Mandatory. */
- /* Ownership of the case is transferred to the callee. */
- void (*write) (struct casewriter *, void *aux, struct ccase *);
- void (*destroy) (struct casewriter *, void *aux);
+ /* Mandatory.
- /* Optional. */
+ Writes case C to WRITER. Destroys C before returning.
+
+ If an I/O error occurs, this function should call
+ casewriter_force_error on WRITER. Some I/O error
+ detection may be deferred to the "destroy" member function
+ (e.g. writes to disk need not be flushed by "write") . */
+ void (*write) (struct casewriter *writer, void *aux, struct ccase *c);
+
+ /* Mandatory.
+
+ Finalizes output and destroys WRITER.
+
+ If an I/O error is detected while finalizing output
+ (e.g. while flushing output to disk), this function should
+ call casewriter_force_error on WRITER. */
+ void (*destroy) (struct casewriter *writer, void *aux);
+
+ /* Optional: supply if practical and desired by clients.
+
+ Finalizes output to WRITER, destroys WRITER, and in its
+ place returns a casereader that can be used to read back
+ the data written to WRITER. WRITER will not be used again
+ after calling this function, even as an argument to
+ casewriter_destroy.
+
+ If an I/O error is detected while finalizing output
+ (e.g. while flushing output to disk), this function should
+ call casewriter_force_error on WRITER. The caller will
+ ensure that the error is propagated to the returned
+ casereader. */
struct casereader *(*convert_to_reader) (struct casewriter *, void *aux);
};
Index: data/casereader.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casereader.c,v
retrieving revision 1.1.2.6
retrieving revision 1.1.2.7
diff -u -b -r1.1.2.6 -r1.1.2.7
--- data/casereader.c 6 May 2007 22:48:27 -0000 1.1.2.6
+++ data/casereader.c 7 May 2007 04:38:39 -0000 1.1.2.7
@@ -163,6 +163,8 @@
insert_casereader_buffer (reader);
if (reader->class->peek (reader, reader->aux, idx, c))
return true;
+ else if (casereader_error (reader))
+ reader->case_cnt = 0;
}
if (reader->case_cnt > idx)
reader->case_cnt = idx;
@@ -390,10 +392,10 @@
/* Discards CNT cases from the front of B's window. */
static void
-casereader_buffer_advance (void *b_, casenumber cnt)
+casereader_buffer_advance (void *b_, casenumber case_cnt)
{
struct casereader_buffer *b = b_;
- casewindow_pop_tail (b->window, cnt);
+ casewindow_pop_tail (b->window, case_cnt);
}
/* Class for the buffered reader. */
Index: data/casereader-private.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casereader-private.h,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -b -r1.1.2.2 -r1.1.2.3
--- data/casereader-private.h 4 May 2007 03:48:47 -0000 1.1.2.2
+++ data/casereader-private.h 7 May 2007 04:38:39 -0000 1.1.2.3
@@ -24,20 +24,69 @@
/* This header file should really be renamed: it's not really
private. */
+/* Casereader class. */
struct casereader_class
{
- /* Mandatory. */
- bool (*read) (struct casereader *, void *aux, struct ccase *);
- void (*destroy) (struct casereader *, void *aux);
-
- /* Optional. If convenient and efficiently implementable,
- supply as an optimization for use by casereader_clone. */
- struct casereader *(*clone) (struct casereader *, void *aux);
-
- /* Optional. If convenient and efficiently implementable,
- supply as an optimization for use by casereader_peek. */
- bool (*peek) (struct casereader *, void *aux, casenumber idx,
- struct ccase *);
+ /* Mandatory.
+
+ Reads the next case from READER into case C, which the
+ casereader must create and which the client is responsible
+ for destroying. If successful, returns true and advances
+ READER to the next case, so that the next call to this
+ function will read the next case. The case just read will
+ never be read again by a call to this function for READER.
+
+ At end of file or upon an I/O error, returns false. After
+ false is returned once, this function will not be called
+ again for the given READER.
+
+ If an I/O error occurs, this function should call
+ casereader_force_error on READER. */
+ bool (*read) (struct casereader *reader, void *aux, struct ccase *c);
+
+ /* Mandatory.
+
+ Destroys READER.
+
+ If an I/O error is detected during destruction, this
+ function should call casereader_force_error on READER. */
+ void (*destroy) (struct casereader *reader, void *aux);
+
+ /* Optional: if convenient and efficiently implementable,
+ supply this function as an optimization for use by
+ casereader_clone.
+
+ Creates and returns a clone of READER. The clone must
+ read the same case data in the same sequence as READER,
+ starting from the same position. The only allowable
+ exception to this rule is that I/O errors may force the
+ clone or the original casereader to stop reading after
+ differing numbers of cases.
+
+ The clone should have a clone of READER's taint object,
+ accomplished by passing casereader_get_taint (READER) to
+ casereader_create. */
+ struct casereader *(*clone) (struct casereader *reader, void *aux);
+
+ /* Optional: if convenient and efficiently implementable,
+ supply as an optimization for use by casereader_peek.
+
+ Reads the case at 0-based offset IDX from the beginning of
+ READER into case C, which the casereader must create and
+ which the client is responsible for destroying.
+
+ At end of file or upon an I/O error, returns false. If
+ this function returns false, then it will never be called
+ again for an equal or greater value of IDX, and the "read"
+ member function will never be called to advance as far as
+ IDX cases further into the casereader. That is, returning
+ false indicates that the casereader has fewer than IDX
+ cases left.
+
+ If an I/O error occurs, this function should call
+ casereader_force_error on READER. */
+ bool (*peek) (struct casereader *reader, void *aux, casenumber idx,
+ struct ccase *c);
};
struct casereader *casereader_create (const struct taint *,
Index: data/automake.mk
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/automake.mk,v
retrieving revision 1.15.2.3
retrieving revision 1.15.2.4
diff -u -b -r1.15.2.3 -r1.15.2.4
--- data/automake.mk 6 May 2007 22:48:27 -0000 1.15.2.3
+++ data/automake.mk 7 May 2007 04:38:39 -0000 1.15.2.4
@@ -27,6 +27,7 @@
src/data/casewindow.c \
src/data/casewindow.h \
src/data/casewriter.c \
+ src/data/casewriter-translator.c \
src/data/casewriter.h \
src/data/casewriter-private.h \
src/data/category.c \
Index: data/casewriter-translator.c
===================================================================
RCS file: data/casewriter-translator.c
diff -N data/casewriter-translator.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ data/casewriter-translator.c 7 May 2007 04:38:39 -0000 1.1.2.1
@@ -0,0 +1,86 @@
+/* PSPP - computes sample statistics.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <config.h>
+
+#include <data/casewriter.h>
+#include <data/casewriter-private.h>
+
+#include <stdlib.h>
+
+#include <libpspp/taint.h>
+
+#include "xalloc.h"
+
+struct casewriter_translator
+ {
+ struct casewriter *subwriter;
+
+ void (*translate) (const struct ccase *input, struct ccase *output,
+ void *aux);
+ bool (*destroy) (void *aux);
+ void *aux;
+ };
+
+static struct casewriter_class casewriter_translator_class;
+
+struct casewriter *
+casewriter_create_translator (struct casewriter *subwriter,
+ void (*translate) (const struct ccase *input,
+ struct ccase *output,
+ void *aux),
+ bool (*destroy) (void *aux),
+ void *aux)
+{
+ struct casewriter_translator *ct = xmalloc (sizeof *ct);
+ struct casewriter *writer;
+ ct->subwriter = casewriter_rename (subwriter);
+ ct->translate = translate;
+ ct->destroy = destroy;
+ ct->aux = aux;
+ writer = casewriter_create (&casewriter_translator_class, ct);
+ taint_propagate (casewriter_get_taint (ct->subwriter),
+ casewriter_get_taint (writer));
+ return writer;
+}
+
+static void
+casewriter_translator_write (struct casewriter *writer UNUSED,
+ void *ct_, struct ccase *c)
+{
+ struct casewriter_translator *ct = ct_;
+ struct ccase tmp;
+
+ ct->translate (c, &tmp, ct->aux);
+ casewriter_write (ct->subwriter, &tmp);
+}
+
+static void
+casewriter_translator_destroy (struct casewriter *writer UNUSED, void *ct_)
+{
+ struct casewriter_translator *ct = ct_;
+ casewriter_destroy (ct->subwriter);
+ ct->destroy (ct->aux);
+ free (ct);
+}
+
+static struct casewriter_class casewriter_translator_class =
+ {
+ casewriter_translator_write,
+ casewriter_translator_destroy,
+ };
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pspp-cvs] pspp/src libpspp/taint.h libpspp/taint.c data/s... [simpler-proc],
Ben Pfaff <=