+ v->vardict = NULL;
+}
+\f
+struct pxd_object *
+var_save (const struct variable *var, struct pxd *pxd)
+{
+ struct pxd_builder b;
+ size_t i;
+
+ pxd_builder_init (&b, pxd);
+
+ pxd_builder_put_string (&b, var->name);
+ pxd_builder_put_u16 (&b, var->width);
+ pxd_builder_put_link (&b, mv_save (&var->miss, pxd));
+ pxd_builder_put_u32 (&b, fmt_to_uint (&var->print));
+ pxd_builder_put_u32 (&b, fmt_to_uint (&var->write));
+
+ if (var_has_value_labels (var))
+ {
+ pxd_builder_put_bool (&b, true);
+ pxd_builder_put_link (&b, val_labs_save (var->val_labs, pxd));
+ }
+ else
+ pxd_builder_put_bool (&b, false);
+
+ pxd_builder_put_string (&b, var->label != NULL ? var->label : "");
+
+ pxd_builder_put_u8 (&b, var->measure);
+ pxd_builder_put_u32 (&b, var->display_width);
+ pxd_builder_put_u8 (&b, var->alignment);
+
+ pxd_builder_put_bool (&b, var->leave);
+
+ pxd_builder_put_size_t (&b, var->short_name_cnt);
+ for (i = 0; i < var->short_name_cnt; i++)
+ pxd_builder_put_string (&b, var->short_names[i]);
+
+ pxd_builder_put_link (&b, attrset_save (&var->attributes, pxd));
+
+ return pxd_builder_commit (&b);
+}
+
+struct variable *
+var_load (struct pxd_object *object, const struct pxd *pxd)
+{
+ struct fmt_spec print, write;
+ struct missing_values mv;
+ struct variable *var;
+ struct pxd_parser p;
+ char *label;
+ char *name;
+ int width;
+ size_t i;
+
+#if 0
+ cached_var = pxd_cache_search (&var_cache, pxd_object_id (object));
+ if (cached_var != NULL)
+ {
+ size_t n;
+
+ var = var_clone (cached_var);
+
+ /* var_clone() doesn't copy short names, so we need to. */
+ n = cached_var->short_name_cnt;
+ if (n > 0)
+ {
+ size_t i;
+
+ var->short_name_cnt = n;
+ var->short_names = xmalloc (n * sizeof *var->short_names);
+ for (i = 0; i < n; i++)
+ var->short_names[i] = xstrdup (cached_var->short_names[i]);
+ }
+
+ return var;
+ }
+#endif
+
+ pxd_parser_init (&p, object, pxd);
+
+ name = pxd_parser_get_string (&p);
+ width = pxd_parser_get_u16 (&p);
+ var = var_create (name, width);
+
+ mv_load (&mv, pxd_parser_get_link (&p), pxd);
+ var_set_missing_values (var, &mv);
+ mv_destroy (&mv);
+
+ fmt_from_uint (&print, pxd_parser_get_u32 (&p));
+ var_set_print_format (var, &print);
+
+ fmt_from_uint (&write, pxd_parser_get_u32 (&p));
+ var_set_write_format (var, &write);
+
+ if (pxd_parser_get_bool (&p))
+ var->val_labs = val_labs_load (pxd_parser_get_link (&p), pxd);
+
+ label = pxd_parser_get_string (&p);
+ if (label[0])
+ var_set_label (var, label);
+ free (label);
+
+ var->measure = pxd_parser_get_u8 (&p);
+ var->display_width = pxd_parser_get_u32 (&p);
+ var->alignment = pxd_parser_get_u8 (&p);
+
+ var->leave = pxd_parser_get_bool (&p);
+
+ var->short_name_cnt = pxd_parser_get_size_t (&p);
+ var->short_names = xmalloc (var->short_name_cnt * sizeof *var->short_names);
+ for (i = 0; i < var->short_name_cnt; i++)
+ var->short_names[i] = pxd_parser_get_string (&p);
+
+ attrset_load (&var->attributes, pxd_parser_get_link (&p), pxd);
+
+ pxd_parser_destroy (&p);
+
+ return var;
+}
+
+static void
+var_uncache (struct variable *var UNUSED)
+{