From: Ben Pfaff Date: Fri, 13 Feb 2004 08:01:45 +0000 (+0000) Subject: Add auxiliary argument to procedure() interface. Associated small X-Git-Tag: v0.4.0~363 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5906e30c29662d12594199e1652ba3a7e5670944;p=pspp-builds.git Add auxiliary argument to procedure() interface. Associated small clean-ups of vfm interface. --- diff --git a/src/ChangeLog b/src/ChangeLog index d463a513..0c7b9fb1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,58 @@ +Thu Feb 12 23:35:15 2004 Ben Pfaff + + Add auxiliary argument to procedure() interface. Associated small + clean-ups of vfm interface. + + * Updated every caller of procedure() and process_active_file() to + reflect modified interface. Simple, ordinary changes not listed + otherwise below. + + * Updated every function that implements struct case_stream's + `read' function to take a write_case_func and a write_case_data. + Also updated every caller of write_case() to instead call them + through these arguments. In some cases this meant that the extra + args had to be threaded through a couple of extra levels. This + wasn't difficult or interesting so the details won't be given. + + * data-list.c: (struct repeating_data_trns) Add members + `write_case', `wc_data' as kluge. + (read_one_set_of_repetitions) Rename repeating_data_trns_proc and + make non-static. + (repeating_data_set_write_case) New function. + + * data-list.h: New file to declare repeating_data_trns_proc() and + repeating_data_set_write_case(). + + * inpt-pgm.c: (input_program_source_read) Call + repeating_data_set_write_case() for all the REPEATING DATA + transformations, so that they know where to send their cases. + It's a big kluge. Also kluge in END CASE. + (end_case_trns_proc) Never called anymore, but we still need it, + so just assert(0). + + * sort.c: (read_sort_output) Update to match struct case_stream + `read' member. + + * vfm.c: (struct write_case_data) New structure. + (proc_func) Removed. + (virt_proc_func) Removed. + (begin_func) Removed. + (virt_begin_func) Removed. + (end_func) Removed. + (write_case) Removed. + (procedure) Added an auxiliary parameter to each function pointer + argument's prototype. Added an auxiliary data parameter. + Rewrote. + (process_active_file) Ditto. + (process_active_file_write_case) Pass aux data along. + (close_active_file) Ditto. + (procedure_write_case) Ditto. + (SPLIT_FILE_procfunc) Ditto. + + * vfm.h: (typedef write_case_data) New. + (typedef write_case_func) New. + (struct case_stream) Add parameters to `read' member prototype. + Thu Feb 12 19:24:53 WST 2004 John Darrington * t-test.q: Added calculations for independent samples. (But no Levene diff --git a/src/aggregate.c b/src/aggregate.c index 1c885b1b..2a564167 100644 --- a/src/aggregate.c +++ b/src/aggregate.c @@ -141,11 +141,11 @@ static int aggregate_single_case (struct ccase *input, struct ccase *output); static int create_sysfile (void); static int agr_00x_trns_proc (struct trns_header *, struct ccase *); -static void agr_00x_end_func (void); +static void agr_00x_end_func (void *); static int agr_10x_trns_proc (struct trns_header *, struct ccase *); static void agr_10x_trns_free (struct trns_header *); -static void agr_10x_end_func (void); -static int agr_11x_func (void); +static void agr_10x_end_func (void *); +static int agr_11x_func (write_case_data); #if DEBUGGING static void debug_print (int flags); @@ -343,7 +343,7 @@ cmd_aggregate (void) agr_dict = NULL; - procedure (NULL, NULL, agr_00x_end_func); + procedure (NULL, NULL, agr_00x_end_func, NULL); break; } @@ -359,7 +359,7 @@ cmd_aggregate (void) t->free = agr_10x_trns_free; add_transformation (t); - procedure (NULL, NULL, agr_10x_end_func); + procedure (NULL, NULL, agr_10x_end_func, NULL); } break; @@ -371,12 +371,12 @@ cmd_aggregate (void) if (!create_sysfile ()) goto lossage; - read_sort_output (agr_11x_func); + read_sort_output (agr_11x_func, NULL); { struct ccase *save_temp_case = temp_case; temp_case = NULL; - agr_11x_func (); + agr_11x_func (NULL); temp_case = save_temp_case; } @@ -1207,7 +1207,7 @@ agr_00x_trns_proc (struct trns_header *h UNUSED, struct ccase *c) the cases have been output; very little has been cleaned up at this point. */ static void -agr_00x_end_func (void) +agr_00x_end_func (void *aux UNUSED) { /* Ensure that info for the last break group gets written to the active file. */ @@ -1272,7 +1272,7 @@ agr_10x_trns_free (struct trns_header *h UNUSED) /* Ensure that info for the last break group gets written to the system file. */ static void -agr_10x_end_func (void) +agr_10x_end_func (void *aux UNUSED) { dump_aggregate_info (buf_1xx); write_case_to_sfm (); @@ -1283,7 +1283,7 @@ agr_10x_end_func (void) appropriate. If temp_case is NULL, finishes up writing the last case if necessary. */ static int -agr_11x_func (void) +agr_11x_func (write_case_data wc_data UNUSED) { if (temp_case != NULL) { diff --git a/src/autorecode.c b/src/autorecode.c index c487255f..edc07701 100644 --- a/src/autorecode.c +++ b/src/autorecode.c @@ -76,7 +76,7 @@ static int print; static int autorecode_trns_proc (struct trns_header *, struct ccase *); static void autorecode_trns_free (struct trns_header *); -static int autorecode_proc_func (struct ccase *); +static int autorecode_proc_func (struct ccase *, void *); static hsh_compare_func compare_alpha_value, compare_numeric_value; static hsh_hash_func hash_alpha_value, hash_numeric_value; static void recode (void); @@ -153,7 +153,7 @@ cmd_autorecode (void) h_trans[i] = hsh_create (10, compare_numeric_value, hash_numeric_value, NULL, NULL); - procedure (NULL, autorecode_proc_func, NULL); + procedure (NULL, autorecode_proc_func, NULL, NULL); for (i = 0; i < nv_dest; i++) { @@ -309,7 +309,7 @@ hash_numeric_value (const void *a_, void *foo UNUSED) } static int -autorecode_proc_func (struct ccase * c) +autorecode_proc_func (struct ccase *c, void *aux UNUSED) { int i; diff --git a/src/command.c b/src/command.c index f4c76c33..b386317a 100644 --- a/src/command.c +++ b/src/command.c @@ -561,7 +561,7 @@ int cmd_execute (void) { lex_match_id ("EXECUTE"); - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); return lex_end_of_command (); } diff --git a/src/crosstabs.q b/src/crosstabs.q index 7502259a..11f3832d 100644 --- a/src/crosstabs.q +++ b/src/crosstabs.q @@ -148,10 +148,10 @@ static struct pool *pl_tc; /* For table cells. */ static struct pool *pl_col; /* For column data. */ static int internal_cmd_crosstabs (void); -static void precalc (void); -static int calc_general (struct ccase *); -static int calc_integer (struct ccase *); -static void postcalc (void); +static void precalc (void *); +static int calc_general (struct ccase *, void *); +static int calc_integer (struct ccase *, void *); +static void postcalc (void *); static void submit (struct tab_table *); #if DEBUGGING @@ -277,7 +277,8 @@ internal_cmd_crosstabs (void) else write = CRS_WR_NONE; - procedure (precalc, mode == GENERAL ? calc_general : calc_integer, postcalc); + procedure (precalc, mode == GENERAL ? calc_general : calc_integer, postcalc, + NULL); return CMD_SUCCESS; } @@ -515,7 +516,7 @@ static unsigned hash_table_entry (const void *, void *); /* Set up the crosstabulation tables for processing. */ static void -precalc (void) +precalc (void *aux UNUSED) { if (mode == GENERAL) { @@ -584,7 +585,7 @@ precalc (void) /* Form crosstabulations for general mode. */ static int -calc_general (struct ccase *c) +calc_general (struct ccase *c, void *aux UNUSED) { /* Case weight. */ double weight = dict_get_case_weight (default_dict, c); @@ -654,7 +655,7 @@ calc_general (struct ccase *c) } static int -calc_integer (struct ccase *c) +calc_integer (struct ccase *c, void *aux UNUSED) { /* Case weight. */ double weight = dict_get_case_weight (default_dict, c); @@ -807,7 +808,7 @@ static void output_pivot_table (struct table_entry **, struct table_entry **, static void make_summary_table (void); static void -postcalc (void) +postcalc (void *aux UNUSED) { if (mode == GENERAL) { diff --git a/src/data-list.c b/src/data-list.c index 1a6b9af8..7512a8e1 100644 --- a/src/data-list.c +++ b/src/data-list.c @@ -18,6 +18,7 @@ 02111-1307, USA. */ #include +#include "data-list.h" #include #include #include @@ -967,14 +968,13 @@ cut_field (char **ret_cp, int *ret_len) static int read_from_data_list_fixed (void); static int read_from_data_list_free (void); static int read_from_data_list_list (void); -static int do_reading (int flag); /* FLAG==0: reads any number of cases into temp_case and calls write_case() for each one, returns garbage. FLAG!=0: reads one case into temp_case and returns -2 on eof, -1 otherwise. Uses dlsp as the relevant parsing description. */ static int -do_reading (int flag) +do_reading (int flag, write_case_func *write_case, write_case_data wc_data) { int (*func) (void); @@ -1030,7 +1030,7 @@ do_reading (int flag) else { while (func () != -2) - if (!write_case ()) + if (!write_case (wc_data)) { debug_printf ((_("abort in write_case()\n"))); break; @@ -1202,16 +1202,16 @@ static int read_one_case (struct trns_header *t, struct ccase *c UNUSED) { dlsp = (struct data_list_pgm *) t; - return do_reading (1); + return do_reading (1, NULL, NULL); } /* Reads all the records from the data file and passes them to write_case(). */ static void -data_list_source_read (void) +data_list_source_read (write_case_func *write_case, write_case_data wc_data) { dlsp = &dls; - do_reading (0); + do_reading (0, write_case, wc_data); } /* Destroys the source's internal data. */ @@ -1258,12 +1258,14 @@ struct repeating_data_trns int id_beg, id_end; /* ID subcommand, beginning & end columns. */ struct variable *id_var; /* ID subcommand, DATA LIST variable. */ struct fmt_spec id_spec; /* ID subcommand, input format spec. */ + write_case_func *write_case; + write_case_data wc_data; }; /* Information about the transformation being parsed. */ static struct repeating_data_trns rpd; -static int read_one_set_of_repetitions (struct trns_header *, struct ccase *); +int repeating_data_trns_proc (struct trns_header *, struct ccase *); static int parse_num_or_var (struct rpd_num_or_var *, const char *); static int parse_repeating_data (void); static void find_variable_input_spec (struct variable *v, @@ -1523,7 +1525,7 @@ cmd_repeating_data (void) { struct repeating_data_trns *new_trns; - rpd.h.proc = read_one_set_of_repetitions; + rpd.h.proc = repeating_data_trns_proc; rpd.h.free = destroy_dls; new_trns = xmalloc (sizeof *new_trns); @@ -1787,7 +1789,7 @@ rpd_parse_record (int beg, int end, int ofs, struct ccase *c, cur += ofs; - if (!write_case ()) + if (!t->write_case (t->wc_data)) return 0; } } @@ -1798,8 +1800,8 @@ rpd_parse_record (int beg, int end, int ofs, struct ccase *c, /* Analogous to read_one_case; reads one set of repetitions of the elements in the REPEATING DATA structure. Returns -1 on success, -2 on end of file or on failure. */ -static int -read_one_set_of_repetitions (struct trns_header *trns, struct ccase *c) +int +repeating_data_trns_proc (struct trns_header *trns, struct ccase *c) { dfm_push (dlsp->handle); @@ -1932,3 +1934,19 @@ read_one_set_of_repetitions (struct trns_header *trns, struct ccase *c) transformations. */ return -3; } + +/* This is a kluge. It is only here until I have more time + tocome up with something better. It lets + repeating_data_trns_proc() know how to write the cases that it + composes. */ +void +repeating_data_set_write_case (struct trns_header *trns, + write_case_func *write_case, + write_case_data wc_data) +{ + struct repeating_data_trns *t = (struct repeating_data_trns *) trns; + + assert (trns->proc == repeating_data_trns_proc); + t->write_case = write_case; + t->wc_data = wc_data; +} diff --git a/src/data-list.h b/src/data-list.h new file mode 100644 index 00000000..736d2a50 --- /dev/null +++ b/src/data-list.h @@ -0,0 +1,33 @@ +/* PSPP - computes sample statistics. + Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef INCLUDED_DATA_LIST_H +#define INCLUDED_DATA_LIST_H + +/* FIXME: This header is a kluge and should go away when we come + up with a less-klugy solution. */ + +#include "var.h" +#include "vfm.h" + +int repeating_data_trns_proc (struct trns_header *, struct ccase *); +void repeating_data_set_write_case (struct trns_header *, + write_case_func *, write_case_data); + +#endif /* data-list.h */ diff --git a/src/descript.q b/src/descript.q index 6ccec2a4..84bc16c5 100644 --- a/src/descript.q +++ b/src/descript.q @@ -178,9 +178,9 @@ static void dump_z_table (void); static void run_z_pass (void); /* Procedure execution functions. */ -static int calc (struct ccase *); -static void precalc (void); -static void postcalc (void); +static int calc (struct ccase *, void *); +static void precalc (void *); +static void postcalc (void *); static void display (void); /* Parser and outline. */ @@ -289,7 +289,7 @@ cmd_descriptives (void) /* Data pass! */ bad_weight = 0; - procedure (precalc, calc, postcalc); + procedure (precalc, calc, postcalc, NULL); if (bad_weight) msg (SW, _("At least one case in the data file had a weight value " @@ -569,7 +569,7 @@ run_z_pass (void) /* Statistical calculation. */ static void -precalc (void) +precalc (void *aux UNUSED) { int i; @@ -593,7 +593,7 @@ precalc (void) } static int -calc (struct ccase * c) +calc (struct ccase * c, void *aux UNUSED) { int i; @@ -685,7 +685,7 @@ iterate: } static void -postcalc (void) +postcalc (void *aux UNUSED) { int i; diff --git a/src/dfm.c b/src/dfm.c index b5023a82..9905b6b3 100644 --- a/src/dfm.c +++ b/src/dfm.c @@ -669,7 +669,7 @@ cmd_begin_data (void) /* We don't actually read from the inline file. The input procedure is what reads from it. */ getl_prompt = GETL_PRPT_DATA; - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); ext = inline_file->ext; diff --git a/src/file-type.c b/src/file-type.c index 4181538f..44aa9bd9 100644 --- a/src/file-type.c +++ b/src/file-type.c @@ -610,7 +610,8 @@ cmd_end_file_type (void) /* Reads any number of cases into temp_case and calls write_case() for each one. Compare data-list.c:read_from_data_list. */ static void -file_type_source_read (void) +file_type_source_read (write_case_func *write_case UNUSED, + write_case_data wc_data UNUSED) { char *line; int len; diff --git a/src/flip.c b/src/flip.c index de02119e..c4bb5fdc 100644 --- a/src/flip.c +++ b/src/flip.c @@ -100,7 +100,7 @@ cmd_flip (void) temp_trns = temporary = 0; vfm_sink = &flip_stream; new_names_tail = NULL; - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); dict_clear (default_dict); if (!build_dictionary ()) @@ -258,7 +258,7 @@ flip_stream_init (void) /* Reads the FLIP stream and passes it to write_case(). */ static void -flip_stream_read (void) +flip_stream_read (write_case_func *write_case, write_case_data wc_data) { if (src || (src == NULL && src_file == NULL)) { @@ -276,7 +276,7 @@ flip_stream_read (void) for (iter = src, j = 1; iter; iter = iter->next, j++) temp_case->data[j].f = iter->v[i]; - if (!write_case ()) + if (!write_case (wc_data)) return; } } @@ -295,7 +295,7 @@ flip_stream_read (void) msg (FE, _("Error reading FLIP source file: %s."), strerror (errno)); - if (!write_case ()) + if (!write_case (wc_data)) return; } } diff --git a/src/frequencies.q b/src/frequencies.q index d1a75f72..850beda2 100644 --- a/src/frequencies.q +++ b/src/frequencies.q @@ -160,9 +160,9 @@ static struct pool *gen_pool; /* General mode. */ static void determine_charts (void); -static void precalc (void); -static int calc (struct ccase *); -static void postcalc (void); +static void precalc (void *); +static int calc (struct ccase *, void *); +static void postcalc (void *); static void postprocess_freq_tab (struct variable *); static void dump_full (struct variable *); @@ -246,7 +246,7 @@ internal_cmd_frequencies (void) cmd.sort = FRQ_AVALUE; /* Do it! */ - procedure (precalc, calc, postcalc); + procedure (precalc, calc, postcalc, NULL); return CMD_SUCCESS; } @@ -355,7 +355,7 @@ determine_charts (void) /* Add data from case C to the frequency table. */ static int -calc (struct ccase *c) +calc (struct ccase *c, void *aux UNUSED) { double weight; int i; @@ -408,7 +408,7 @@ calc (struct ccase *c) /* Prepares each variable that is the target of FREQUENCIES by setting up its hash table. */ static void -precalc (void) +precalc (void *aux UNUSED) { int i; @@ -451,7 +451,7 @@ precalc (void) /* Finishes up with the variables after frequencies have been calculated. Displays statistics, percentiles, ... */ static void -postcalc (void) +postcalc (void *aux UNUSED) { int i; diff --git a/src/get.c b/src/get.c index 72c49833..182ef0e7 100644 --- a/src/get.c +++ b/src/get.c @@ -61,7 +61,7 @@ static struct file_handle *get_file; static struct save_trns *trns; static int trim_dictionary (struct dictionary * dict, int *options); -static int save_write_case_func (struct ccase *); +static int save_write_case_func (struct ccase *, void *); static int save_trns_proc (struct trns_header *, struct ccase *); static void save_trns_free (struct trns_header *); @@ -192,7 +192,7 @@ cmd_save_internal (int xsave) if (xsave == 0) /* SAVE. */ { - procedure (NULL, save_write_case_func, NULL); + procedure (NULL, save_write_case_func, NULL, NULL); save_trns_free (&t->h); } else @@ -217,7 +217,7 @@ cmd_xsave (void) } static int -save_write_case_func (struct ccase * c) +save_write_case_func (struct ccase * c, void *aux UNUSED) { save_trns_proc (&trns->h, c); return 1; @@ -477,10 +477,10 @@ get_source_destroy_source (void) /* Reads all the cases from the data file and passes them to write_case(). */ static void -get_source_read (void) +get_source_read (write_case_func *write_case, write_case_data wc_data) { while (sfm_read_case (get_file, temp_case->data, default_dict) - && write_case ()) + && write_case (wc_data)) ; get_source_destroy_source (); } @@ -546,9 +546,9 @@ static void mtf_free_file (struct mtf_file *file); static int mtf_merge_dictionary (struct mtf_file *f); static void mtf_delete_file_in_place (struct mtf_file **file); -static void mtf_read_nonactive_records (void); -static void mtf_processing_finish (void); -static int mtf_processing (struct ccase *); +static void mtf_read_nonactive_records (void *); +static void mtf_processing_finish (void *); +static int mtf_processing (struct ccase *, void *); static char *var_type_description (struct variable *); @@ -857,7 +857,7 @@ cmd_match_files (void) dict_get_var_cnt (mtf_master) * sizeof *mtf_seq_nums); process_active_file (mtf_read_nonactive_records, mtf_processing, - mtf_processing_finish); + mtf_processing_finish, NULL); mtf_master = NULL; mtf_free (); @@ -870,7 +870,7 @@ lossage: /* Repeats 2...8 an arbitrary number of times. */ static void -mtf_processing_finish (void) +mtf_processing_finish (void *aux UNUSED) { /* Find the active file and delete it. */ { @@ -885,7 +885,7 @@ mtf_processing_finish (void) } while (mtf_head && mtf_head->type == MTF_FILE) - if (!mtf_processing (temp_case)) + if (!mtf_processing (temp_case, NULL)) break; } @@ -980,7 +980,7 @@ mtf_delete_file_in_place (struct mtf_file **file) /* Read a record from every input file except the active file. */ static void -mtf_read_nonactive_records (void) +mtf_read_nonactive_records (void *aux UNUSED) { struct mtf_file *iter; @@ -1046,7 +1046,7 @@ mtf_compare_BY_values (struct mtf_file *a, struct mtf_file *b) /* Perform one iteration of steps 3...7 above. */ static int -mtf_processing (struct ccase *c UNUSED) +mtf_processing (struct ccase *c UNUSED, void *aux UNUSED) { /* List of files with minimum BY values. */ struct mtf_file *min_head, *min_tail; @@ -1412,10 +1412,10 @@ cmd_import (void) /* Reads all the cases from the data file and passes them to write_case(). */ static void -import_source_read (void) +import_source_read (write_case_func *write_case, write_case_data wc_data) { while (pfm_read_case (get_file, temp_case->data, default_dict) - && write_case ()) + && write_case (wc_data)) ; get_source_destroy_source (); } @@ -1431,7 +1431,7 @@ struct case_stream import_source = "IMPORT", }; -static int export_write_case_func (struct ccase *c); +static int export_write_case_func (struct ccase *c, void *); /* Parses the EXPORT command. */ /* FIXME: same as cmd_save_internal(). */ @@ -1492,14 +1492,14 @@ cmd_export (void) t->case_buf = xmalloc (sizeof *t->case_buf * t->nvar); dict_destroy (dict); - procedure (NULL, export_write_case_func, NULL); + procedure (NULL, export_write_case_func, NULL, NULL); save_trns_free (&t->h); return CMD_SUCCESS; } static int -export_write_case_func (struct ccase *c) +export_write_case_func (struct ccase *c, void *aux UNUSED) { union value *p = (union value *) trns->case_buf; int i; diff --git a/src/inpt-pgm.c b/src/inpt-pgm.c index 7ef6904b..144aceb5 100644 --- a/src/inpt-pgm.c +++ b/src/inpt-pgm.c @@ -23,6 +23,7 @@ #include #include "alloc.h" #include "command.h" +#include "data-list.h" #include "dfm.h" #include "error.h" #include "expr.h" @@ -168,7 +169,8 @@ clear_case (void) file. -1 means go on to the next transformation. Otherwise the return value is the index of the transformation to go to next. */ static void -input_program_source_read (void) +input_program_source_read (write_case_func *write_case, + write_case_data wc_data) { int i; @@ -182,6 +184,12 @@ input_program_source_read (void) if (t_trns[i]->proc == end_case_trns_proc) end_case = 1; + /* FIXME: This code should not be necessary. It is an ugly + kluge. */ + for (i = 0; i < f_trns; i++) + if (t_trns[i]->proc == repeating_data_trns_proc) + repeating_data_set_write_case (t_trns[i], write_case, wc_data); + init_case (); for (;;) { @@ -201,6 +209,16 @@ input_program_source_read (void) if (t_trns[i]->proc == end_case_trns_proc) printf ("\n"); #endif + + if (t_trns[i]->proc == end_case_trns_proc) + { + if (!write_case (wc_data)) + return; + clear_case (); + i++; + continue; + } + code = t_trns[i]->proc (t_trns[i], temp_case); switch (code) { @@ -224,7 +242,7 @@ input_program_source_read (void) /* Write the case if appropriate. */ if (!end_case) - if (!write_case ()) + if (!write_case (wc_data)) return; /* Blank out the case for the next iteration. */ @@ -278,13 +296,7 @@ cmd_end_case (void) int end_case_trns_proc (struct trns_header *t UNUSED, struct ccase * c UNUSED) { -#if DEBUGGING - printf ("END CASE\n"); -#endif - if (!write_case ()) - return -2; - clear_case (); - return -1; + assert (0); } /* REREAD transformation. */ diff --git a/src/list.q b/src/list.q index 952283bc..5e312f81 100644 --- a/src/list.q +++ b/src/list.q @@ -77,11 +77,11 @@ static int n_chars_width (struct outp_driver *d); static void write_line (struct outp_driver *d, char *s); /* Other functions. */ -static int list_cases (struct ccase *); +static int list_cases (struct ccase *, void *); static void determine_layout (void); static void clean_up (void); static void write_header (struct outp_driver *); -static void write_all_headers (void); +static void write_all_headers (void *); /* Returns the number of text lines that can fit on the remainder of the page. */ @@ -227,7 +227,7 @@ cmd_list (void) determine_layout (); case_num = 0; - procedure (write_all_headers, list_cases, NULL); + procedure (write_all_headers, list_cases, NULL, NULL); free (line_buf); clean_up (); @@ -238,7 +238,7 @@ cmd_list (void) /* Writes headers to all devices. This is done at the beginning of each SPLIT FILE group. */ static void -write_all_headers (void) +write_all_headers (void *aux UNUSED) { struct outp_driver *d; @@ -618,7 +618,7 @@ determine_layout (void) } static int -list_cases (struct ccase *c) +list_cases (struct ccase *c, void *aux UNUSED) { struct outp_driver *d; diff --git a/src/matrix-data.c b/src/matrix-data.c index 4af89083..fd3d3807 100644 --- a/src/matrix-data.c +++ b/src/matrix-data.c @@ -1029,8 +1029,9 @@ static double *split_values; static int nr_read_splits (int compare); static int nr_read_factors (int cell); -static void nr_output_data (void); -static int matrix_data_read_without_rowtype (void); +static void nr_output_data (write_case_func *, write_case_data); +static void matrix_data_read_without_rowtype (write_case_func *, + write_case_data); /* Read from the data file and write it to the active file. */ static void @@ -1045,10 +1046,10 @@ read_matrices_without_rowtype (void) nr_factor_values = xmalloc (sizeof *nr_factor_values * n_factors * cells); max_cell_index = 0; - matrix_data_source.read = (void (*)(void)) matrix_data_read_without_rowtype; + matrix_data_source.read = matrix_data_read_without_rowtype; vfm_source = &matrix_data_source; - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); free (split_values); free (nr_factor_values); @@ -1213,8 +1214,9 @@ nr_read_data_lines (int per_factor, int cell, int content, int compare) /* When ROWTYPE_ does not appear in the data, reads the matrices and writes them to the output file. Returns success. */ -static int -matrix_data_read_without_rowtype (void) +static void +matrix_data_read_without_rowtype (write_case_func *write_case, + write_case_data wc_data) { { int *cp; @@ -1257,7 +1259,7 @@ matrix_data_read_without_rowtype (void) int *bp, *ep, *np; if (!nr_read_splits (0)) - return 0; + return; for (bp = contents; *bp != EOC; bp = np) { @@ -1292,15 +1294,15 @@ matrix_data_read_without_rowtype (void) for (cp = bp; cp < ep; cp++) if (!nr_read_data_lines (per_factor, i, *cp, cp != bp)) - return 0; + return; } } } - nr_output_data (); + nr_output_data (write_case, wc_data); if (dict_get_split_cnt (default_dict) == 0 || !another_token ()) - return 1; + return; } } @@ -1411,7 +1413,8 @@ nr_read_factors (int cell) /* Write the contents of a cell having content type CONTENT and data CP to the active file. */ static void -dump_cell_content (int content, double *cp) +dump_cell_content (int content, double *cp, + write_case_func *write_case, write_case_data wc_data) { int type = content_type[content]; @@ -1442,14 +1445,14 @@ dump_cell_content (int content, double *cp) dict_get_var (default_dict, first_continuous + i)->name, 8); - write_case (); + write_case (wc_data); } } } /* Finally dump out everything from nr_data[] to the output file. */ static void -nr_output_data (void) +nr_output_data (write_case_func *write_case, write_case_data wc_data) { { struct variable *const *split; @@ -1487,7 +1490,8 @@ nr_output_data (void) assert (nr_data[content] != NULL && nr_data[content][cell] != NULL); - dump_cell_content (content, nr_data[content][cell]); + dump_cell_content (content, nr_data[content][cell], + write_case, wc_data); } } } @@ -1505,7 +1509,8 @@ nr_output_data (void) for (content = 0; content <= PROX; content++) if (!is_per_factor[content] && nr_data[content] != NULL) - dump_cell_content (content, nr_data[content][0]); + dump_cell_content (content, nr_data[content][0], + write_case, wc_data); } } @@ -1529,12 +1534,13 @@ struct factor_data *wr_data; /* Current factor. */ struct factor_data *wr_current; -static int wr_read_splits (void); -static int wr_output_data (void); +static int wr_read_splits (write_case_func *, write_case_data); +static int wr_output_data (write_case_func *, write_case_data); static int wr_read_rowtype (void); static int wr_read_factors (void); static int wr_read_indeps (void); -static int matrix_data_read_with_rowtype (void); +static void matrix_data_read_with_rowtype (write_case_func *, + write_case_data); /* When ROWTYPE_ appears in the data, reads the matrices and writes them to the output file. */ @@ -1546,40 +1552,40 @@ read_matrices_with_rowtype (void) split_values = NULL; cells = 0; - matrix_data_source.read = (void (*)(void)) matrix_data_read_with_rowtype; + matrix_data_source.read = matrix_data_read_with_rowtype; vfm_source = &matrix_data_source; - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); free (split_values); fh_close_handle (data_file); } /* Read from the data file and write it to the active file. */ -static int -matrix_data_read_with_rowtype (void) +static void +matrix_data_read_with_rowtype (write_case_func *write_case, + write_case_data wc_data) { do { - if (!wr_read_splits ()) - return 0; + if (!wr_read_splits (write_case, wc_data)) + return; if (!wr_read_factors ()) - return 0; + return; if (!wr_read_indeps ()) - return 0; + return; } while (another_token ()); - wr_output_data (); - return 1; + wr_output_data (write_case, wc_data); } /* Read the split file variables. If they differ from the previous set of split variables then output the data. Returns success. */ static int -wr_read_splits (void) +wr_read_splits (write_case_func *write_case, write_case_data wc_data) { int compare; size_t split_cnt; @@ -1614,7 +1620,7 @@ wr_read_splits (void) if (compare && split_values[i] != mtokval && !different) { - if (!wr_output_data ()) + if (!wr_output_data (write_case, wc_data)) return 0; different = 1; cells = 0; @@ -1664,7 +1670,7 @@ compare_factors (const void *a_, const void *b_) /* Write out the data for the current split file to the active file. */ static int -wr_output_data (void) +wr_output_data (write_case_func *write_case, write_case_data wc_data) { { struct variable *const *split; @@ -1742,7 +1748,8 @@ wr_output_data (void) fill_matrix (content, iter->data[content]); - dump_cell_content (content, iter->data[content]); + dump_cell_content (content, iter->data[content], + write_case, wc_data); } } } diff --git a/src/modify-vars.c b/src/modify-vars.c index bce6ea1b..c68941a3 100644 --- a/src/modify-vars.c +++ b/src/modify-vars.c @@ -309,7 +309,7 @@ cmd_modify_vars (void) if (already_encountered & (1 | 4)) { /* Read the data. */ - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); } if (!rearrange_dict (default_dict, &vm)) diff --git a/src/sort.c b/src/sort.c index de3ff977..d17075ad 100644 --- a/src/sort.c +++ b/src/sort.c @@ -62,7 +62,7 @@ static int compare_case_lists (const void *, const void *); static int do_internal_sort (int separate); static int do_external_sort (int separate); int parse_sort_variables (void); -void read_sort_output (int (*write_case) (void)); +void read_sort_output (write_case_func *write_case, write_case_data wc_data); /* Performs the SORT CASES procedures. */ int @@ -154,7 +154,7 @@ sort_cases (int separate) /* Not sure this is necessary but it's good to be safe. */ if (separate && vfm_source == &sort_stream) - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); /* SORT CASES cancels PROCESS IF. */ expr_free (process_if_expr); @@ -175,7 +175,7 @@ do_internal_sort (int separate) if (vfm_source != &vfm_disk_stream) { if (vfm_source != &vfm_memory_stream) - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); if (vfm_source == &vfm_memory_stream) { struct case_list **case_tab = malloc (sizeof *case_tab @@ -745,7 +745,7 @@ write_initial_runs (int separate) vfm_sink->destroy_sink (); vfm_sink = &sort_stream; } - procedure (NULL, NULL, NULL); + procedure (NULL, NULL, NULL, NULL); /* Final iterations of steps R4, R5, R6, R7, R2, R3, ... */ for (;;) @@ -1221,16 +1221,16 @@ lossage: /* Reads all the records from the source stream and passes them to write_case(). */ static void -sort_stream_read (void) +sort_stream_read (write_case_func *write_case, write_case_data wc_data) { - read_sort_output (write_case); + read_sort_output (write_case, wc_data); } /* Reads all the records from the output stream and passes them to the function provided, which must have an interface identical to write_case(). */ void -read_sort_output (int (*write_case) (void)) +read_sort_output (write_case_func *write_case, write_case_data wc_data) { int i; FILE *f; @@ -1243,7 +1243,7 @@ read_sort_output (int (*write_case) (void)) for (p = separate_case_tab; *p; p++) { temp_case = &(*p)->c; - write_case (); + write_case (wc_data); } free (separate_case_tab); @@ -1275,7 +1275,7 @@ read_sort_output (int (*write_case) (void)) break; } - if (!write_case ()) + if (!write_case (wc_data)) break; } diff --git a/src/sort.h b/src/sort.h index e6c9fed9..15a5b2db 100644 --- a/src/sort.h +++ b/src/sort.h @@ -20,9 +20,11 @@ #if !sort_h #define sort_h 1 +#include "vfm.h" + /* SORT CASES programmatic interface. */ int sort_cases (int separate); -void read_sort_output (int (*write_case)(void)); +void read_sort_output (write_case_func *, write_case_data); /* Variables to sort. */ extern struct variable **v_sort; diff --git a/src/t-test.q b/src/t-test.q index e673395b..69d658ae 100644 --- a/src/t-test.q +++ b/src/t-test.q @@ -164,21 +164,21 @@ enum { }; -static int common_calc (struct ccase *); -static void common_precalc (void); -static void common_postcalc (void); +static int common_calc (struct ccase *, void *); +static void common_precalc (void *); +static void common_postcalc (void *); -static int one_sample_calc (struct ccase *); -static void one_sample_precalc (void); -static void one_sample_postcalc (void); +static int one_sample_calc (struct ccase *, void *); +static void one_sample_precalc (void *); +static void one_sample_postcalc (void *); -static int paired_calc (struct ccase *); -static void paired_precalc (void); -static void paired_postcalc (void); +static int paired_calc (struct ccase *, void *); +static void paired_precalc (void *); +static void paired_postcalc (void *); -static void group_precalc (void); -static int group_calc (struct ccase *); -static void group_postcalc (void); +static void group_precalc (void *); +static int group_calc (struct ccase *, void *); +static void group_postcalc (void *); static int compare_var_name (const void *a_, const void *b_, void *v_ UNUSED); @@ -269,18 +269,18 @@ cmd_t_test(void) } - procedure(common_precalc,common_calc,common_postcalc); + procedure(common_precalc,common_calc,common_postcalc, NULL); switch(mode) { case T_1_SAMPLE: - procedure(one_sample_precalc,one_sample_calc,one_sample_postcalc); + procedure(one_sample_precalc,one_sample_calc,one_sample_postcalc, NULL); break; case T_PAIRED: - procedure(paired_precalc,paired_calc,paired_postcalc); + procedure(paired_precalc,paired_calc,paired_postcalc, NULL); break; case T_IND_SAMPLES: - procedure(group_precalc,group_calc,group_postcalc); + procedure(group_precalc,group_calc,group_postcalc, NULL); break; } @@ -1347,7 +1347,7 @@ pscbox(void) /* Per case calculations common to all variants of the T test */ static int -common_calc (struct ccase *c) +common_calc (struct ccase *c, void *aux UNUSED) { int i; @@ -1373,7 +1373,7 @@ common_calc (struct ccase *c) /* Pre calculations common to all variants of the T test */ static void -common_precalc (void) +common_precalc (void *aux UNUSED) { int i=0; @@ -1391,7 +1391,7 @@ common_precalc (void) /* Post calculations common to all variants of the T test */ void -common_postcalc (void) +common_postcalc (void *aux UNUSED) { int i=0; @@ -1417,7 +1417,7 @@ common_postcalc (void) /* Per case calculations for one sample t test */ static int -one_sample_calc (struct ccase *c) +one_sample_calc (struct ccase *c, void *aux UNUSED) { int i; @@ -1440,7 +1440,7 @@ one_sample_calc (struct ccase *c) /* Pre calculations for one sample t test */ static void -one_sample_precalc (void) +one_sample_precalc (void *aux UNUSED) { int i=0; @@ -1455,7 +1455,7 @@ one_sample_precalc (void) /* Post calculations for one sample t test */ static void -one_sample_postcalc (void) +one_sample_postcalc (void *aux UNUSED) { int i=0; @@ -1490,7 +1490,7 @@ hash_var_name (const void *a_, void *v_ UNUSED) static void -paired_precalc (void) +paired_precalc (void *aux UNUSED) { int i; @@ -1504,7 +1504,7 @@ paired_precalc (void) } static int -paired_calc (struct ccase *c) +paired_calc (struct ccase *c, void *aux UNUSED) { int i; @@ -1530,7 +1530,7 @@ paired_calc (struct ccase *c) } static void -paired_postcalc (void) +paired_postcalc (void *aux UNUSED) { int i; @@ -1582,7 +1582,7 @@ get_group(const union value *val, struct variable *var) static void -group_precalc (void) +group_precalc (void *aux UNUSED) { int i; int j; @@ -1602,7 +1602,7 @@ group_precalc (void) } static int -group_calc (struct ccase *c) +group_calc (struct ccase *c, void *aux UNUSED) { int i; union value *gv = &c->data[groups->fv]; @@ -1626,7 +1626,7 @@ group_calc (struct ccase *c) } static void -group_postcalc (void) +group_postcalc (void *aux UNUSED) { int i; int j; diff --git a/src/vfm.c b/src/vfm.c index 84efc3e0..173bbb0f 100644 --- a/src/vfm.c +++ b/src/vfm.c @@ -50,6 +50,15 @@ #include "debug-print.h" +/* Procedure execution data. */ +struct write_case_data + { + void (*beginfunc) (void *); + int (*procfunc) (struct ccase *, void *); + void (*endfunc) (void *); + void *aux; + }; + /* This is used to read from the active file. */ struct case_stream *vfm_source; @@ -98,14 +107,6 @@ static int paging = 0; /* Time at which vfm was last invoked. */ time_t last_vfm_invocation; -/* Functions called during procedure processing. */ -static int (*proc_func) (struct ccase *); /* Called for each case. */ -static int (*virt_proc_func) (struct ccase *); /* From SPLIT_FILE_procfunc. */ -static void (*begin_func) (void); /* Called at beginning of a series. */ -static void (*virt_begin_func) (void); /* Called by SPLIT_FILE_procfunc. */ -static void (*end_func) (void); /* Called after end of a series. */ -int (*write_case) (void); - /* Number of cases passed to proc_func(). */ static int case_count; @@ -116,53 +117,66 @@ static int lag_head; /* Index where next case will be added. */ static struct ccase **lag_queue; /* Array of n_lag ccase * elements. */ static void open_active_file (void); -static void close_active_file (void); -static int SPLIT_FILE_procfunc (struct ccase *); +static void close_active_file (struct write_case_data *); +static int SPLIT_FILE_procfunc (struct ccase *, void *); static void finish_compaction (void); static void lag_case (void); -static int procedure_write_case (void); +static int procedure_write_case (struct write_case_data *); /* Public functions. */ -/* Reads all the cases from the active file, transforms them by the - active set of transformations, calls PROCFUNC with CURCASE set to - the case and CASENUM set to the case number, and writes them to a - new active file. +/* Reads all the cases from the active file, transforms them by + the active set of transformations, calls PROCFUNC with CURCASE + set to the case , and writes them to a new active file. Divides the active file into zero or more series of one or more cases each. BEGINFUNC is called before each series. ENDFUNC is - called after each series. */ + called after each series. + + Arbitrary user-specified data AUX is passed to BEGINFUNC, + PROCFUNC, and ENDFUNC as auxiliary data. */ void -procedure (void (*beginfunc) (void), - int (*procfunc) (struct ccase *curcase), - void (*endfunc) (void)) +procedure (void (*beginfunc) (void *), + int (*procfunc) (struct ccase *curcase, void *), + void (*endfunc) (void *), + void *aux) { - end_func = endfunc; - write_case = procedure_write_case; + struct write_case_data procedure_write_data; + struct write_case_data split_file_data; - if (dict_get_split_cnt (default_dict) != 0 && procfunc != NULL) + if (dict_get_split_cnt (default_dict) == 0) { - virt_proc_func = procfunc; - proc_func = SPLIT_FILE_procfunc; - - virt_begin_func = beginfunc; - begin_func = NULL; - } else { - begin_func = beginfunc; - proc_func = procfunc; + /* Normally we just use the data passed by the user. */ + procedure_write_data.beginfunc = beginfunc; + procedure_write_data.procfunc = procfunc; + procedure_write_data.endfunc = endfunc; + procedure_write_data.aux = aux; + } + else + { + /* Under SPLIT FILE, we add a layer of indirection. */ + procedure_write_data.beginfunc = NULL; + procedure_write_data.procfunc = SPLIT_FILE_procfunc; + procedure_write_data.endfunc = endfunc; + procedure_write_data.aux = &split_file_data; + + split_file_data.beginfunc = beginfunc; + split_file_data.procfunc = procfunc; + split_file_data.endfunc = endfunc; + split_file_data.aux = aux; } last_vfm_invocation = time (NULL); open_active_file (); - vfm_source->read (); - close_active_file (); + vfm_source->read (procedure_write_case, &procedure_write_data); + close_active_file (&procedure_write_data); } /* Active file processing support. Subtly different semantics from procedure(). */ -static int process_active_file_write_case (void); +static int process_active_file_write_case (struct write_case_data *data); /* The casefunc might want us to stop calling it. */ static int not_canceled; @@ -175,28 +189,35 @@ static int not_canceled; process_active_file() ignores TEMPORARY, SPLIT FILE, and N. */ void -process_active_file (void (*beginfunc) (void), - int (*casefunc) (struct ccase *curcase), - void (*endfunc) (void)) +process_active_file (void (*beginfunc) (void *), + int (*casefunc) (struct ccase *curcase, void *), + void (*endfunc) (void *), + void *aux) { - proc_func = casefunc; - write_case = process_active_file_write_case; + struct write_case_data process_active_write_data; + + process_active_write_data.beginfunc = beginfunc; + process_active_write_data.procfunc = casefunc; + process_active_write_data.endfunc = endfunc; + process_active_write_data.aux = aux; + not_canceled = 1; open_active_file (); - beginfunc (); + beginfunc (aux); /* There doesn't necessarily need to be an active file. */ if (vfm_source) - vfm_source->read (); + vfm_source->read (process_active_file_write_case, + &process_active_write_data); - endfunc (); - close_active_file (); + endfunc (aux); + close_active_file (&process_active_write_data); } /* Pass the current case to casefunc. */ static int -process_active_file_write_case (void) +process_active_file_write_case (struct write_case_data *data) { /* Index of current transformation. */ int cur_trns; @@ -230,7 +251,7 @@ process_active_file_write_case (void) && !FILTERED && (process_if_expr == NULL || expr_evaluate (process_if_expr, temp_case, NULL) == 1.0)) - not_canceled = proc_func (temp_case); + not_canceled = data->procfunc (temp_case, data->aux); case_count++; @@ -515,11 +536,11 @@ open_active_file (void) /* Closes the active file. */ static void -close_active_file (void) +close_active_file (struct write_case_data *data) { /* Close the current case group. */ - if (case_count && end_func != NULL) - end_func (); + if (case_count && data->endfunc != NULL) + data->endfunc (data->aux); /* Stop lagging (catch up?). */ if (n_lag) @@ -619,7 +640,7 @@ disk_stream_init (void) /* Reads all cases from the disk source and passes them one by one to write_case(). */ static void -disk_stream_read (void) +disk_stream_read (write_case_func *write_case, write_case_data wc_data) { int i; @@ -634,7 +655,7 @@ disk_stream_read (void) return; } - if (!write_case ()) + if (!write_case (wc_data)) return; } } @@ -738,7 +759,7 @@ memory_stream_init (void) /* Reads the case stream from memory and passes it to write_case(). */ static void -memory_stream_read (void) +memory_stream_read (write_case_func *write_case, write_case_data wc_data) { while (memory_source_cases != NULL) { @@ -750,7 +771,7 @@ memory_stream_read (void) free (current); } - if (!write_case ()) + if (!write_case (wc_data)) return; } } @@ -954,7 +975,7 @@ lagged_case (int n_before) otherwise. Do not call this function again after it has returned zero once. */ int -procedure_write_case (void) +procedure_write_case (write_case_data wc_data) { /* Index of current transformation. */ int cur_trns; @@ -1012,16 +1033,16 @@ procedure_write_case (void) } /* Call the beginning of group function. */ - if (!case_count && begin_func != NULL) - begin_func (); + if (!case_count && wc_data->beginfunc != NULL) + wc_data->beginfunc (wc_data->aux); /* Call the procedure if there is one and FILTER and PROCESS IF don't prohibit it. */ - if (proc_func != NULL + if (wc_data->procfunc != NULL && !FILTERED && (process_if_expr == NULL || expr_evaluate (process_if_expr, temp_case, NULL) == 1.0)) - proc_func (temp_case); + wc_data->procfunc (temp_case, wc_data->aux); case_count++; @@ -1125,8 +1146,9 @@ dump_splits (struct ccase *c) SPLIT FILE is active. This function forms a wrapper around that procfunc by dividing the input into series. */ static int -SPLIT_FILE_procfunc (struct ccase *c) +SPLIT_FILE_procfunc (struct ccase *c, void *data_) { + struct write_case_data *data = data_; static struct ccase *prev_case; struct variable *const *split; size_t split_cnt; @@ -1142,10 +1164,10 @@ SPLIT_FILE_procfunc (struct ccase *c) memcpy (prev_case, c, vfm_sink_info.case_size); dump_splits (c); - if (virt_begin_func != NULL) - virt_begin_func (); + if (data->beginfunc != NULL) + data->beginfunc (data->aux); - return virt_proc_func (c); + return data->procfunc (c, data->aux); } /* Compare the value of each SPLIT FILE variable to the values on @@ -1170,19 +1192,19 @@ SPLIT_FILE_procfunc (struct ccase *c) assert (0); } } - return virt_proc_func (c); + return data->procfunc (c, data->aux); not_equal: /* The values of the SPLIT FILE variable are different from the values on the previous case. That means that it's time to begin a new series. */ - if (end_func != NULL) - end_func (); + if (data->endfunc != NULL) + data->endfunc (data->aux); dump_splits (c); - if (virt_begin_func != NULL) - virt_begin_func (); + if (data->beginfunc != NULL) + data->beginfunc (data->aux); memcpy (prev_case, c, vfm_sink_info.case_size); - return virt_proc_func (c); + return data->procfunc (c, data->aux); } /* Case compaction. */ diff --git a/src/vfm.h b/src/vfm.h index b2a1e6ef..27cac235 100644 --- a/src/vfm.h +++ b/src/vfm.h @@ -35,14 +35,18 @@ extern struct long_vec reinit_blanks; /* Blanks for every case. */ extern struct long_vec init_zero; /* Zero for first case only. */ extern struct long_vec init_blanks; /* Blanks for first case only. */ +typedef struct write_case_data *write_case_data; +typedef int write_case_func (write_case_data); + /* A case stream: either a source or a sink, depending on context. */ struct case_stream { /* Initializes sink. */ void (*init) (void); - /* Reads all the cases and passes them to WRITE_CASE. */ - void (*read) (void); + /* Reads all the cases and calls WRITE_CASE passing the given + AUX data for each one. */ + void (*read) (write_case_func *, write_case_data); /* Writes a single case, temp_case. */ void (*write) (void); @@ -83,18 +87,18 @@ extern struct case_stream matrix_data_source; /* Number of cases to lag. */ extern int n_lag; -extern int (*write_case) (void); - -void procedure (void (*beginfunc) (void), - int (*procfunc) (struct ccase *curcase), - void (*endfunc) (void)); +void procedure (void (*beginfunc) (void *aux), + int (*procfunc) (struct ccase *curcase, void *aux), + void (*endfunc) (void *aux), + void *aux); struct ccase *lagged_case (int n_before); void compact_case (struct ccase *dest, const struct ccase *src); void page_to_disk (void); -void process_active_file (void (*beginfunc) (void), - int (*casefunc) (struct ccase *curcase), - void (*endfunc) (void)); +void process_active_file (void (*beginfunc) (void *), + int (*casefunc) (struct ccase *curcase, void *), + void (*endfunc) (void *), + void *aux); void process_active_file_output_case (void); #endif /* !vfm_h */