/* PSPP - a program for statistical analysis.
- Copyright (C) 2010 Free Software Foundation, Inc.
+ Copyright (C) 2010, 2011, 2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <stdlib.h>
#include "data/dictionary.h"
+#include "data/identifier.h"
#include "data/val-type.h"
#include "data/variable.h"
+#include "libpspp/message.h"
+#include "libpspp/pxd.h"
#include "gl/xalloc.h"
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
/* Creates and returns a clone of OLD. The caller is responsible for freeing
the new multiple response set (using mrset_destroy()). */
struct mrset *
}
}
+/* Returns true if the UTF-8 encoded NAME is a valid name for a multiple
+ response set in a dictionary encoded in DICT_ENCODING, false otherwise. If
+ ISSUE_ERROR is true, issues an explanatory error message on failure. */
+bool
+mrset_is_valid_name (const char *name, const char *dict_encoding,
+ bool issue_error)
+{
+ if (!id_is_valid (name, dict_encoding, issue_error))
+ return false;
+
+ if (name[0] != '$')
+ {
+ if (issue_error)
+ msg (SE, _("%s is not a valid name for a multiple response "
+ "set. Multiple response set names must begin with "
+ "`$'."), name);
+ return false;
+ }
+
+ return true;
+}
+
/* Checks various constraints on MRSET:
- - MRSET has a valid name for a multiple response set (beginning with '$').
+ - MRSET's name begins with '$' and is valid as an identifier in DICT.
- MRSET has a valid type.
size_t i;
if (mrset->name == NULL
- || mrset->name[0] != '$'
+ || !mrset_is_valid_name (mrset->name, dict_get_encoding (dict), false)
|| (mrset->type != MRSET_MD && mrset->type != MRSET_MC)
|| mrset->vars == NULL
|| mrset->n_vars < 2)
return true;
}
+
+struct pxd_object *
+mrset_save (const struct mrset *mrset, struct pxd *pxd)
+{
+ struct pxd_builder b;
+ size_t i;
+
+ pxd_builder_init (&b, pxd);
+
+ pxd_builder_put_string (&b, mrset->name);
+ pxd_builder_put_string (&b, mrset->label != NULL ? mrset->label : "");
+ pxd_builder_put_u8 (&b, mrset->type);
+
+ pxd_builder_put_size_t (&b, mrset->n_vars);
+ for (i = 0; i < mrset->n_vars; i++)
+ pxd_builder_put_string (&b, var_get_name (mrset->vars[i]));
+
+ if (mrset->type == MRSET_MD)
+ {
+ pxd_builder_put_u8 (&b, mrset->cat_source);
+ pxd_builder_put_bool (&b, mrset->label_from_var_label);
+ pxd_builder_put_u16 (&b, mrset->width);
+ pxd_builder_put_value (&b, &mrset->counted, mrset->width);
+ }
+
+ return pxd_builder_commit (&b);
+}
+
+struct mrset *
+mrset_load (struct pxd_object *object, const struct pxd *pxd,
+ const struct dictionary *dict)
+{
+ struct pxd_parser p;
+ struct mrset *mrset;
+ size_t i;
+
+ mrset = xzalloc (sizeof *mrset);
+
+ pxd_parser_init (&p, object, pxd);
+
+ mrset->name = pxd_parser_get_string (&p);
+
+ mrset->label = pxd_parser_get_string (&p);
+ if (mrset->label[0] == '\0')
+ {
+ free (mrset->label);
+ mrset->label = NULL;
+ }
+
+ mrset->type = pxd_parser_get_u8 (&p);
+
+ mrset->n_vars = pxd_parser_get_size_t (&p);
+ mrset->vars = xmalloc (mrset->n_vars * sizeof *mrset->vars);
+ for (i = 0; i < mrset->n_vars; i++)
+ {
+ char *name = pxd_parser_get_string (&p);
+ mrset->vars[i] = dict_lookup_var_assert (dict, name);
+ free (name);
+ }
+
+ if (mrset->type == MRSET_MD)
+ {
+ mrset->cat_source = pxd_parser_get_u8 (&p);
+ mrset->label_from_var_label = pxd_parser_get_bool (&p);
+ mrset->width = pxd_parser_get_u16 (&p);
+ pxd_parser_get_value (&p, &mrset->counted, mrset->width);
+ }
+ else
+ value_init (&mrset->counted, 0);
+
+ return mrset;
+}