From 0d7b430cd1cef60b963a54307622d6f4aa8efeb4 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 27 Apr 2006 02:42:01 +0000 Subject: [PATCH] Continue reforming procedure execution. In this phase, break procedure.c into multiple files. --- src/ChangeLog | 32 ++++ src/data/ChangeLog | 19 +++ src/data/automake.mk | 6 + src/data/case-sink.c | 66 ++++++++ src/data/case-sink.h | 65 ++++++++ src/data/case-source.c | 59 +++++++ src/data/case-source.h | 65 ++++++++ src/data/storage-stream.c | 172 +++++++++++++++++++++ src/data/storage-stream.h | 32 ++++ src/language/data-io/data-list.h | 1 + src/language/data-io/file-type.c | 1 + src/language/data-io/get.c | 25 +-- src/language/data-io/matrix-data.c | 19 ++- src/language/expressions/parse.c | 8 +- src/language/stats/aggregate.c | 22 +-- src/language/stats/flip.c | 28 ++-- src/math/sort.c | 22 +-- src/procedure.c | 240 ++--------------------------- src/procedure.h | 103 ++----------- 19 files changed, 618 insertions(+), 367 deletions(-) create mode 100644 src/data/case-sink.c create mode 100644 src/data/case-sink.h create mode 100644 src/data/case-source.c create mode 100644 src/data/case-source.h create mode 100644 src/data/storage-stream.c create mode 100644 src/data/storage-stream.h diff --git a/src/ChangeLog b/src/ChangeLog index a8123a4b..7d0e1b27 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,35 @@ +Wed Apr 26 19:33:52 2006 Ben Pfaff + + Continue reforming procedure execution. In this phase, break + procedure.c into multiple files. + + * procedure.c (vfm_last_invocation): Rename + time_of_last_procedure(). Update all references. + (struct storage_stream_info) Move to data/storage-stream.c. + (storage_sink_open) Ditto. + (destroy_storage_stream_info) Ditto. + (storage_sink_write) Ditto. + (storage_sink_destroy) Ditto. + (storage_sink_make_source) Ditto. + (var storage_sink_class) Ditto. + (storage_source_count) Ditto. + (storage_source_read) Ditto. + (storage_source_destroy) Ditto. + (storage_source_class) Ditto. + (storage_source_get_casefile) Ditto. + (storage_source_create) Ditto. + (null_sink_class) Move to data/case-sink.c. + (create_case_source) Move to data/case-source.c. + (free_case_source) Ditto. + (case_source_is_class) Ditto. + (create_case_sink) Move to data/case-sink.c. + (free_case_sink) Ditto. + + * procedure.h: (struct case_source) Move to data/case-source.h. + (struct case_source_class) Ditto. + (struct case_sink) Move to data/case-sink.h. + (struct case_sink_class) Ditto. + Thu Apr 27 09:28:25 WST 2006 John Darrington * automake.mk: Removed explicit dependencies for message.o, since diff --git a/src/data/ChangeLog b/src/data/ChangeLog index c7cd626e..07df9af0 100644 --- a/src/data/ChangeLog +++ b/src/data/ChangeLog @@ -1,3 +1,22 @@ +Wed Apr 26 19:39:28 2006 Ben Pfaff + + Continue reforming procedure execution. In this phase, break + procedure.c into multiple files. + + * automake.mk: (src_data_libdata_a_SOURCES) Add all the new files. + + * case-sink.c: New file. + + * case-sink.h: New file. + + * case-source.c: New file. + + * case-source.h: New file. + + * storage-stream.c: New file. + + * storage-stream.h: New file. + Wed Apr 26 14:55:19 2006 Ben Pfaff * variable.h: (struct variable) Remove `init' member and all diff --git a/src/data/automake.mk b/src/data/automake.mk index 86fcade1..459ea2fa 100644 --- a/src/data/automake.mk +++ b/src/data/automake.mk @@ -9,6 +9,10 @@ src_data_libdata_a_SOURCES = \ src/data/any-writer.h \ src/data/calendar.c \ src/data/calendar.h \ + src/data/case-sink.c \ + src/data/case-sink.h \ + src/data/case-source.c \ + src/data/case-source.h \ src/data/case.c \ src/data/casefile.c \ src/data/casefile.h \ @@ -47,6 +51,8 @@ src_data_libdata_a_SOURCES = \ src/data/settings.c \ src/data/settings.h \ src/data/sfm-private.h \ + src/data/storage-stream.c \ + src/data/storage-stream.h \ src/data/sys-file-reader.c \ src/data/sys-file-reader.h \ src/data/sys-file-writer.c \ diff --git a/src/data/case-sink.c b/src/data/case-sink.c new file mode 100644 index 00000000..ff4dfe32 --- /dev/null +++ b/src/data/case-sink.c @@ -0,0 +1,66 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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 + +#include + +#include + +#include + +#include "xalloc.h" + +/* Creates a case sink to accept cases from the given DICT with + class CLASS and auxiliary data AUX. */ +struct case_sink * +create_case_sink (const struct case_sink_class *class, + const struct dictionary *dict, + void *aux) +{ + struct case_sink *sink = xmalloc (sizeof *sink); + sink->class = class; + sink->value_cnt = dict_get_compacted_value_cnt (dict); + sink->aux = aux; + return sink; +} + +/* Destroys case sink SINK. */ +void +free_case_sink (struct case_sink *sink) +{ + if (sink != NULL) + { + if (sink->class->destroy != NULL) + sink->class->destroy (sink); + free (sink); + } +} +/* Null sink. Used by a few procedures that keep track of output + themselves and would throw away anything that the sink + contained anyway. */ + +const struct case_sink_class null_sink_class = + { + "null", + NULL, + NULL, + NULL, + NULL, + }; diff --git a/src/data/case-sink.h b/src/data/case-sink.h new file mode 100644 index 00000000..d1d6daeb --- /dev/null +++ b/src/data/case-sink.h @@ -0,0 +1,65 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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. */ + +#ifndef CASE_SINK_H +#define CASE_SINK_H 1 + +#include +#include + +struct ccase; +struct dictionary; + +/* A case sink. */ +struct case_sink + { + const struct case_sink_class *class; /* Class. */ + void *aux; /* Auxiliary data. */ + size_t value_cnt; /* Number of `union value's in case. */ + }; + +/* A case sink class. */ +struct case_sink_class + { + const char *name; /* Identifying name. */ + + /* Opens the sink for writing. */ + void (*open) (struct case_sink *); + + /* Writes a case to the sink. */ + bool (*write) (struct case_sink *, const struct ccase *); + + /* Closes and destroys the sink. */ + void (*destroy) (struct case_sink *); + + /* Closes the sink and returns a source that can read back + the cases that were written, perhaps transformed in some + way. The sink must still be separately destroyed by + calling destroy(). */ + struct case_source *(*make_source) (struct case_sink *); + }; + +extern const struct case_sink_class null_sink_class; + +struct case_sink *create_case_sink (const struct case_sink_class *, + const struct dictionary *, + void *); +void free_case_sink (struct case_sink *); + +#endif /* case-sink.h */ diff --git a/src/data/case-source.c b/src/data/case-source.c new file mode 100644 index 00000000..21413fe2 --- /dev/null +++ b/src/data/case-source.c @@ -0,0 +1,59 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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 + +#include + +#include + +#include "xalloc.h" + +/* Creates a case source with class CLASS and auxiliary data AUX + and based on dictionary DICT. */ +struct case_source * +create_case_source (const struct case_source_class *class, + void *aux) +{ + struct case_source *source = xmalloc (sizeof *source); + source->class = class; + source->aux = aux; + return source; +} + +/* Destroys case source SOURCE. It is the caller's responsible to + call the source's destroy function, if any. */ +void +free_case_source (struct case_source *source) +{ + if (source != NULL) + { + if (source->class->destroy != NULL) + source->class->destroy (source); + free (source); + } +} + +/* Returns nonzero if CLASS is the class of SOURCE. */ +int +case_source_is_class (const struct case_source *source, + const struct case_source_class *class) +{ + return source != NULL && source->class == class; +} diff --git a/src/data/case-source.h b/src/data/case-source.h new file mode 100644 index 00000000..4da72806 --- /dev/null +++ b/src/data/case-source.h @@ -0,0 +1,65 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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. */ + +#ifndef CASE_SOURCE_H +#define CASE_SOURCE_H 1 + +#include + +struct ccase; + +typedef struct write_case_data *write_case_data; +typedef bool write_case_func (write_case_data); + +/* A case source. */ +struct case_source + { + const struct case_source_class *class; /* Class. */ + void *aux; /* Auxiliary data. */ + }; + +/* A case source class. */ +struct case_source_class + { + const char *name; /* Identifying name. */ + + /* Returns the exact number of cases that READ will pass to + WRITE_CASE, if known, or -1 otherwise. */ + int (*count) (const struct case_source *); + + /* Reads the cases one by one into C and for each one calls + WRITE_CASE passing the given AUX data. + Returns true if successful, false if an I/O error occurred. */ + bool (*read) (struct case_source *, + struct ccase *c, + write_case_func *write_case, write_case_data aux); + + /* Destroys the source. */ + void (*destroy) (struct case_source *); + }; + + +struct case_source *create_case_source (const struct case_source_class *, + void *); +void free_case_source (struct case_source *); + +int case_source_is_class (const struct case_source *, + const struct case_source_class *); + +#endif /* case-source.h */ diff --git a/src/data/storage-stream.c b/src/data/storage-stream.c new file mode 100644 index 00000000..a758c5a1 --- /dev/null +++ b/src/data/storage-stream.c @@ -0,0 +1,172 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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 + +#include + +#include + +#include +#include +#include +#include + +#include "xalloc.h" + +/* Information about storage sink or source. */ +struct storage_stream_info + { + struct casefile *casefile; /* Storage. */ + }; + +/* Storage sink. */ + +/* Initializes a storage sink. */ +static void +storage_sink_open (struct case_sink *sink) +{ + struct storage_stream_info *info; + + sink->aux = info = xmalloc (sizeof *info); + info->casefile = casefile_create (sink->value_cnt); +} + +/* Destroys storage stream represented by INFO. */ +static void +destroy_storage_stream_info (struct storage_stream_info *info) +{ + if (info != NULL) + { + casefile_destroy (info->casefile); + free (info); + } +} + +/* Writes case C to the storage sink SINK. + Returns true if successful, false if an I/O error occurred. */ +static bool +storage_sink_write (struct case_sink *sink, const struct ccase *c) +{ + struct storage_stream_info *info = sink->aux; + + return casefile_append (info->casefile, c); +} + +/* Destroys internal data in SINK. */ +static void +storage_sink_destroy (struct case_sink *sink) +{ + destroy_storage_stream_info (sink->aux); +} + +/* Closes the sink and returns a storage source to read back the + written data. */ +static struct case_source * +storage_sink_make_source (struct case_sink *sink) +{ + struct case_source *source + = create_case_source (&storage_source_class, sink->aux); + sink->aux = NULL; + return source; +} + +/* Storage sink. */ +const struct case_sink_class storage_sink_class = + { + "storage", + storage_sink_open, + storage_sink_write, + storage_sink_destroy, + storage_sink_make_source, + }; + +/* Storage source. */ + +/* Returns the number of cases that will be read by + storage_source_read(). */ +static int +storage_source_count (const struct case_source *source) +{ + struct storage_stream_info *info = source->aux; + + return casefile_get_case_cnt (info->casefile); +} + +/* Reads all cases from the storage source and passes them one by one to + write_case(). */ +static bool +storage_source_read (struct case_source *source, + struct ccase *output_case, + write_case_func *write_case, write_case_data wc_data) +{ + struct storage_stream_info *info = source->aux; + struct ccase casefile_case; + struct casereader *reader; + bool ok = true; + + for (reader = casefile_get_reader (info->casefile); + ok && casereader_read (reader, &casefile_case); + case_destroy (&casefile_case)) + { + case_copy (output_case, 0, + &casefile_case, 0, + casefile_get_value_cnt (info->casefile)); + ok = write_case (wc_data); + } + casereader_destroy (reader); + + return ok; +} + +/* Destroys the source's internal data. */ +static void +storage_source_destroy (struct case_source *source) +{ + destroy_storage_stream_info (source->aux); +} + +/* Storage source. */ +const struct case_source_class storage_source_class = + { + "storage", + storage_source_count, + storage_source_read, + storage_source_destroy, + }; + +struct casefile * +storage_source_get_casefile (struct case_source *source) +{ + struct storage_stream_info *info = source->aux; + + assert (source->class == &storage_source_class); + return info->casefile; +} + +struct case_source * +storage_source_create (struct casefile *cf) +{ + struct storage_stream_info *info; + + info = xmalloc (sizeof *info); + info->casefile = cf; + + return create_case_source (&storage_source_class, info); +} diff --git a/src/data/storage-stream.h b/src/data/storage-stream.h new file mode 100644 index 00000000..0b23331a --- /dev/null +++ b/src/data/storage-stream.h @@ -0,0 +1,32 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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. */ + +#ifndef STORAGE_STREAM_H +#define STORAGE_STREAM_H 1 + +struct case_source; +struct casefile; + +extern const struct case_sink_class storage_sink_class; +extern const struct case_source_class storage_source_class; + +struct casefile *storage_source_get_casefile (struct case_source *); +struct case_source *storage_source_create (struct casefile *); + +#endif /* storage-stream.h */ diff --git a/src/language/data-io/data-list.h b/src/language/data-io/data-list.h index 10316621..fa5f907b 100644 --- a/src/language/data-io/data-list.h +++ b/src/language/data-io/data-list.h @@ -23,6 +23,7 @@ /* FIXME: This header is a kluge and should go away when we come up with a less-klugy solution. */ +#include #include #include diff --git a/src/language/data-io/file-type.c b/src/language/data-io/file-type.c index 4633c7c0..31df716b 100644 --- a/src/language/data-io/file-type.c +++ b/src/language/data-io/file-type.c @@ -23,6 +23,7 @@ #include +#include #include #include #include diff --git a/src/language/data-io/get.c b/src/language/data-io/get.c index 25387d8b..b73a2bda 100644 --- a/src/language/data-io/get.c +++ b/src/language/data-io/get.c @@ -18,26 +18,31 @@ 02110-1301, USA. */ #include -#include + #include -#include + #include #include +#include +#include #include -#include -#include #include -#include -#include -#include -#include -#include #include #include +#include #include -#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include "gettext.h" diff --git a/src/language/data-io/matrix-data.c b/src/language/data-io/matrix-data.c index 4db8f90a..eb2d226f 100644 --- a/src/language/data-io/matrix-data.c +++ b/src/language/data-io/matrix-data.c @@ -18,25 +18,28 @@ 02110-1301, USA. */ #include -#include + #include #include #include -#include -#include + +#include #include -#include -#include #include -#include #include -#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include #include #include #include -#include #include #include "gettext.h" diff --git a/src/language/expressions/parse.c b/src/language/expressions/parse.c index e063acb5..f2bc3254 100644 --- a/src/language/expressions/parse.c +++ b/src/language/expressions/parse.c @@ -731,11 +731,11 @@ parse_sysvar (struct expression *e) "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", }; - time_t last_vfm_invocation = vfm_last_invocation (); + time_t last_proc_time = time_of_last_procedure (); struct tm *time; char temp_buf[10]; - time = localtime (&last_vfm_invocation); + time = localtime (&last_proc_time); sprintf (temp_buf, "%02d %s %02d", abs (time->tm_mday) % 100, months[abs (time->tm_mon) % 12], abs (time->tm_year) % 100); @@ -749,7 +749,7 @@ parse_sysvar (struct expression *e) return expr_allocate_number (e, SYSMIS); else if (lex_match_id ("$JDATE")) { - time_t time = vfm_last_invocation (); + time_t time = time_of_last_procedure (); struct tm *tm = localtime (&time); return expr_allocate_number (e, expr_ymd_to_ofs (tm->tm_year + 1900, tm->tm_mon + 1, @@ -757,7 +757,7 @@ parse_sysvar (struct expression *e) } else if (lex_match_id ("$TIME")) { - time_t time = vfm_last_invocation (); + time_t time = time_of_last_procedure (); struct tm *tm = localtime (&time); return expr_allocate_number (e, expr_ymd_to_date (tm->tm_year + 1900, diff --git a/src/language/stats/aggregate.c b/src/language/stats/aggregate.c index f3929815..a0887e3b 100644 --- a/src/language/stats/aggregate.c +++ b/src/language/stats/aggregate.c @@ -18,27 +18,31 @@ 02110-1301, USA. */ #include -#include + #include -#include + #include +#include #include #include -#include #include -#include #include +#include +#include +#include +#include +#include #include #include #include +#include +#include +#include #include -#include #include -#include -#include -#include #include -#include +#include +#include #include #include "gettext.h" diff --git a/src/language/stats/flip.c b/src/language/stats/flip.c index 95a5f6d1..f3286107 100644 --- a/src/language/stats/flip.c +++ b/src/language/stats/flip.c @@ -18,31 +18,35 @@ 02110-1301, USA. */ #include "config.h" -#include + #include #include #include #include #include -#include -#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#include +#include #include -#include #include -#include -#include "intprops.h" +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include -#include #include -#include -#include #include -#ifdef HAVE_SYS_TYPES_H -#include -#endif +#include "intprops.h" #include "gettext.h" #define _(msgid) gettext (msgid) diff --git a/src/math/sort.c b/src/math/sort.c index c20b809a..8b06867f 100644 --- a/src/math/sort.c +++ b/src/math/sort.c @@ -18,24 +18,28 @@ 02110-1301, USA. */ #include + #include "sort.h" -#include -#include + +#include #include +#include #include #include -#include -#include -#include + +#include #include #include -#include +#include +#include +#include #include - +#include +#include +#include +#include #include -#include #include -#include #include #include "gettext.h" diff --git a/src/procedure.c b/src/procedure.c index 69665c8b..e0280028 100644 --- a/src/procedure.c +++ b/src/procedure.c @@ -18,28 +18,33 @@ 02110-1301, USA. */ #include + #include -#include +#include +#include +#include + #include #include #include #include -#include + +#include "expressions/public.h" #include #include -#include #include +#include +#include +#include +#include #include +#include +#include #include -#include "expressions/public.h" -#include #include -#include +#include #include #include -#include -#include -#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -109,7 +114,7 @@ static bool close_active_file (void); /* Returns the last time the data was read. */ time_t -vfm_last_invocation (void) +time_of_last_procedure (void) { if (last_vfm_invocation == 0) update_last_vfm_invocation (); @@ -376,7 +381,7 @@ execute_transformations (struct ccase *c, } /* Returns nonzero if case C with case number CASE_NUM should be - exclude as specified on FILTER or PROCESS IF, otherwise + excluded as specified on FILTER or PROCESS IF, otherwise zero. */ static int filter_case (const struct ccase *c, int case_idx) @@ -481,160 +486,6 @@ close_active_file (void) return cancel_transformations (); } -/* Storage case stream. */ - -/* Information about storage sink or source. */ -struct storage_stream_info - { - struct casefile *casefile; /* Storage. */ - }; - -/* Initializes a storage sink. */ -static void -storage_sink_open (struct case_sink *sink) -{ - struct storage_stream_info *info; - - sink->aux = info = xmalloc (sizeof *info); - info->casefile = casefile_create (sink->value_cnt); -} - -/* Destroys storage stream represented by INFO. */ -static void -destroy_storage_stream_info (struct storage_stream_info *info) -{ - if (info != NULL) - { - casefile_destroy (info->casefile); - free (info); - } -} - -/* Writes case C to the storage sink SINK. - Returns true if successful, false if an I/O error occurred. */ -static bool -storage_sink_write (struct case_sink *sink, const struct ccase *c) -{ - struct storage_stream_info *info = sink->aux; - - return casefile_append (info->casefile, c); -} - -/* Destroys internal data in SINK. */ -static void -storage_sink_destroy (struct case_sink *sink) -{ - destroy_storage_stream_info (sink->aux); -} - -/* Closes the sink and returns a storage source to read back the - written data. */ -static struct case_source * -storage_sink_make_source (struct case_sink *sink) -{ - struct case_source *source - = create_case_source (&storage_source_class, sink->aux); - sink->aux = NULL; - return source; -} - -/* Storage sink. */ -const struct case_sink_class storage_sink_class = - { - "storage", - storage_sink_open, - storage_sink_write, - storage_sink_destroy, - storage_sink_make_source, - }; - -/* Storage source. */ - -/* Returns the number of cases that will be read by - storage_source_read(). */ -static int -storage_source_count (const struct case_source *source) -{ - struct storage_stream_info *info = source->aux; - - return casefile_get_case_cnt (info->casefile); -} - -/* Reads all cases from the storage source and passes them one by one to - write_case(). */ -static bool -storage_source_read (struct case_source *source, - struct ccase *output_case, - write_case_func *write_case, write_case_data wc_data) -{ - struct storage_stream_info *info = source->aux; - struct ccase casefile_case; - struct casereader *reader; - bool ok = true; - - for (reader = casefile_get_reader (info->casefile); - ok && casereader_read (reader, &casefile_case); - case_destroy (&casefile_case)) - { - case_copy (output_case, 0, - &casefile_case, 0, - casefile_get_value_cnt (info->casefile)); - ok = write_case (wc_data); - } - casereader_destroy (reader); - - return ok; -} - -/* Destroys the source's internal data. */ -static void -storage_source_destroy (struct case_source *source) -{ - destroy_storage_stream_info (source->aux); -} - -/* Storage source. */ -const struct case_source_class storage_source_class = - { - "storage", - storage_source_count, - storage_source_read, - storage_source_destroy, - }; - -struct casefile * -storage_source_get_casefile (struct case_source *source) -{ - struct storage_stream_info *info = source->aux; - - assert (source->class == &storage_source_class); - return info->casefile; -} - -struct case_source * -storage_source_create (struct casefile *cf) -{ - struct storage_stream_info *info; - - info = xmalloc (sizeof *info); - info->casefile = cf; - - return create_case_source (&storage_source_class, info); -} - -/* Null sink. Used by a few procedures that keep track of output - themselves and would throw away anything that the sink - contained anyway. */ - -const struct case_sink_class null_sink_class = - { - "null", - NULL, - NULL, - NULL, - NULL, - }; - /* Returns a pointer to the lagged case from N_BEFORE cases before the current one, or NULL if there haven't been that many cases yet. */ struct ccase * @@ -701,65 +552,6 @@ cancel_transformations (void) return ok; } -/* Creates a case source with class CLASS and auxiliary data AUX - and based on dictionary DICT. */ -struct case_source * -create_case_source (const struct case_source_class *class, - void *aux) -{ - struct case_source *source = xmalloc (sizeof *source); - source->class = class; - source->aux = aux; - return source; -} - -/* Destroys case source SOURCE. It is the caller's responsible to - call the source's destroy function, if any. */ -void -free_case_source (struct case_source *source) -{ - if (source != NULL) - { - if (source->class->destroy != NULL) - source->class->destroy (source); - free (source); - } -} - -/* Returns nonzero if CLASS is the class of SOURCE. */ -int -case_source_is_class (const struct case_source *source, - const struct case_source_class *class) -{ - return source != NULL && source->class == class; -} - -/* Creates a case sink to accept cases from the given DICT with - class CLASS and auxiliary data AUX. */ -struct case_sink * -create_case_sink (const struct case_sink_class *class, - const struct dictionary *dict, - void *aux) -{ - struct case_sink *sink = xmalloc (sizeof *sink); - sink->class = class; - sink->value_cnt = dict_get_compacted_value_cnt (dict); - sink->aux = aux; - return sink; -} - -/* Destroys case sink SINK. */ -void -free_case_sink (struct case_sink *sink) -{ - if (sink != NULL) - { - if (sink->class->destroy != NULL) - sink->class->destroy (sink); - free (sink); - } -} - /* Represents auxiliary data for handling SPLIT FILE. */ struct split_aux_data { diff --git a/src/procedure.h b/src/procedure.h index dd305a29..f9f43f49 100644 --- a/src/procedure.h +++ b/src/procedure.h @@ -1,5 +1,5 @@ /* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. Written by Ben Pfaff . This program is free software; you can redistribute it and/or @@ -17,113 +17,34 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#if !vfm_h -#define vfm_h 1 +#ifndef PROCEDURE_H +#define PROCEDURE_H 1 #include #include struct ccase; -typedef struct write_case_data *write_case_data; -typedef bool write_case_func (write_case_data); - +struct casefile; + /* The current active file, from which cases are read. */ extern struct case_source *vfm_source; -/* A case source. */ -struct case_source - { - const struct case_source_class *class; /* Class. */ - void *aux; /* Auxiliary data. */ - }; - -/* A case source class. */ -struct case_source_class - { - const char *name; /* Identifying name. */ - - /* Returns the exact number of cases that READ will pass to - WRITE_CASE, if known, or -1 otherwise. */ - int (*count) (const struct case_source *); - - /* Reads the cases one by one into C and for each one calls - WRITE_CASE passing the given AUX data. - Returns true if successful, false if an I/O error occurred. */ - bool (*read) (struct case_source *, - struct ccase *c, - write_case_func *write_case, write_case_data aux); - - /* Destroys the source. */ - void (*destroy) (struct case_source *); - }; - -extern const struct case_source_class storage_source_class; - -struct dictionary; -struct case_source *create_case_source (const struct case_source_class *, - void *); -void free_case_source (struct case_source *); - -int case_source_is_class (const struct case_source *, - const struct case_source_class *); - -struct casefile *storage_source_get_casefile (struct case_source *); -struct case_source *storage_source_create (struct casefile *); - /* The replacement active file, to which cases are written. */ extern struct case_sink *vfm_sink; -/* A case sink. */ -struct case_sink - { - const struct case_sink_class *class; /* Class. */ - void *aux; /* Auxiliary data. */ - size_t value_cnt; /* Number of `union value's in case. */ - }; - -/* A case sink class. */ -struct case_sink_class - { - const char *name; /* Identifying name. */ - - /* Opens the sink for writing. */ - void (*open) (struct case_sink *); - - /* Writes a case to the sink. */ - bool (*write) (struct case_sink *, const struct ccase *); - - /* Closes and destroys the sink. */ - void (*destroy) (struct case_sink *); - - /* Closes the sink and returns a source that can read back - the cases that were written, perhaps transformed in some - way. The sink must still be separately destroyed by - calling destroy(). */ - struct case_source *(*make_source) (struct case_sink *); - }; - -extern const struct case_sink_class storage_sink_class; -extern const struct case_sink_class null_sink_class; - -struct case_sink *create_case_sink (const struct case_sink_class *, - const struct dictionary *, - void *); -void free_case_sink (struct case_sink *); - -/* Number of cases to lag. */ -extern int n_lag; - bool procedure (bool (*proc_func) (struct ccase *, void *aux), void *aux); bool procedure_with_splits (void (*begin_func) (void *aux), bool (*proc_func) (struct ccase *, void *aux), void (*end_func) (void *aux), void *aux); -struct ccase *lagged_case (int n_before); - bool multipass_procedure_with_splits (bool (*) (const struct casefile *, void *), void *aux); - -time_t vfm_last_invocation (void); +time_t time_of_last_procedure (void); + +/* Number of cases to lag. */ +extern int n_lag; + +struct ccase *lagged_case (int n_before); -#endif /* !vfm_h */ +#endif /* procedure.h */ -- 2.30.2