1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "data/session.h"
24 #include "data/dataset.h"
25 #include "libpspp/assertion.h"
26 #include "libpspp/cast.h"
27 #include "libpspp/hash-functions.h"
28 #include "libpspp/i18n.h"
29 #include "libpspp/str.h"
30 #include "libpspp/hmapx.h"
32 #include "gl/xalloc.h"
36 struct session *parent;
37 struct hmapx datasets;
38 struct dataset *active;
39 char *syntax_encoding; /* Default encoding for syntax files. */
40 unsigned int n_dataset_names; /* For session_generate_dataset_name(). */
43 static struct hmapx_node *session_lookup_dataset__ (const struct session *,
47 session_create (struct session *parent)
51 s = xmalloc (sizeof *s);
53 hmapx_init (&s->datasets);
55 s->syntax_encoding = xstrdup (s->parent != NULL
56 ? s->parent->syntax_encoding : "Auto");
57 s->n_dataset_names = 0;
62 session_destroy (struct session *s)
66 struct hmapx_node *node, *next;
70 HMAPX_FOR_EACH_SAFE (ds, node, next, &s->datasets)
72 hmapx_destroy (&s->datasets);
73 free (s->syntax_encoding);
79 session_active_dataset (struct session *s)
85 session_set_active_dataset (struct session *s, struct dataset *ds)
87 assert (ds == NULL || dataset_session (ds) == s);
92 session_add_dataset (struct session *s, struct dataset *ds)
96 old = session_lookup_dataset (s, dataset_name (ds));
101 session_remove_dataset (s, old);
102 dataset_destroy (old);
105 hmapx_insert (&s->datasets, ds,
106 utf8_hash_case_string (dataset_name (ds), 0));
107 if (s->active == NULL)
110 dataset_set_session__ (ds, s);
114 session_remove_dataset (struct session *s, struct dataset *ds)
116 assert (ds != s->active);
117 hmapx_delete (&s->datasets, session_lookup_dataset__ (s, dataset_name (ds)));
118 dataset_set_session__ (ds, NULL);
122 session_lookup_dataset (const struct session *s, const char *name)
124 struct hmapx_node *node = session_lookup_dataset__ (s, name);
125 return (node != NULL ? node->data
126 : s->parent != NULL ? session_lookup_dataset (s->parent, name)
131 session_lookup_dataset_assert (const struct session *s, const char *name)
133 struct dataset *ds = session_lookup_dataset (s, name);
139 session_set_default_syntax_encoding (struct session *s, const char *encoding)
141 free (s->syntax_encoding);
142 s->syntax_encoding = xstrdup (encoding);
146 session_get_default_syntax_encoding (const struct session *s)
148 return s->syntax_encoding;
152 session_n_datasets (const struct session *s)
154 return hmapx_count (&s->datasets);
158 session_for_each_dataset (const struct session *s,
159 void (*cb) (struct dataset *, void *aux),
162 struct hmapx_node *node, *next;
165 HMAPX_FOR_EACH_SAFE (ds, node, next, &s->datasets)
170 session_get_dataset_by_seqno (const struct session *s, unsigned int seqno)
172 struct hmapx_node *node;
175 HMAPX_FOR_EACH (ds, node, &s->datasets)
176 if (dataset_seqno (ds) == seqno)
181 /* Returns an identifier that is is not currently in use as a dataset name.
182 The caller must free the returned identifier, with free(). */
184 session_generate_dataset_name (struct session *s)
190 s->n_dataset_names++;
191 assert(s->n_dataset_names != 0);
193 name = xasprintf ("DataSet%u", s->n_dataset_names);
194 if (!session_lookup_dataset (s, name))
200 static struct hmapx_node *
201 session_lookup_dataset__ (const struct session *s_, const char *name)
203 struct session *s = CONST_CAST (struct session *, s_);
204 struct hmapx_node *node;
207 HMAPX_FOR_EACH_WITH_HASH (ds, node, utf8_hash_case_string (name, 0),
209 if (!utf8_strcasecmp (dataset_name (ds), name))