1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2010, 2011 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 "language/command.h"
21 #include "data/dataset.h"
22 #include "data/session.h"
23 #include "language/lexer/lexer.h"
24 #include "libpspp/message.h"
25 #include "output/pivot-table.h"
28 #define N_(msgid) msgid
29 #define _(msgid) gettext (msgid)
32 parse_window (struct lexer *lexer, unsigned int allowed,
33 enum dataset_display def)
35 if (!lex_match_id (lexer, "WINDOW"))
37 lex_match (lexer, T_EQUALS);
39 if (allowed & (1 << DATASET_MINIMIZED) && lex_match_id (lexer, "MINIMIZED"))
40 return DATASET_MINIMIZED;
41 else if (allowed & (1 << DATASET_ASIS) && lex_match_id (lexer, "ASIS"))
43 else if (allowed & (1 << DATASET_FRONT) && lex_match_id (lexer, "FRONT"))
45 else if (allowed & (1 << DATASET_HIDDEN) && lex_match_id (lexer, "HIDDEN"))
46 return DATASET_HIDDEN;
48 const char *allowed_s[4];
50 if (allowed & (1 << DATASET_MINIMIZED))
51 allowed_s[n_allowed++] = "MINIMIZED";
52 if (allowed & (1 << DATASET_ASIS))
53 allowed_s[n_allowed++] = "ASIS";
54 if (allowed & (1 << DATASET_FRONT))
55 allowed_s[n_allowed++] = "FRONT";
56 if (allowed & (1 << DATASET_HIDDEN))
57 allowed_s[n_allowed++] = "HIDDEN";
58 lex_error_expecting_array (lexer, allowed_s, n_allowed);
62 static struct dataset *
63 parse_dataset_name (struct lexer *lexer, struct session *session)
65 if (!lex_force_id (lexer))
68 struct dataset *ds = session_lookup_dataset (session, lex_tokcstr (lexer));
72 lex_error (lexer, _("There is no dataset named %s."), lex_tokcstr (lexer));
77 cmd_dataset_name (struct lexer *lexer, struct dataset *active)
79 if (!lex_force_id (lexer))
81 dataset_set_name (active, lex_tokcstr (lexer));
84 int display = parse_window (lexer, (1 << DATASET_ASIS) | (1 << DATASET_FRONT),
88 else if (display != DATASET_ASIS)
89 dataset_set_display (active, display);
95 cmd_dataset_activate (struct lexer *lexer, struct dataset *active)
97 struct session *session = dataset_session (active);
101 ds = parse_dataset_name (lexer, session);
107 proc_execute (active);
108 session_set_active_dataset (session, ds);
109 if (dataset_name (active)[0] == '\0')
110 dataset_destroy (active);
114 display = parse_window (lexer, (1 << DATASET_ASIS) | (1 << DATASET_FRONT),
118 else if (display != DATASET_ASIS)
119 dataset_set_display (ds, display);
125 cmd_dataset_copy (struct lexer *lexer, struct dataset *old)
127 struct session *session = dataset_session (old);
129 /* Parse the entire command first. proc_execute() can attempt to parse
130 BEGIN DATA...END DATA and it will fail confusingly if we are in the
131 middle of the command at the point. */
132 if (!lex_force_id (lexer))
134 char *name = xstrdup (lex_tokcstr (lexer));
137 int display = parse_window (lexer, ((1 << DATASET_MINIMIZED)
138 | (1 << DATASET_HIDDEN)
139 | (1 << DATASET_FRONT)),
148 if (session_lookup_dataset (session, name) == old)
151 dataset_set_name (old, "");
156 new = dataset_clone (old, name);
158 dataset_set_display (new, display);
165 cmd_dataset_declare (struct lexer *lexer, struct dataset *ds)
167 struct session *session = dataset_session (ds);
169 if (!lex_force_id (lexer))
172 struct dataset *new = session_lookup_dataset (session, lex_tokcstr (lexer));
174 new = dataset_create (session, lex_tokcstr (lexer));
177 int display = parse_window (lexer, ((1 << DATASET_MINIMIZED)
178 | (1 << DATASET_HIDDEN)
179 | (1 << DATASET_FRONT)),
183 dataset_set_display (new, display);
189 dataset_close_cb (struct dataset *ds, void *session_)
191 struct session *session = session_;
193 if (ds != session_active_dataset (session))
194 dataset_destroy (ds);
198 cmd_dataset_close (struct lexer *lexer, struct dataset *ds)
200 struct session *session = dataset_session (ds);
202 if (lex_match (lexer, T_ALL))
204 session_for_each_dataset (session, dataset_close_cb, session);
205 dataset_set_name (session_active_dataset (session), "");
209 if (!lex_match (lexer, T_ASTERISK))
211 ds = parse_dataset_name (lexer, session);
216 if (ds == session_active_dataset (session))
217 dataset_set_name (ds, "");
219 dataset_destroy (ds);
226 dataset_display_cb (struct dataset *ds, void *p_)
228 struct dataset ***p = p_;
234 sort_datasets (const void *a_, const void *b_)
236 struct dataset *const *a = a_;
237 struct dataset *const *b = b_;
239 return strcmp (dataset_name (*a), dataset_name (*b));
243 cmd_dataset_display (struct lexer *lexer UNUSED, struct dataset *ds)
245 struct session *session = dataset_session (ds);
246 size_t n = session_n_datasets (session);
247 struct dataset **datasets = xmalloc (n * sizeof *datasets);
248 struct dataset **p = datasets;
249 session_for_each_dataset (session, dataset_display_cb, &p);
250 qsort (datasets, n, sizeof *datasets, sort_datasets);
252 struct pivot_table *table = pivot_table_create (N_("Datasets"));
254 struct pivot_dimension *datasets_dim = pivot_dimension_create (
255 table, PIVOT_AXIS_ROW, N_("Dataset"));
256 datasets_dim->hide_all_labels = true;
258 for (size_t i = 0; i < n; i++)
260 struct dataset *ds = datasets[i];
263 name = dataset_name (ds);
265 name = _("unnamed dataset");
267 char *text = (ds == session_active_dataset (session)
268 ? xasprintf ("%s (%s)", name, _("active dataset"))
271 int dataset_idx = pivot_category_create_leaf (
272 datasets_dim->root, pivot_value_new_integer (i));
274 pivot_table_put1 (table, dataset_idx,
275 pivot_value_new_user_text_nocopy (text));
280 pivot_table_submit (table);