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. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
-#include <assert.h>
+#include "error.h"
#include <stddef.h>
#include <stdlib.h>
#include "alloc.h"
-#include "avl.h"
#include "command.h"
+#include "dictionary.h"
#include "do-ifP.h"
#include "error.h"
+#include "hash.h"
#include "lexer.h"
#include "str.h"
+#include "value-labels.h"
#include "var.h"
-#undef DEBUGGING
-/*#define DEBUGGING 1*/
-#include "debug-print.h"
-
int temporary;
struct dictionary *temp_dict;
int temp_trns;
-#if 0
-/* Displays all the value labels in TREE, with label S. */
-void
-display_tree (char *s, avl_tree *tree)
-{
- value_label *iter;
- avl_traverser *trav = NULL;
-
- printf("%s tree:\n", s);
- fflush(stdout);
- while ((iter = avl_traverse (tree, &trav)) != NULL)
- printf (" %g: %s\n", iter->v.f, iter->s);
-}
-#endif
-
/* Parses the TEMPORARY command. */
int
cmd_temporary (void)
{
- lex_match_id ("TEMPORARY");
-
/* TEMPORARY is not allowed inside DO IF or LOOP. */
if (ctl_stack)
{
return CMD_FAILURE;
}
- /* Everything is temporary, even if we think it'll last forever.
- Especially then. */
+ /* Make a copy of the current dictionary. */
temporary = 1;
- temp_dict = save_dictionary ();
- if (f_trns == n_trns)
- temp_trns = -1;
- else
- temp_trns = n_trns;
- debug_printf (("TEMPORARY: temp_trns=%d\n", temp_trns));
+ temp_dict = dict_clone (default_dict);
+ temp_trns = n_trns;
return lex_end_of_command ();
}
-/* Copies a variable structure. */
-void
-copy_variable (struct variable *dest, const struct variable *src)
-{
- int i, n;
-
- assert (dest != src);
- dest->type = src->type;
- dest->left = src->left;
- dest->width = src->width;
- dest->fv = src->fv;
- dest->nv = src->nv;
- dest->miss_type = src->miss_type;
-
- switch (src->miss_type)
- {
- case MISSING_NONE:
- n = 0;
- break;
- case MISSING_1:
- n = 1;
- break;
- case MISSING_2:
- case MISSING_RANGE:
- n = 2;
- break;
- case MISSING_3:
- case MISSING_RANGE_1:
- n = 3;
- break;
- default:
- assert (0);
- break;
- }
-
- for (i = 0; i < n; i++)
- dest->missing[i] = src->missing[i];
- dest->print = src->print;
- dest->write = src->write;
-
- dest->val_lab = copy_value_labels (src->val_lab);
- dest->label = src->label ? xstrdup (src->label) : NULL;
-}
-
-/* Returns a newly created empty dictionary. The file label and
- documents are copied from default_dict if COPY is nonzero. */
-struct dictionary *
-new_dictionary (int copy)
-{
- struct dictionary *d = xmalloc (sizeof *d);
-
- d->var = NULL;
- d->var_by_name = avl_create (NULL, cmp_variable, NULL);
- d->nvar = 0;
-
- d->N = 0;
-
- d->nval = 0;
-
- d->n_splits = 0;
- d->splits = NULL;
-
- if (default_dict.label && copy)
- d->label = xstrdup (default_dict.label);
- else
- d->label = NULL;
-
- if (default_dict.n_documents && copy)
- {
- d->n_documents = default_dict.n_documents;
- if (d->n_documents)
- {
- d->documents = malloc (default_dict.n_documents * 80);
- memcpy (d->documents, default_dict.documents,
- default_dict.n_documents * 80);
- }
- }
- else
- {
- d->n_documents = 0;
- d->documents = NULL;
- }
-
- d->weight_index = -1;
- d->weight_var[0] = 0;
-
- d->filter_var[0] = 0;
-
- return d;
-}
-
-/* Copies the current dictionary info into a newly allocated
- dictionary structure, which is returned. */
-struct dictionary *
-save_dictionary (void)
-{
- /* Dictionary being created. */
- struct dictionary *d;
-
- int i;
-
- d = xmalloc (sizeof *d);
-
- /* First the easy stuff. */
- *d = default_dict;
- d->label = default_dict.label ? xstrdup (default_dict.label) : NULL;
- if (default_dict.n_documents)
- {
- d->documents = malloc (default_dict.n_documents * 80);
- memcpy (d->documents, default_dict.documents,
- default_dict.n_documents * 80);
- }
- else d->documents = NULL;
-
- /* Then the variables. */
- d->var_by_name = avl_create (NULL, cmp_variable, NULL);
- d->var = xmalloc (default_dict.nvar * sizeof *d->var);
- for (i = 0; i < default_dict.nvar; i++)
- {
- d->var[i] = xmalloc (sizeof *d->var[i]);
- copy_variable (d->var[i], default_dict.var[i]);
- strcpy (d->var[i]->name, default_dict.var[i]->name);
- d->var[i]->index = i;
- avl_force_insert (d->var_by_name, d->var[i]);
- }
-
- /* Then the SPLIT FILE variables. */
- if (default_dict.splits)
- {
- int i;
-
- d->n_splits = default_dict.n_splits;
- d->splits = xmalloc ((default_dict.n_splits + 1) * sizeof *d->splits);
- for (i = 0; i < default_dict.n_splits; i++)
- d->splits[i] = d->var[default_dict.splits[i]->index];
- d->splits[default_dict.n_splits] = NULL;
- }
- else
- {
- d->n_splits = 0;
- d->splits = NULL;
- }
-
- return d;
-}
-
-/* Copies dictionary D into the active file dictionary. Deletes
- dictionary D. */
-void
-restore_dictionary (struct dictionary * d)
-{
- int i;
-
- /* 1. Delete the current dictionary. */
- default_dict.n_splits = 0;
- free (default_dict.splits);
- default_dict.splits = NULL;
-
- avl_destroy (default_dict.var_by_name, NULL);
- default_dict.var_by_name = NULL;
-
- for (i = 0; i < default_dict.nvar; i++)
- {
- clear_variable (&default_dict, default_dict.var[i]);
- free (default_dict.var[i]);
- }
-
- free (default_dict.var);
- free (default_dict.label);
- free (default_dict.documents);
-
- /* 2. Copy dictionary D into the active file dictionary. */
-#if __CHECKER__
- {
- size_t offset;
-
- offset = offsetof (struct dictionary, filter_var) + sizeof d->filter_var;
- strncpy (d->weight_var, d->weight_var, 9);
- strncpy (d->filter_var, d->filter_var, 9);
- memset (&((char *) d)[offset], '*', sizeof *d - offset);
- }
-#endif
- default_dict = *d;
- if (!default_dict.var_by_name)
- {
- default_dict.var_by_name = avl_create (NULL, cmp_variable, NULL);
-
- for (i = 0; i < default_dict.nvar; i++)
- avl_force_insert (default_dict.var_by_name, default_dict.var[i]);
- }
-
- /* 3. Destroy dictionary D. */
- free (d);
-}
-
-/* Destroys dictionary D. */
-void
-free_dictionary (struct dictionary * d)
-{
- int i;
-
- d->n_splits = 0;
- free (d->splits);
- d->splits = NULL;
-
- if (d->var_by_name)
- avl_destroy (d->var_by_name, NULL);
-
- for (i = 0; i < d->nvar; i++)
- {
- struct variable *v = d->var[i];
-
- if (v->val_lab)
- {
- avl_destroy (v->val_lab, free_val_lab);
- v->val_lab = NULL;
- }
- if (v->label)
- {
- free (v->label);
- v->label = NULL;
- }
- free (d->var[i]);
- }
- free (d->var);
-
- free (d->label);
- free (d->documents);
-
- free (d);
-}
-
/* Cancels the temporary transformation, if any. */
void
cancel_temporary (void)
{
if (temporary)
{
- if (temp_dict)
- free_dictionary (temp_dict);
+ if (temp_dict)
+ {
+ dict_destroy (temp_dict);
+ temp_dict = NULL;
+ }
temporary = 0;
temp_trns = 0;
}