free (input_format);
}
hmap_destroy (&dict->input_formats);
- dict_destroy (dict->dict);
+ dict_unref (dict->dict);
free (dict);
}
dataset_reader_close (struct any_reader *r_)
{
struct dataset_reader *r = dataset_reader_cast (r_);
- dict_destroy (r->dict);
+ dict_unref (r->dict);
casereader_destroy (r->reader);
free (r);
else
{
casereader_destroy (reader);
- dict_destroy (writer->dict);
+ dict_unref (writer->dict);
}
fh_unlock (writer->lock);
{
dataset_set_session (ds, NULL);
dataset_clear (ds);
- dict_destroy (ds->dict);
+ dict_unref (ds->dict);
caseinit_destroy (ds->caseinit);
trns_chain_destroy (ds->permanent_trns_chain);
dataset_transformations_changed__ (ds, false);
dataset_clear (ds);
- dict_destroy (ds->dict);
+ dict_unref (ds->dict);
ds->dict = dict;
dict_set_change_callback (ds->dict, dict_callback, ds);
}
ds->cur_trns_chain = ds->permanent_trns_chain;
- dict_destroy (ds->permanent_dict);
+ dict_unref (ds->permanent_dict);
ds->permanent_dict = NULL;
return true;
{
if (proc_in_temporary_transformations (ds))
{
- dict_destroy (ds->dict);
+ dict_unref (ds->dict);
ds->dict = ds->permanent_dict;
ds->permanent_dict = NULL;
/* A dictionary. */
struct dictionary
{
+ int ref_cnt;
struct vardict_info *var; /* Variables. */
size_t var_cnt, var_cap; /* Number of variables, capacity. */
struct caseproto *proto; /* Prototype for dictionary cases
d->names_must_be_ids = true;
hmap_init (&d->name_map);
attrset_init (&d->attributes);
+ d->ref_cnt = 1;
return d;
}
+struct dictionary *
+dict_ref (struct dictionary *s)
+{
+ s->ref_cnt++;
+ return s;
+}
+
/* Creates and returns a (deep) copy of an existing
dictionary.
d->split_cnt = s->split_cnt;
if (d->split_cnt > 0)
{
- d->split = xnmalloc (d->split_cnt, sizeof *d->split);
+ d->split = xnmalloc (d->split_cnt, sizeof *d->split);
for (i = 0; i < d->split_cnt; i++)
d->split[i] = dict_lookup_var_assert (d, var_get_name (s->split[i]));
}
}
/* Clears a dictionary and destroys it. */
+static void
+_dict_destroy (struct dictionary *d)
+{
+ /* In general, we don't want callbacks occurring, if the dictionary
+ is being destroyed */
+ d->callbacks = NULL ;
+
+ dict_clear (d);
+ string_array_destroy (&d->documents);
+ hmap_destroy (&d->name_map);
+ attrset_destroy (&d->attributes);
+ dict_clear_mrsets (d);
+ free (d->encoding);
+ free (d);
+}
+
void
-dict_destroy (struct dictionary *d)
+dict_unref (struct dictionary *d)
{
- if (d != NULL)
- {
- /* In general, we don't want callbacks occurring, if the dictionary
- is being destroyed */
- d->callbacks = NULL ;
-
- dict_clear (d);
- string_array_destroy (&d->documents);
- hmap_destroy (&d->name_map);
- attrset_destroy (&d->attributes);
- dict_clear_mrsets (d);
- free (d->encoding);
- free (d);
- }
+ if (d == NULL)
+ return;
+ d->ref_cnt--;
+ assert (d->ref_cnt >= 0);
+ if (d->ref_cnt == 0)
+ _dict_destroy (d);
}
/* Returns the number of variables in D. */
valgrind --leak-check --show-reachable won't show internal_dict. */
if (dict_get_var_cnt (internal_dict) == 0)
{
- dict_destroy (internal_dict);
+ dict_unref (internal_dict);
internal_dict = NULL;
}
}
/* Creating dictionaries. */
struct dictionary *dict_create (const char *encoding);
-struct dictionary *dict_clone (const struct dictionary *);
+struct dictionary *dict_clone (const struct dictionary *) WARN_UNUSED_RESULT;
+struct dictionary *dict_ref (struct dictionary *s) WARN_UNUSED_RESULT;
/* Clearing and destroying dictionaries. */
void dict_clear (struct dictionary *);
-void dict_destroy (struct dictionary *);
+void dict_unref (struct dictionary *);
/* Common ways to access variables. */
struct variable *dict_lookup_var (const struct dictionary *, const char *);
free (r->sheets);
state_data_destroy (&r->msd);
- dict_destroy (r->dict);
+ dict_unref (r->dict);
free (s->file_name);
xmlFree (r->sheets[i].name);
}
- dict_destroy (r->dict);
+ dict_unref (r->dict);
zip_reader_destroy (r->zreader);
free (r->sheets);
error:
pcp_close (&r->any_reader);
- dict_destroy (dict);
+ dict_unref (dict);
*dictp = NULL;
return NULL;
}
struct pfm_reader *r = pfm_reader_cast (r_);
bool ok;
- dict_destroy (r->dict);
+ dict_unref (r->dict);
any_read_info_destroy (&r->info);
if (r->file)
{
&psql_casereader_class, r);
error:
- dict_destroy (*dict);
+ dict_unref (*dict);
psql_casereader_destroy (NULL, r);
return NULL;
int n_sheets;
/* The dictionary for client's reference.
- Client must clone if it needs a permanent or modifiable copy. */
- const struct dictionary *dict;
+ Client must ref or clone it if it needs a permanent or modifiable copy. */
+ struct dictionary *dict;
int ref_cnt;
};
error:
sfm_close (r_);
- dict_destroy (dict);
+ dict_unref (dict);
*dictp = NULL;
return NULL;
}
subcase_destroy (&file->dst);
free (file->mv);
fh_unref (file->handle);
- dict_destroy (file->dict);
+ dict_unref (file->dict);
casereader_destroy (file->reader);
case_unref (file->data);
free (file->in_name);
free_comb_proc (struct comb_proc *proc)
{
close_all_comb_files (proc);
- dict_destroy (proc->dict);
+ dict_unref (proc->dict);
casewriter_destroy (proc->output);
case_matcher_destroy (proc->matcher);
if (proc->prev_BY)
error:
data_parser_destroy (parser);
if (!in_input_program ())
- dict_destroy (dict);
+ dict_unref (dict);
fh_unref (fh);
free (encoding);
return CMD_CASCADING_FAILURE;
error:
data_parser_destroy (parser);
- dict_destroy (dict);
+ dict_unref (dict);
fh_unref (fh);
free (name);
free (encoding);
fh_unref (fh);
casereader_destroy (reader);
if (dict != NULL)
- dict_destroy (dict);
+ dict_unref (dict);
free (encoding);
return CMD_CASCADING_FAILURE;
}
error:
data_parser_destroy (parser);
if (!in_input_program ())
- dict_destroy (dict);
+ dict_unref (dict);
fh_unref (fh);
free (encoding);
free (mformat.split_vars);
case_map_stage_destroy (stage);
if (map != NULL)
writer = case_map_create_output_translator (map, writer);
- dict_destroy (dict);
+ dict_unref (dict);
casereader_transfer (proc_open_filtering (ds, !retain_unselected), writer);
ok = casewriter_destroy (writer);
error:
case_map_stage_destroy (stage);
fh_unref (handle);
- dict_destroy (dict);
+ dict_unref (dict);
case_map_destroy (map);
return CMD_FAILURE;
}
case_map_stage_destroy (stage);
if (map != NULL)
writer = case_map_create_output_translator (map, writer);
- dict_destroy (dict);
+ dict_unref (dict);
fh_unref (handle);
fh_unref (metadata);
fh_unref (handle);
fh_unref (metadata);
casewriter_destroy (writer);
- dict_destroy (dict);
+ dict_unref (dict);
case_map_destroy (map);
return NULL;
}
{
/* FIXME: display new dictionary. */
}
- dict_destroy (temp);
+ dict_unref (temp);
}
else
{
table_item_submit (table_item_create (table, NULL /* XXX */, NULL));
- dict_destroy (d);
+ dict_unref (d);
fh_unref (h);
free (encoding);
free (iter);
}
if (agr->dict != NULL)
- dict_destroy (agr->dict);
+ dict_unref (agr->dict);
}
\f
/* Execution. */
return CMD_SUCCESS;
error:
- dict_destroy (new_dict);
+ dict_unref (new_dict);
destroy_flip_pgm (flip);
return CMD_CASCADING_FAILURE;
}
PsppireDict *d = PSPPIRE_DICT (object);
dict_set_callbacks (d->dict, NULL, NULL);
+ dict_unref (d->dict);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
psppire_dict_new_from_dict (struct dictionary *d)
{
PsppireDict *new_dict = g_object_new (PSPPIRE_TYPE_DICT, NULL);
- new_dict->dict = d;
+ new_dict->dict = dict_ref (d);
dict_set_callbacks (new_dict->dict, &gui_callbacks, new_dict);
{
struct variable *var = dict_get_weight (d);
+ struct dictionary *old_dict = dict->dict;
+
guint old_n = dict_get_var_cnt (dict->dict);
guint new_n = dict_get_var_cnt (d);
- dict->dict = d;
+ dict->dict = dict_ref (d);
+ dict_unref (old_dict);
weight_changed_callback (d, var ? var_get_dict_index (var) : -1, dict);
ds_destroy (&ia->quotes);
+ dict_unref (ia->dict);
+
g_object_unref (ia->builder);
ia->response = -1;
struct casereader *reader = spreadsheet_make_reader (ia->spreadsheet, &opts);
- PsppireDict *dict = psppire_dict_new_from_dict (dict_clone (ia->spreadsheet->dict));
+ PsppireDict *dict = psppire_dict_new_from_dict (ia->spreadsheet->dict);
PsppireDataStore *store = psppire_data_store_new (dict);
psppire_data_store_set_reader (store, reader);
g_object_set (ia->data_sheet, "data-model", store, NULL);
error (1, 0, _("%s: error writing output file"), output_filename);
exit:
- dict_destroy (dict);
+ dict_unref (dict);
fh_unref (output_fh);
fh_unref (input_fh);
fh_done ();
return 0;
error:
- dict_destroy (dict);
+ dict_unref (dict);
fh_unref (output_fh);
fh_unref (input_fh);
fh_done ();