- 100 (4): Pass it through an aggregate transformation that doesn't
- modify the data but merely writes it to the output file.
-
- 101 (5): Handled as 100.
-
- 110 (6): Set up a SORT CASES and capture the output, aggregate
- it, write it to the output file without modifying the active
- file.
-
- 111 (7): Handled as 110. */
-
- {
- unsigned type = 0;
-
- if (outfile != NULL)
- type |= 4;
- if (nv_sort != 0 && (seen & 4) == 0)
- type |= 2;
- if (temporary)
- type |= 1;
-
- switch (type)
- {
- case 3:
- cancel_temporary ();
- /* fall through */
- case 2:
- sort_cases (0);
- goto case0;
-
- case 1:
- cancel_temporary ();
- /* fall through */
- case 0:
- case0:
- {
- struct trns_header *t = xmalloc (sizeof *t);
- t->proc = agr_00x_trns_proc;
- t->free = NULL;
- add_transformation (t);
-
- temporary = 2;
- temp_dict = agr_dict;
- temp_trns = n_trns;
-
- agr_dict = NULL;
-
- procedure (NULL, NULL, agr_00x_end_func, NULL);
- break;
- }
-
- case 4:
- case 5:
- {
- if (!create_sysfile ())
- goto lossage;
-
- {
- struct trns_header *t = xmalloc (sizeof *t);
- t->proc = agr_10x_trns_proc;
- t->free = agr_10x_trns_free;
- add_transformation (t);
-
- procedure (NULL, NULL, agr_10x_end_func, NULL);
- }
-
- break;
- }
-
- case 6:
- case 7:
- sort_cases (1);
-
- if (!create_sysfile ())
- goto lossage;
- read_sort_output (agr_11x_func, NULL);
-
- {
- struct ccase *save_temp_case = temp_case;
- temp_case = NULL;
- agr_11x_func (NULL);
- temp_case = save_temp_case;
- }
-
- break;
-
- default:
- assert (0);
- }
- }
-
- free (buf64_1xx);
- free (buf_1xx);
-
- /* Clean up. */
- free (v_sort);
- free_aggregate_functions ();
- free (prev_case);
+ /* Output to active file or external file? */
+ if (out_file == NULL)
+ {
+ /* The active file will be replaced by the aggregated data,
+ so TEMPORARY is moot. */
+ cancel_temporary ();
+
+ if (agr.sort != NULL && (seen & 4) == 0)
+ sort_active_file_in_place (agr.sort);
+
+ agr.sink = create_case_sink (&storage_sink_class, agr.dict, NULL);
+ if (agr.sink->class->open != NULL)
+ agr.sink->class->open (agr.sink);
+ vfm_sink = create_case_sink (&null_sink_class, default_dict, NULL);
+ procedure (agr_to_active_file, &agr);
+ if (agr.case_cnt > 0)
+ {
+ dump_aggregate_info (&agr, &agr.agr_case);
+ agr.sink->class->write (agr.sink, &agr.agr_case);
+ }
+ dict_destroy (default_dict);
+ default_dict = agr.dict;
+ agr.dict = NULL;
+ vfm_source = agr.sink->class->make_source (agr.sink);
+ free_case_sink (agr.sink);
+ }
+ else
+ {
+ agr.writer = sfm_open_writer (out_file, agr.dict, get_scompression ());
+ if (agr.writer == NULL)
+ goto error;
+
+ if (agr.sort != NULL && (seen & 4) == 0)
+ {
+ /* Sorting is needed. */
+ struct casefile *dst;
+ struct casereader *reader;
+ struct ccase c;
+
+ dst = sort_active_file_to_casefile (agr.sort);
+ if (dst == NULL)
+ goto error;
+ reader = casefile_get_destructive_reader (dst);
+ while (casereader_read_xfer (reader, &c))
+ {
+ if (aggregate_single_case (&agr, &c, &agr.agr_case))
+ sfm_write_case (agr.writer, &agr.agr_case);
+ case_destroy (&c);
+ }
+ casereader_destroy (reader);
+ casefile_destroy (dst);
+ }
+ else
+ {
+ /* Active file is already sorted. */
+ procedure (presorted_agr_to_sysfile, &agr);
+ }
+
+ if (agr.case_cnt > 0)
+ {
+ dump_aggregate_info (&agr, &agr.agr_case);
+ sfm_write_case (agr.writer, &agr.agr_case);
+ }
+ }