#include "vfm.h"
#include "vfmP.h"
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
#include "debug-print.h"
/* Rearranging and reducing a dictionary. */
dict_set_case_limit (mtf.dict, dict_get_case_limit (default_dict));
lex_match ('/');
- while (lex_id_match ("FILE", tokid) || lex_id_match ("TABLE", tokid))
+ while (token == T_ID
+ && (lex_id_match ("FILE", tokid) || lex_id_match ("TABLE", tokid)))
{
struct mtf_file *file = xmalloc (sizeof *file);
}
else
assert (0);
+ lex_match ('=');
file->by = NULL;
file->handle = NULL;
mtf.head = file;
first_table->prev = file;
}
-
- lex_match ('=');
-
+
if (lex_match ('*'))
{
file->handle = NULL;
}
}
}
+ free (by);
}
else if (lex_match_id ("FIRST"))
{
}
}
+ /* Set up mapping from each file's variables to master
+ variables. */
for (iter = mtf.head; iter != NULL; iter = iter->next)
{
struct dictionary *d = iter->dict;
}
}
+ /* Add IN variables to master dictionary. */
for (iter = mtf.head; iter != NULL; iter = iter->next)
if (iter->in_name != NULL)
{
- static const struct fmt_spec f1_0 = {FMT_F, 1, 0};
-
iter->in_var = dict_create_var (mtf.dict, iter->in_name, 0);
if (iter->in_var == NULL)
{
msg (SE, _("IN variable name %s duplicates an "
"existing variable name."),
- iter->in_var);
+ iter->in_var->name);
goto error;
}
- iter->in_var->print = iter->in_var->write = f1_0;
+ iter->in_var->print = iter->in_var->write
+ = make_output_format (FMT_F, 1, 0);
}
/* MATCH FILES performs an n-way merge on all its input files.
if (mtf.sink->class->open != NULL)
mtf.sink->class->open (mtf.sink);
- mtf.seq_nums = xcalloc (dict_get_var_cnt (mtf.dict) * sizeof *mtf.seq_nums);
+ mtf.seq_nums = xcalloc (dict_get_var_cnt (mtf.dict), sizeof *mtf.seq_nums);
case_create (&mtf.mtf_case, dict_get_next_value_idx (mtf.dict));
mtf_read_nonactive_records (&mtf);
procedure (mtf_processing, &mtf);
mtf_processing_finish (&mtf);
+ free_case_source (vfm_source);
+ vfm_source = NULL;
+
dict_destroy (default_dict);
default_dict = mtf.dict;
mtf.dict = NULL;
bool read_active_file;
assert (mtf->head != NULL);
- assert (mtf->head->type == MTF_FILE);
+ if (mtf->head->type == MTF_TABLE)
+ return 1;
+
do
{
struct mtf_file *min_head, *min_tail; /* Files with minimum BY values. */
min_head = min_tail = mtf->head;
max_head = max_tail = NULL;
for (iter = mtf->head->next; iter && iter->type == MTF_FILE;
- iter = iter->next)
- switch (mtf_compare_BY_values (mtf, min_head, iter, c))
- {
- case -1:
- if (max_head)
- max_tail = max_tail->next_min = iter;
- else
- max_head = max_tail = iter;
- break;
-
- case 0:
+ iter = iter->next)
+ {
+ int cmp = mtf_compare_BY_values (mtf, min_head, iter, c);
+ if (cmp < 0)
+ {
+ if (max_head)
+ max_tail = max_tail->next_min = iter;
+ else
+ max_head = max_tail = iter;
+ }
+ else if (cmp == 0)
min_tail = min_tail->next_min = iter;
- break;
-
- case 1:
- if (max_head)
- {
- max_tail->next_min = min_head;
- max_tail = min_tail;
- }
- else
- {
- max_head = min_head;
- max_tail = min_tail;
- }
- min_head = min_tail = iter;
- break;
-
- default:
- assert (0);
- }
-
+ else /* cmp > 0 */
+ {
+ if (max_head)
+ {
+ max_tail->next_min = min_head;
+ max_tail = min_tail;
+ }
+ else
+ {
+ max_head = min_head;
+ max_tail = min_tail;
+ }
+ min_head = min_tail = iter;
+ }
+ }
+
/* 4. For every TABLE, read another record as long as the BY
values on the TABLE's input record are less than the FILEs'
BY values. If an exact match is found, store all the values
assert (iter->type == MTF_TABLE);
next = iter->next;
-
- again:
- switch (mtf_compare_BY_values (mtf, min_head, iter, c))
- {
- case -1:
- if (max_head)
- max_tail = max_tail->next_min = iter;
- else
- max_head = max_tail = iter;
- break;
-
- case 0:
- min_tail = min_tail->next_min = iter;
- break;
-
- case 1:
- if (iter->handle == NULL)
- return 1;
- if (sfm_read_case (iter->reader, &iter->input))
- goto again;
- mtf_delete_file_in_place (mtf, &iter);
- break;
-
- default:
- assert (0);
- }
+ for (;;)
+ {
+ int cmp = mtf_compare_BY_values (mtf, min_head, iter, c);
+ if (cmp < 0)
+ {
+ if (max_head)
+ max_tail = max_tail->next_min = iter;
+ else
+ max_head = max_tail = iter;
+ }
+ else if (cmp == 0)
+ min_tail = min_tail->next_min = iter;
+ else /* cmp > 0 */
+ {
+ if (iter->handle == NULL)
+ return 1;
+ if (sfm_read_case (iter->reader, &iter->input))
+ continue;
+ mtf_delete_file_in_place (mtf, &iter);
+ }
+ break;
+ }
}
/* Next sequence number. */
}
}
- dict_compact_values (d);
-
for (i = 0; i < dict_get_var_cnt (d); i++)
{
struct variable *dv = dict_get_var (d, i);
struct variable *mv = dict_lookup_var (m, dv->name);
+ if (dict_class_from_id (dv->name) == DC_SCRATCH)
+ continue;
+
if (mv != NULL)
{
if (mv->width != dv->width)