+/* Destroys case sink SINK. It is the caller's responsible to
+ call the sink's destroy function, if any. */
+void
+free_case_sink (struct case_sink *sink)
+{
+ free (sink->idx_to_fv);
+ free (sink);
+}
+\f
+/* Represents auxiliary data for handling SPLIT FILE. */
+struct split_aux_data
+ {
+ size_t case_count; /* Number of cases so far. */
+ struct ccase *prev_case; /* Data in previous case. */
+
+ /* Functions to call... */
+ void (*begin_func) (void *); /* ...before data. */
+ int (*proc_func) (struct ccase *, void *); /* ...with data. */
+ void (*end_func) (void *); /* ...after data. */
+ void *func_aux; /* Auxiliary data. */
+ };
+
+static int equal_splits (const struct ccase *, const struct ccase *);
+static int procedure_with_splits_callback (struct ccase *, void *);
+static void dump_splits (struct ccase *);
+
+/* Like procedure(), but it automatically breaks the case stream
+ into SPLIT FILE break groups. Before each group of cases with
+ identical SPLIT FILE variable values, BEGIN_FUNC is called.
+ Then PROC_FUNC is called with each case in the group.
+ END_FUNC is called when the group is finished. FUNC_AUX is
+ passed to each of the functions as auxiliary data.
+
+ If the active file is empty, none of BEGIN_FUNC, PROC_FUNC,
+ and END_FUNC will be called at all.
+
+ If SPLIT FILE is not in effect, then there is one break group
+ (if the active file is nonempty), and BEGIN_FUNC and END_FUNC
+ will be called once. */
+void
+procedure_with_splits (void (*begin_func) (void *aux),
+ int (*proc_func) (struct ccase *, void *aux),
+ void (*end_func) (void *aux),
+ void *func_aux)
+{
+ struct split_aux_data split_aux;
+
+ split_aux.case_count = 0;
+ split_aux.prev_case = xmalloc (dict_get_case_size (default_dict));
+ split_aux.begin_func = begin_func;
+ split_aux.proc_func = proc_func;
+ split_aux.end_func = end_func;
+ split_aux.func_aux = func_aux;
+
+ procedure (procedure_with_splits_callback, &split_aux);
+
+ if (split_aux.case_count > 0 && end_func != NULL)
+ end_func (func_aux);
+ free (split_aux.prev_case);