-/* Transforms trns_case and writes it to the replacement active
- file if advisable. Returns nonzero if more cases can be
- accepted, zero otherwise. Do not call this function again
- after it has returned zero once. */
-int
-procedure_write_case (write_case_data wc_data)
-{
- struct procedure_aux_data *proc_aux = wc_data->aux;
-
- /* Index of current transformation. */
- int cur_trns;
-
- /* Return value: whether it's reasonable to write any more cases. */
- int more_cases = 1;
-
- cur_trns = f_trns;
- for (;;)
- {
- /* Output the case if this is temp_trns. */
- if (cur_trns == temp_trns)
- {
- int case_limit;
-
- if (n_lag)
- lag_case (proc_aux->trns_case);
-
- vfm_sink->class->write (vfm_sink, proc_aux->trns_case);
-
- proc_aux->cases_written++;
- case_limit = dict_get_case_limit (default_dict);
- if (case_limit != 0 && proc_aux->cases_written >= case_limit)
- more_cases = 0;
- }
-
- /* Are we done? */
- if (cur_trns >= n_trns)
- break;
-
- /* Decide which transformation should come next. */
- {
- int code;
-
- code = t_trns[cur_trns]->proc (t_trns[cur_trns], proc_aux->trns_case,
- proc_aux->cases_written + 1);
- switch (code)
- {
- case -1:
- /* Next transformation. */
- cur_trns++;
- break;
- case -2:
- /* Delete this case. */
- goto done;
- default:
- /* Go to that transformation. */
- cur_trns = code;
- break;
- }
- }
- }
-
- /* Call the beginning of group function. */
- if (!case_count && wc_data->begin_func != NULL)
- wc_data->begin_func (wc_data->func_aux);
-
- /* Call the procedure if there is one and FILTER and PROCESS IF
- don't prohibit it. */
- if (wc_data->proc_func != NULL
- && !exclude_this_case (proc_aux->trns_case, proc_aux->cases_written + 1))
- wc_data->proc_func (proc_aux->trns_case, wc_data->func_aux);
-
- case_count++;
-
-done:
- clear_case (proc_aux->trns_case);
-
- /* Return previously determined value. */
- return more_cases;
-}
-
-/* Clears the variables in C that need to be cleared between
- processing cases. */
-static void
-clear_case (struct ccase *c)
-{
- /* FIXME? This is linear in the number of variables, but
- doesn't need to be, so it's an easy optimization target. */
- size_t var_cnt = dict_get_var_cnt (default_dict);
- size_t i;
-
- for (i = 0; i < var_cnt; i++)
- {
- struct variable *v = dict_get_var (default_dict, i);
- if (v->init && v->reinit)
- {
- if (v->type == NUMERIC)
- c->data[v->fv].f = SYSMIS;
- else
- memset (c->data[v->fv].s, ' ', v->width);
- }
- }
-}
-
-/* Returns nonzero if case C with case number CASE_NUM should be
- exclude as specified on FILTER or PROCESS IF, otherwise
- zero. */
-static int
-exclude_this_case (const struct ccase *c, int case_num)
-{
- /* FILTER. */
- struct variable *filter_var = dict_get_filter (default_dict);
- if (filter_var != NULL)
- {
- double f = c->data[filter_var->fv].f;
- if (f == 0.0 || f == SYSMIS || is_num_user_missing (f, filter_var))
- return 1;
- }
-
- /* PROCESS IF. */
- if (process_if_expr != NULL
- && expr_evaluate (process_if_expr, c, case_num, NULL) != 1.0)
- return 1;
-
- return 0;
-}
-