? opaque-var.patch
? src/cscope.files
? src/cscope.in.out
? src/cscope.out
? src/cscope.po.out
Index: src/data/ChangeLog
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/ChangeLog,v
retrieving revision 1.77
diff -u -p -r1.77 ChangeLog
--- src/data/ChangeLog	5 Dec 2006 05:39:29 -0000	1.77
+++ src/data/ChangeLog	5 Dec 2006 06:36:31 -0000
@@ -1,3 +1,59 @@
+Mon Dec  4 22:20:17 2006  Ben Pfaff  <blp@gnu.org>
+
+	Start converting struct variable to an opaque.  In this phase, we
+	add a bunch of setter and getter functions and convert most of the
+	PSPP code to use them.  The resulting changes are pervasive but
+	mostly trivial, and only the notable changes are logged.
+	
+	* format.c (fmt_equal): New function.
+	
+	* variable.c (var_type_is_valid): New function.
+	(measure_is_valid) Moved here, from format.c.
+	(alignment_is_valid) Moved here, from format.c.
+	(var_get_name) New function.
+	(var_set_name) New function.
+	(width_to_type) New function.
+	(var_get_type) New function.
+	(var_get_width) New function.
+	(var_set_width) New function.
+	(var_is_numeric) New function.
+	(var_is_alpha) New function.
+	(var_is_short_string) New function.
+	(var_is_long_string) New function.
+	(var_is_very_long_string) New function.
+	(var_get_missing_values) New function.
+	(var_set_missing_values) New function.
+	(var_clear_missing_values) New function.
+	(var_has_missing_values) New function.
+	(var_is_value_missing) New function.
+	(var_is_num_missing) New function.
+	(var_is_str_missing) New function.
+	(var_is_value_user_missing) New function.
+	(var_is_num_user_missing) New function.
+	(var_is_str_user_missing) New function.
+	(var_is_value_system_missing) New function.
+	(var_get_print_format) New function.
+	(var_set_print_format) New function.
+	(var_get_write_format) New function.
+	(var_set_write_format) New function.
+	(var_set_both_formats) New function.
+	(var_get_label) New function.
+	(var_set_label) New function.
+	(var_clear_label) New function.
+	(var_has_label) New function.
+	(var_get_measure) New function.
+	(var_set_measure) New function.
+	(var_get_display_width) New function.
+	(var_set_display_width) New function.
+	(var_get_alignment) New function.
+	(var_set_alignment) New function.
+	(var_get_value_cnt) New function.
+	(var_get_leave) New function.
+	(var_get_short_name) New function.
+
+	* variable.h: (struct variable) Removed "type" and "nv" members;
+	they are now computed from "width" where needed.
+
 Mon Dec  4 21:38:40 2006  Ben Pfaff  <blp@gnu.org>
 
 	* missing-values.c (mv_resize): Don't write beyond end of the
Index: src/data/case.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/case.c,v
retrieving revision 1.6
diff -u -p -r1.6 case.c
--- src/data/case.c	14 Oct 2006 00:25:20 -0000	1.6
+++ src/data/case.c	5 Dec 2006 06:36:32 -0000
@@ -338,10 +338,9 @@ case_compare_2dict (const struct ccase *
       const struct variable *va = *vap;
       const struct variable *vb = *vbp;
 
-      assert (va->type == vb->type);
-      assert (va->width == vb->width);
+      assert (var_get_width (va) == var_get_width (vb));
       
-      if (va->width == 0) 
+      if (var_get_width (va) == 0) 
         {
           double af = case_num (ca, va->fv);
           double bf = case_num (cb, vb->fv);
@@ -353,7 +352,7 @@ case_compare_2dict (const struct ccase *
         {
           const char *as = case_str (ca, va->fv);
           const char *bs = case_str (cb, vb->fv);
-          int cmp = memcmp (as, bs, va->width);
+          int cmp = memcmp (as, bs, var_get_width (va));
 
           if (cmp != 0)
             return cmp;
Index: src/data/casefilter.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/casefilter.c,v
retrieving revision 1.1
diff -u -p -r1.1 casefilter.c
--- src/data/casefilter.c	5 Nov 2006 00:35:43 -0000	1.1
+++ src/data/casefilter.c	5 Dec 2006 06:36:32 -0000
@@ -64,7 +64,7 @@ casefilter_variable_missing (const struc
     return true;
 
   if ( filter->exclude_user_missing && 
-       mv_is_value_user_missing (&var->miss, val) ) 
+       var_is_value_user_missing (var, val) ) 
     return true;
 
   return false;
Index: src/data/category.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/category.c,v
retrieving revision 1.4
diff -u -p -r1.4 category.c
--- src/data/category.c	8 Jul 2006 03:05:51 -0000	1.4
+++ src/data/category.c	5 Dec 2006 06:36:32 -0000
@@ -92,7 +92,7 @@ cat_value_find (const struct variable *v
     {
       candidate = v->obs_vals->vals + i;
       assert (candidate != NULL);
-      if (!compare_values (candidate, val, v->width))
+      if (!compare_values (candidate, val, var_get_width (v)))
 	{
 	  return i;
 	}
@@ -108,7 +108,7 @@ cat_value_update (struct variable *v, co
 {
   struct cat_vals *cv;
 
-  if (v->type == ALPHA)
+  if (var_is_alpha (v))
     {
       assert (val != NULL);
       assert (v != NULL);
Index: src/data/dictionary.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/dictionary.c,v
retrieving revision 1.19
diff -u -p -r1.19 dictionary.c
--- src/data/dictionary.c	25 Nov 2006 02:15:00 -0000	1.19
+++ src/data/dictionary.c	5 Dec 2006 06:36:33 -0000
@@ -99,8 +99,8 @@ dict_clone (const struct dictionary *s) 
   for (i = 0; i < s->var_cnt; i++) 
     {
       struct variable *sv = s->var[i];
-      struct variable *dv = dict_clone_var_assert (d, sv, sv->name);
-      var_set_short_name (dv, sv->short_name);
+      struct variable *dv = dict_clone_var_assert (d, sv, var_get_name (sv));
+      var_set_short_name (dv, var_get_short_name (sv));
     }
 
   d->next_value_idx = s->next_value_idx;
@@ -110,14 +110,14 @@ dict_clone (const struct dictionary *s) 
     {
       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, s->split[i]->name);
+        d->split[i] = dict_lookup_var_assert (d, var_get_name (s->split[i]));
     }
 
   if (s->weight != NULL) 
-    d->weight = dict_lookup_var_assert (d, s->weight->name);
+    d->weight = dict_lookup_var_assert (d, var_get_name (s->weight));
 
   if (s->filter != NULL) 
-    d->filter = dict_lookup_var_assert (d, s->filter->name);
+    d->filter = dict_lookup_var_assert (d, var_get_name (s->filter));
 
   d->case_limit = s->case_limit;
   dict_set_label (d, dict_get_label (s));
@@ -158,6 +158,7 @@ dict_clear (struct dictionary *d) 
       struct variable *v = d->var[i];
       var_clear_aux (v);
       val_labs_destroy (v->val_labs);
+      var_clear_label (v);
       free (v->label);
       free (v); 
     }
@@ -246,14 +247,20 @@ dict_get_vars (const struct dictionary *
   
   count = 0;
   for (i = 0; i < d->var_cnt; i++)
-    if (!(exclude_classes & (1u << dict_class_from_id (d->var[i]->name))))
-      count++;
-
+    {
+      enum dict_class class = dict_class_from_id (var_get_name (d->var[i]));
+      if (!(exclude_classes & (1u << class)))
+        count++;
+    }
+  
   *vars = xnmalloc (count, sizeof **vars);
   *cnt = 0;
-  for (i = 0; i < d->var_cnt; i++)
-    if (!(exclude_classes & (1u << dict_class_from_id (d->var[i]->name))))
-      (*vars)[(*cnt)++] = d->var[i];
+  for (i = 0; i < d->var_cnt; i++) 
+    {
+      enum dict_class class = dict_class_from_id (var_get_name (d->var[i]));
+      if (!(exclude_classes & (1u << class)))
+        (*vars)[(*cnt)++] = d->var[i]; 
+    }
   assert (*cnt == count);
 }
 
@@ -279,15 +286,13 @@ dict_create_var (struct dictionary *d, c
 
   /* Allocate and initialize variable. */
   v = xmalloc (sizeof *v);
-  str_copy_trunc (v->name, sizeof v->name, name);
-  v->type = width == 0 ? NUMERIC : ALPHA;
+  var_set_name (v, name);
   v->width = width;
   v->fv = d->next_value_idx;
-  v->nv = width == 0 ? 1 : DIV_RND_UP (width, MAX_SHORT_STRING);
-  v->leave = dict_class_from_id (v->name) == DC_SCRATCH;
+  v->leave = dict_class_from_id (var_get_name (v)) == DC_SCRATCH;
   v->index = d->var_cnt;
   mv_init (&v->miss, width);
-  if (v->type == NUMERIC)
+  if (var_is_numeric (v))
     {
       v->print = fmt_for_output (FMT_F, 8, 2);
       v->alignment = ALIGN_RIGHT;
@@ -296,13 +301,13 @@ dict_create_var (struct dictionary *d, c
     }
   else
     {
-      v->print = fmt_for_output (FMT_A, v->width, 0);
+      v->print = fmt_for_output (FMT_A, var_get_width (v), 0);
       v->alignment = ALIGN_LEFT;
       v->display_width = 8;
       v->measure = MEASURE_NOMINAL;
     }
   v->write = v->print;
-  v->val_labs = val_labs_create (v->width);
+  v->val_labs = val_labs_create (var_get_width (v));
   v->label = NULL;
   var_clear_short_name (v);
   v->aux = NULL;
@@ -319,7 +324,7 @@ dict_create_var (struct dictionary *d, c
   d->var_cnt++;
   hsh_force_insert (d->name_tab, v);
 
-  d->next_value_idx += v->nv;
+  d->next_value_idx += var_get_value_cnt (v);
 
   return v;
 }
@@ -352,7 +357,7 @@ dict_clone_var (struct dictionary *d, co
   assert (strlen (name) >= 1);
   assert (strlen (name) <= LONG_NAME_LEN);
 
-  nv = dict_create_var (d, name, ov->width);
+  nv = dict_create_var (d, name, var_get_width (ov));
   if (nv == NULL)
     return NULL;
 
@@ -360,17 +365,16 @@ dict_clone_var (struct dictionary *d, co
      short_name[] is intentionally not copied, because there is
      no reason to give a new variable with potentially a new name
      the same short name. */
-  nv->leave = ov->leave;
-  mv_copy (&nv->miss, &ov->miss);
-  nv->print = ov->print;
-  nv->write = ov->write;
+  nv->leave = var_get_leave (ov);
+  var_set_missing_values (nv, var_get_missing_values (ov));
+  var_set_print_format (nv, var_get_print_format (ov));
+  var_set_write_format (nv, var_get_write_format (ov));
   val_labs_destroy (nv->val_labs);
   nv->val_labs = val_labs_copy (ov->val_labs);
-  if (ov->label != NULL)
-    nv->label = xstrdup (ov->label);
-  nv->measure = ov->measure;
-  nv->display_width = ov->display_width;
-  nv->alignment = ov->alignment;
+  var_set_label (nv, var_get_label (ov));
+  var_set_measure (nv, var_get_measure (ov));
+  var_set_display_width (nv, var_get_display_width (ov));
+  var_set_alignment (nv, var_get_alignment (ov));
 
   return nv;
 }
@@ -511,7 +515,7 @@ dict_delete_scratch_vars (struct diction
   assert (d != NULL);
 
   for (i = 0; i < d->var_cnt; )
-    if (dict_class_from_id (d->var[i]->name) == DC_SCRATCH)
+    if (dict_class_from_id (var_get_name (d->var[i])) == DC_SCRATCH)
       dict_delete_var (d, d->var[i]);
     else
       i++;
@@ -587,11 +591,11 @@ dict_rename_var (struct dictionary *d, s
   assert (new_name != NULL);
   assert (var_is_plausible_name (new_name, false));
   assert (dict_contains_var (d, v));
-  assert (!compare_var_names (v->name, new_name, NULL)
+  assert (!compare_var_names (var_get_name (v), new_name, NULL)
           || dict_lookup_var (d, new_name) == NULL);
 
   hsh_force_delete (d->name_tab, v);
-  str_copy_trunc (v->name, sizeof v->name, new_name);
+  var_set_name (v, new_name);
   hsh_force_insert (d->name_tab, v);
 
   if (get_algorithm () == ENHANCED)
@@ -625,8 +629,8 @@ dict_rename_vars (struct dictionary *d,
       assert (d->var[vars[i]->index] == vars[i]);
       assert (var_is_plausible_name (new_names[i], false));
       hsh_force_delete (d->name_tab, vars[i]);
-      old_names[i] = xstrdup (vars[i]->name);
-      strcpy (vars[i]->name, new_names[i]);
+      old_names[i] = xstrdup (var_get_name (vars[i]));
+      var_set_name (vars[i], new_names[i]);
     }
 
   /* Add the renamed variables back into the name hash,
@@ -652,7 +656,7 @@ dict_rename_vars (struct dictionary *d,
           
           for (i = 0; i < count; i++)
             {
-              strcpy (vars[i]->name, old_names[i]);
+              var_set_name (vars[i], old_names[i]);
               hsh_force_insert (d->name_tab, vars[i]);
             }
 
@@ -703,7 +707,7 @@ dict_get_case_weight (const struct dicti
   else 
     {
       double w = case_num (c, d->weight->fv);
-      if (w < 0.0 || mv_is_num_missing (&d->weight->miss, w))
+      if (w < 0.0 || var_is_num_missing (d->weight, w))
         w = 0.0;
       if ( w == 0.0 && *warn_on_invalid ) {
 	  *warn_on_invalid = false;
@@ -722,7 +726,7 @@ dict_set_weight (struct dictionary *d, s
 {
   assert (d != NULL);
   assert (v == NULL || dict_contains_var (d, v));
-  assert (v == NULL || v->type == NUMERIC);
+  assert (v == NULL || var_is_numeric (v));
 
   d->weight = v;
 }
@@ -802,10 +806,10 @@ dict_compact_values (struct dictionary *
     {
       struct variable *v = d->var[i];
 
-      if (dict_class_from_id (v->name) != DC_SCRATCH) 
+      if (dict_class_from_id (var_get_name (v)) != DC_SCRATCH) 
         {
           v->fv = d->next_value_idx;
-          d->next_value_idx += v->nv;
+          d->next_value_idx += var_get_value_cnt (v);
           i++;
         }
       else
@@ -823,8 +827,8 @@ dict_get_compacted_value_cnt (const stru
 
   cnt = 0;
   for (i = 0; i < d->var_cnt; i++)
-    if (dict_class_from_id (d->var[i]->name) != DC_SCRATCH) 
-      cnt += d->var[i]->nv;
+    if (dict_class_from_id (var_get_name (d->var[i])) != DC_SCRATCH) 
+      cnt += var_get_value_cnt (d->var[i]);
   return cnt;
 }
 
@@ -845,10 +849,10 @@ dict_get_compacted_idx_to_fv (const stru
     {
       struct variable *v = d->var[i];
 
-      if (dict_class_from_id (v->name) != DC_SCRATCH) 
+      if (dict_class_from_id (var_get_name (v)) != DC_SCRATCH) 
         {
           idx_to_fv[i] = next_value_idx;
-          next_value_idx += v->nv;
+          next_value_idx += var_get_value_cnt (v);
         }
       else 
         idx_to_fv[i] = -1;
@@ -891,7 +895,7 @@ dict_compacting_would_change (const stru
       struct variable *v = dict_get_var (d, i);
       if (v->fv != case_idx)
         return true;
-      case_idx += v->nv;
+      case_idx += var_get_value_cnt (v);
     }
   return false;
 }
@@ -937,10 +941,10 @@ dict_make_compactor (const struct dictio
     {
       struct variable *v = d->var[i];
 
-      if (dict_class_from_id (v->name) == DC_SCRATCH)
+      if (dict_class_from_id (var_get_name (v)) == DC_SCRATCH)
         continue;
       if (map != NULL && map->src_idx + map->cnt == v->fv) 
-        map->cnt += v->nv;
+        map->cnt += var_get_value_cnt (v);
       else 
         {
           if (compactor->map_cnt == map_allocated)
@@ -949,9 +953,9 @@ dict_make_compactor (const struct dictio
           map = &compactor->maps[compactor->map_cnt++];
           map->src_idx = v->fv;
           map->dst_idx = value_idx;
-          map->cnt = v->nv;
+          map->cnt = var_get_value_cnt (v);
         }
-      value_idx += v->nv;
+      value_idx += var_get_value_cnt (v);
     }
 
   return compactor;
@@ -1198,9 +1202,10 @@ dict_assign_short_names (struct dictiona
   for (i = 0; i < d->var_cnt; i++)
     {
       struct variable *v = d->var[i];
-      if (strlen (v->name) <= SHORT_NAME_LEN)
-        var_set_short_name (v, v->name);
-      else if (dict_lookup_var (d, v->short_name) != NULL)
+      const char *short_name = var_get_short_name (v);
+      if (strlen (var_get_name (v)) <= SHORT_NAME_LEN)
+        var_set_short_name (v, var_get_name (v));
+      else if (short_name != NULL && dict_lookup_var (d, short_name) != NULL)
         var_clear_short_name (v);
     }
 
@@ -1211,7 +1216,8 @@ dict_assign_short_names (struct dictiona
   for (i = 0; i < d->var_cnt; i++)
     {
       struct variable *v = d->var[i];
-      if (v->short_name[0] && hsh_insert (short_names, v->short_name) != NULL)
+      const char *name = var_get_short_name (v);
+      if (name != NULL && hsh_insert (short_names, (char *) name) != NULL)
         var_clear_short_name (v);
     }
   
@@ -1219,16 +1225,23 @@ dict_assign_short_names (struct dictiona
   for (i = 0; i < d->var_cnt; i++)
     {
       struct variable *v = d->var[i];
-      if (v->short_name[0] == '\0') 
+      const char *name = var_get_short_name (v);
+      if (name == NULL) 
         {
-          int sfx;
-
-          /* Form initial short_name. */
-          var_set_short_name (v, v->name);
+          /* Form initial short_name from the variable name, then
+             try _A, _B, ... _AA, _AB, etc., if needed.*/
+          int trial = 0;
+          do
+            {
+              if (trial == 0)
+                var_set_short_name (v, var_get_name (v));
+              else
+                var_set_short_name_suffix (v, var_get_name (v), trial - 1);
 
-          /* Try _A, _B, ... _AA, _AB, etc., if needed. */
-          for (sfx = 0; hsh_insert (short_names, v->short_name) != NULL; sfx++)
-            var_set_short_name_suffix (v, v->name, sfx);
+              trial++;
+            }
+          while (hsh_insert (short_names, (char *) var_get_short_name (v))
+                 != NULL);
         } 
     }
 
Index: src/data/format.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/format.c,v
retrieving revision 1.14
diff -u -p -r1.14 format.c
--- src/data/format.c	22 Nov 2006 04:24:02 -0000	1.14
+++ src/data/format.c	5 Dec 2006 06:36:33 -0000
@@ -362,6 +362,14 @@ fmt_to_string (const struct fmt_spec *f,
               "%s%d", fmt_name (f->type), f->w);
   return buffer;
 }
+
+/* Returns true if A and B are identical formats,
+   false otherwise. */
+bool
+fmt_equal (const struct fmt_spec *a, const struct fmt_spec *b) 
+{
+  return a->type == b->type && a->w == b->w && a->d == b->d;
+}
 
 /* Describes a display format. */
 struct fmt_desc
@@ -899,22 +907,6 @@ fmt_set_decimal (char decimal)
   init_style (FMT_CCE, "", "", decimal, grouping);
 }
 
-/* Returns true if M is a valid variable measurement level,
-   false otherwise. */
-bool
-measure_is_valid (enum measure m)
-{
-  return m > 0 && m < n_MEASURES;
-}
-
-/* Returns true if A is a valid alignment,
-   false otherwise. */
-bool
-alignment_is_valid (enum alignment a)
-{
-  return a < n_ALIGN;
-}
-
 /* Returns the struct fmt_desc for the given format TYPE. */
 static const struct fmt_desc *
 get_fmt_desc (enum fmt_type type)
Index: src/data/format.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/format.h,v
retrieving revision 1.9
diff -u -p -r1.9 format.h
--- src/data/format.h	5 Nov 2006 05:20:53 -0000	1.9
+++ src/data/format.h	5 Dec 2006 06:36:33 -0000
@@ -76,17 +76,19 @@ void fmt_done (void);
 struct fmt_spec fmt_for_input (enum fmt_type, int w, int d) PURE_FUNCTION;
 struct fmt_spec fmt_for_output (enum fmt_type, int w, int d) PURE_FUNCTION;
 struct fmt_spec fmt_for_output_from_input (const struct fmt_spec *);
+struct fmt_spec fmt_default_for_width (int var_width);
 
 /* Verifying formats. */
 bool fmt_check (const struct fmt_spec *, bool for_input);
 bool fmt_check_input (const struct fmt_spec *);
 bool fmt_check_output (const struct fmt_spec *);
 bool fmt_check_type_compat (const struct fmt_spec *, int var_type);
-bool fmt_check_width_compat (const struct fmt_spec *, int width);
+bool fmt_check_width_compat (const struct fmt_spec *, int var_width);
 
 /* Working with formats. */
 int fmt_var_width (const struct fmt_spec *);
 char *fmt_to_string (const struct fmt_spec *, char s[FMT_STRING_LEN_MAX + 1]);
+bool fmt_equal (const struct fmt_spec *, const struct fmt_spec *);
 
 /* Format types. */
 const char *fmt_name (enum fmt_type) PURE_FUNCTION;
@@ -142,26 +144,5 @@ int fmt_decimal_char (enum fmt_type);
 int fmt_grouping_char (enum fmt_type);
 
 void fmt_set_decimal (char);
-
-/* Alignment of data for display. */
-enum alignment 
-  {
-    ALIGN_LEFT = 0,
-    ALIGN_RIGHT = 1,
-    ALIGN_CENTRE = 2, 
-    n_ALIGN
-  };
-
-/* How data is measured. */
-enum measure
-  {
-    MEASURE_NOMINAL=1,
-    MEASURE_ORDINAL=2,
-    MEASURE_SCALE=3,
-    n_MEASURES
-  };
-
-bool measure_is_valid(enum measure m);
-bool alignment_is_valid(enum alignment a);
 
 #endif /* format.h */
Index: src/data/missing-values.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/missing-values.c,v
retrieving revision 1.4
diff -u -p -r1.4 missing-values.c
--- src/data/missing-values.c	5 Dec 2006 05:39:29 -0000	1.4
+++ src/data/missing-values.c	5 Dec 2006 06:36:34 -0000
@@ -437,5 +437,5 @@ bool
 mv_is_value_system_missing (const struct missing_values *mv,
                             const union value *v)
 {
-  return mv->width == 0 ? v->f == SYSMIS : false;
+  return mv->width == 0 && v->f == SYSMIS;
 }
Index: src/data/missing-values.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/missing-values.h,v
retrieving revision 1.1
diff -u -p -r1.1 missing-values.h
--- src/data/missing-values.h	4 Mar 2006 01:11:57 -0000	1.1
+++ src/data/missing-values.h	5 Dec 2006 06:36:34 -0000
@@ -72,8 +72,8 @@ void mv_peek_range (const struct missing
 bool mv_is_resizable (struct missing_values *, int width);
 void mv_resize (struct missing_values *, int width);
 
-typedef bool is_missing_func (const struct missing_values *,
-                              const union value *);
+typedef bool mv_is_missing_func (const struct missing_values *,
+                                 const union value *);
 
 /* Is a value system or user missing? */
 bool mv_is_value_missing (const struct missing_values *, const union value *);
Index: src/data/por-file-reader.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/por-file-reader.c,v
retrieving revision 1.12
diff -u -p -r1.12 por-file-reader.c
--- src/data/por-file-reader.c	3 Nov 2006 04:53:51 -0000	1.12
+++ src/data/por-file-reader.c	5 Dec 2006 06:36:34 -0000
@@ -464,29 +464,34 @@ read_version_data (struct pfm_reader *r,
 /* Translates a format specification read from portable file R as
    the three integers INTS into a normal format specifier FORMAT,
    checking that the format is appropriate for variable V. */
-static void
+static struct fmt_spec
 convert_format (struct pfm_reader *r, const int portable_format[3],
-                struct fmt_spec *format, struct variable *v)
+                struct variable *v)
 {
+  struct fmt_spec format;
   bool ok;
 
-  if (!fmt_from_io (portable_format[0], &format->type))
+  if (!fmt_from_io (portable_format[0], &format.type))
     error (r, _("%s: Bad format specifier byte (%d)."),
-           v->name, portable_format[0]);
-  format->w = portable_format[1];
-  format->d = portable_format[2];
+           var_get_name (v), portable_format[0]);
+  format.w = portable_format[1];
+  format.d = portable_format[2];
 
   msg_disable ();
-  ok = fmt_check_output (format) && fmt_check_width_compat (format, v->width);
+  ok = (fmt_check_output (&format)
+        && fmt_check_width_compat (&format, var_get_width (v)));
   msg_enable ();
 
   if (!ok)
     {
       char fmt_string[FMT_STRING_LEN_MAX + 1];
       error (r, _("%s variable %s has invalid format specifier %s."),
-             v->type == NUMERIC ? _("Numeric") : _("String"),
-             v->name, fmt_to_string (format, fmt_string)); 
+             var_is_numeric (v) ? _("Numeric") : _("String"),
+             var_get_name (v), fmt_to_string (&format, fmt_string));
+      format = fmt_default_for_width (var_get_width (v));
     }
+
+  return format;
 }
 
 static union value parse_value (struct pfm_reader *, struct variable *);
@@ -522,6 +527,8 @@ read_variables (struct pfm_reader *r, st
       char name[256];
       int fmt[6];
       struct variable *v;
+      struct missing_values miss;
+      struct fmt_spec print, write;
       int j;
 
       if (!match (r, '7'))
@@ -547,33 +554,38 @@ read_variables (struct pfm_reader *r, st
       if (v == NULL)
 	error (r, _("Duplicate variable name %s."), name);
 
-      convert_format (r, &fmt[0], &v->print, v);
-      convert_format (r, &fmt[3], &v->write, v);
+      print = convert_format (r, &fmt[0], v);
+      write = convert_format (r, &fmt[3], v);
+      var_set_print_format (v, &print);
+      var_set_write_format (v, &write);
 
       /* Range missing values. */
+      mv_init (&miss, var_get_width (v));
       if (match (r, 'B')) 
         {
           double x = read_float (r);
           double y = read_float (r);
-          mv_add_num_range (&v->miss, x, y);
+          mv_add_num_range (&miss, x, y);
         }
       else if (match (r, 'A'))
-        mv_add_num_range (&v->miss, read_float (r), HIGHEST);
+        mv_add_num_range (&miss, read_float (r), HIGHEST);
       else if (match (r, '9'))
-        mv_add_num_range (&v->miss, LOWEST, read_float (r));
+        mv_add_num_range (&miss, LOWEST, read_float (r));
 
       /* Single missing values. */
       while (match (r, '8')) 
         {
           union value value = parse_value (r, v);
-          mv_add_value (&v->miss, &value); 
+          mv_add_value (&miss, &value); 
         }
 
+      var_set_missing_values (v, &miss);
+
       if (match (r, 'C')) 
         {
           char label[256];
           read_string (r, label);
-          v->label = xstrdup (label); 
+          var_set_label (v, label);
         }
     }
 
@@ -594,7 +606,7 @@ parse_value (struct pfm_reader *r, struc
 {
   union value v;
   
-  if (vv->type == ALPHA) 
+  if (var_is_alpha (vv)) 
     {
       char string[256];
       read_string (r, string);
@@ -630,10 +642,10 @@ read_value_label (struct pfm_reader *r, 
       if (v[i] == NULL)
 	error (r, _("Unknown variable %s while parsing value labels."), name);
 
-      if (v[0]->width != v[i]->width)
+      if (var_get_width (v[0]) != var_get_width (v[i]))
 	error (r, _("Cannot assign value labels to %s and %s, which "
 		    "have different variable types or widths."),
-	       v[0]->name, v[i]->name);
+	       var_get_name (v[0]), var_get_name (v[i]));
     }
 
   n_labels = read_int (r);
@@ -654,12 +666,12 @@ read_value_label (struct pfm_reader *r, 
 	  if (!val_labs_replace (var->val_labs, val, label))
 	    continue;
 
-	  if (var->type == NUMERIC)
+	  if (var_is_numeric (var))
 	    error (r, _("Duplicate label for value %g for variable %s."),
-		   val.f, var->name);
+		   val.f, var_get_name (var));
 	  else
 	    error (r, _("Duplicate label for value `%.*s' for variable %s."),
-		   var->width, val.s, var->name);
+		   var_get_width (var), val.s, var_get_name (var));
 	}
     }
 }
Index: src/data/por-file-writer.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/por-file-writer.c,v
retrieving revision 1.5
diff -u -p -r1.5 por-file-writer.c
--- src/data/por-file-writer.c	3 Nov 2006 04:53:51 -0000	1.5
+++ src/data/por-file-writer.c	5 Dec 2006 06:36:35 -0000
@@ -133,7 +133,7 @@ pfm_open_writer (struct file_handle *fh,
     {
       const struct variable *dv = dict_get_var (dict, i);
       struct pfm_var *pv = &w->vars[i];
-      pv->width = dv->width;
+      pv->width = var_get_width (dv);
       pv->fv = dv->fv;
     }
 
@@ -280,7 +280,7 @@ write_version_data (struct pfm_writer *w
 
 /* Write format F to file H. */
 static void
-write_format (struct pfm_writer *w, struct fmt_spec *f)
+write_format (struct pfm_writer *w, const struct fmt_spec *f)
 {
   write_int (w, fmt_to_io (f->type));
   write_int (w, f->w);
@@ -291,12 +291,12 @@ write_format (struct pfm_writer *w, stru
 static void
 write_value (struct pfm_writer *w, union value *v, struct variable *vv)
 {
-  if (vv->type == NUMERIC)
+  if (var_is_numeric (vv))
     write_float (w, v->f);
   else 
     {
-      write_int (w, vv->width);
-      buf_write (w, v->s, vv->width); 
+      write_int (w, var_get_width (vv));
+      buf_write (w, v->s, var_get_width (vv)); 
     }
 }
 
@@ -318,13 +318,13 @@ write_variables (struct pfm_writer *w, s
       struct missing_values mv;
       
       buf_write (w, "7", 1);
-      write_int (w, v->width);
-      write_string (w, v->short_name);
-      write_format (w, &v->print);
-      write_format (w, &v->write);
+      write_int (w, var_get_width (v));
+      write_string (w, var_get_short_name (v));
+      write_format (w, var_get_print_format (v));
+      write_format (w, var_get_write_format (v));
 
       /* Write missing values. */
-      mv_copy (&mv, &v->miss);
+      mv_copy (&mv, var_get_missing_values (v));
       while (mv_has_range (&mv))
         {
           double x, y;
@@ -354,10 +354,10 @@ write_variables (struct pfm_writer *w, s
           write_value (w, &value, v);
         }
 
-      if (v->label)
+      if (var_get_label (v) != NULL)
         { 
           buf_write (w, "C", 1);
-          write_string (w, v->label);
+          write_string (w, var_get_label (v));
         }
     }
 }
@@ -379,7 +379,7 @@ write_value_labels (struct pfm_writer *w
 
       buf_write (w, "D", 1);
       write_int (w, 1);
-      write_string (w, v->short_name);
+      write_string (w, var_get_short_name (v));
       write_int (w, val_labs_count (v->val_labs));
 
       for (vl = val_labs_first_sorted (v->val_labs, &j); vl != NULL;
Index: src/data/procedure.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/procedure.c,v
retrieving revision 1.15
diff -u -p -r1.15 procedure.c
--- src/data/procedure.c	26 Oct 2006 06:16:36 -0000	1.15
+++ src/data/procedure.c	5 Dec 2006 06:36:35 -0000
@@ -267,10 +267,10 @@ create_trns_case (struct ccase *trns_cas
       struct variable *v = dict_get_var (dict, i);
       union value *value = case_data_rw (trns_case, v->fv);
 
-      if (v->type == NUMERIC)
-        value->f = v->leave ? 0.0 : SYSMIS;
+      if (var_is_numeric (v))
+        value->f = var_get_leave (v) ? 0.0 : SYSMIS;
       else
-        memset (value->s, ' ', v->width);
+        memset (value->s, ' ', var_get_width (v));
     }
 }
 
@@ -395,12 +395,12 @@ clear_case (const struct dataset *ds, st
   for (i = 0; i < var_cnt; i++) 
     {
       struct variable *v = dict_get_var (ds->dict, i);
-      if (!v->leave) 
+      if (!var_get_leave (v)) 
         {
-          if (v->type == NUMERIC)
+          if (var_is_numeric (v))
             case_data_rw (c, v->fv)->f = SYSMIS;
           else
-            memset (case_data_rw (c, v->fv)->s, ' ', v->width);
+            memset (case_data_rw (c, v->fv)->s, ' ', var_get_width (v));
         } 
     }
 }
@@ -938,7 +938,7 @@ filter_trns_proc (void *filter_var_,
 {
   struct variable *filter_var = filter_var_;
   double f = case_num (c, filter_var->fv);
-  return (f != 0.0 && !mv_is_num_missing (&filter_var->miss, f)
+  return (f != 0.0 && !var_is_num_missing (filter_var, f)
           ? TRNS_CONTINUE : TRNS_DROP_CASE);
 }
 
Index: src/data/sys-file-reader.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/sys-file-reader.c,v
retrieving revision 1.26
diff -u -p -r1.26 sys-file-reader.c
--- src/data/sys-file-reader.c	25 Nov 2006 02:15:00 -0000	1.26
+++ src/data/sys-file-reader.c	5 Dec 2006 06:36:36 -0000
@@ -346,7 +346,7 @@ sfm_open_reader (struct file_handle *fh,
 	lose ((ME,
                _("%s: Weighting variable may not be a continuation of "
 		 "a long string variable."), fh_get_file_name (fh)));
-      else if (weight_var->type == ALPHA)
+      else if (var_is_alpha (weight_var))
 	lose ((ME, _("%s: Weighting variable may not be a string variable."),
 	       fh_get_file_name (fh)));
 
@@ -465,9 +465,9 @@ sfm_open_reader (struct file_handle *fh,
 
 		      v = dict_get_var(*dict, i);
 
-		      v->measure = params.measure;
-		      v->display_width = params.width;
-		      v->alignment = params.align;
+		      var_set_measure (v, params.measure);
+		      var_set_display_width (v, params.width);
+		      var_set_alignment (v, params.align);
 		    }
 		}
 		break;
@@ -630,10 +630,10 @@ sfm_open_reader (struct file_handle *fh,
 				}
 
 			      l = length;
-			      if ( v->width > EFFECTIVE_LONG_STRING_LENGTH ) 
+			      if ( var_get_width (v) > EFFECTIVE_LONG_STRING_LENGTH ) 
 				l -= EFFECTIVE_LONG_STRING_LENGTH;
 			      else
-				l -= v->width;
+				l -= var_get_width (v);
 
 			      idx = v->index;
 			      while ( l > 0 ) 
@@ -641,20 +641,17 @@ sfm_open_reader (struct file_handle *fh,
 				  struct variable *v_next;
 				  v_next = dict_get_var(*dict, idx + 1);
 
-				  if ( v_next->width > EFFECTIVE_LONG_STRING_LENGTH ) 
+				  if ( var_get_width (v_next) > EFFECTIVE_LONG_STRING_LENGTH ) 
 				    l -= EFFECTIVE_LONG_STRING_LENGTH;
 				  else
-				    l -= v_next->width;
+				    l -= var_get_width (v_next);
 
 				  dict_delete_var(*dict, v_next);
 				}
 
 			      assert ( length > MAX_LONG_STRING );
 
-			      v->width = length;
-			      v->print.w = v->width;
-			      v->write.w = v->width;
-			      v->nv = DIV_RND_UP (length, MAX_SHORT_STRING);
+                              var_set_width (v, length);
 			    }
 			  eq_seen = false;
 			  memset(name, 0, SHORT_NAME_LEN+1); 
@@ -725,7 +722,7 @@ sfm_open_reader (struct file_handle *fh,
       {
         struct variable *v = dict_get_var (*dict, i);
         struct sfm_var *sv = &r->vars[i];
-        sv->width = v->width;
+        sv->width = var_get_width (v);
         sv->fv = v->fv; 
       }
   }
@@ -1015,6 +1012,8 @@ read_variables (struct sfm_reader *r,
       char name[SHORT_NAME_LEN + 1];
       int nv;
       int j;
+      struct fmt_spec print, write;
+
 
       assertive_buf_read (r, &sv, sizeof sv, 0);
 
@@ -1101,7 +1100,7 @@ read_variables (struct sfm_reader *r,
                fh_get_file_name (r->fh), name));
 
       /* Set the short name the same as the long name */
-      var_set_short_name (vv, vv->name);
+      var_set_short_name (vv, var_get_name (vv));
 
       /* Case reading data. */
       nv = sv.type == 0 ? 1 : DIV_RND_UP (sv.type, sizeof (flt64));
@@ -1123,15 +1122,16 @@ read_variables (struct sfm_reader *r,
 	  if (len < 0 || len > 255)
 	    lose ((ME, _("%s: Variable %s indicates variable label of invalid "
                          "length %d."),
-                   fh_get_file_name (r->fh), vv->name, len));
+                   fh_get_file_name (r->fh), var_get_name (vv), len));
 
 	  if ( len != 0 ) 
 	    {
 	      /* Read label into variable structure. */
-	      vv->label = buf_read (r, NULL, ROUND_UP (len, sizeof (int32_t)), len + 1);
-	      if (vv->label == NULL)
-		goto error;
-	      vv->label[len] = '\0';
+	      char label[256];
+              assertive_buf_read (r, label, ROUND_UP (len, sizeof (int32_t)),
+                                  0);
+	      label[len] = '\0';
+              var_set_label (vv, label);
 	    }
 	}
 
@@ -1140,48 +1140,54 @@ read_variables (struct sfm_reader *r,
 	{
 	  flt64 mv[3];
           int mv_cnt = abs (sv.n_missing_values);
+          struct missing_values miss;
 
-	  if (vv->width > MAX_SHORT_STRING)
+	  if (var_get_width (vv) > MAX_SHORT_STRING)
 	    lose ((ME, _("%s: Long string variable %s may not have missing "
                          "values."),
-                   fh_get_file_name (r->fh), vv->name));
+                   fh_get_file_name (r->fh), var_get_name (vv)));
+          mv_init (&miss, var_get_width (vv));
 
 	  assertive_buf_read (r, mv, sizeof *mv * mv_cnt, 0);
 
-	  if (r->reverse_endian && vv->type == NUMERIC)
+	  if (r->reverse_endian && var_is_numeric (vv))
 	    for (j = 0; j < mv_cnt; j++)
 	      bswap_flt64 (&mv[j]);
 
 	  if (sv.n_missing_values > 0)
 	    {
               for (j = 0; j < sv.n_missing_values; j++)
-                if (vv->type == NUMERIC)
-                  mv_add_num (&vv->miss, mv[j]);
+                if (var_is_numeric (vv))
+                  mv_add_num (&miss, mv[j]);
                 else
-                  mv_add_str (&vv->miss, (char *) &mv[j]);
+                  mv_add_str (&miss, (char *) &mv[j]);
 	    }
 	  else
 	    {
-	      if (vv->type == ALPHA)
+	      if (var_is_alpha (vv))
 		lose ((ME, _("%s: String variable %s may not have missing "
                              "values specified as a range."),
-                       fh_get_file_name (r->fh), vv->name));
+                       fh_get_file_name (r->fh), var_get_name (vv)));
 
 	      if (mv[0] == r->lowest)
-                mv_add_num_range (&vv->miss, LOWEST, mv[1]);
+                mv_add_num_range (&miss, LOWEST, mv[1]);
 	      else if (mv[1] == r->highest)
-                mv_add_num_range (&vv->miss, mv[0], HIGHEST);
+                mv_add_num_range (&miss, mv[0], HIGHEST);
 	      else
-                mv_add_num_range (&vv->miss, mv[0], mv[1]);
+                mv_add_num_range (&miss, mv[0], mv[1]);
 
 	      if (sv.n_missing_values == -3)
-                mv_add_num (&vv->miss, mv[2]);
+                mv_add_num (&miss, mv[2]);
 	    }
+          var_set_missing_values (vv, &miss);
 	}
 
-      if (!parse_format_spec (r, sv.print, &vv->print, vv)
-	  || !parse_format_spec (r, sv.write, &vv->write, vv))
+      if (!parse_format_spec (r, sv.print, &print, vv)
+	  || !parse_format_spec (r, sv.write, &write, vv))
 	goto error;
+
+      var_set_print_format (vv, &print);
+      var_set_write_format (vv, &write);
     }
 
   /* Some consistency checks. */
@@ -1216,27 +1222,27 @@ parse_format_spec (struct sfm_reader *r,
   f->w = (s >> 8) & 0xff;
   f->d = s & 0xff;
 
-  if ((v->type == ALPHA) ^ (fmt_is_string (f->type) != 0))
+  if (var_is_alpha (v) != fmt_is_string (f->type))
     lose ((ME, _("%s: %s variable %s has %s format specifier %s."),
 	   fh_get_file_name (r->fh),
-           v->type == ALPHA ? _("String") : _("Numeric"),
-	   v->name,
+           var_is_alpha (v) ? _("String") : _("Numeric"),
+	   var_get_name (v),
 	   fmt_is_string (f->type) ? _("string") : _("numeric"),
 	   fmt_name (f->type)));
 
   msg_disable ();
-  ok = fmt_check_output (f) && fmt_check_width_compat (f, v->width);
+  ok = fmt_check_output (f) && fmt_check_width_compat (f, var_get_width (v)); 
   msg_enable ();
   
   if (!ok) 
     {
       char fmt_string[FMT_STRING_LEN_MAX + 1];
       msg (ME, _("%s variable %s has invalid format specifier %s."),
-           v->type == NUMERIC ? _("Numeric") : _("String"),
-           v->name, fmt_to_string (f, fmt_string));
-      *f = (v->type == NUMERIC
+           var_is_numeric (v) ? _("Numeric") : _("String"),
+           var_get_name (v), fmt_to_string (f, fmt_string));
+      *f = (var_is_numeric (v)
             ? fmt_for_output (FMT_F, 8, 2) 
-            : fmt_for_output (FMT_A, v->width, 0));
+            : fmt_for_output (FMT_A, var_get_width (v), 0));
     }
   return 1;
 
@@ -1356,10 +1362,10 @@ read_value_labels (struct sfm_reader *r,
                      "refers to a continuation of a string variable, not to "
                      "an actual variable."),
                fh_get_file_name (r->fh), var_idx));
-      if (v->type == ALPHA && v->width > MAX_SHORT_STRING)
+      if (var_is_long_string (v))
 	lose ((ME, _("%s: Value labels are not allowed on long string "
                      "variables (%s)."),
-               fh_get_file_name (r->fh), v->name));
+               fh_get_file_name (r->fh), var_get_name (v)));
 
       /* Add it to the list of variables. */
       var[i] = v;
@@ -1367,20 +1373,22 @@ read_value_labels (struct sfm_reader *r,
 
   /* Type check the variables. */
   for (i = 1; i < n_vars; i++)
-    if (var[i]->type != var[0]->type)
+    if (var_get_type (var[i]) != var_get_type (var[0]))
       lose ((ME, _("%s: Variables associated with value label are not all of "
                    "identical type.  Variable %s has %s type, but variable "
                    "%s has %s type."),
              fh_get_file_name (r->fh),
-	     var[0]->name, var[0]->type == ALPHA ? _("string") : _("numeric"),
-	     var[i]->name, var[i]->type == ALPHA ? _("string") : _("numeric")));
+	     var_get_name (var[0]),
+             var_is_alpha (var[0]) ? _("string") : _("numeric"),
+	     var_get_name (var[i]),
+             var_is_alpha (var[i]) ? _("string") : _("numeric")));
 
   /* Fill in labels[].value, now that we know the desired type. */
   for (i = 0; i < n_labels; i++) 
     {
       struct label *label = labels + i;
       
-      if (var[0]->type == ALPHA)
+      if (var_is_alpha (var[0]))
         {
           const int copy_len = MIN (sizeof label->raw_value,
                                     sizeof label->label);
@@ -1408,14 +1416,15 @@ read_value_labels (struct sfm_reader *r,
 	  if (!val_labs_replace (v->val_labs, label->value, label->label))
 	    continue;
 
-	  if (var[0]->type == NUMERIC)
+	  if (var_is_numeric (var[0]))
 	    msg (MW, _("%s: File contains duplicate label for value %g for "
                        "variable %s."),
-                 fh_get_file_name (r->fh), label->value.f, v->name);
+                 fh_get_file_name (r->fh), label->value.f, var_get_name (v));
 	  else
 	    msg (MW, _("%s: File contains duplicate label for value `%.*s' "
                        "for variable %s."),
-                 fh_get_file_name (r->fh), v->width, label->value.s, v->name);
+                 fh_get_file_name (r->fh), var_get_width (v),
+                 label->value.s, var_get_name (v));
 	}
     }
 
Index: src/data/sys-file-writer.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/sys-file-writer.c,v
retrieving revision 1.16
diff -u -p -r1.16 sys-file-writer.c
--- src/data/sys-file-writer.c	25 Nov 2006 02:15:00 -0000	1.16
+++ src/data/sys-file-writer.c	5 Dec 2006 06:36:38 -0000
@@ -114,13 +114,14 @@ static inline int
 var_flt64_cnt (const struct variable *v) 
 {
   assert(sizeof(flt64) == MAX_SHORT_STRING);
-  return width_to_bytes(v->width) / MAX_SHORT_STRING ;
+  return width_to_bytes(var_get_width (v)) / MAX_SHORT_STRING ;
 }
 
 static inline int
 var_flt64_cnt_nom (const struct variable *v) 
 {
-  return v->type == NUMERIC ? 1 : DIV_RND_UP (v->width, sizeof (flt64));
+  return (var_is_numeric (v)
+          ? 1 : DIV_RND_UP (var_get_width (v), sizeof (flt64)));
 }
 
 
@@ -215,9 +216,9 @@ sfm_open_writer (struct file_handle *fh,
     {
       const struct variable *dv = dict_get_var (d, i);
       struct sfm_var *sv = &w->vars[i];
-      sv->width = dv->width;
+      sv->width = var_get_width (dv);
       /* spss compatibility nonsense */
-      if ( dv->width > MAX_LONG_STRING ) 
+      if ( var_is_very_long_string (dv) ) 
 	  w->has_vls = true;
 
       sv->fv = dv->fv;
@@ -240,34 +241,32 @@ sfm_open_writer (struct file_handle *fh,
     {
       int count = 0;
       const struct variable *v = dict_get_var(d, i);
-      int wcount = v->width;
+      int wcount = var_get_width (v);
 
       do {
 	struct variable var_cont = *v;
-	if ( v->type == ALPHA) 
+	if ( var_is_alpha (v)) 
 	  {
 	    if ( 0 != count ) 
 	      {
-		mv_init(&var_cont.miss, 0);
-		strcpy(var_cont.short_name,
-		       cont_var_name(v->short_name, count));
-		var_cont.label = NULL;
+		var_clear_missing_values (&var_cont);
+                var_set_short_name (&var_cont,
+                                    cont_var_name (var_get_short_name (v),
+                                                   count));
+                var_clear_label (&var_cont);
 		w->var_cnt_vls++;
 	      }
 	    count++;
 	    if ( wcount > MAX_LONG_STRING ) 
 	      {
-		var_cont.width = MAX_LONG_STRING;
+                var_set_width (&var_cont, MAX_LONG_STRING);
 		wcount -= EFFECTIVE_LONG_STRING_LENGTH;
 	      }
 	    else
 	      {
-		var_cont.width = wcount;
-		wcount -= var_cont.width;
+		var_set_width (&var_cont, wcount);
+		wcount -= var_get_width (&var_cont);
 	      }
-	
-	    var_cont.write.w = var_cont.width;
-	    var_cont.print.w = var_cont.width;
 	  }
 
 	write_variable (w, &var_cont);
@@ -456,12 +455,13 @@ write_variable (struct sfm_writer *w, co
   struct missing_values mv;
   flt64 m[3];           /* Missing value values. */
   int nm;               /* Number of missing values, possibly negative. */
+  const char *label = var_get_label (v);
 
   sv.rec_type = 2;
-  sv.type = MIN(v->width, MAX_LONG_STRING);
-  sv.has_var_label = (v->label != NULL);
+  sv.type = MIN(var_get_width (v), MAX_LONG_STRING);
+  sv.has_var_label = label != NULL;
 
-  mv_copy (&mv, &v->miss);
+  mv_copy (&mv, var_get_missing_values (v));
   nm = 0;
   if (mv_has_range (&mv)) 
     {
@@ -474,22 +474,23 @@ write_variable (struct sfm_writer *w, co
     {
       union value value;
       mv_pop_value (&mv, &value);
-      if (v->type == NUMERIC)
+      if (var_is_numeric (v))
         m[nm] = value.f;
       else
-        buf_copy_rpad ((char *) &m[nm], sizeof m[nm], value.s, v->width);
+        buf_copy_rpad ((char *) &m[nm], sizeof m[nm], value.s,
+                       var_get_width (v));
       nm++;
     }
-  if (mv_has_range (&v->miss))
+  if (mv_has_range (var_get_missing_values (v)))
     nm = -nm;
 
   sv.n_missing_values = nm;
-  write_format_spec (&v->print, &sv.print);
-  write_format_spec (&v->write, &sv.write);
-  buf_copy_str_rpad (sv.name, sizeof sv.name, v->short_name);
+  write_format_spec (var_get_print_format (v), &sv.print);
+  write_format_spec (var_get_write_format (v), &sv.write);
+  buf_copy_str_rpad (sv.name, sizeof sv.name, var_get_short_name (v));
   buf_write (w, &sv, sizeof sv);
 
-  if (v->label)
+  if (label != NULL)
     {
       struct label
 	{
@@ -500,9 +501,9 @@ write_variable (struct sfm_writer *w, co
 
       int ext_len;
 
-      l.label_len = MIN (strlen (v->label), 255);
+      l.label_len = MIN (strlen (label), 255);
       ext_len = ROUND_UP (l.label_len, sizeof l.label_len);
-      memcpy (l.label, v->label, l.label_len);
+      memcpy (l.label, label, l.label_len);
       memset (&l.label[l.label_len], ' ', ext_len - l.label_len);
 
       buf_write (w, &l, offsetof (struct label, label) + ext_len);
@@ -511,7 +512,7 @@ write_variable (struct sfm_writer *w, co
   if (nm)
     buf_write (w, m, sizeof *m * abs (nm));
 
-  if (v->type == ALPHA && v->width > (int) sizeof (flt64))
+  if (var_is_alpha (v) && var_get_width (v) > (int) sizeof (flt64))
     {
       int i;
       int pad_count;
@@ -523,7 +524,7 @@ write_variable (struct sfm_writer *w, co
       memset (&sv.write, 0, sizeof sv.write);
       memset (&sv.name, 0, sizeof sv.name);
 
-      pad_count = DIV_RND_UP (MIN(v->width, MAX_LONG_STRING),
+      pad_count = DIV_RND_UP (MIN(var_get_width (v), MAX_LONG_STRING),
 			      (int) sizeof (flt64)) - 1;
       for (i = 0; i < pad_count; i++)
 	buf_write (w, &sv, sizeof sv);
@@ -649,15 +650,15 @@ write_variable_display_parameters (struc
 
       v = dict_get_var(dict, i);
 
-      params.measure = v->measure;
-      params.width = v->display_width;
-      params.align = v->alignment;
+      params.measure = var_get_measure (v);
+      params.width = var_get_display_width (v);
+      params.align = var_get_alignment (v);
       
       buf_write (w, &params, sizeof(params));
 
-      if ( v->width > MAX_LONG_STRING ) 
+      if (var_is_long_string (v))
 	{
-	  int wcount = v->width - EFFECTIVE_LONG_STRING_LENGTH ;
+	  int wcount = var_get_width (v) - EFFECTIVE_LONG_STRING_LENGTH ;
 
 	  while (wcount > 0) 
 	    {
@@ -698,10 +699,11 @@ write_vls_length_table (struct sfm_write
     {
       const struct variable *v = dict_get_var (dict, i);
       
-      if ( v->width <=  MAX_LONG_STRING ) 
+      if ( var_get_width (v) <=  MAX_LONG_STRING ) 
 	continue;
 
-      ds_put_format (&vls_length_map, "%s=%05d", v->short_name, v->width);
+      ds_put_format (&vls_length_map, "%s=%05d",
+                     var_get_short_name (v), var_get_width (v));
       ds_put_char (&vls_length_map, '\0');
       ds_put_char (&vls_length_map, '\t');
     }
@@ -739,7 +741,8 @@ write_longvar_table (struct sfm_writer *
       
       if (i)
         ds_put_char (&long_name_map, '\t');
-      ds_put_format (&long_name_map, "%s=%s", v->short_name, v->name);
+      ds_put_format (&long_name_map, "%s=%s",
+                     var_get_short_name (v), var_get_name (v));
     }
 
   lv_hdr.rec_type = 7;
Index: src/data/value-labels.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/value-labels.c,v
retrieving revision 1.9
diff -u -p -r1.9 value-labels.c
--- src/data/value-labels.c	5 Nov 2006 05:20:53 -0000	1.9
+++ src/data/value-labels.c	5 Dec 2006 06:36:38 -0000
@@ -546,8 +546,9 @@ value_to_string (const union value *val,
   if (s == NULL) 
     {
       static char buf[MAX_STRING + 1];
-      data_out (val, &var->print, buf);
-      buf[var->print.w] = '\0';
+      const struct fmt_spec *print = var_get_print_format (var);
+      data_out (val, print, buf);
+      buf[print->w] = '\0';
       s = buf;
     }
   
Index: src/data/variable.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/variable.c,v
retrieving revision 1.13
diff -u -p -r1.13 variable.c
--- src/data/variable.c	3 Dec 2006 22:16:45 -0000	1.13
+++ src/data/variable.c	5 Dec 2006 06:36:38 -0000
@@ -36,6 +36,13 @@
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
+/* Returns true if VAR_TYPE is a valid variable type. */
+bool
+var_type_is_valid (enum var_type var_type) 
+{
+  return var_type == NUMERIC || var_type == ALPHA;
+}
+
 /* Returns an adjective describing the given variable TYPE,
    suitable for use in phrases like "numeric variable". */
 const char *
@@ -51,7 +58,23 @@ var_type_noun (enum var_type type) 
 {
   return type == NUMERIC ? _("number") : _("string");
 }
+
+/* Returns true if M is a valid variable measurement level,
+   false otherwise. */
+bool
+measure_is_valid (enum measure m)
+{
+  return m == MEASURE_NOMINAL || m == MEASURE_ORDINAL || m == MEASURE_SCALE;
+}
 
+/* Returns true if A is a valid alignment,
+   false otherwise. */
+bool
+alignment_is_valid (enum alignment a)
+{
+  return a == ALIGN_LEFT || a == ALIGN_RIGHT || a == ALIGN_CENTRE;
+}
+
 /* Assign auxiliary data AUX to variable V, which must not
    already have auxiliary data.  Before V's auxiliary data is
    cleared, AUX_DTOR(V) will be called. */
@@ -124,10 +147,24 @@ hash_value(const union value  *v, int wi
 
   return id_hash;
 }
+
+/* Return variable V's name. */
+const char *
+var_get_name (const struct variable *v) 
+{
+  return v->name;
+}
 
+/* Sets V's name to NAME. */
+void
+var_set_name (struct variable *v, const char *name) 
+{
+  assert (name[0] != '\0');
+  assert (lex_id_to_token (ss_cstr (name)) == T_ID);
 
+  str_copy_trunc (v->name, sizeof v->name, name);
+}
 
-
 /* Returns true if NAME is an acceptable name for a variable,
    false otherwise.  If ISSUE_ERROR is true, issues an
    explanatory error message on failure. */
@@ -223,7 +260,7 @@ compare_var_names (const void *a_, const
   const struct variable *a = a_;
   const struct variable *b = b_;
 
-  return strcasecmp (a->name, b->name);
+  return strcasecmp (var_get_name (a), var_get_name (b));
 }
 
 /* A hsh_hash_func that hashes variable V based on its name. */
@@ -232,7 +269,7 @@ hash_var_name (const void *v_, const voi
 {
   const struct variable *v = v_;
 
-  return hsh_hash_case_string (v->name);
+  return hsh_hash_case_string (var_get_name (v));
 }
 
 /* A hsh_compare_func that orders pointers to variables A and B
@@ -243,7 +280,7 @@ compare_var_ptr_names (const void *a_, c
   struct variable *const *a = a_;
   struct variable *const *b = b_;
 
-  return strcasecmp ((*a)->name, (*b)->name);
+  return strcasecmp (var_get_name (*a), var_get_name (*b));
 }
 
 /* A hsh_hash_func that hashes pointer to variable V based on its
@@ -253,20 +290,383 @@ hash_var_ptr_name (const void *v_, const
 {
   struct variable *const *v = v_;
 
-  return hsh_hash_case_string ((*v)->name);
+  return hsh_hash_case_string (var_get_name (*v));
 }
 
+/* Returns the type of a variable with the given WIDTH. */
+static enum var_type
+width_to_type (int width) 
+{
+  return width == 0 ? NUMERIC : ALPHA;
+}
+
+/* Returns the type of variable V. */
+enum var_type
+var_get_type (const struct variable *v) 
+{
+  return width_to_type (v->width);
+}
+
+/* Returns the width of variable V. */
+int
+var_get_width (const struct variable *v) 
+{
+  return v->width;
+}
+
+/* Sets the width of V to WIDTH. */
+void
+var_set_width (struct variable *v, int new_width) 
+{
+  enum var_type new_type = width_to_type (new_width);
+  
+  if (mv_is_resizable (&v->miss, new_width))
+    mv_resize (&v->miss, new_width);
+  else
+    mv_init (&v->miss, new_width);
+
+  if (v->val_labs != NULL) 
+    {
+      if (val_labs_can_set_width (v->val_labs, new_width))
+        val_labs_set_width (v->val_labs, new_width);
+      else 
+        {
+          val_labs_destroy (v->val_labs);
+          v->val_labs = NULL;
+        }
+    }
+  
+  if (var_get_type (v) != new_type) 
+    {
+      v->print = (new_type == NUMERIC
+                  ? fmt_for_output (FMT_F, 8, 2)
+                  : fmt_for_output (FMT_A, new_width, 0));
+      v->write = v->print;
+    }
+  else if (new_type == ALPHA) 
+    {
+      v->print.w = v->print.type == FMT_AHEX ? new_width * 2 : new_width;
+      v->write.w = v->write.type == FMT_AHEX ? new_width * 2 : new_width;
+    }
+
+  v->width = new_width;
+}
+
+/* Returns true if variable V is numeric, false otherwise. */
+bool
+var_is_numeric (const struct variable *v) 
+{
+  return var_get_type (v) == NUMERIC;
+}
+
+/* Returns true if variable V is a string variable, false
+   otherwise. */
+bool
+var_is_alpha (const struct variable *v) 
+{
+  return var_get_type (v) == ALPHA;
+}
+
+/* Returns true if variable V is a short string variable, false
+   otherwise. */
+bool
+var_is_short_string (const struct variable *v) 
+{
+  return v->width > 0 && v->width <= MAX_SHORT_STRING;
+}
+
+/* Returns true if variable V is a long string variable, false
+   otherwise. */
+bool
+var_is_long_string (const struct variable *v) 
+{
+  return v->width > MAX_SHORT_STRING;
+}
+
+/* Returns true if variable V is a very long string variable,
+   false otherwise. */
+bool
+var_is_very_long_string (const struct variable *v) 
+{
+  return v->width > MAX_LONG_STRING;
+}
+
+/* Returns variable V's missing values. */
+const struct missing_values *
+var_get_missing_values (const struct variable *v) 
+{
+  return &v->miss;
+}
+
+/* Sets variable V's missing values to MISS, which must be of the
+   correct width. */
+void
+var_set_missing_values (struct variable *v, const struct missing_values *miss)
+{
+  if (miss != NULL) 
+    {
+      assert (v->width == mv_get_width (miss));
+      mv_copy (&v->miss, miss);
+    }
+  else
+    mv_init (&v->miss, v->width);
+}
+
+/* Sets variable V to have no user-missing values. */
+void
+var_clear_missing_values (struct variable *v) 
+{
+  var_set_missing_values (v, NULL);
+}
+
+/* Returns true if V has any user-missing values,
+   false otherwise. */
+bool
+var_has_missing_values (const struct variable *v) 
+{
+  return !mv_is_empty (&v->miss);
+}
+
+/* Returns true if VALUE is system missing or user-missing value
+   for V, false otherwise. */
+bool
+var_is_value_missing (const struct variable *v, const union value *value) 
+{
+  return mv_is_value_missing (&v->miss, value);
+}
+
+/* Returns true if D is system missing or a missing value in V,
+   false otherwise.
+   V must be a numeric variable. */
+bool
+var_is_num_missing (const struct variable *v, double d) 
+{
+  return mv_is_num_missing (&v->miss, d);
+}
+
+/* Returns true if S[] is a missing value for V, false otherwise.
+   S[] must contain exactly as many characters as V's width.
+   V must be a string variable. */
+bool
+var_is_str_missing (const struct variable *v, const char s[]) 
+{
+  return mv_is_str_missing (&v->miss, s);
+}
+
+/* Returns true if VALUE is a missing value for V, false
+   otherwise. */
+bool
+var_is_value_user_missing (const struct variable *v, const union value *value) 
+{
+  return mv_is_value_user_missing (&v->miss, value);
+}
+
+/* Returns true if D is a user-missing value for V, false
+   otherwise.  V must be a numeric variable. */
+bool
+var_is_num_user_missing (const struct variable *v, double d) 
+{
+  return mv_is_num_user_missing (&v->miss, d);
+}
+
+/* Returns true if S[] is a missing value for V, false otherwise.
+   V must be a string variable. 
+   S[] must contain exactly as many characters as V's width. */
+bool
+var_is_str_user_missing (const struct variable *v, const char s[]) 
+{
+  return mv_is_str_user_missing (&v->miss, s);
+}
+
+/* Returns true if V is a numeric variable and VALUE is the
+   system missing value. */
+bool
+var_is_value_system_missing (const struct variable *v,
+                             const union value *value) 
+{
+  return mv_is_value_system_missing (&v->miss, value);
+}
+
+/* Print and write formats. */
+
+/* Returns V's print format specification. */
+const struct fmt_spec *
+var_get_print_format (const struct variable *v) 
+{
+  return &v->print;
+}
+
+/* Sets V's print format specification to PRINT, which must be a
+   valid format specification for outputting a variable of V's
+   width. */
+void
+var_set_print_format (struct variable *v, const struct fmt_spec *print) 
+{
+  assert (fmt_check_width_compat (print, v->width));
+  v->print = *print;
+}
+
+/* Returns V's write format specification. */
+const struct fmt_spec *
+var_get_write_format (const struct variable *v) 
+{
+  return &v->write;
+}
+
+/* Sets V's write format specification to WRITE, which must be a
+   valid format specification for outputting a variable of V's
+   width. */
+void
+var_set_write_format (struct variable *v, const struct fmt_spec *write) 
+{
+  assert (fmt_check_width_compat (write, v->width));
+  v->write = *write;
+}
+
+/* Sets V's print and write format specifications to FORMAT,
+   which must be a valid format specification for outputting a
+   variable of V's width. */
+void
+var_set_both_formats (struct variable *v, const struct fmt_spec *format) 
+{
+  var_set_print_format (v, format);
+  var_set_write_format (v, format);
+}
+
+/* Returns V's variable label, or a null pointer if it has none. */
+const char *
+var_get_label (const struct variable *v) 
+{
+  return v->label;
+}
+
+/* Sets V's variable label to LABEL, stripping off leading and
+   trailing white space and truncating to 255 characters.
+   If LABEL is a null pointer or if LABEL is an empty string
+   (after stripping white space), then V's variable label (if
+   any) is removed. */
+void
+var_set_label (struct variable *v, const char *label) 
+{
+  free (v->label);
+  v->label = NULL;
+
+  if (label != NULL) 
+    {
+      struct substring s = ss_cstr (label);
+      ss_trim (&s, ss_cstr (CC_SPACES));
+      ss_truncate (&s, 255);
+      if (!ss_is_empty (s)) 
+        v->label = ss_xstrdup (s);
+    }
+}
+
+/* Removes any variable label from V. */
+void
+var_clear_label (struct variable *v) 
+{
+  var_set_label (v, NULL);
+}
+
+/* Returns true if V has a variable V,
+   false otherwise. */
+bool
+var_has_label (const struct variable *v) 
+{
+  return v->label != NULL;
+}
+
+/* Returns V's measurement level. */
+enum measure
+var_get_measure (const struct variable *v) 
+{
+  return v->measure;
+}
+
+/* Sets V's measurement level to MEASURE. */
+void
+var_set_measure (struct variable *v, enum measure measure) 
+{
+  assert (measure_is_valid (measure));
+  v->measure = measure;
+}
+
+/* Returns V's display width, which applies only to GUIs. */
+int
+var_get_display_width (const struct variable *v) 
+{
+  return v->display_width;
+}
+
+/* Sets V's display width to DISPLAY_WIDTH. */
+void
+var_set_display_width (struct variable *v, int display_width) 
+{
+  v->display_width = display_width;
+}
+
+/* Returns V's display alignment, which applies only to GUIs. */
+enum alignment
+var_get_alignment (const struct variable *v) 
+{
+  return v->alignment;
+}
+
+/* Sets V's display alignment to ALIGNMENT. */
+void
+var_set_alignment (struct variable *v, enum alignment alignment) 
+{
+  assert (alignment_is_valid (alignment));
+  v->alignment = alignment;
+}
+
+/* Returns the number of "union value"s need to store a value of
+   variable V. */
+size_t
+var_get_value_cnt (const struct variable *v) 
+{
+  return v->width == 0 ? 1 : DIV_RND_UP (v->width, MAX_SHORT_STRING);
+}
+
+/* Return whether variable V's values should be preserved from
+   case to case. */
+bool
+var_get_leave (const struct variable *v) 
+{
+  return v->leave;
+}
+
+/* Returns V's short name, if it has one, or a null pointer
+   otherwise.
+
+   Short names are used only for system and portable file input
+   and output.  They are upper-case only, not necessarily unique,
+   and limited to SHORT_NAME_LEN characters (plus a null
+   terminator).  Any variable may have no short name, indicated
+   by returning a null pointer. */
+const char *
+var_get_short_name (const struct variable *v) 
+{
+  return v->short_name[0] != '\0' ? v->short_name : NULL;
+}
+
 /* Sets V's short_name to SHORT_NAME, truncating it to
    SHORT_NAME_LEN characters and converting it to uppercase in
-   the process. */
+   the process.  Specifying a null pointer for SHORT_NAME clears
+   the variable's short name. */
 void
 var_set_short_name (struct variable *v, const char *short_name) 
 {
   assert (v != NULL);
-  assert (short_name[0] == '\0' || var_is_plausible_name (short_name, false));
-  
-  str_copy_trunc (v->short_name, sizeof v->short_name, short_name);
-  str_uppercase (v->short_name);
+  assert (short_name == NULL || var_is_plausible_name (short_name, false));
+
+  if (short_name != NULL) 
+    {
+      str_copy_trunc (v->short_name, sizeof v->short_name, short_name);
+      str_uppercase (v->short_name); 
+    }
+  else
+    v->short_name[0] = '\0';
 }
 
 /* Clears V's short name. */
@@ -280,41 +680,46 @@ var_clear_short_name (struct variable *v
 
 /* Sets V's short name to BASE, followed by a suffix of the form
    _A, _B, _C, ..., _AA, _AB, etc. according to the value of
-   SUFFIX.  Truncates BASE as necessary to fit. */
+   SUFFIX_NUMBER.  Truncates BASE as necessary to fit. */
 void
-var_set_short_name_suffix (struct variable *v, const char *base, int suffix)
+var_set_short_name_suffix (struct variable *v, const char *base,
+                           int suffix_number)
 {
-  char string[SHORT_NAME_LEN + 1];
+  char suffix[SHORT_NAME_LEN + 1];
+  char short_name[SHORT_NAME_LEN + 1];
   char *start, *end;
   int len, ofs;
 
   assert (v != NULL);
-  assert (suffix >= 0);
-  assert (strlen (v->short_name) > 0);
+  assert (suffix_number >= 0);
 
   /* Set base name. */
   var_set_short_name (v, base);
 
-  /* Compose suffix_string. */
-  start = end = string + sizeof string - 1;
+  /* Compose suffix. */
+  start = end = suffix + sizeof suffix - 1;
   *end = '\0';
   do 
     {
-      *--start = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[suffix % 26];
-      if (start <= string + 1)
+      *--start = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[suffix_number % 26];
+      if (start <= suffix + 1)
         msg (SE, _("Variable suffix too large."));
-      suffix /= 26;
+      suffix_number /= 26;
     }
-  while (suffix > 0);
+  while (suffix_number > 0);
   *--start = '_';
 
-  /* Append suffix_string to V's short name. */
+  /* Append suffix to V's short name. */
+  str_copy_trunc (short_name, sizeof short_name, base);
   len = end - start;
-  if (len + strlen (v->short_name) > SHORT_NAME_LEN)
+  if (len + strlen (short_name) > SHORT_NAME_LEN)
     ofs = SHORT_NAME_LEN - len;
   else
-    ofs = strlen (v->short_name);
-  strcpy (v->short_name + ofs, start);
+    ofs = strlen (short_name);
+  strcpy (short_name + ofs, start);
+
+  /* Set name. */
+  var_set_short_name (v, short_name);
 }
 
 
Index: src/data/variable.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/variable.h,v
retrieving revision 1.13
diff -u -p -r1.13 variable.h
--- src/data/variable.h	29 Oct 2006 09:51:36 -0000	1.13
+++ src/data/variable.h	5 Dec 2006 06:36:38 -0000
@@ -35,9 +35,32 @@ enum var_type
     ALPHA			/* A string variable. */
   };
 
+bool var_type_is_valid (enum var_type);
 const char *var_type_adj (enum var_type);
 const char *var_type_noun (enum var_type);
 
+/* Alignment of data for display. */
+enum alignment 
+  {
+    ALIGN_LEFT = 0,
+    ALIGN_RIGHT = 1,
+    ALIGN_CENTRE = 2,
+    n_ALIGN
+  };
+
+bool alignment_is_valid (enum alignment);
+
+/* How data is measured. */
+enum measure
+  {
+    MEASURE_NOMINAL = 1,
+    MEASURE_ORDINAL = 2,
+    MEASURE_SCALE = 3,
+    n_MEASURES
+  };
+
+bool measure_is_valid (enum measure);
+
 /* Maximum lengths of short and long variable names.
    Most operations support long variable names,
    but some file formats are limited to short names. */
@@ -49,19 +72,20 @@ struct variable
   {
     /* Dictionary information. */
     char name[LONG_NAME_LEN + 1]; /* Variable name.  Mixed case. */
-    enum var_type type;         /* NUMERIC or ALPHA. */
-    int width;			/* Size of string variables in chars. */
+    int width;			/* 0 for numeric, otherwise string width. */
     struct missing_values miss; /* Missing values. */
     struct fmt_spec print;	/* Default format for PRINT. */
     struct fmt_spec write;	/* Default format for WRITE. */
     struct val_labs *val_labs;  /* Value labels. */
     char *label;		/* Variable label. */
+
+    /* GUI information. */
     enum measure measure;       /* Nominal, ordinal, or continuous. */
     int display_width;          /* Width of data editor column. */
     enum alignment alignment;   /* Alignment of data in GUI. */
 
     /* Case information. */
-    int fv, nv;			/* Index into `value's, number of values. */
+    int fv;			/* Index into `value's. */
     bool leave;                 /* Leave value from case to case? */
 
     /* Data for use by containing dictionary. */
@@ -85,12 +109,73 @@ struct variable
   };
 
 /* Variable names. */
+const char *var_get_name (const struct variable *);
+void var_set_name (struct variable *, const char *);
 bool var_is_valid_name (const char *, bool issue_error);
 bool var_is_plausible_name (const char *name, bool issue_error);
 int  compare_var_names (const void *, const void *, const void *);
 unsigned hash_var_name (const void *, const void *);
 
+/* Variable types and widths. */
+enum var_type var_get_type (const struct variable *);
+int var_get_width (const struct variable *);
+void var_set_width (struct variable *, int width);
+bool var_is_numeric (const struct variable *);
+bool var_is_alpha (const struct variable *);
+bool var_is_short_string (const struct variable *);
+bool var_is_long_string (const struct variable *);
+bool var_is_very_long_string (const struct variable *);
+
+/* Variables' missing values. */
+const struct missing_values *var_get_missing_values (const struct variable *);
+void var_set_missing_values (struct variable *, const struct missing_values *);
+void var_clear_missing_values (struct variable *);
+bool var_has_missing_values (const struct variable *);
+
+typedef bool var_is_missing_func (const struct variable *,
+                                  const union value *);
+bool var_is_value_missing (const struct variable *, const union value *);
+bool var_is_num_missing (const struct variable *, double);
+bool var_is_str_missing (const struct variable *, const char[]);
+bool var_is_value_user_missing (const struct variable *,
+                                const union value *);
+bool var_is_num_user_missing (const struct variable *, double);
+bool var_is_str_user_missing (const struct variable *, const char[]);
+bool var_is_value_system_missing (const struct variable *,
+                                  const union value *);
+
+/* Print and write formats. */
+const struct fmt_spec *var_get_print_format (const struct variable *);
+void var_set_print_format (struct variable *, const struct fmt_spec *);
+const struct fmt_spec *var_get_write_format (const struct variable *);
+void var_set_write_format (struct variable *, const struct fmt_spec *);
+void var_set_both_formats (struct variable *, const struct fmt_spec *);
+
+/* Variable labels. */
+const char *var_get_label (const struct variable *);
+void var_set_label (struct variable *, const char *);
+void var_clear_label (struct variable *);
+bool var_has_label (const struct variable *);
+
+/* GUI information. */
+enum measure var_get_measure (const struct variable *);
+void var_set_measure (struct variable *, enum measure);
+
+int var_get_display_width (const struct variable *);
+void var_set_display_width (struct variable *, int display_width);
+
+enum alignment var_get_alignment (const struct variable *);
+void var_set_alignment (struct variable *, enum alignment);
+
+/* Variable location in cases. */
+size_t var_get_value_cnt (const struct variable *);
+
+/* Whether variables' values should be preserved from case to
+   case. */
+bool var_get_leave (const struct variable *);
+
 /* Short names. */
+const char *var_get_short_name (const struct variable *);
 void var_set_short_name (struct variable *, const char *);
 void var_set_short_name_suffix (struct variable *, const char *, int suffix);
 void var_clear_short_name (struct variable *);
Index: src/language/data-io/data-list.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/data-io/data-list.c,v
retrieving revision 1.26
diff -u -p -r1.26 data-list.c
--- src/language/data-io/data-list.c	22 Nov 2006 04:24:02 -0000	1.26
+++ src/language/data-io/data-list.c	5 Dec 2006 06:36:39 -0000
@@ -336,8 +336,7 @@ parse_fixed (struct lexer *lexer, struct
               {
                 /* Success. */
                 struct fmt_spec output = fmt_for_output_from_input (f);
-                v->print = output;
-                v->write = output;
+                var_set_both_formats (v, &output);
               }
             else
               {
@@ -353,14 +352,14 @@ parse_fixed (struct lexer *lexer, struct
                   }
 
                 v = dict_lookup_var_assert (dict, name);
-                if ((width != 0) != (v->width != 0))
+                if ((width != 0) != (var_get_width (v) != 0))
                   {
                     msg (SE, _("There is already a variable %s of a "
                                "different type."),
                          name);
                     return false;
                   }
-                if (width != 0 && width != v->width)
+                if (width != 0 && width != var_get_width (v))
                   {
                     msg (SE, _("There is already a string variable %s of a "
                                "different width."), name);
@@ -374,7 +373,7 @@ parse_fixed (struct lexer *lexer, struct
             spec->fv = v->fv;
             spec->record = record;
             spec->first_column = column;
-            strcpy (spec->name, v->name);
+            strcpy (spec->name, var_get_name (v));
             ll_push_tail (&dls->specs, &spec->ll);
 
             column += f->w;
@@ -495,12 +494,12 @@ parse_free (struct lexer *lexer, struct 
 	      msg (SE, _("%s is a duplicate variable name."), name[i]);
 	      return 0;
 	    }
-	  v->print = v->write = output;
+          var_set_both_formats (v, &output);
 
           spec = pool_alloc (dls->pool, sizeof *spec);
           spec->input = input;
 	  spec->fv = v->fv;
-	  strcpy (spec->name, v->name);
+	  strcpy (spec->name, var_get_name (v));
           ll_push_tail (&dls->specs, &spec->ll);
 	}
     }
Index: src/language/data-io/get.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/data-io/get.c,v
retrieving revision 1.22
diff -u -p -r1.22 get.c
--- src/language/data-io/get.c	3 Dec 2006 22:16:45 -0000	1.22
+++ src/language/data-io/get.c	5 Dec 2006 06:36:40 -0000
@@ -642,7 +642,8 @@ rename_variables (struct lexer *lexer, s
 		     "a variable named %s.  To rename variables with "
 		     "overlapping names, use a single RENAME subcommand "
 		     "such as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, "
-		     "\"/RENAME (A B C=B C A)\"."), v->name, lex_tokid (lexer), lex_tokid (lexer));
+		     "\"/RENAME (A B C=B C A)\"."),
+               var_get_name (v), lex_tokid (lexer), lex_tokid (lexer));
 	  return 0;
 	}
       
@@ -979,12 +980,13 @@ cmd_match_files (struct lexer *lexer, st
 
               for (i = 0; i < mtf.by_cnt; i++)
                 {
-                  iter->by[i] = dict_lookup_var (iter->dict, by[i]->name);
+                  iter->by[i] = dict_lookup_var (iter->dict,
+                                                 var_get_name (by[i]));
                   if (iter->by[i] == NULL)
                     {
                       msg (SE, _("File %s lacks BY variable %s."),
                            iter->handle ? fh_get_name (iter->handle) : "*",
-                           by[i]->name);
+                           var_get_name (by[i]));
                       free (by);
                       goto error;
                     }
@@ -1071,7 +1073,7 @@ cmd_match_files (struct lexer *lexer, st
       for (i = 0; i < dict_get_var_cnt (d); i++)
         {
           struct variable *v = dict_get_var (d, i);
-          struct variable *mv = dict_lookup_var (mtf.dict, v->name);
+          struct variable *mv = dict_lookup_var (mtf.dict, var_get_name (v));
           if (mv != NULL)
             set_master (v, mv);
         }
@@ -1081,16 +1083,16 @@ cmd_match_files (struct lexer *lexer, st
   for (iter = mtf.head; iter != NULL; iter = iter->next) 
     if (iter->in_name != NULL)
       {
+        struct fmt_spec format = fmt_for_output (FMT_F, 1, 0);
         iter->in_var = dict_create_var (mtf.dict, iter->in_name, 0);
         if (iter->in_var == NULL)
           {
             msg (SE, _("IN variable name %s duplicates an "
                        "existing variable name."),
-                 iter->in_var->name);
+                 var_get_name (iter->in_var));
             goto error;
           }
-        iter->in_var->print = iter->in_var->write
-          = fmt_for_output (FMT_F, 1, 0);
+        var_set_both_formats (iter->in_var, &format);
       }
     
   /* MATCH FILES performs an n-way merge on all its input files.
@@ -1201,13 +1203,10 @@ var_type_description (struct variable *v
   x ^= 1;
   s = buf[x];
 
-  if (v->type == NUMERIC)
+  if (var_is_numeric (v))
     strcpy (s, "numeric");
   else
-    {
-      assert (v->type == ALPHA);
-      sprintf (s, "string with width %d", v->width);
-    }
+    sprintf (s, "string with width %d", var_get_width (v));
   return s;
 }
 
@@ -1282,10 +1281,10 @@ mtf_delete_file_in_place (struct mtf_pro
         {
           union value *out = case_data_rw (&mtf->mtf_case, mv->fv);
 	  
-          if (v->type == NUMERIC)
+          if (var_is_numeric (v))
             out->f = SYSMIS;
           else
-            memset (out->s, ' ', v->width);
+            memset (out->s, ' ', var_get_width (v));
         } 
     }
 
@@ -1436,10 +1435,11 @@ mtf_processing (const struct ccase *c, v
                   union value *out = case_data_rw (&mtf->mtf_case, mv->fv);
 
                   mtf->seq_nums[mv->index] = mtf->seq_num;
-                  if (v->type == NUMERIC)
+                  if (var_is_numeric (v))
                     out->f = case_num (record, v->fv);
                   else
-                    memcpy (out->s, case_str (record, v->fv), v->width);
+                    memcpy (out->s, case_str (record, v->fv),
+                            var_get_width (v));
                 } 
             }
           if (iter->in_var != NULL)
@@ -1467,10 +1467,10 @@ mtf_processing (const struct ccase *c, v
                   union value *out = case_data_rw (&mtf->mtf_case, mv->fv);
                   mtf->seq_nums[mv->index] = mtf->seq_num;
 
-                  if (v->type == NUMERIC)
+                  if (var_is_numeric (v))
                     out->f = SYSMIS;
                   else
-                    memset (out->s, ' ', v->width);
+                    memset (out->s, ' ', var_get_width (v));
                 }
             }
           if (iter->in_var != NULL)
@@ -1533,24 +1533,24 @@ mtf_merge_dictionary (struct dictionary 
   for (i = 0; i < dict_get_var_cnt (d); i++)
     {
       struct variable *dv = dict_get_var (d, i);
-      struct variable *mv = dict_lookup_var (m, dv->name);
+      struct variable *mv = dict_lookup_var (m, var_get_name (dv));
 
-      if (dict_class_from_id (dv->name) == DC_SCRATCH)
+      if (dict_class_from_id (var_get_name (dv)) == DC_SCRATCH)
         continue;
 
       if (mv != NULL)
         {
-          if (mv->width != dv->width) 
+          if (var_get_width (mv) != var_get_width (dv)) 
             {
               msg (SE, _("Variable %s in file %s (%s) has different "
                          "type or width from the same variable in "
                          "earlier file (%s)."),
-                   dv->name, fh_get_name (f->handle),
+                   var_get_name (dv), fh_get_name (f->handle),
                    var_type_description (dv), var_type_description (mv));
               return 0;
             }
         
-          if (dv->width == mv->width)
+          if (var_get_width (dv) == var_get_width (mv))
             {
               if (val_labs_count (dv->val_labs)
                   && !val_labs_count (mv->val_labs)) 
@@ -1558,15 +1558,15 @@ mtf_merge_dictionary (struct dictionary 
                   val_labs_destroy (mv->val_labs);
                   mv->val_labs = val_labs_copy (dv->val_labs); 
                 }
-              if (!mv_is_empty (&dv->miss) && mv_is_empty (&mv->miss))
-                mv_copy (&mv->miss, &dv->miss);
+              if (var_has_missing_values (dv) && !var_has_missing_values (mv))
+                var_set_missing_values (mv, var_get_missing_values (dv));
             }
 
-          if (dv->label && !mv->label)
-            mv->label = xstrdup (dv->label);
+          if (var_get_label (dv) && !var_get_label (mv))
+            var_set_label (mv, var_get_label (dv));
         }
       else
-        mv = dict_clone_var_assert (m, dv, dv->name);
+        mv = dict_clone_var_assert (m, dv, var_get_name (dv));
     }
 
   return 1;
@@ -1652,13 +1652,14 @@ finish_case_map (struct dictionary *d) 
   for (i = 0; i < var_cnt; i++) 
     {
       struct variable *v = dict_get_var (d, i);
+      size_t value_cnt = var_get_value_cnt (v);
       int *src_fv = (int *) var_detach_aux (v);
       size_t idx;
 
       if (v->fv != *src_fv)
         identity_map = 0;
       
-      for (idx = 0; idx < v->nv; idx++)
+      for (idx = 0; idx < value_cnt; idx++)
         {
           int src_idx = *src_fv + idx;
           int dst_idx = v->fv + idx;
Index: src/language/data-io/inpt-pgm.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/data-io/inpt-pgm.c,v
retrieving revision 1.18
diff -u -p -r1.18 inpt-pgm.c
--- src/language/data-io/inpt-pgm.c	1 Dec 2006 05:52:59 -0000	1.18
+++ src/language/data-io/inpt-pgm.c	5 Dec 2006 06:36:40 -0000
@@ -161,13 +161,14 @@ cmd_input_program (struct lexer *lexer, 
   for (i = 0; i < dict_get_var_cnt (dataset_dict (ds)); i++)
     {
       struct variable *var = dict_get_var (dataset_dict (ds), i);
+      size_t value_cnt = var_get_value_cnt (var);
       enum value_init_type value_init;
       size_t j;
       
-      value_init = var->type == NUMERIC ? INP_NUMERIC : INP_STRING;
-      value_init |= var->leave ? INP_INIT_ONCE : INP_REINIT;
+      value_init = var_is_numeric (var) ? INP_NUMERIC : INP_STRING;
+      value_init |= var_get_leave (var) ? INP_INIT_ONCE : INP_REINIT;
 
-      for (j = 0; j < var->nv; j++)
+      for (j = 0; j < value_cnt; j++)
         inp->init[j + var->fv] = value_init;
     }
   for (i = 0; i < inp->init_cnt; i++)
Index: src/language/data-io/list.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/data-io/list.q,v
retrieving revision 1.21
diff -u -p -r1.21 list.q
--- src/language/data-io/list.q	25 Nov 2006 02:15:01 -0000	1.21
+++ src/language/data-io/list.q	5 Dec 2006 06:36:40 -0000
@@ -213,12 +213,12 @@ cmd_list (struct lexer *lexer, struct da
   if (cmd.numbering == LST_NUMBERED)
     {
       /* Initialize the case-number variable. */
-      strcpy (casenum_var.name, "Case#");
-      casenum_var.type = NUMERIC;
+      int width = cmd.last == LONG_MAX ? 5 : intlog10 (cmd.last);
+      struct fmt_spec format = fmt_for_output (FMT_F, width, 0);
+      var_set_name (&casenum_var, "Case#");
+      casenum_var.width = 0;
       casenum_var.fv = -1;
-      casenum_var.print = fmt_for_output (FMT_F,
-                                          (cmd.last == LONG_MAX
-                                           ? 5 : intlog10 (cmd.last)), 0);
+      var_set_both_formats (&casenum_var, &format);
 
       /* Add the weight variable at the beginning of the variable list. */
       cmd.n_variables++;
@@ -266,7 +266,7 @@ write_all_headers (const struct ccase *c
 
 	    for (i = 0; i < cmd.n_variables; i++)
 	      fprintf (x->file, "    <TH><EM>%s</EM></TH>\n",
-		       cmd.v_variables[i]->name);
+		       var_get_name (cmd.v_variables[i]));
 	  }
 
 	  fputs ("  </TR>\n", x->file);
@@ -313,12 +313,15 @@ write_header (struct outp_driver *d)
       for (i = x = 0; i < prc->n_vertical; i++)
 	{
 	  struct variable *v = cmd.v_variables[i];
+          const char *name = var_get_name (v);
+          size_t name_len = strlen (name);
+          const struct fmt_spec *print = var_get_print_format (v);
 	  size_t j;
 
-	  memset (&prc->header[prc->header_rows - 1][x], '-', v->print.w);
-	  x += v->print.w - 1;
-	  for (j = 0; j < strlen (v->name); j++)
-	    prc->header[strlen (v->name) - j - 1][x] = v->name[j];
+	  memset (&prc->header[prc->header_rows - 1][x], '-', print->w);
+	  x += print->w - 1;
+	  for (j = 0; j < name_len; j++)
+	    prc->header[name_len - j - 1][x] = name[j];
 	  x += 2;
 	}
 
@@ -326,13 +329,16 @@ write_header (struct outp_driver *d)
       for (; i < cmd.n_variables; i++)
 	{
 	  struct variable *v = cmd.v_variables[i];
+          const char *name = var_get_name (v);
+          size_t name_len = strlen (name);
+          const struct fmt_spec *print = var_get_print_format (v);
 	  
 	  memset (&prc->header[prc->header_rows - 1][x], '-',
-		  MAX (v->print.w, (int) strlen (v->name)));
-	  if ((int) strlen (v->name) < v->print.w)
-	    x += v->print.w - strlen (v->name);
- 	  memcpy (&prc->header[0][x], v->name, strlen (v->name));
-	  x += strlen (v->name) + 1;
+		  MAX (print->w, (int) name_len));
+	  if ((int) name_len < print->w)
+	    x += print->w - name_len;
+ 	  memcpy (&prc->header[0][x], name, name_len);
+	  x += name_len + 1;
 	}
 
       /* Add null bytes. */
@@ -466,7 +472,7 @@ write_fallback_headers (struct outp_driv
 
 	entry:
 	  {
-	    int var_width = cmd.v_variables[index]->print.w;
+	    int var_width = var_get_print_format (cmd.v_variables[index])->w;
 	    if (width + var_width > max_width && width != 0)
 	      {
 		width = 0;
@@ -480,7 +486,7 @@ write_fallback_headers (struct outp_driv
 	  {
 	    char varname[LONG_NAME_LEN + 2];
 	    snprintf (varname, sizeof varname,
-                      " %s", cmd.v_variables[index]->name);
+                      " %s", var_get_name (cmd.v_variables[index]));
 	    write_varname (d, varname, leader_width);
 	  }
 	}
@@ -546,7 +552,9 @@ determine_layout (void)
       for (width = cmd.n_variables - 1, column = 0; column < cmd.n_variables; column++)
 	{
 	  struct variable *v = cmd.v_variables[column];
-	  width += MAX (v->print.w, (int) strlen (v->name));
+          int fmt_width = var_get_print_format (v)->w;
+          int name_len = strlen (var_get_name (v));
+	  width += MAX (fmt_width, name_len);
 	}
       if (width <= max_width)
 	{
@@ -560,9 +568,11 @@ determine_layout (void)
 	   column++) 
         {
           struct variable *v = cmd.v_variables[column];
-          width += v->print.w;
-          if (strlen (v->name) > height)
-            height = strlen (v->name);
+          int fmt_width = var_get_print_format (v)->w;
+          size_t name_len = strlen (var_get_name (v));
+          width += fmt_width;
+          if (name_len > height)
+            height = name_len;
         }
       
       /* If it fit then we need to determine how many labels can be
@@ -575,9 +585,9 @@ determine_layout (void)
 	  for (column = cmd.n_variables; column-- != 0; )
 	    {
 	      struct variable *v = cmd.v_variables[column];
-	      int trial_width = (width - v->print.w
-				 + MAX (v->print.w, (int) strlen (v->name)));
-	      
+              int name_len = strlen (var_get_name (v));
+              int fmt_width = var_get_print_format (v)->w;
+	      int trial_width = width - fmt_width + MAX (fmt_width, name_len);
 	      if (trial_width > max_width)
 		{
 		  prc->n_vertical = column + 1;
@@ -591,9 +601,12 @@ determine_layout (void)
 	  /* Finally determine the length of the headers. */
 	  for (prc->header_rows = 0, column = 0;
 	       column < prc->n_vertical;
-	       column++)
-	    prc->header_rows = MAX (prc->header_rows,
-				    strlen (cmd.v_variables[column]->name));
+	       column++) 
+            {
+              struct variable *var = cmd.v_variables[column];
+              size_t name_len = strlen (var_get_name (var));
+              prc->header_rows = MAX (prc->header_rows, name_len); 
+            }
 	  prc->header_rows++;
 	  continue;
 	}
@@ -630,19 +643,24 @@ list_cases (const struct ccase *c, void 
 
 	if (!prc->header_rows)
 	  {
-	    ds_put_format(&line_buffer, "%8s: ", cmd.v_variables[0]->name);
+	    ds_put_format(&line_buffer, "%8s: ",
+                          var_get_name (cmd.v_variables[0]));
 	  }
 	
       
 	for (column = 0; column < cmd.n_variables; column++)
 	  {
 	    struct variable *v = cmd.v_variables[column];
+            const struct fmt_spec *print = var_get_print_format (v);
 	    int width;
 
-	    if (prc->type == 0 && column >= prc->n_vertical)
-	      width = MAX ((int) strlen (v->name), v->print.w);
+	    if (prc->type == 0 && column >= prc->n_vertical) 
+              {
+                int name_len = strlen (var_get_name (v));
+                width = MAX (name_len, print->w); 
+              }
 	    else
-	      width = v->print.w;
+	      width = print->w;
 
 	    if (width + ds_length(&line_buffer) > max_width && 
 		ds_length(&line_buffer) != 0)
@@ -657,27 +675,23 @@ list_cases (const struct ccase *c, void 
 		ds_clear(&line_buffer);
 
 		if (!prc->header_rows)
-		  {
-		    ds_put_format (&line_buffer, "%8s: ", v->name);
-		  }
+                  ds_put_format (&line_buffer, "%8s: ", var_get_name (v));
 	      }
 
-	    if (width > v->print.w)
-	      {
-		ds_put_char_multiple(&line_buffer, ' ', width - v->print.w);
-	      }
+	    if (width > print->w)
+              ds_put_char_multiple(&line_buffer, ' ', width - print->w);
 
-            if (fmt_is_string (v->print.type) || v->fv != -1)
+            if (fmt_is_string (print->type) || v->fv != -1)
 	      {
-                data_out (case_data (c, v->fv), &v->print,
-                          ds_put_uninit (&line_buffer, v->print.w));
+                data_out (case_data (c, v->fv), print,
+                          ds_put_uninit (&line_buffer, print->w));
 	      }
             else 
               {
                 union value case_idx_value;
                 case_idx_value.f = case_idx;
-                data_out (&case_idx_value, &v->print,
-                          ds_put_uninit (&line_buffer,v->print.w)); 
+                data_out (&case_idx_value, print,
+                          ds_put_uninit (&line_buffer,print->w)); 
               }
 
 	    ds_put_char(&line_buffer, ' ');
@@ -702,19 +716,20 @@ list_cases (const struct ccase *c, void 
 	for (column = 0; column < cmd.n_variables; column++)
 	  {
 	    struct variable *v = cmd.v_variables[column];
+            const struct fmt_spec *print = var_get_print_format (v);
 	    char buf[256];
 	    
-            if (fmt_is_string (v->print.type) || v->fv != -1)
-	      data_out (case_data (c, v->fv), &v->print, buf);
+            if (fmt_is_string (print->type) || v->fv != -1)
+	      data_out (case_data (c, v->fv), print, buf);
             else 
               {
                 union value case_idx_value;
                 case_idx_value.f = case_idx;
-                data_out (&case_idx_value, &v->print, buf);
+                data_out (&case_idx_value, print, buf);
               }
 
             fputs ("    <TD>", x->file);
-            html_put_cell_contents (d, TAB_FIX, ss_buffer (buf, v->print.w));
+            html_put_cell_contents (d, TAB_FIX, ss_buffer (buf, print->w));
             fputs ("</TD>\n", x->file);
 	  }
 	  
Index: src/language/data-io/matrix-data.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/data-io/matrix-data.c,v
retrieving revision 1.19
diff -u -p -r1.19 matrix-data.c
--- src/language/data-io/matrix-data.c	25 Nov 2006 02:15:01 -0000	1.19
+++ src/language/data-io/matrix-data.c	5 Dec 2006 06:36:42 -0000
@@ -610,7 +610,7 @@ cmd_matrix_data (struct lexer *lexer, st
 	int type = mv->var_type;
 	
 	assert (type >= 0 && type < MXD_COUNT);
-	v->print = v->write = fmt_tab[type];
+        var_set_both_formats (v, &fmt_tab[type]);
 
 	if (type == MXD_CONTINUOUS)
 	  mx->n_continuous++;
@@ -1085,7 +1085,7 @@ nr_read_data_lines (struct nr_aux_data *
 	    if (token.type != MNUM)
 	      {
 		msg (SE, _("expecting value for %s %s"),
-		     dict_get_var (nr->dict, j)->name,
+		     var_get_name (dict_get_var (nr->dict, j)),
                      context (mx->reader));
 		return 0;
 	      }
@@ -1260,7 +1260,7 @@ nr_read_splits (struct nr_aux_data *nr, 
         {
           msg (SE, _("Expecting value %g for %s."),
                nr->split_values[i],
-               dict_get_split_vars (nr->dict)[i]->name);
+               var_get_name (dict_get_split_vars (nr->dict)[i]));
           return false;
         }
     }
@@ -1310,7 +1310,7 @@ nr_read_factors (struct nr_aux_data *nr,
 	  {
 	    msg (SE, _("Syntax error expecting value %g for %s %s."),
 		 nr->factor_values[i + mx->n_factors * cell],
-		 mx->factors[i]->name, context (mx->reader));
+		 var_get_name (mx->factors[i]), context (mx->reader));
 	    return false;
 	  }
       }
@@ -1354,8 +1354,8 @@ dump_cell_content (const struct dictiona
 	  }
 	if (type == 1)
 	  buf_copy_str_rpad (case_data_rw (c, mx->varname_->fv)->s, 8,
-                             dict_get_var (dict,
-                                           mx->first_continuous + i)->name);
+                             var_get_name (
+                               dict_get_var (dict, mx->first_continuous + i)));
 	if (!write_case (wc_data))
           return false;
       }
@@ -1957,7 +1957,8 @@ wr_read_indeps (struct wr_aux_data *wr)
 	if (token.type != MNUM)
 	  {
 	    msg (SE, _("Syntax error expecting value for %s %s."),
-                 dict_get_var (wr->dict, mx->first_continuous + j)->name,
+                 var_get_name (dict_get_var (wr->dict,
+                                             mx->first_continuous + j)),
                  context (mx->reader));
 	    return false;
 	  }
Index: src/language/data-io/print.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/data-io/print.c,v
retrieving revision 1.20
diff -u -p -r1.20 print.c
--- src/language/data-io/print.c	11 Nov 2006 23:10:00 -0000	1.20
+++ src/language/data-io/print.c	5 Dec 2006 06:36:42 -0000
@@ -334,7 +334,9 @@ parse_variable_argument (struct lexer *l
       for (i = 0; i < var_cnt; i++) 
         {
           struct variable *v = vars[i];
-          formats[i] = which_formats == PRINT ? v->print : v->write; 
+          formats[i] = (which_formats == PRINT
+                        ? *var_get_print_format (v)
+                        : *var_get_write_format (v));
         }
       add_space = which_formats == PRINT;
     }
@@ -347,7 +349,7 @@ parse_variable_argument (struct lexer *l
         struct prt_out_spec *spec;
 
         var = vars[var_idx++];
-        if (!fmt_check_width_compat (f, var->width))
+        if (!fmt_check_width_compat (f, var_get_width (var)))
           return false;
 
         spec = pool_alloc (trns->pool, sizeof *spec);
@@ -363,7 +365,7 @@ parse_variable_argument (struct lexer *l
            filled with spaces, instead of using the normal format
            that usually contains a period. */ 
         spec->sysmis_as_spaces = (which_formats == WRITE
-                                  && var->type == NUMERIC
+                                  && var_is_numeric (var)
                                   && (fmt_get_category (spec->format.type)
                                       != FMT_CAT_BINARY));
 
@@ -410,7 +412,7 @@ dump_table (struct print_trns *trns, con
           width = ds_length (&spec->string);
           break;
         case PRT_VAR:
-          tab_text (t, 0, row, TAB_LEFT, spec->var->name);
+          tab_text (t, 0, row, TAB_LEFT, var_get_name (spec->var));
           tab_text (t, 3, row, TAB_LEFT | TAB_FIX,
                     fmt_to_string (&spec->format, fmt_string));
           width = spec->format.w;
Index: src/language/dictionary/apply-dictionary.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/apply-dictionary.c,v
retrieving revision 1.10
diff -u -p -r1.10 apply-dictionary.c
--- src/language/dictionary/apply-dictionary.c	11 Nov 2006 23:10:00 -0000	1.10
+++ src/language/dictionary/apply-dictionary.c	5 Dec 2006 06:36:42 -0000
@@ -63,60 +63,66 @@ cmd_apply_dictionary (struct lexer *lexe
   for (i = 0; i < dict_get_var_cnt (dict); i++)
     {
       struct variable *s = dict_get_var (dict, i);
-      struct variable *t = dict_lookup_var (dataset_dict (ds), s->name);
+      struct variable *t = dict_lookup_var (dataset_dict (ds),
+                                            var_get_name (s));
       if (t == NULL)
 	continue;
 
       n_matched++;
-      if (s->type != t->type)
+      if (var_get_type (s) != var_get_type (t))
 	{
 	  msg (SW, _("Variable %s is %s in target file, but %s in "
 		     "source file."),
-	       s->name,
-	       t->type == ALPHA ? _("string") : _("numeric"),
-	       s->type == ALPHA ? _("string") : _("numeric"));
+	       var_get_name (s),
+	       var_is_alpha (t) ? _("string") : _("numeric"),
+	       var_is_alpha (s) ? _("string") : _("numeric"));
 	  continue;
 	}
 
-      if (s->label && strcspn (s->label, " ") != strlen (s->label))
-	{
-	  free (t->label);
-	  t->label = s->label;
-	  s->label = NULL;
-	}
-
-      if (val_labs_count (s->val_labs) && t->width > MAX_SHORT_STRING)
+      if (var_get_label (s))
+        {
+          const char *label = var_get_label (s);
+          if (strcspn (label, " ") != strlen (label))
+            var_set_label (t, label);
+        }
+      
+      if (val_labs_count (s->val_labs) && var_is_long_string (t))
 	msg (SW, _("Cannot add value labels from source file to "
 		   "long string variable %s."),
-	     s->name);
+	     var_get_name (s));
       else if (val_labs_count (s->val_labs))
 	{
-          if (val_labs_can_set_width (s->val_labs, t->width))
+          if (val_labs_can_set_width (s->val_labs, var_get_width (t)))
             {
               val_labs_destroy (t->val_labs);
               t->val_labs = s->val_labs;
-              val_labs_set_width (t->val_labs, t->width);
-              s->val_labs = val_labs_create (s->width);
+              val_labs_set_width (t->val_labs, var_get_width (t));
+              s->val_labs = val_labs_create (var_get_width (s));
             }
 	}
 
-      if (!mv_is_empty (&s->miss) && t->width > MAX_SHORT_STRING)
-	msg (SW, _("Cannot apply missing values from source file to "
-		   "long string variable %s."),
-	     s->name);
-      else if (!mv_is_empty (&s->miss))
-	{
-          if (mv_is_resizable (&s->miss, t->width)) 
+      if (var_has_missing_values (s))
+        {
+          if (!var_is_long_string (t))
             {
-              mv_copy (&t->miss, &s->miss);
-              mv_resize (&t->miss, t->width); 
+              struct missing_values miss;
+              mv_copy (&miss, var_get_missing_values (s));
+              if (mv_is_resizable (&miss, var_get_width (t))) 
+                {
+                  mv_resize (&miss, var_get_width (t));
+                  var_set_missing_values (t, &miss);
+                }
             }
-	}
+          else
+            msg (SW, _("Cannot apply missing values from source file to "
+                       "long string variable %s."),
+                 var_get_name (s));
+        }
 
-      if (s->type == NUMERIC)
+      if (var_is_numeric (s))
 	{
-	  t->print = s->print;
-	  t->write = s->write;
+          var_set_print_format (t, var_get_print_format (s));
+          var_set_write_format (t, var_get_write_format (s));
 	}
     }
 
@@ -128,7 +134,8 @@ cmd_apply_dictionary (struct lexer *lexe
   if (dict_get_weight (dict) != NULL) 
     {
       struct variable *new_weight
-        = dict_lookup_var (dataset_dict (ds), dict_get_weight (dict)->name);
+        = dict_lookup_var (dataset_dict (ds),
+                           var_get_name (dict_get_weight (dict)));
 
       if (new_weight != NULL)
         dict_set_weight (dataset_dict (ds), new_weight);
Index: src/language/dictionary/formats.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/formats.c,v
retrieving revision 1.13
diff -u -p -r1.13 formats.c
--- src/language/dictionary/formats.c	11 Nov 2006 23:10:00 -0000	1.13
+++ src/language/dictionary/formats.c	5 Dec 2006 06:36:42 -0000
@@ -85,7 +85,7 @@ internal_cmd_formats (struct lexer *lexe
 
       if (!parse_variables (lexer, dataset_dict (ds), &v, &cv, PV_NUMERIC))
 	return CMD_FAILURE;
-      type = v[0]->type;
+      type = var_get_type (v[0]);
 
       if (!lex_match (lexer, '('))
 	{
@@ -106,9 +106,9 @@ internal_cmd_formats (struct lexer *lexe
       for (i = 0; i < cv; i++)
 	{
 	  if (which & FORMATS_PRINT)
-	    v[i]->print = f;
+            var_set_print_format (v[i], &f);
 	  if (which & FORMATS_WRITE)
-	    v[i]->write = f;
+            var_set_write_format (v[i], &f);
 	}
       free (v);
       v = NULL;
Index: src/language/dictionary/missing-values.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/missing-values.c,v
retrieving revision 1.12
diff -u -p -r1.12 missing-values.c
--- src/language/dictionary/missing-values.c	22 Nov 2006 04:24:02 -0000	1.12
+++ src/language/dictionary/missing-values.c	5 Dec 2006 06:36:42 -0000
@@ -59,32 +59,33 @@ cmd_missing_values (struct lexer *lexer,
         }
 
       for (i = 0; i < nv; i++)
-        mv_init (&v[i]->miss, v[i]->width);
+        var_clear_missing_values (v[i]);
 
       if (!lex_match (lexer, ')')) 
         {
           struct missing_values mv;
 
           for (i = 0; i < nv; i++)
-            if (v[i]->type != v[0]->type)
+            if (var_get_type (v[i]) != var_get_type (v[0]))
               {
-                const struct variable *n = v[0]->type == NUMERIC ? v[0] : v[i];
-                const struct variable *s = v[0]->type == NUMERIC ? v[i] : v[0];
+                const struct variable *n = var_is_numeric (v[0]) ? v[0] : v[i];
+                const struct variable *s = var_is_numeric (v[0]) ? v[i] : v[0];
                 msg (SE, _("Cannot mix numeric variables (e.g. %s) and "
                            "string variables (e.g. %s) within a single list."),
-                     n->name, s->name);
+                     var_get_name (n), var_get_name (s));
                 goto done;
               }
 
-          if (v[0]->type == NUMERIC) 
+          if (var_is_numeric (v[0])) 
             {
               mv_init (&mv, 0);
               while (!lex_match (lexer, ')'))
                 {
+                  enum fmt_type type = var_get_print_format (v[0])->type;
                   double x, y;
                   bool ok;
 
-                  if (!parse_num_range (lexer, &x, &y, &v[0]->print.type))
+                  if (!parse_num_range (lexer, &x, &y, &type))
                     goto done;
                   
                   ok = (x == y
@@ -132,17 +133,19 @@ cmd_missing_values (struct lexer *lexer,
           
           for (i = 0; i < nv; i++) 
             {
-              if (!mv_is_resizable (&mv, v[i]->width)) 
+              if (!mv_is_resizable (&mv, var_get_width (v[i]))) 
                 {
                   msg (SE, _("Missing values provided are too long to assign "
                              "to variable of width %d."),
-                       v[i]->width);
+                       var_get_width (v[i]));
                   deferred_errors = true;
                 }
               else 
                 {
-                  mv_copy (&v[i]->miss, &mv);
-                  mv_resize (&v[i]->miss, v[i]->width);
+                  struct missing_values tmp;
+                  mv_copy (&tmp, &mv);
+                  mv_resize (&tmp, var_get_width (v[i]));
+                  var_set_missing_values (v[i], &tmp);
                 }
             }
         }
Index: src/language/dictionary/modify-variables.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/modify-variables.c,v
retrieving revision 1.12
diff -u -p -r1.12 modify-variables.c
--- src/language/dictionary/modify-variables.c	11 Nov 2006 23:10:00 -0000	1.12
+++ src/language/dictionary/modify-variables.c	5 Dec 2006 06:36:43 -0000
@@ -357,7 +357,7 @@ compare_variables_given_ordering (const 
   if (ordering->positional)
     result = a->index < b->index ? -1 : a->index > b->index;
   else
-    result = strcasecmp (a->name, b->name);
+    result = strcasecmp (var_get_name (a), var_get_name (b));
   if (!ordering->forward)
     result = -result;
   return result;
@@ -430,7 +430,7 @@ validate_var_modification (const struct 
   for (i = 0; i < keep_cnt; i++) 
     {
       var_renaming[i].var = keep_vars[i];
-      strcpy (var_renaming[i].new_name, keep_vars[i]->name);
+      strcpy (var_renaming[i].new_name, var_get_name (keep_vars[i]));
     }
   
   /* Rename variables in var_renaming array. */
@@ -493,7 +493,7 @@ rearrange_dict (struct dictionary *d, co
      still exist, but we can still look them up by name. */
   rename_old_names = xnmalloc (vm->rename_cnt, sizeof *rename_old_names);
   for (i = 0; i < vm->rename_cnt; i++)
-    rename_old_names[i] = xstrdup (vm->rename_vars[i]->name);
+    rename_old_names[i] = xstrdup (var_get_name (vm->rename_vars[i]));
 
   /* Reorder and delete variables. */
   dict_reorder_vars (d, vm->reorder_vars, vm->reorder_cnt);
Index: src/language/dictionary/numeric.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/numeric.c,v
retrieving revision 1.16
diff -u -p -r1.16 numeric.c
--- src/language/dictionary/numeric.c	11 Nov 2006 23:10:00 -0000	1.16
+++ src/language/dictionary/numeric.c	5 Dec 2006 06:36:43 -0000
@@ -85,7 +85,7 @@ cmd_numeric (struct lexer *lexer, struct
 	  else
 	    {
 	      if (f.type != -1)
-		new_var->print = new_var->write = f;
+                var_set_both_formats (new_var, &f);
 	    }
 	}
 
@@ -152,7 +152,7 @@ cmd_string (struct lexer *lexer, struct 
 	  if (!new_var)
 	    msg (SE, _("There is already a variable named %s."), v[i]);
 	  else
-            new_var->print = new_var->write = f;
+            var_set_both_formats (new_var, &f);
 	}
 
       /* Clean up. */
Index: src/language/dictionary/split-file.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/split-file.c,v
retrieving revision 1.11
diff -u -p -r1.11 split-file.c
--- src/language/dictionary/split-file.c	11 Nov 2006 23:10:00 -0000	1.11
+++ src/language/dictionary/split-file.c	5 Dec 2006 06:36:43 -0000
@@ -92,14 +92,14 @@ output_split_file_values (const struct d
       struct variable *v = split[i];
       char temp_buf[80];
       const char *val_lab;
+      const struct fmt_spec *print = var_get_print_format (v);
 
-      assert (v->type == NUMERIC || v->type == ALPHA);
-      tab_text (t, 0, i + 1, TAB_LEFT | TAT_PRINTF, "%s", v->name);
+      tab_text (t, 0, i + 1, TAB_LEFT | TAT_PRINTF, "%s", var_get_name (v));
       
-      data_out (case_data (c, v->fv), &v->print, temp_buf);
-      
-      temp_buf[v->print.w] = 0;
-      tab_text (t, 1, i + 1, TAT_PRINTF, "%.*s", v->print.w, temp_buf);
+      data_out (case_data (c, v->fv), print, temp_buf);
+      temp_buf[print->w] = 0;
+
+      tab_text (t, 1, i + 1, TAT_PRINTF, "%.*s", print->w, temp_buf);
 
       val_lab = val_labs_find (v->val_labs, *case_data (c, v->fv));
       if (val_lab)
Index: src/language/dictionary/sys-file-info.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/sys-file-info.c,v
retrieving revision 1.16
diff -u -p -r1.16 sys-file-info.c
--- src/language/dictionary/sys-file-info.c	3 Dec 2006 22:16:45 -0000	1.16
+++ src/language/dictionary/sys-file-info.c	5 Dec 2006 06:36:43 -0000
@@ -130,7 +130,8 @@ cmd_sysfile_info (struct lexer *lexer, s
   {
     struct variable *weight_var = dict_get_weight (d);
     tab_text (t, 1, 7, TAB_LEFT,
-              weight_var != NULL ? weight_var->name : _("Not weighted.")); 
+              (weight_var != NULL
+               ? var_get_name (weight_var) : _("Not weighted."))); 
   }
   tab_text (t, 0, 8, TAB_LEFT, _("Mode:"));
   tab_text (t, 1, 8, TAB_LEFT | TAT_PRINTF,
@@ -258,7 +259,7 @@ cmd_display (struct lexer *lexer, struct
 	{
 	  size_t i, m;
 	  for (i = 0, m = n; i < n; i++)
-	    if (dict_class_from_id (vl[i]->name) != DC_SCRATCH)
+	    if (dict_class_from_id (var_get_name (vl[i])) != DC_SCRATCH)
 	      {
 		vl[i] = NULL;
 		m--;
@@ -409,10 +410,13 @@ display_variables (struct variable **vl,
 
 	  r = describe_variable (v, t, r, as);
 	} else {
-	  tab_text (t, 0, r, TAB_LEFT, v->name);
-	  if (as == AS_LABELS)
-	    tab_joint_text (t, 1, r, 2, r, TAB_LEFT,
-			    v->label == NULL ? "(no label)" : v->label);
+	  tab_text (t, 0, r, TAB_LEFT, var_get_name (v));
+	  if (as == AS_LABELS) 
+            {
+              const char *label = var_get_label (v);
+              tab_joint_text (t, 1, r, 2, r, TAB_LEFT,
+                              label != NULL ? "(no label)" : label); 
+            }
 	  if (as != AS_NAMES)
 	    {
 	      tab_text (t, pc, r, TAT_PRINTF, "%d", v->index + 1);
@@ -442,39 +446,40 @@ display_variables (struct variable **vl,
 static int 
 describe_variable (struct variable *v, struct tab_table *t, int r, int as)
 {
+  const struct fmt_spec *print = var_get_print_format (v);
+  const struct fmt_spec *write = var_get_write_format (v);
+
   /* Put the name, var label, and position into the first row. */
-  tab_text (t, 0, r, TAB_LEFT, v->name);
+  tab_text (t, 0, r, TAB_LEFT, var_get_name (v));
   tab_text (t, 3, r, TAT_PRINTF, "%d", v->index + 1);
 
-  if (as == AS_DICTIONARY && v->label)
+  if (as == AS_DICTIONARY && var_has_label (v)) 
     {
-      tab_joint_text (t, 1, r, 2, r, TAB_LEFT, v->label);
+      tab_joint_text (t, 1, r, 2, r, TAB_LEFT, var_get_label (v));
       r++;
     }
   
   /* Print/write format, or print and write formats. */
-  if (v->print.type == v->write.type
-      && v->print.w == v->write.w
-      && v->print.d == v->write.d)
+  if (fmt_equal (print, write))
     {
       char str[FMT_STRING_LEN_MAX + 1];
       tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF, _("Format: %s"),
-		      fmt_to_string (&v->print, str));
+		      fmt_to_string (print, str));
       r++;
     }
   else
     {
       char str[FMT_STRING_LEN_MAX + 1];
       tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
-		      _("Print Format: %s"), fmt_to_string (&v->print, str));
+		      _("Print Format: %s"), fmt_to_string (print, str));
       r++;
       tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
-		      _("Write Format: %s"), fmt_to_string (&v->write, str));
+		      _("Write Format: %s"), fmt_to_string (write, str));
       r++;
     }
 
   /* Missing values if any. */
-  if (!mv_is_empty (&v->miss))
+  if (var_has_missing_values (v))
     {
       char buf[128];
       char *cp;
@@ -482,7 +487,8 @@ describe_variable (struct variable *v, s
       int cnt = 0;
       
       cp = stpcpy (buf, _("Missing Values: "));
-      mv_copy (&mv, &v->miss);
+      
+      mv_copy (&mv, var_get_missing_values (v));
       if (mv_has_range (&mv)) 
         {
           double x, y;
@@ -501,13 +507,13 @@ describe_variable (struct variable *v, s
           mv_pop_value (&mv, &value);
           if (cnt++ > 0)
             cp += sprintf (cp, "; ");
-          if (v->type == NUMERIC)
+          if (var_is_numeric (v))
             cp += sprintf (cp, "%g", value.f);
           else 
             {
               *cp++ = '"';
-	      memcpy (cp, value.s, v->width);
-	      cp += v->width;
+	      memcpy (cp, value.s, var_get_width (v));
+	      cp += var_get_width (v);
 	      *cp++ = '"';
               *cp = '\0';
             }
@@ -536,10 +542,10 @@ describe_variable (struct variable *v, s
         {
 	  char buf[128];
 
-	  if (v->type == ALPHA)
+	  if (var_is_alpha (v))
 	    {
-	      memcpy (buf, vl->value.s, v->width);
-	      buf[v->width] = 0;
+	      memcpy (buf, vl->value.s, var_get_width (v));
+	      buf[var_get_width (v)] = 0;
 	    }
 	  else
 	    sprintf (buf, "%g", vl->value.f);
Index: src/language/dictionary/value-labels.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/value-labels.c,v
retrieving revision 1.12
diff -u -p -r1.12 value-labels.c
--- src/language/dictionary/value-labels.c	1 Dec 2006 06:06:52 -0000	1.12
+++ src/language/dictionary/value-labels.c	5 Dec 2006 06:36:43 -0000
@@ -118,10 +118,10 @@ verify_val_labs (struct variable **vars,
     {
       struct variable *vp = vars[i];
 
-      if (vp->type == ALPHA && vp->width > MAX_SHORT_STRING)
+      if (var_is_long_string (vp))
 	{
 	  msg (SE, _("It is not possible to assign value labels to long "
-		     "string variables such as %s."), vp->name);
+		     "string variables such as %s."), var_get_name (vp));
 	  return 0;
 	}
     }
@@ -152,7 +152,7 @@ get_label (struct lexer *lexer, struct v
       size_t i;
 
       /* Set value. */
-      if (vars[0]->type == ALPHA)
+      if (var_is_alpha (vars[0]))
 	{
 	  if (lex_token (lexer) != T_STRING)
 	    {
Index: src/language/dictionary/variable-display.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/variable-display.c,v
retrieving revision 1.10
diff -u -p -r1.10 variable-display.c
--- src/language/dictionary/variable-display.c	11 Nov 2006 23:10:00 -0000	1.10
+++ src/language/dictionary/variable-display.c	5 Dec 2006 06:36:43 -0000
@@ -71,9 +71,8 @@ cmd_variable_alignment (struct lexer *le
           return CMD_FAILURE; 
         }
 
-      for( i = 0 ; i < nv ; ++i ) 
-	v[i]->alignment = align;
-
+      for( i = 0 ; i < nv ; ++i )
+        var_set_alignment (v[i], align);
 
       while (lex_token (lexer) == '/')
 	lex_get (lexer);
@@ -110,7 +109,7 @@ cmd_variable_width (struct lexer *lexer,
 	}
 
       for( i = 0 ; i < nv ; ++i ) 
-	  v[i]->display_width = lex_tokval (lexer);
+        var_set_display_width (v[i], lex_integer (lexer));
 
       while (lex_token (lexer) == '/')
 	lex_get (lexer);
@@ -158,7 +157,7 @@ cmd_variable_level (struct lexer *lexer,
         }
       
       for( i = 0 ; i < nv ; ++i ) 
-	v[i]->measure = level ;
+	var_set_measure (v[i], level);
 
 
       while (lex_token (lexer) == '/')
Index: src/language/dictionary/variable-label.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/variable-label.c,v
retrieving revision 1.11
diff -u -p -r1.11 variable-label.c
--- src/language/dictionary/variable-label.c	11 Nov 2006 23:10:00 -0000	1.11
+++ src/language/dictionary/variable-label.c	5 Dec 2006 06:36:43 -0000
@@ -62,11 +62,7 @@ cmd_variable_labels (struct lexer *lexer
 	  ds_truncate (&label, 255);
 	}
       for (i = 0; i < nv; i++)
-	{
-	  if (v[i]->label)
-	    free (v[i]->label);
-	  v[i]->label = ds_xstrdup (&label);
-	}
+        var_set_label (v[i], ds_cstr (&label));
       ds_destroy (&label);
 
       lex_get (lexer);
@@ -83,8 +79,11 @@ cmd_variable_labels (struct lexer *lexer
 const char *
 var_to_string(const struct variable *var)
 {
+  const char *label;
+  
   if ( !var ) 
     return 0;
 
-  return ( var->label ? var->label : var->name);
+  label = var_get_label (var);
+  return label ? label : var_get_name (var);
 }
Index: src/language/dictionary/weight.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/dictionary/weight.c,v
retrieving revision 1.8
diff -u -p -r1.8 weight.c
--- src/language/dictionary/weight.c	11 Nov 2006 23:10:00 -0000	1.8
+++ src/language/dictionary/weight.c	5 Dec 2006 06:36:43 -0000
@@ -47,12 +47,12 @@ cmd_weight (struct lexer *lexer, struct 
       v = parse_variable (lexer, dict);
       if (!v)
 	return CMD_CASCADING_FAILURE;
-      if (v->type == ALPHA)
+      if (var_is_alpha (v))
 	{
 	  msg (SE, _("The weighting variable must be numeric."));
 	  return CMD_CASCADING_FAILURE;
 	}
-      if (dict_class_from_id (v->name) == DC_SCRATCH)
+      if (dict_class_from_id (var_get_name (v)) == DC_SCRATCH)
 	{
 	  msg (SE, _("The weighting variable may not be scratch."));
 	  return CMD_CASCADING_FAILURE;
Index: src/language/expressions/evaluate.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/expressions/evaluate.c,v
retrieving revision 1.11
diff -u -p -r1.11 evaluate.c
--- src/language/expressions/evaluate.c	22 Nov 2006 04:24:02 -0000	1.11
+++ src/language/expressions/evaluate.c	5 Dec 2006 06:36:43 -0000
@@ -183,7 +183,7 @@ cmd_debug_evaluate (struct lexer *lexer,
             case_data_rw (c, v->fv)->f = lex_tokval (lexer);
           else
             memcpy (case_data_rw (c, v->fv)->s, ds_data (lex_tokstr (lexer)),
-                    v->width);
+                    var_get_width (v));
           lex_get (lexer);
 
           if (!lex_force_match (lexer, ')'))
@@ -309,7 +309,7 @@ expr_debug_print_postfix (const struct e
           }
           break;
         case OP_variable:
-          fprintf (stderr, "v<%s>", op->variable->name);
+          fprintf (stderr, "v<%s>", var_get_name (op->variable));
           break;
         case OP_vector:
           fprintf (stderr, "vec<%s>", op->vector->name);
Index: src/language/expressions/operations.def
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/expressions/operations.def,v
retrieving revision 1.9
diff -u -p -r1.9 operations.def
--- src/language/expressions/operations.def	22 Nov 2006 04:24:02 -0000	1.9
+++ src/language/expressions/operations.def	5 Dec 2006 06:36:44 -0000
@@ -908,7 +908,7 @@ no_opt operator VEC_ELEM_NUM (idx)
     {
       const struct variable *var = v->var[(int) idx - 1];
       double value = case_num (c, var->fv);
-      return !mv_is_num_user_missing (&var->miss, value) ? value : SYSMIS; 
+      return !var_is_num_user_missing (var, value) ? value : SYSMIS; 
     }
   else
     {
@@ -932,7 +932,7 @@ absorb_miss no_opt string operator VEC_E
   if (idx >= 1 && idx <= v->cnt)
     {
       struct variable *var = v->var[(int) idx - 1];
-      return copy_string (e, case_str (c, var->fv), var->width);
+      return copy_string (e, case_str (c, var->fv), var_get_width (var));
     }
   else
     {
@@ -955,7 +955,7 @@ no_opt operator NUM_VAR ()
      num_var v;
 {
   double d = case_num (c, v->fv);
-  return !mv_is_num_user_missing (&v->miss, d) ? d : SYSMIS;
+  return !var_is_num_user_missing (v, d) ? d : SYSMIS;
 }
 
 no_opt string operator STR_VAR ()
@@ -963,8 +963,8 @@ no_opt string operator STR_VAR ()
      expression e;
      str_var v;
 {
-  struct substring s = alloc_string (e, v->width);
-  memcpy (s.string, case_str (c, v->fv), v->width);
+  struct substring s = alloc_string (e, var_get_width (v));
+  memcpy (s.string, case_str (c, v->fv), var_get_width (v));
   return s;
 }
 
@@ -975,7 +975,7 @@ no_opt perm_only function LAG (num_var v
   if (c != NULL)
     {
       double x = case_num (c, v->fv);
-      return !mv_is_num_user_missing (&v->miss, x) ? x : SYSMIS;
+      return !var_is_num_user_missing (v, x) ? x : SYSMIS;
     }
   else
     return SYSMIS;
@@ -988,7 +988,7 @@ no_opt perm_only function LAG (num_var v
   if (c != NULL)
     {
       double x = case_num (c, v->fv);
-      return !mv_is_num_user_missing (&v->miss, x) ? x : SYSMIS;
+      return !var_is_num_user_missing (v, x) ? x : SYSMIS;
     }
   else
     return SYSMIS;
@@ -1000,7 +1000,7 @@ no_opt perm_only string function LAG (st
 {
   struct ccase *c = lagged_case (ds, n_before);
   if (c != NULL)
-    return copy_string (e, case_str (c, v->fv), v->width);
+    return copy_string (e, case_str (c, v->fv), var_get_width (v));
   else
     return empty_string;
 }
@@ -1011,7 +1011,7 @@ no_opt perm_only string function LAG (st
 {
   struct ccase *c = lagged_case (ds, 1);
   if (c != NULL)
-    return copy_string (e, case_str (c, v->fv), v->width);
+    return copy_string (e, case_str (c, v->fv), var_get_width (v));
   else
     return empty_string;
 }
Index: src/language/expressions/parse.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/expressions/parse.c,v
retrieving revision 1.18
diff -u -p -r1.18 parse.c
--- src/language/expressions/parse.c	11 Nov 2006 23:10:00 -0000	1.18
+++ src/language/expressions/parse.c	5 Dec 2006 06:36:47 -0000
@@ -901,7 +901,7 @@ parse_vector_element (struct lexer *lexe
       || !lex_match (lexer, ')'))
     return NULL;
 
-  return expr_allocate_binary (e, (vector->var[0]->type == NUMERIC
+  return expr_allocate_binary (e, (var_is_numeric (vector->var[0])
                                    ? OP_VEC_ELEM_NUM : OP_VEC_ELEM_STR),
                                element, expr_allocate_vector (e, vector));
 }
@@ -1464,7 +1464,7 @@ union any_node *
 expr_allocate_variable (struct expression *e, struct variable *v)
 {
   union any_node *n = pool_alloc (e->expr_pool, sizeof n->variable);
-  n->type = v->type == NUMERIC ? OP_num_var : OP_str_var;
+  n->type = var_is_numeric (v) ? OP_num_var : OP_str_var;
   n->variable.v = v;
   return n;
 }
@@ -1484,6 +1484,6 @@ static union any_node *
 allocate_unary_variable (struct expression *e, struct variable *v) 
 {
   assert (v != NULL);
-  return expr_allocate_unary (e, v->type == NUMERIC ? OP_NUM_VAR : OP_STR_VAR,
+  return expr_allocate_unary (e, var_is_numeric (v) ? OP_NUM_VAR : OP_STR_VAR,
                               expr_allocate_variable (e, v));
 }
Index: src/language/lexer/variable-parser.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/lexer/variable-parser.c,v
retrieving revision 1.11
diff -u -p -r1.11 variable-parser.c
--- src/language/lexer/variable-parser.c	11 Nov 2006 23:10:00 -0000	1.11
+++ src/language/lexer/variable-parser.c	5 Dec 2006 06:36:47 -0000
@@ -148,7 +148,7 @@ parse_var_idx_class (struct lexer *lexer
   if (!parse_vs_variable_idx (lexer, vs, idx))
     return false;
 
-  *class = dict_class_from_id (var_set_get_var (vs, *idx)->name);
+  *class = dict_class_from_id (var_get_name (var_set_get_var (vs, *idx)));
   return true;
 }
 
@@ -163,24 +163,26 @@ add_variable (struct variable ***v, size
               const struct var_set *vs, size_t idx)
 {
   struct variable *add = var_set_get_var (vs, idx);
+  const char *add_name = var_get_name (add);
 
-  if ((pv_opts & PV_NUMERIC) && add->type != NUMERIC) 
+  if ((pv_opts & PV_NUMERIC) && !var_is_numeric (add)) 
     msg (SW, _("%s is not a numeric variable.  It will not be "
-               "included in the variable list."), add->name);
-  else if ((pv_opts & PV_STRING) && add->type != ALPHA) 
+               "included in the variable list."), add_name);
+  else if ((pv_opts & PV_STRING) && !var_is_alpha (add)) 
     msg (SE, _("%s is not a string variable.  It will not be "
-               "included in the variable list."), add->name);
+               "included in the variable list."), add_name);
   else if ((pv_opts & PV_NO_SCRATCH)
-           && dict_class_from_id (add->name) == DC_SCRATCH)
+           && dict_class_from_id (add_name) == DC_SCRATCH)
     msg (SE, _("Scratch variables (such as %s) are not allowed "
-               "here."), add->name);
-  else if ((pv_opts & PV_SAME_TYPE) && *nv && add->type != (*v)[0]->type) 
+               "here."), add_name);
+  else if ((pv_opts & PV_SAME_TYPE) && *nv
+           && var_get_type (add) != var_get_type ((*v)[0])) 
     msg (SE, _("%s and %s are not the same type.  All variables in "
                "this variable list must be of the same type.  %s "
                "will be omitted from list."),
-         (*v)[0]->name, add->name, add->name);
+         var_get_name ((*v)[0]), add_name, add_name);
   else if ((pv_opts & PV_NO_DUPLICATE) && included[idx]) 
-    msg (SE, _("Variable %s appears twice in variable list."), add->name);
+    msg (SE, _("Variable %s appears twice in variable list."), add_name);
   else if ((pv_opts & PV_DUPLICATE) || !included[idx])
     {
       if (*nv >= *mv)
@@ -208,7 +210,7 @@ add_variables (struct variable ***v, siz
   size_t i;
   
   for (i = first_idx; i <= last_idx; i++)
-    if (dict_class_from_id (var_set_get_var (vs, i)->name) == class)
+    if (dict_class_from_id (var_get_name (var_set_get_var (vs, i))) == class)
       add_variable (v, nv, mv, included, pv_opts, vs, i);
 }
 
@@ -285,10 +287,11 @@ parse_var_set_vars (struct lexer *lexer,
 
               if (last_idx < first_idx)
                 {
+                  const char *first_name = var_get_name (first_var);
+                  const char *last_name = var_get_name (last_var);
                   msg (SE, _("%s TO %s is not valid syntax since %s "
                              "precedes %s in the dictionary."),
-                       first_var->name, last_var->name,
-                       first_var->name, last_var->name);
+                       first_name, last_name, first_name, last_name);
                   goto fail;
                 }
 
@@ -299,8 +302,9 @@ parse_var_set_vars (struct lexer *lexer,
                              "the same variable dictionaries, of either "
                              "ordinary, scratch, or system variables.  "
                              "%s is a %s variable, whereas %s is %s."),
-                       first_var->name, dict_class_to_name (class),
-                       last_var->name, dict_class_to_name (last_class));
+                       var_get_name (first_var), dict_class_to_name (class),
+                       var_get_name (last_var),
+                       dict_class_to_name (last_class));
                   goto fail;
                 }
 
@@ -552,7 +556,7 @@ parse_mixed_vars (struct lexer *lexer, c
 	    goto fail;
 	  *names = xnrealloc (*names, *nnames + nv, sizeof **names);
 	  for (i = 0; i < nv; i++)
-	    (*names)[*nnames + i] = xstrdup (v[i]->name);
+	    (*names)[*nnames + i] = xstrdup (var_get_name (v[i]));
 	  free (v);
 	  *nnames += nv;
 	}
Index: src/language/stats/ChangeLog
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/ChangeLog,v
retrieving revision 1.31
diff -u -p -r1.31 ChangeLog
--- src/language/stats/ChangeLog	5 Nov 2006 00:35:43 -0000	1.31
+++ src/language/stats/ChangeLog	5 Dec 2006 06:36:47 -0000
@@ -1,3 +1,15 @@
+Mon Dec  4 22:33:46 2006  Ben Pfaff  <blp@gnu.org>
+
+	* crosstabs.q (insert_summary): Use var_to_string for labeling.
+	(output_pivot_table) Ditto.
+	(submit) Ditto.
+
+	* frequencies.q (setup_z_trns): Ditto.
+	(dump_full) Ditto.
+	(dump_condensed) Ditto.
+	(dump_statistics) Ditto.
+	
+
 Sun Nov  5 08:31:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
 
 	* t-test.q, oneway.q: Changed to use the new casefilter structure.
Index: src/language/stats/aggregate.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/aggregate.c,v
retrieving revision 1.20
diff -u -p -r1.20 aggregate.c
--- src/language/stats/aggregate.c	25 Nov 2006 02:15:01 -0000	1.20
+++ src/language/stats/aggregate.c	5 Dec 2006 06:36:47 -0000
@@ -237,7 +237,7 @@ cmd_aggregate (struct lexer *lexer, stru
 	  
           for (i = 0; i < agr.break_var_cnt; i++)
             dict_clone_var_assert (agr.dict, agr.break_vars[i],
-                                   agr.break_vars[i]->name);
+                                   var_get_name (agr.break_vars[i]));
 
           /* BREAK must follow the options. */
           break;
@@ -508,7 +508,7 @@ parse_aggregate_functions (struct lexer 
 	    
 		lex_get (lexer);
 
-		if (type != src[0]->type)
+		if (type != var_get_type (src[0]))
 		  {
 		    msg (SE, _("Arguments to %s must be of same type as "
 			       "source variables."),
@@ -540,9 +540,9 @@ parse_aggregate_functions (struct lexer 
 
           if ((func_index == PIN || func_index == POUT
               || func_index == FIN || func_index == FOUT) 
-              && ((src[0]->type == NUMERIC && arg[0].f > arg[1].f)
-                  || (src[0]->type == ALPHA
-                      && str_compare_rpad (arg[0].c, arg[1].c) > 0)))
+              && (var_is_numeric (src[0])
+                  ? arg[0].f > arg[1].f
+                  : str_compare_rpad (arg[0].c, arg[1].c) > 0))
             {
               union agr_argument t = arg[0];
               arg[0] = arg[1];
@@ -581,17 +581,17 @@ parse_aggregate_functions (struct lexer 
 	      {
 		v->src = src[i];
 		
-		if (src[i]->type == ALPHA)
+		if (var_is_alpha (src[i]))
 		  {
 		    v->function |= FSTRING;
-		    v->string = xmalloc (src[i]->width);
+		    v->string = xmalloc (var_get_width (src[i]));
 		  }
 
 		if (function->alpha_type == ALPHA)
 		  destvar = dict_clone_var (agr->dict, v->src, dest[i]);
 		else
                   {
-                    assert (v->src->type == NUMERIC
+                    assert (var_is_numeric (v->src)
                             || function->alpha_type == NUMERIC);
                     destvar = dict_create_var (agr->dict, dest[i], 0);
                     if (destvar != NULL) 
@@ -602,7 +602,7 @@ parse_aggregate_functions (struct lexer 
                           f = fmt_for_output (FMT_F, 8, 2); 
                         else
                           f = function->format;
-                        destvar->print = destvar->write = f;
+                        var_set_both_formats (destvar, &f);
                       }
                   }
 	      } else {
@@ -613,7 +613,7 @@ parse_aggregate_functions (struct lexer 
                   f = fmt_for_output (FMT_F, 8, 2); 
                 else
                   f = function->format;
-                destvar->print = destvar->write = f;
+                var_set_both_formats (destvar, &f);
 	      }
 	  
 	    if (!destvar)
@@ -628,10 +628,7 @@ parse_aggregate_functions (struct lexer 
 
 	    free (dest[i]);
 	    if (dest_label[i])
-	      {
-		destvar->label = dest_label[i];
-		dest_label[i] = NULL;
-	      }
+              var_set_label (destvar, dest_label[i]);
 
 	    v->dest = destvar;
 	  }
@@ -642,7 +639,7 @@ parse_aggregate_functions (struct lexer 
 	    {
 	      int j;
 
-	      if (v->src->type == NUMERIC)
+	      if (var_is_numeric (v->src))
 		for (j = 0; j < function->n_args; j++)
 		  v->arg[j].f = arg[j].f;
 	      else
@@ -651,7 +648,7 @@ parse_aggregate_functions (struct lexer 
 	    }
 	}
       
-      if (src != NULL && src[0]->type == ALPHA)
+      if (src != NULL && var_is_alpha (src[0]))
 	for (i = 0; i < function->n_args; i++)
 	  {
 	    free (arg[i].c);
@@ -683,7 +680,7 @@ parse_aggregate_functions (struct lexer 
       free (dest_label);
       free (arg[0].c);
       free (arg[1].c);
-      if (src && n_src && src[0]->type == ALPHA)
+      if (src && n_src && var_is_alpha (src[0]))
 	for (i = 0; i < function->n_args; i++)
 	  {
 	    free (arg[i].c);
@@ -775,11 +772,11 @@ accumulate_aggregate_info (struct agr_pr
     if (iter->src)
       {
 	const union value *v = case_data (input, iter->src->fv);
+        int src_width = var_get_width (iter->src);
 
-	if ((!iter->include_missing
-             && mv_is_value_missing (&iter->src->miss, v))
-	    || (iter->include_missing && iter->src->type == NUMERIC
-		&& v->f == SYSMIS))
+	if (iter->include_missing
+            ? var_is_numeric (iter->src) && v->f == SYSMIS
+            : var_is_value_missing (iter->src, v))
 	  {
 	    switch (iter->function)
 	      {
@@ -815,8 +812,8 @@ accumulate_aggregate_info (struct agr_pr
 	    iter->int1 = 1;
 	    break;
 	  case MAX | FSTRING:
-	    if (memcmp (iter->string, v->s, iter->src->width) < 0)
-	      memcpy (iter->string, v->s, iter->src->width);
+	    if (memcmp (iter->string, v->s, src_width) < 0)
+	      memcpy (iter->string, v->s, src_width);
 	    iter->int1 = 1;
 	    break;
 	  case MIN:
@@ -824,8 +821,8 @@ accumulate_aggregate_info (struct agr_pr
 	    iter->int1 = 1;
 	    break;
 	  case MIN | FSTRING:
-	    if (memcmp (iter->string, v->s, iter->src->width) > 0)
-	      memcpy (iter->string, v->s, iter->src->width);
+	    if (memcmp (iter->string, v->s, src_width) > 0)
+	      memcpy (iter->string, v->s, src_width);
 	    iter->int1 = 1;
 	    break;
 	  case FGT:
@@ -836,7 +833,7 @@ accumulate_aggregate_info (struct agr_pr
             break;
 	  case FGT | FSTRING:
 	  case PGT | FSTRING:
-            if (memcmp (iter->arg[0].c, v->s, iter->src->width) < 0)
+            if (memcmp (iter->arg[0].c, v->s, src_width) < 0)
               iter->dbl[0] += weight;
             iter->dbl[1] += weight;
             break;
@@ -848,7 +845,7 @@ accumulate_aggregate_info (struct agr_pr
             break;
 	  case FLT | FSTRING:
 	  case PLT | FSTRING:
-            if (memcmp (iter->arg[0].c, v->s, iter->src->width) > 0)
+            if (memcmp (iter->arg[0].c, v->s, src_width) > 0)
               iter->dbl[0] += weight;
             iter->dbl[1] += weight;
             break;
@@ -860,8 +857,8 @@ accumulate_aggregate_info (struct agr_pr
             break;
 	  case FIN | FSTRING:
 	  case PIN | FSTRING:
-            if (memcmp (iter->arg[0].c, v->s, iter->src->width) <= 0
-                && memcmp (iter->arg[1].c, v->s, iter->src->width) >= 0)
+            if (memcmp (iter->arg[0].c, v->s, src_width) <= 0
+                && memcmp (iter->arg[1].c, v->s, src_width) >= 0)
               iter->dbl[0] += weight;
             iter->dbl[1] += weight;
             break;
@@ -873,8 +870,8 @@ accumulate_aggregate_info (struct agr_pr
             break;
 	  case FOUT | FSTRING:
 	  case POUT | FSTRING:
-            if (memcmp (iter->arg[0].c, v->s, iter->src->width) > 0
-                || memcmp (iter->arg[1].c, v->s, iter->src->width) < 0)
+            if (memcmp (iter->arg[0].c, v->s, src_width) > 0
+                || memcmp (iter->arg[1].c, v->s, src_width) < 0)
               iter->dbl[0] += weight;
             iter->dbl[1] += weight;
             break;
@@ -896,7 +893,7 @@ accumulate_aggregate_info (struct agr_pr
 	  case FIRST | FSTRING:
 	    if (iter->int1 == 0)
 	      {
-		memcpy (iter->string, v->s, iter->src->width);
+		memcpy (iter->string, v->s, src_width);
 		iter->int1 = 1;
 	      }
 	    break;
@@ -905,7 +902,7 @@ accumulate_aggregate_info (struct agr_pr
 	    iter->int1 = 1;
 	    break;
 	  case LAST | FSTRING:
-	    memcpy (iter->string, v->s, iter->src->width);
+	    memcpy (iter->string, v->s, src_width);
 	    iter->int1 = 1;
 	    break;
           case NMISS:
@@ -946,10 +943,11 @@ dump_aggregate_info (struct agr_proc *ag
     for (i = 0; i < agr->break_var_cnt; i++) 
       {
         struct variable *v = agr->break_vars[i];
+        size_t value_cnt = var_get_value_cnt (v);
         memcpy (case_data_rw (output, value_idx),
                 case_data (&agr->break_case, v->fv),
-                sizeof (union value) * v->nv);
-        value_idx += v->nv; 
+                sizeof (union value) * value_cnt);
+        value_idx += value_cnt; 
       }
   }
   
@@ -964,8 +962,8 @@ dump_aggregate_info (struct agr_proc *ag
 	    && (i->function & FUNC) != N && (i->function & FUNC) != NU
 	    && (i->function & FUNC) != NMISS && (i->function & FUNC) != NUMISS)
 	  {
-	    if (i->dest->type == ALPHA)
-	      memset (v->s, ' ', i->dest->width);
+	    if (var_is_alpha (i->dest))
+	      memset (v->s, ' ', var_get_width (i->dest));
 	    else
 	      v->f = SYSMIS;
 	    continue;
@@ -999,9 +997,9 @@ dump_aggregate_info (struct agr_proc *ag
 	  case MAX | FSTRING:
 	  case MIN | FSTRING:
 	    if (i->int1)
-	      memcpy (v->s, i->string, i->dest->width);
+	      memcpy (v->s, i->string, var_get_width (i->dest));
 	    else
-	      memset (v->s, ' ', i->dest->width);
+	      memset (v->s, ' ', var_get_width (i->dest));
 	    break;
 	  case FGT:
 	  case FGT | FSTRING:
@@ -1038,9 +1036,9 @@ dump_aggregate_info (struct agr_proc *ag
 	  case FIRST | FSTRING:
 	  case LAST | FSTRING:
 	    if (i->int1)
-	      memcpy (v->s, i->string, i->dest->width);
+	      memcpy (v->s, i->string, var_get_width (i->dest));
 	    else
-	      memset (v->s, ' ', i->dest->width);
+	      memset (v->s, ' ', var_get_width (i->dest));
 	    break;
 	  case N_NO_VARS:
 	    v->f = i->dbl[0];
@@ -1083,13 +1081,13 @@ initialize_aggregate_info (struct agr_pr
 	  iter->dbl[0] = DBL_MAX;
 	  break;
 	case MIN | FSTRING:
-	  memset (iter->string, 255, iter->src->width);
+	  memset (iter->string, 255, var_get_width (iter->src));
 	  break;
 	case MAX:
 	  iter->dbl[0] = -DBL_MAX;
 	  break;
 	case MAX | FSTRING:
-	  memset (iter->string, 0, iter->src->width);
+	  memset (iter->string, 0, var_get_width (iter->src));
 	  break;
         case SD:
           if (iter->moments == NULL)
Index: src/language/stats/autorecode.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/autorecode.c,v
retrieving revision 1.14
diff -u -p -r1.14 autorecode.c
--- src/language/stats/autorecode.c	11 Nov 2006 23:10:00 -0000	1.14
+++ src/language/stats/autorecode.c	5 Dec 2006 06:36:47 -0000
@@ -178,7 +178,7 @@ cmd_autorecode (struct lexer *lexer, str
   arc.dst_vars = xnmalloc (arc.var_cnt, sizeof *arc.dst_vars);
   arc.src_values = xnmalloc (arc.var_cnt, sizeof *arc.src_values);
   for (i = 0; i < dst_cnt; i++)
-    if (arc.src_vars[i]->type == ALPHA)
+    if (var_is_alpha (arc.src_vars[i]))
       arc.src_values[i] = hsh_create (10, compare_alpha_value,
                                       hash_alpha_value, NULL, arc.src_vars[i]);
     else
@@ -246,7 +246,7 @@ recode (struct dataset *ds, const struct
       spec->src = arc->src_vars[i];
       spec->dest = arc->dst_vars[i];
 
-      if (arc->src_vars[i]->type == ALPHA)
+      if (var_is_alpha (arc->src_vars[i]))
 	spec->items = hsh_create (2 * count, compare_alpha_value,
 				  hash_alpha_value, NULL, arc->src_vars[i]);
       else
@@ -258,11 +258,11 @@ recode (struct dataset *ds, const struct
 	  struct arc_item *item = pool_alloc (trns->pool, sizeof *item);
           union arc_value *vp = *p;
           
-	  if (arc->src_vars[i]->type == NUMERIC)
+	  if (var_is_numeric (arc->src_vars[i]))
             item->from.f = vp->f;
           else
 	    item->from.c = pool_clone (trns->pool, vp->c,
-                                       arc->src_vars[i]->width);
+                                       var_get_width (arc->src_vars[i]));
 	  item->to = arc->direction == ASCENDING ? j + 1 : count - j;
 	  hsh_force_insert (spec->items, item);
 	}
@@ -284,7 +284,7 @@ autorecode_trns_proc (void *trns_, struc
       struct arc_item *item;
       union arc_value v;
 
-      if (spec->src->type == NUMERIC)
+      if (var_is_numeric (spec->src))
         v.f = case_num (c, spec->src->fv);
       else
         v.c = (char *) case_str (c, spec->src->fv);
@@ -317,7 +317,7 @@ compare_alpha_value (const void *a_, con
   const union arc_value *b = b_;
   const struct variable *v = v_;
 
-  return memcmp (a->c, b->c, v->width);
+  return memcmp (a->c, b->c, var_get_width (v));
 }
 
 static unsigned
@@ -326,7 +326,7 @@ hash_alpha_value (const void *a_, const 
   const union arc_value *a = a_;
   const struct variable *v = v_;
   
-  return hsh_hash_bytes (a->c, v->width);
+  return hsh_hash_bytes (a->c, var_get_width (v));
 }
 
 static int
@@ -356,7 +356,7 @@ autorecode_proc_func (const struct ccase
     {
       union arc_value v, *vp, **vpp;
 
-      if (arc->src_vars[i]->type == NUMERIC)
+      if (var_is_numeric (arc->src_vars[i]))
         v.f = case_num (c, arc->src_vars[i]->fv);
       else
         v.c = (char *) case_str (c, arc->src_vars[i]->fv);
@@ -365,11 +365,11 @@ autorecode_proc_func (const struct ccase
       if (*vpp == NULL)
         {
           vp = pool_alloc (arc->src_values_pool, sizeof *vp);
-          if (arc->src_vars[i]->type == NUMERIC)
+          if (var_is_numeric (arc->src_vars[i]))
             vp->f = v.f;
           else
             vp->c = pool_clone (arc->src_values_pool,
-                                v.c, arc->src_vars[i]->width);
+                                v.c, var_get_width (arc->src_vars[i]));
           *vpp = vp;
         }
     }
Index: src/language/stats/crosstabs.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/crosstabs.q,v
retrieving revision 1.23
diff -u -p -r1.23 crosstabs.q
--- src/language/stats/crosstabs.q	25 Nov 2006 02:15:01 -0000	1.23
+++ src/language/stats/crosstabs.q	5 Dec 2006 06:36:48 -0000
@@ -593,25 +593,24 @@ calc_general (const struct ccase *c, voi
 	for (j = 0; j < x->nvar; j++)
 	  {
             const union value *v = case_data (c, x->vars[j]->fv);
-            const struct missing_values *mv = &x->vars[j]->miss;
-	    if ((cmd.miss == CRS_TABLE && mv_is_value_missing (mv, v))
+	    if ((cmd.miss == CRS_TABLE && var_is_value_missing (x->vars[j], v))
 		|| (cmd.miss == CRS_INCLUDE
-		    && mv_is_value_system_missing (mv, v)))
+		    && var_is_value_system_missing (x->vars[j], v)))
 	      {
 		x->missing += weight;
 		goto next_crosstab;
 	      }
 	      
-	    if (x->vars[j]->type == NUMERIC)
+	    if (var_is_numeric (x->vars[j]))
 	      te->values[j].f = case_num (c, x->vars[j]->fv);
 	    else
 	      {
 		memcpy (te->values[j].s, case_str (c, x->vars[j]->fv),
-                        x->vars[j]->width);
+                        var_get_width (x->vars[j]));
 	      
 		/* Necessary in order to simplify comparisons. */
-		memset (&te->values[j].s[x->vars[j]->width], 0,
-			sizeof (union value) - x->vars[j]->width);
+		memset (&te->values[j].s[var_get_width (x->vars[j])], 0,
+			sizeof (union value) - var_get_width (x->vars[j]));
 	      }
 	  }
       }
@@ -666,8 +665,7 @@ calc_integer (const struct ccase *c, voi
 	  
 	  /* Note that the first test also rules out SYSMIS. */
 	  if ((value < vr->min || value >= vr->max)
-	      || (cmd.miss == CRS_TABLE
-                  && mv_is_num_user_missing (&v->miss, value)))
+	      || (cmd.miss == CRS_TABLE && var_is_num_user_missing (v, value)))
 	    {
 	      x->missing += weight;
 	      goto next_crosstab;
@@ -716,7 +714,7 @@ compare_table_entry (const void *a_, con
     int i;
 
     for (i = x->nvar - 1; i >= 0; i--)
-      if (x->vars[i]->type == NUMERIC)
+      if (var_is_numeric (x->vars[i]))
 	{
 	  const double diffnum = a->values[i].f - b->values[i].f;
 	  if (diffnum < 0)
@@ -725,15 +723,12 @@ compare_table_entry (const void *a_, con
 	    return 1;
 	}
       else 
-	{
-	  assert (x->vars[i]->type == ALPHA);
-	  {
-	    const int diffstr = strncmp (a->values[i].s, b->values[i].s,
-                                         x->vars[i]->width);
-	    if (diffstr)
-	      return diffstr;
-	  }
-	}
+        {
+          const int diffstr = strncmp (a->values[i].s, b->values[i].s,
+                                       var_get_width (x->vars[i]));
+          if (diffstr)
+            return diffstr;
+        }
   }
   
   return 0;
@@ -902,8 +897,7 @@ insert_summary (struct tab_table *t, int
 	if (i > 0)
 	  cp = stpcpy (cp, " * ");
 
-	cp = stpcpy (cp,
-                     x->vars[i]->label ? x->vars[i]->label : x->vars[i]->name);
+	cp = stpcpy (cp, var_to_string (x->vars[i]));
       }
     tab_text (t, 0, 0, TAB_LEFT, buf);
 
@@ -1010,7 +1004,7 @@ output_pivot_table (struct table_entry *
 
       /* First header line. */
       tab_joint_text (table, nvar - 1, 0, (nvar - 1) + (n_cols - 1), 0,
-		      TAB_CENTER | TAT_TITLE, x->vars[COL_VAR]->name);
+		      TAB_CENTER | TAT_TITLE, var_get_name (x->vars[COL_VAR]));
   
       tab_hline (table, TAL_1, nvar - 1, nvar + n_cols - 2, 1);
 	     
@@ -1020,11 +1014,9 @@ output_pivot_table (struct table_entry *
 
 	for (i = 2; i < nvar; i++)
 	  tab_joint_text (table, nvar - i - 1, 0, nvar - i - 1, 1,
-			  TAB_RIGHT | TAT_TITLE,
-			  (x->vars[i]->label
-                           ? x->vars[i]->label : x->vars[i]->name));
+			  TAB_RIGHT | TAT_TITLE, var_to_string (x->vars[i]));
 	tab_text (table, nvar - 2, 1, TAB_RIGHT | TAT_TITLE,
-		  x->vars[ROW_VAR]->name);
+		  var_get_name (x->vars[ROW_VAR]));
 	for (i = 0; i < n_cols; i++)
 	  table_value_missing (table, nvar + i - 1, 1, TAB_RIGHT, &cols[i],
 			       x->vars[COL_VAR]);
@@ -1045,12 +1037,13 @@ output_pivot_table (struct table_entry *
 	    {
 	      if (i)
 		cp = stpcpy (cp, " by ");
-	      cp = stpcpy (cp, x->vars[i]->name);
+	      cp = stpcpy (cp, var_get_name (x->vars[i]));
 	    }
 	else
 	  {
 	    cp = spprintf (cp, "%s by %s for",
-                           x->vars[0]->name, x->vars[1]->name);
+                           var_get_name (x->vars[0]),
+                           var_get_name (x->vars[1]));
 	    for (i = 2; i < nvar; i++)
 	      {
 		char buf[64], *bufp;
@@ -1058,9 +1051,10 @@ output_pivot_table (struct table_entry *
 		if (i > 2)
 		  *cp++ = ',';
 		*cp++ = ' ';
-		cp = stpcpy (cp, x->vars[i]->name);
+		cp = stpcpy (cp, var_get_name (x->vars[i]));
 		*cp++ = '=';
-		format_short (buf, &x->vars[i]->print, &(*pb)->values[i]);
+		format_short (buf, var_get_print_format (x->vars[i]),
+                              &(*pb)->values[i]);
 		for (bufp = buf; isspace ((unsigned char) *bufp); bufp++)
 		  ;
 		cp = stpcpy (cp, bufp);
@@ -1429,7 +1423,7 @@ delete_missing (void)
     int r;
 
     for (r = 0; r < n_rows; r++)
-      if (mv_is_num_user_missing (&x->vars[ROW_VAR]->miss, rows[r].f))
+      if (var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f))
 	{
 	  int c;
 
@@ -1443,7 +1437,7 @@ delete_missing (void)
     int c;
 
     for (c = 0; c < n_cols; c++)
-      if (mv_is_num_user_missing (&x->vars[COL_VAR]->miss, cols[c].f))
+      if (var_is_num_user_missing (x->vars[COL_VAR], cols[c].f))
 	{
 	  int r;
 
@@ -1473,7 +1467,7 @@ submit (struct tab_table *t)
   if (t != table)
     for (i = 2; i < nvar; i++)
       tab_text (t, nvar - i - 1, 0, TAB_RIGHT | TAT_TITLE,
-		x->vars[i]->label ? x->vars[i]->label : x->vars[i]->name);
+                var_to_string (x->vars[i]));
   tab_box (t, TAL_2, TAL_2, -1, -1, 0, 0, tab_nc (t) - 1, tab_nr (t) - 1);
   tab_box (t, -1, -1, -1, TAL_1, tab_l (t), tab_t (t) - 1, tab_nc (t) - 1,
 	   tab_nr (t) - 1);
@@ -1641,7 +1635,7 @@ enum_var_values (struct table_entry **en
 
   if (mode == GENERAL)
     {
-      int width = v->width;
+      int width = var_get_width (v);
       int i;
 
       *values = xnmalloc (entry_cnt, sizeof **values);
@@ -1671,6 +1665,7 @@ table_value_missing (struct tab_table *t
 		     const union value *v, const struct variable *var)
 {
   struct substring s;
+  const struct fmt_spec *print = var_get_print_format (var);
 
   const char *label = val_labs_find (var->val_labs, *v);
   if (label) 
@@ -1679,10 +1674,10 @@ table_value_missing (struct tab_table *t
       return;
     }
 
-  s.string = tab_alloc (table, var->print.w);
-  format_short (s.string, &var->print, v);
+  s.string = tab_alloc (table, print->w);
+  format_short (s.string, print, v);
   s.length = strlen (s.string);
-  if (cmd.miss == CRS_REPORT && mv_is_num_user_missing (&var->miss, v->f))
+  if (cmd.miss == CRS_REPORT && var_is_num_user_missing (var, v->f))
     s.string[s.length++] = 'M';
   while (s.length && *s.string == ' ')
     {
@@ -1765,9 +1760,8 @@ display_crosstabulation (void)
             bool mark_missing = false;
             double expected_value = row_tot[r] * col_tot[c] / W;
             if (cmd.miss == CRS_REPORT
-                && (mv_is_num_user_missing (&x->vars[COL_VAR]->miss, cols[c].f)
-                    || mv_is_num_user_missing (&x->vars[ROW_VAR]->miss,
-                                               rows[r].f)))
+                && (var_is_num_user_missing (x->vars[COL_VAR], cols[c].f)
+                    || var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f)))
               mark_missing = true;
 	    for (i = 0; i < num_cells; i++)
 	      {
@@ -1831,7 +1825,7 @@ display_crosstabulation (void)
         bool mark_missing = false;
 
         if (cmd.miss == CRS_REPORT
-            && mv_is_num_user_missing (&x->vars[ROW_VAR]->miss, rows[r].f))
+            && var_is_num_user_missing (x->vars[ROW_VAR], rows[r].f))
           mark_missing = true;
 
         for (i = 0; i < num_cells; i++)
@@ -1886,7 +1880,7 @@ display_crosstabulation (void)
         int i;
 	    
         if (cmd.miss == CRS_REPORT && c < n_cols 
-            && mv_is_num_user_missing (&x->vars[COL_VAR]->miss, cols[c].f))
+            && var_is_num_user_missing (x->vars[COL_VAR], cols[c].f))
           mark_missing = true;
 
         for (i = 0; i < num_cells; i++)
@@ -2082,24 +2076,24 @@ display_risk (void)
       switch (i)
 	{
 	case 0:
-	  if (x->vars[COL_VAR]->type == NUMERIC)
+	  if (var_is_numeric (x->vars[COL_VAR]))
 	    sprintf (buf, _("Odds Ratio for %s (%g / %g)"),
-		     x->vars[COL_VAR]->name, c[0].f, c[1].f);
+		     var_get_name (x->vars[COL_VAR]), c[0].f, c[1].f);
 	  else
 	    sprintf (buf, _("Odds Ratio for %s (%.*s / %.*s)"),
-		     x->vars[COL_VAR]->name,
-		     x->vars[COL_VAR]->width, c[0].s,
-		     x->vars[COL_VAR]->width, c[1].s);
+		     var_get_name (x->vars[COL_VAR]),
+		     var_get_width (x->vars[COL_VAR]), c[0].s,
+		     var_get_width (x->vars[COL_VAR]), c[1].s);
 	  break;
 	case 1:
 	case 2:
-	  if (x->vars[ROW_VAR]->type == NUMERIC)
+	  if (var_is_numeric (x->vars[ROW_VAR]))
 	    sprintf (buf, _("For cohort %s = %g"),
-		     x->vars[ROW_VAR]->name, rows[i - 1].f);
+		     var_get_name (x->vars[ROW_VAR]), rows[i - 1].f);
 	  else
 	    sprintf (buf, _("For cohort %s = %.*s"),
-		     x->vars[ROW_VAR]->name,
-		     x->vars[ROW_VAR]->width, rows[i - 1].s);
+		     var_get_name (x->vars[ROW_VAR]),
+		     var_get_width (x->vars[ROW_VAR]), rows[i - 1].s);
 	  break;
 	}
 		   
@@ -2208,15 +2202,15 @@ display_directional (void)
 	      
 	      for (; j < 3; j++)
 		{
-		  char *string;
+		  const char *string;
 		  int k = last[j] = stats_lookup[j][i];
 
 		  if (k == 0)
 		    string = NULL;
 		  else if (k == 1)
-		    string = x->vars[0]->name;
+		    string = var_get_name (x->vars[0]);
 		  else
-		    string = x->vars[1]->name;
+		    string = var_get_name (x->vars[1]);
 		  
 		  tab_text (direct, j, 0, TAB_LEFT | TAT_PRINTF,
 			    gettext (stats_names[j][k]), string);
@@ -2386,7 +2380,7 @@ calc_chisq (double chisq[N_CHISQ], int d
     }
 
   /* Calculate Mantel-Haenszel. */
-  if (x->vars[ROW_VAR]->type == NUMERIC && x->vars[COL_VAR]->type == NUMERIC)
+  if (var_is_numeric (x->vars[ROW_VAR]) && var_is_numeric (x->vars[COL_VAR]))
     {
       double r, ase_0, ase_1;
       calc_r ((double *) rows, (double *) cols, &r, &ase_0, &ase_1);
Index: src/language/stats/descriptives.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/descriptives.c,v
retrieving revision 1.17
diff -u -p -r1.17 descriptives.c
--- src/language/stats/descriptives.c	11 Nov 2006 23:10:00 -0000	1.17
+++ src/language/stats/descriptives.c	5 Dec 2006 06:36:49 -0000
@@ -378,7 +378,8 @@ cmd_descriptives (struct lexer *lexer, s
             if (dsc->vars[i].z_name[0] == 0) 
               {
                 if (!generate_z_varname (dict, dsc, dsc->vars[i].z_name,
-                                         dsc->vars[i].v->name, &gen_cnt))
+                                         var_get_name (dsc->vars[i].v),
+                                         &gen_cnt))
                   goto error;
                 z_cnt++;
               } 
@@ -567,7 +568,7 @@ dump_z_table (struct dsc_proc *dsc)
     for (i = 0, y = 1; i < dsc->var_cnt; i++)
       if (dsc->vars[i].z_name[0] != '\0')
 	{
-	  tab_text (t, 0, y, TAB_LEFT, dsc->vars[i].v->name);
+	  tab_text (t, 0, y, TAB_LEFT, var_get_name (dsc->vars[i].v));
 	  tab_text (t, 1, y++, TAB_LEFT, dsc->vars[i].z_name);
 	}
   }
@@ -598,7 +599,7 @@ descriptives_trns_proc (void *trns_, str
 	  double score = case_num (c, (*vars)->fv);
 	  if ( score == SYSMIS
                || (!t->include_user_missing 
-                   && mv_is_num_user_missing (&(*vars)->miss, score)))
+                   && var_is_num_user_missing (*vars, score)))
 	    {
 	      all_sysmis = 1;
 	      break;
@@ -614,7 +615,7 @@ descriptives_trns_proc (void *trns_, str
       if (z->mean == SYSMIS || z->std_dev == SYSMIS 
 	  || all_sysmis || input == SYSMIS 
 	  || (!t->include_user_missing
-              && mv_is_num_user_missing (&z->v->miss, input)))
+              && var_is_num_user_missing (z->v, input)))
 	*output = SYSMIS;
       else
 	*output = (input - z->mean) / z->std_dev;
@@ -669,22 +670,11 @@ setup_z_trns (struct dsc_proc *dsc, stru
       if (dv->z_name[0] != '\0')
 	{
           struct dsc_z_score *z;
-	  char *cp;
 	  struct variable *dst_var;
 
 	  dst_var = dict_create_var_assert (dataset_dict (ds), dv->z_name, 0);
-	  if (dv->v->label)
-	    {
-	      dst_var->label = xmalloc (strlen (dv->v->label) + 12);
-	      cp = stpcpy (dst_var->label, _("Z-score of "));
-	      strcpy (cp, dv->v->label);
-	    }
-	  else
-	    {
-	      dst_var->label = xmalloc (strlen (dv->v->name) + 12);
-	      cp = stpcpy (dst_var->label, _("Z-score of "));
-	      strcpy (cp, dv->v->name);
-	    }
+          var_set_label (dst_var, xasprintf (_("Z-score of %s"),
+                                             var_to_string (dv->v)));
 
           z = &t->z_scores[cnt++];
           z->src_idx = dv->v->fv;
@@ -756,7 +746,7 @@ calc_descriptives (const struct ccase *f
           if (dsc->missing_type != DSC_LISTWISE
               && (x == SYSMIS
                   || (!dsc->include_user_missing
-                      && mv_is_num_user_missing (&dv->v->miss, x))))
+                      && var_is_num_user_missing (dv->v, x))))
             {
               dv->missing += weight;
               continue;
@@ -798,7 +788,7 @@ calc_descriptives (const struct ccase *f
               if (dsc->missing_type != DSC_LISTWISE
                   && (x == SYSMIS
                       || (!dsc->include_user_missing
-                          && mv_is_num_user_missing (&dv->v->miss, x))))
+                          && var_is_num_user_missing (dv->v, x))))
                 continue;
 
               if (dv->moments != NULL)
@@ -864,7 +854,7 @@ listwise_missing (struct dsc_proc *dsc, 
 
       if (x == SYSMIS
           || (!dsc->include_user_missing
-              && mv_is_num_user_missing (&dv->v->miss, x)))
+              && var_is_num_user_missing (dv->v, x)))
         return true;
     }
   return false;
@@ -922,7 +912,7 @@ display (struct dsc_proc *dsc)
       size_t j;
 
       nc = 0;
-      tab_text (t, nc++, i + 1, TAB_LEFT, dv->v->name);
+      tab_text (t, nc++, i + 1, TAB_LEFT, var_get_name (dv->v));
       tab_text (t, nc++, i + 1, TAT_PRINTF, "%g", dv->valid);
       if (dsc->format == DSC_SERIAL)
 	tab_text (t, nc++, i + 1, TAT_PRINTF, "%g", dv->missing);
@@ -949,7 +939,7 @@ descriptives_compare_dsc_vars (const voi
   int result;
 
   if (dsc->sort_by_stat == DSC_NAME)
-    result = strcasecmp (a->v->name, b->v->name);
+    result = strcasecmp (var_get_name (a->v), var_get_name (b->v));
   else 
     {
       double as = a->stats[dsc->sort_by_stat];
Index: src/language/stats/examine.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/examine.q,v
retrieving revision 1.17
diff -u -p -r1.17 examine.q
--- src/language/stats/examine.q	25 Nov 2006 02:15:01 -0000	1.17
+++ src/language/stats/examine.q	5 Dec 2006 06:36:50 -0000
@@ -180,7 +180,7 @@ const char *factor_to_string_concise (co
 
 
 /* Function to use for testing for missing values */
-static is_missing_func *value_is_missing;
+static var_is_missing_func *value_is_missing;
 
 
 /* PERCENTILES */
@@ -208,9 +208,9 @@ cmd_examine (struct lexer *lexer, struct
 
   /* If /MISSING=INCLUDE is set, then user missing values are ignored */
   if (cmd.incl == XMN_INCLUDE ) 
-    value_is_missing = mv_is_value_system_missing;
+    value_is_missing = var_is_value_system_missing;
   else
-    value_is_missing = mv_is_value_missing;
+    value_is_missing = var_is_value_missing;
 
   if ( cmd.st_n == SYSMIS ) 
     cmd.st_n = 5;
@@ -678,7 +678,7 @@ factor_calc (struct ccase *c, int case_n
 	  const struct variable *var = dependent_vars[v];
 	  const union value *val = case_data (c, var->fv);
 
-	  if ( value_is_missing (&var->miss, val) || case_missing ) 
+	  if ( value_is_missing (var, val) || case_missing ) 
 	    val = 0;
 	  
 	  metrics_calc ( & (*foo)->m[v], val, weight, case_no);
@@ -740,7 +740,7 @@ run_examine (const struct ccase *first, 
 	      const struct variable *var = dependent_vars[v];
 	      const union value *val = case_data (&c, var->fv);
 
-	      if ( value_is_missing (&var->miss, val))
+	      if ( value_is_missing (var, val))
 		case_missing = 1;
 		   
 	    }
@@ -751,7 +751,7 @@ run_examine (const struct ccase *first, 
 	  const struct variable *var = dependent_vars[v];
 	  const union value *val = case_data (&c, var->fv);
 
-	  if ( value_is_missing (&var->miss, val) || case_missing ) 
+	  if ( value_is_missing (var, val) || case_missing ) 
 	    val = 0;
 
 	  metrics_calc (&totals[v], val, weight, case_no);
@@ -1023,7 +1023,7 @@ show_summary (struct variable **dependen
 	      static union value prev;
 	      
 	      if ( 0 != compare_values (&prev, & (*fs)->id[0], 
-				       fctr->indep_var[0]->width))
+                                        var_get_width (fctr->indep_var[0])))
 		{
 		  tab_text (tbl, 
 			    1,
@@ -1196,7 +1196,7 @@ show_extremes (struct variable **depende
 
 
 	      if ( 0 != compare_values (&prev, & (*fs)->id[0], 
-				       fctr->indep_var[0]->width))
+                                        var_get_width (fctr->indep_var[0])))
 		{
 		  
 		  if ( count > 0 ) 
@@ -1434,7 +1434,7 @@ show_descriptives (struct variable **dep
 
 
 	      if ( 0 != compare_values (&prev, & (*fs)->id[0], 
-				       fctr->indep_var[0]->width))
+                                        var_get_width (fctr->indep_var[0])))
 		{
 		  
 		  if ( count > 0 ) 
@@ -2062,7 +2062,7 @@ show_percentiles (struct variable **depe
 
 
 	      if ( 0 != compare_values (&prev, & (*fs)->id[0], 
-				       fctr->indep_var[0]->width))
+                                        var_get_width (fctr->indep_var[0])))
 		{
 		  
 		  if ( count > 0 ) 
Index: src/language/stats/flip.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/flip.c,v
retrieving revision 1.15
diff -u -p -r1.15 flip.c
--- src/language/stats/flip.c	25 Nov 2006 02:15:01 -0000	1.15
+++ src/language/stats/flip.c	5 Dec 2006 06:36:51 -0000
@@ -301,7 +301,7 @@ flip_sink_create (struct dictionary *dic
   /* Write variable names as first case. */
   for (i = 0; i < flip->var_cnt; i++) 
     buf_copy_str_rpad (flip->output_buf[i].s, MAX_SHORT_STRING,
-                       flip->var[i]->name);
+                       var_get_name (flip->var[i]));
   if (fwrite (flip->output_buf, sizeof *flip->output_buf,
               flip->var_cnt, flip->file) != (size_t) flip->var_cnt) 
     {
@@ -328,7 +328,7 @@ flip_sink_write (struct case_sink *sink,
     {
       struct varname *v = pool_alloc (flip->pool, sizeof *v);
       v->next = NULL;
-      if (flip->new_names->type == NUMERIC) 
+      if (var_is_numeric (flip->new_names))
         {
           double f = case_num (c, flip->idx_to_fv[flip->new_names->index]);
 
@@ -343,7 +343,7 @@ flip_sink_write (struct case_sink *sink,
         }
       else
 	{
-	  int width = MIN (flip->new_names->width, MAX_SHORT_STRING);
+	  int width = MIN (var_get_width (flip->new_names), MAX_SHORT_STRING);
 	  memcpy (v->name, case_str (c, flip->idx_to_fv[flip->new_names->index]),
                   width);
 	  v->name[width] = 0;
@@ -361,7 +361,7 @@ flip_sink_write (struct case_sink *sink,
     {
       double out;
       
-      if (flip->var[i]->type == NUMERIC)
+      if (var_is_numeric (flip->var[i]))
         out = case_num (c, flip->idx_to_fv[flip->var[i]->index]);
       else
         out = SYSMIS;
Index: src/language/stats/frequencies.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/frequencies.q,v
retrieving revision 1.23
diff -u -p -r1.23 frequencies.q
--- src/language/stats/frequencies.q	25 Nov 2006 02:15:01 -0000	1.23
+++ src/language/stats/frequencies.q	5 Dec 2006 06:36:51 -0000
@@ -585,7 +585,7 @@ precalc (const struct ccase *first, void
           hsh_hash_func *hash;
 	  hsh_compare_func *compare;
 
-	  if (v->type == NUMERIC) 
+	  if (var_is_numeric (v))
             {
               hash = hash_value_numeric;
               compare = compare_value_numeric_a; 
@@ -722,7 +722,7 @@ not_missing (const void *f_, const void 
   const struct freq *f = f_;
   const struct variable *v = v_;
 
-  return !mv_is_value_missing (&v->miss, f->v);
+  return !var_is_value_missing (v, f->v);
 }
 
 /* Summarizes the frequency table data for variable V. */
@@ -738,7 +738,7 @@ postprocess_freq_tab (struct variable *v
 
   ft = &get_var_freqs (v)->tab;
   assert (ft->mode == FRQM_GENERAL);
-  compare = get_freq_comparator (cmd.sort, v->type);
+  compare = get_freq_comparator (cmd.sort, var_get_type (v));
 
   /* Extract data from hash table. */
   count = hsh_count (ft->data);
@@ -843,13 +843,13 @@ frq_custom_variables (struct lexer *lexe
       if (v->aux != NULL)
 	{
 	  msg (SE, _("Variable %s specified multiple times on VARIABLES "
-		     "subcommand."), v->name);
+		     "subcommand."), var_get_name (v));
 	  return 0;
 	}
-      if (mode == FRQM_INTEGER && v->type != NUMERIC)
+      if (mode == FRQM_INTEGER && !var_is_numeric (v))
         {
           msg (SE, _("Integer mode specified, but %s is not a numeric "
-                     "variable."), v->name);
+                     "variable."), var_get_name (v));
           return 0;
         }
 
@@ -867,12 +867,13 @@ frq_custom_variables (struct lexer *lexe
         vf->tab.vector = NULL;
       vf->n_groups = 0;
       vf->groups = NULL;
-      vf->width = v->width;
-      vf->print = v->print;
+      vf->width = var_get_width (v);
+      vf->print = *var_get_print_format (v);
       if (vf->width > MAX_SHORT_STRING && get_algorithm () == COMPATIBLE) 
         {
+          enum fmt_type type = var_get_print_format (v)->type;
           vf->width = MAX_SHORT_STRING;
-          vf->print.w = MAX_SHORT_STRING * (v->print.type == FMT_AHEX ? 2 : 1);
+          vf->print.w = MAX_SHORT_STRING * (type == FMT_AHEX ? 2 : 1);
         }
     }
   return 1;
@@ -934,14 +935,14 @@ frq_custom_grouped (struct lexer *lexer,
 	for (i = 0; i < n; i++)
           if (v[i]->aux == NULL)
             msg (SE, _("Variables %s specified on GROUPED but not on "
-                       "VARIABLES."), v[i]->name);
+                       "VARIABLES."), var_get_name (v[i]));
           else 
             {
               struct var_freqs *vf = get_var_freqs (v[i]);
                 
               if (vf->groups != NULL)
                 msg (SE, _("Variables %s specified multiple times on GROUPED "
-                           "subcommand."), v[i]->name);
+                           "subcommand."), var_get_name (v[i]));
               else
                 {
                   vf->n_groups = nl;
@@ -1258,9 +1259,8 @@ dump_full (struct variable *v)
   tab_float (t, 2 + lab, r, TAB_NONE, 100.0, 5, 1);
   tab_float (t, 3 + lab, r, TAB_NONE, 100.0, 5, 1);
 
-  tab_title (t, "%s: %s", v->name, v->label ? v->label : "");
+  tab_title (t, "%s", var_to_string (v));
   tab_submit (t);
-
 }
 
 /* Sets the widths of all the columns and heights of all the rows in
@@ -1334,7 +1334,7 @@ dump_condensed (struct variable *v)
 	   cmd.spaces == FRQ_SINGLE ? -1 : TAL_GAP, TAL_1,
 	   0, 0, 3, r - 1);
   tab_hline (t, TAL_2, 0, 3, 2);
-  tab_title (t, "%s: %s", v->name, v->label ? v->label : "");
+  tab_title (t, "%s", var_to_string (v));
   tab_columns (t, SOM_COL_DOWN, 1);
   tab_submit (t);
 }
@@ -1518,13 +1518,13 @@ dump_statistics (struct variable *v, int
   if ( implicit_50th && n_percentiles > 0 ) 
     --n_percentiles;
 
-  if (v->type == ALPHA)
+  if (var_is_alpha (v))
     return;
   ft = &get_var_freqs (v)->tab;
   if (ft->n_valid == 0)
     {
       msg (SW, _("No valid data for variable %s; statistics not displayed."),
-	   v->name);
+	   var_get_name (v));
       return;
     }
   calc_stats (v, stat_value);
@@ -1571,12 +1571,7 @@ dump_statistics (struct variable *v, int
 
   tab_columns (t, SOM_COL_DOWN, 1);
   if (show_varname)
-    {
-      if (v->label)
-	tab_title (t, "%s: %s", v->name, v->label);
-      else
-	tab_title (t, "%s", v->name);
-    }
+    tab_title (t, "%s", var_to_string (v));
   else
     tab_flags (t, SOMF_NO_TITLE);
 
@@ -1603,7 +1598,7 @@ freq_tab_to_hist(const struct freq_tab *
   /* Find out the extremes of the x value */
   for ( frq = hsh_first(fh, &hi); frq != 0; frq = hsh_next(fh, &hi) ) 
     {
-      if ( mv_is_value_missing(&var->miss, frq->v))
+      if ( var_is_value_missing(var, frq->v))
 	continue;
 
       if ( frq->v[0].f < x_min ) x_min = frq->v[0].f ;
Index: src/language/stats/oneway.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/oneway.q,v
retrieving revision 1.15
diff -u -p -r1.15 oneway.q
--- src/language/stats/oneway.q	11 Nov 2006 23:10:00 -0000	1.15
+++ src/language/stats/oneway.q	5 Dec 2006 06:36:52 -0000
@@ -867,7 +867,7 @@ precalc ( struct cmd_oneway *cmd UNUSED 
 		   (hsh_compare_func *) compare_group,
 		   (hsh_hash_func *) hash_group,
 		   (hsh_free_func *) free_group,
-		   (void *) indep_var->width );
+		   (void *) var_get_width (indep_var) );
 
 
       totals->sum=0;
@@ -896,7 +896,7 @@ run_oneway(const struct ccase *first, co
 				 (hsh_compare_func *) compare_values,
 				 (hsh_hash_func *) hash_value,
 				 0,
-				 (void *) indep_var->width );
+				 (void *) var_get_width (indep_var) );
 
   precalc(cmd);
 
Index: src/language/stats/rank.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/rank.q,v
retrieving revision 1.19
diff -u -p -r1.19 rank.q
--- src/language/stats/rank.q	11 Nov 2006 23:10:00 -0000	1.19
+++ src/language/stats/rank.q	5 Dec 2006 06:36:53 -0000
@@ -148,7 +148,7 @@ struct rank_spec
 
 
 /* Function to use for testing for missing values */
-static is_missing_func *value_is_missing;
+static mv_is_missing_func *value_is_missing;
 
 static struct rank_spec *rank_specs;
 static size_t n_rank_specs;
@@ -216,17 +216,18 @@ create_var_label (struct variable *dest_
       for (g = 0 ; g < n_group_vars ; ++g ) 
 	{
 	  if ( g > 0 ) ds_put_cstr (&group_var_str, " ");
-	  ds_put_cstr (&group_var_str, group_vars[g]->name);
+	  ds_put_cstr (&group_var_str, var_get_name (group_vars[g]));
 	}
 
       ds_put_format (&label, _("%s of %s by %s"), function_name[f], 
-		     src_var->name, ds_cstr (&group_var_str));
+		     var_get_name (src_var), ds_cstr (&group_var_str));
       ds_destroy (&group_var_str);
     }
   else
-    ds_put_format (&label,_("%s of %s"), function_name[f], src_var->name);  
+    ds_put_format (&label, _("%s of %s"),
+                   function_name[f], var_get_name (src_var));  
 
-  dest_var->label = strdup (ds_cstr (&label) );
+  var_set_label (dest_var, ds_cstr (&label));
 
   ds_destroy (&label);
 }
@@ -247,13 +248,13 @@ rank_cmd (struct dataset *ds, const stru
     {
       struct variable *v = dict_get_split_vars (dataset_dict (ds))[i];
       criteria.crits[i].fv = v->fv;
-      criteria.crits[i].width = v->width;
+      criteria.crits[i].width = var_get_width (v);
       criteria.crits[i].dir = SRT_ASCEND;
     }
   for (i = 0; i < n_group_vars; i++) 
     {
       criteria.crits[i + n_splits].fv = group_vars[i]->fv;
-      criteria.crits[i + n_splits].width = group_vars[i]->width;
+      criteria.crits[i + n_splits].width = var_get_width (group_vars[i]);
       criteria.crits[i + n_splits].dir = SRT_ASCEND;
     }
   for (i = 0 ; i < sc->crit_cnt ; ++i )
@@ -279,7 +280,7 @@ rank_cmd (struct dataset *ds, const stru
       out = rank_sorted_casefile (sorted_cf, &criteria,
 				  dataset_dict (ds),
                                   rank_specs, n_rank_specs, 
-				  i, &src_vars[i]->miss)  ;
+				  i, var_get_missing_values (src_vars[i]));
       if ( NULL == out ) 
 	{
 	  result = false ;
@@ -685,8 +686,8 @@ create_rank_variable (struct dictionary 
 
   if ( NULL == var )
     {
-      snprintf(name, SHORT_NAME_LEN + 1, "%c%s", 
-	       function_name[f][0], src_var->name);
+      snprintf (name, SHORT_NAME_LEN + 1, "%c%s", 
+                function_name[f][0], var_get_name (src_var));
   
       var = dict_create_var(dict, name, 0);
     }
@@ -724,7 +725,7 @@ create_rank_variable (struct dictionary 
       return NULL;
     }
 
-  var->write = var->print = dest_format[f];
+  var_set_both_formats (var, &dest_format[f]); 
 
   return var;
 }
@@ -834,7 +835,7 @@ cmd_rank (struct lexer *lexer, struct da
 		  ds_init_empty (&varlist);
 		  for ( g = 0 ; g < n_group_vars ; ++g ) 
 		    {
-		      ds_put_cstr (&varlist, group_vars[g]->name);
+		      ds_put_cstr (&varlist, var_get_name (group_vars[g]));
 
 		      if ( g < n_group_vars - 1)
 			ds_put_cstr (&varlist, " ");
@@ -844,10 +845,10 @@ cmd_rank (struct lexer *lexer, struct da
 		       rank_specs[i].rfunc == PROPORTION ) 
 		    tab_output_text (TAT_PRINTF,
 				     _("%s into %s(%s of %s using %s BY %s)"), 
-				     src_vars[v]->name,
-				     rank_specs[i].destvars[v]->name,
+				     var_get_name (src_vars[v]),
+				     var_get_name (rank_specs[i].destvars[v]),
 				     function_name[rank_specs[i].rfunc],
-				     src_vars[v]->name,
+				     var_get_name (src_vars[v]),
 				     fraction_name(),
 				     ds_cstr (&varlist)
 				     );
@@ -855,10 +856,10 @@ cmd_rank (struct lexer *lexer, struct da
 		  else
 		    tab_output_text (TAT_PRINTF,
 				     _("%s into %s(%s of %s BY %s)"), 
-				     src_vars[v]->name,
-				     rank_specs[i].destvars[v]->name,
+				     var_get_name (src_vars[v]),
+				     var_get_name (rank_specs[i].destvars[v]),
 				     function_name[rank_specs[i].rfunc],
-				     src_vars[v]->name,
+				     var_get_name (src_vars[v]),
 				     ds_cstr (&varlist)
 				     );
 		  ds_destroy (&varlist);
@@ -869,20 +870,20 @@ cmd_rank (struct lexer *lexer, struct da
 		       rank_specs[i].rfunc == PROPORTION ) 
 		    tab_output_text (TAT_PRINTF,
 				     _("%s into %s(%s of %s using %s)"), 
-				     src_vars[v]->name,
-				     rank_specs[i].destvars[v]->name,
+				     var_get_name (src_vars[v]),
+				     var_get_name (rank_specs[i].destvars[v]),
 				     function_name[rank_specs[i].rfunc],
-				     src_vars[v]->name,
+				     var_get_name (src_vars[v]),
 				     fraction_name()
 				     );
 		    
 		  else
 		    tab_output_text (TAT_PRINTF,
 				     _("%s into %s(%s of %s)"), 
-				     src_vars[v]->name,
-				     rank_specs[i].destvars[v]->name,
+				     var_get_name (src_vars[v]),
+				     var_get_name (rank_specs[i].destvars[v]),
 				     function_name[rank_specs[i].rfunc],
-				     src_vars[v]->name
+				     var_get_name (src_vars[v])
 				     );
 		}
 	    }
Index: src/language/stats/regression.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/regression.q,v
retrieving revision 1.38
diff -u -p -r1.38 regression.q
--- src/language/stats/regression.q	11 Nov 2006 23:10:00 -0000	1.38
+++ src/language/stats/regression.q	5 Dec 2006 06:36:53 -0000
@@ -230,7 +230,7 @@ reg_stats_coeff (pspp_linreg_cache * c)
       label = var_to_string (v);
       /* Do not overwrite the variable's name. */
       strncpy (tmp, label, MAX_STRING);
-      if (v->type == ALPHA)
+      if (var_is_alpha (v))
 	{
 	  /*
 	     Append the value associated with this coefficient.
@@ -748,12 +748,12 @@ reg_print_categorical_encoding (FILE * f
     {
       coeff = c->coeff[i];
       v = pspp_coeff_get_var (coeff, 0);
-      if (v->type == ALPHA)
+      if (var_is_alpha (v))
 	{
 	  if (!reg_inserted (v, varlist, n_vars))
 	    {
 	      fprintf (fp, "struct pspp_reg_categorical_variable %s;\n\t",
-		       v->name);
+		       var_get_name (v));
 	      varlist[n_vars] = (struct variable *) v;
 	      n_vars++;
 	    }
@@ -764,22 +764,25 @@ reg_print_categorical_encoding (FILE * f
 	   n_vars);
   for (i = 0; i < n_vars - 1; i++)
     {
-      fprintf (fp, "&%s,\n\t\t", varlist[i]->name);
+      fprintf (fp, "&%s,\n\t\t", var_get_name (varlist[i]));
     }
-  fprintf (fp, "&%s};\n\t", varlist[i]->name);
+  fprintf (fp, "&%s};\n\t", var_get_name (varlist[i]));
 
   for (i = 0; i < n_vars; i++)
     {
       coeff = c->coeff[i];
-      fprintf (fp, "%s.name = \"%s\";\n\t", varlist[i]->name,
-	       varlist[i]->name);
-      fprintf (fp, "%s.n_vals = %d;\n\t", varlist[i]->name,
+      fprintf (fp, "%s.name = \"%s\";\n\t",
+               var_get_name (varlist[i]),
+	       var_get_name (varlist[i]));
+      fprintf (fp, "%s.n_vals = %d;\n\t",
+               var_get_name (varlist[i]),
 	       varlist[i]->obs_vals->n_categories);
 
       for (j = 0; j < varlist[i]->obs_vals->n_categories; j++)
 	{
 	  val = cat_subscript_to_value ((const size_t) j, varlist[i]);
-	  fprintf (fp, "%s.values[%d] = \"%s\";\n\t", varlist[i]->name, j,
+	  fprintf (fp, "%s.values[%d] = \"%s\";\n\t",
+                   var_get_name (varlist[i]), j,
 		   value_to_string (val, varlist[i]));
 	}
     }
@@ -798,11 +801,11 @@ reg_print_depvars (FILE * fp, pspp_linre
     {
       coeff = c->coeff[i];
       v = pspp_coeff_get_var (coeff, 0);
-      fprintf (fp, "\"%s\",\n\t\t", v->name);
+      fprintf (fp, "\"%s\",\n\t\t", var_get_name (v));
     }
   coeff = c->coeff[i];
   v = pspp_coeff_get_var (coeff, 0);
-  fprintf (fp, "\"%s\"};\n\t", v->name);
+  fprintf (fp, "\"%s\"};\n\t", var_get_name (v));
 }
 static void
 reg_print_getvar (FILE * fp, pspp_linreg_cache * c)
@@ -824,10 +827,8 @@ reg_has_categorical (pspp_linreg_cache *
   for (i = 1; i < c->n_coeffs; i++)
     {
       v = pspp_coeff_get_var (c->coeff[i], 0);
-      if (v->type == ALPHA)
-	{
-	  return 1;
-	}
+      if (var_is_alpha (v))
+        return 1;
     }
   return 0;
 }
@@ -987,7 +988,7 @@ mark_missing_cases (const struct casefil
 
       val = case_data (&c, v->fv);
       cat_value_update (v, val);
-      if (mv_is_value_missing (&v->miss, val))
+      if (var_is_value_missing (v, val))
 	{
 	  if (!is_missing_case[row])
 	    {
@@ -1071,7 +1072,7 @@ prepare_data (int n_data, int is_missing
 	{
 	  indep_vars[j] = v_variables[i];
 	  j++;
-	  if (v_variables[i]->type == ALPHA)
+	  if (var_is_alpha (v_variables[i]))
 	    {
 	      /* Make a place to hold the binary vectors 
 	         corresponding to this variable's values. */
@@ -1135,7 +1136,7 @@ run_regression (const struct ccase *firs
 
   for (i = 0; i < cmd.n_dependent; i++)
     {
-      if (cmd.v_dependent[i]->type != NUMERIC)
+      if (!var_is_numeric (cmd.v_dependent[i]))
 	{
 	  msg (SE, gettext ("Dependent variable must be numeric."));
 	  pspp_reg_rc = CMD_FAILURE;
@@ -1209,12 +1210,12 @@ run_regression (const struct ccase *firs
 		   */
 		  if (!is_depvar (i, cmd.v_dependent[k]))
 		    {
-		      if (v_variables[i]->type == ALPHA)
+		      if (var_is_alpha (v_variables[i]))
 			{
 			  design_matrix_set_categorical (X, row,
 							 v_variables[i], val);
 			}
-		      else if (v_variables[i]->type == NUMERIC)
+		      else
 			{
 			  design_matrix_set_numeric (X, row, v_variables[i],
 						     val);
Index: src/language/stats/sort-criteria.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/sort-criteria.c,v
retrieving revision 1.4
diff -u -p -r1.4 sort-criteria.c
--- src/language/stats/sort-criteria.c	11 Nov 2006 23:10:00 -0000	1.4
+++ src/language/stats/sort-criteria.c	5 Dec 2006 06:36:54 -0000
@@ -116,7 +116,7 @@ sort_parse_criteria (struct lexer *lexer
         {
           struct sort_criterion *c = &criteria->crits[prev_var_cnt];
           c->fv = (*vars)[prev_var_cnt]->fv;
-          c->width = (*vars)[prev_var_cnt]->width;
+          c->width = var_get_width ((*vars)[prev_var_cnt]);
           c->dir = direction;
         }
     }
Index: src/language/stats/t-test.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/stats/t-test.q,v
retrieving revision 1.15
diff -u -p -r1.15 t-test.q
--- src/language/stats/t-test.q	11 Nov 2006 23:10:00 -0000	1.15
+++ src/language/stats/t-test.q	5 Dec 2006 06:36:55 -0000
@@ -375,16 +375,16 @@ tts_custom_groups (struct lexer *lexer, 
       return 0;
     }
 
-  if (indep_var->type == T_STRING && indep_var->width > MAX_SHORT_STRING)
+  if (var_is_long_string (indep_var))
     {
       msg (SE, _("Long string variable %s is not valid here."),
-	   indep_var->name);
+	   var_get_name (indep_var));
       return 0;
     }
 
   if (!lex_match (lexer, '('))
     {
-      if (indep_var->type == NUMERIC)
+      if (var_is_numeric (indep_var))
 	{
 	  gp.v.g_value[0].f = 1;
 	  gp.v.g_value[1].f = 2;
@@ -403,15 +403,14 @@ tts_custom_groups (struct lexer *lexer, 
 	}
     }
 
-  if (!parse_value (lexer, &gp.v.g_value[0], indep_var->type))
+  if (!parse_value (lexer, &gp.v.g_value[0], var_get_type (indep_var)))
       return 0;
 
   lex_match (lexer, ',');
   if (lex_match (lexer, ')'))
     {
-      if (indep_var->type != NUMERIC)
+      if (var_is_alpha (indep_var))
 	{
-
 	  msg (SE, _("When applying GROUPS to a string variable, two "
 		     "values must be specified."));
 	  return 0;
@@ -423,7 +422,7 @@ tts_custom_groups (struct lexer *lexer, 
       return 1;
     }
 
-  if (!parse_value (lexer, &gp.v.g_value[1], indep_var->type))
+  if (!parse_value (lexer, &gp.v.g_value[1], var_get_type (indep_var)))
     return 0;
 
   n_group_values = 2;
@@ -702,7 +701,7 @@ ssbox_independent_samples_init(struct ss
   ssbox_base_init(this, hsize,vsize);
   tab_vline (this->t, TAL_GAP, 1, 0,vsize - 1);
   tab_title (this->t, _("Group Statistics"));
-  tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, indep_var->name);
+  tab_text (this->t, 1, 0, TAB_CENTER | TAT_TITLE, var_get_name (indep_var));
   tab_text (this->t, 2, 0, TAB_CENTER | TAT_TITLE, _("N"));
   tab_text (this->t, 3, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
   tab_text (this->t, 4, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
@@ -723,7 +722,7 @@ ssbox_independent_samples_populate(struc
 
   char prefix[2][3]={"",""};
 
-  if ( indep_var->type == NUMERIC ) 
+  if ( var_is_numeric (indep_var) ) 
     {
       val_lab0 = val_labs_find( indep_var->val_labs,gp.v.g_value[0]); 
       val_lab1 = val_labs_find( indep_var->val_labs,gp.v.g_value[1]);
@@ -755,7 +754,8 @@ ssbox_independent_samples_populate(struc
       struct hsh_table *grp_hash = group_proc_get (var)->group_hash;
       int count=0;
 
-      tab_text (ssb->t, 0, i*2+1, TAB_LEFT, cmd->v_variables[i]->name);
+      tab_text (ssb->t, 0, i*2+1, TAB_LEFT,
+                var_get_name (cmd->v_variables[i]));
 
       if (val_lab0)
 	tab_text (ssb->t, 1, i*2+1, TAB_LEFT | TAT_PRINTF, 
@@ -856,7 +856,8 @@ ssbox_paired_populate(struct ssbox *ssb,
 
 	  /* Titles */
 
-	  tab_text (ssb->t, 1, i*2+j+1, TAB_LEFT, pairs[i].v[j]->name);
+	  tab_text (ssb->t, 1, i*2+j+1, TAB_LEFT,
+                    var_get_name (pairs[i].v[j]));
 
 	  /* Values */
 	  tab_float (ssb->t,2, i*2+j+1, TAB_RIGHT, pairs[i].mean[j], 8, 2);
@@ -880,7 +881,7 @@ ssbox_one_sample_populate(struct ssbox *
     {
       struct group_statistics *gs = &group_proc_get (cmd->v_variables[i])->ugs;
 
-      tab_text (ssb->t, 0, i+1, TAB_LEFT, cmd->v_variables[i]->name);
+      tab_text (ssb->t, 0, i+1, TAB_LEFT, var_get_name (cmd->v_variables[i]));
       tab_float (ssb->t,1, i+1, TAB_RIGHT, gs->n, 2, 0);
       tab_float (ssb->t,2, i+1, TAB_RIGHT, gs->mean, 8, 2);
       tab_float (ssb->t,3, i+1, TAB_RIGHT, gs->std_dev, 8, 2);
@@ -1039,7 +1040,7 @@ trbox_independent_samples_populate(struc
       assert(gs1);
 
 	  
-      tab_text (self->t, 0, i*2+3, TAB_LEFT, cmd->v_variables[i]->name);
+      tab_text (self->t, 0, i*2+3, TAB_LEFT, var_get_name (cmd->v_variables[i]));
 
       tab_text (self->t, 1, i*2+3, TAB_LEFT, _("Equal variances assumed"));
 
@@ -1193,7 +1194,8 @@ trbox_paired_populate(struct trbox *trb,
       tab_text (trb->t, 0, i+3, TAB_LEFT | TAT_PRINTF, _("Pair %d"),i); 
 
       tab_text (trb->t, 1, i+3, TAB_LEFT | TAT_PRINTF, "%s - %s",
-		pairs[i].v[0]->name, pairs[i].v[1]->name);
+		var_get_name (pairs[i].v[0]),
+                var_get_name (pairs[i].v[1]));
 
       tab_float(trb->t, 2, i+3, TAB_RIGHT, pairs[i].mean_diff, 8, 4);
 
@@ -1287,7 +1289,7 @@ trbox_one_sample_populate(struct trbox *
       struct group_statistics *gs = &group_proc_get (cmd->v_variables[i])->ugs;
 
 
-      tab_text (trb->t, 0, i+3, TAB_LEFT, cmd->v_variables[i]->name);
+      tab_text (trb->t, 0, i+3, TAB_LEFT, var_get_name (cmd->v_variables[i]));
 
       t = (gs->mean - cmd->n_testval[0] ) * sqrt(gs->n) / gs->std_dev ;
 
@@ -1383,7 +1385,9 @@ pscbox(void)
 	       _("Pair %d"), i);
       
       tab_text(table, 1,i+1, TAB_LEFT | TAT_TITLE | TAT_PRINTF, 
-	       _("%s & %s"), pairs[i].v[0]->name, pairs[i].v[1]->name);
+	       _("%s & %s"),
+               var_get_name (pairs[i].v[0]),
+               var_get_name (pairs[i].v[1]));
 
 
       /* row data */
@@ -1653,7 +1657,7 @@ group_precalc (struct cmd_t_test *cmd )
       /* There's always 2 groups for a T - TEST */
       ttpr->n_groups = 2;
 
-      gp.indep_width = indep_var->width;
+      gp.indep_width = var_get_width (indep_var);
       
       ttpr->group_hash = hsh_create(2, 
 				    (hsh_compare_func *) compare_group_binary,
Index: src/language/utilities/set.q
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/utilities/set.q,v
retrieving revision 1.22
diff -u -p -r1.22 set.q
--- src/language/utilities/set.q	3 Dec 2006 22:16:46 -0000	1.22
+++ src/language/utilities/set.q	5 Dec 2006 06:36:55 -0000
@@ -774,7 +774,7 @@ show_weight (const struct dataset *ds) 
   if (var == NULL)
     msg (SN, _("WEIGHT is off."));
   else
-    msg (SN, _("WEIGHT is variable %s."), var->name);
+    msg (SN, _("WEIGHT is variable %s."), var_get_name (var));
 }
 
 static void
Index: src/language/xforms/compute.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/xforms/compute.c,v
retrieving revision 1.11
diff -u -p -r1.11 compute.c
--- src/language/xforms/compute.c	1 Dec 2006 06:51:08 -0000	1.11
+++ src/language/xforms/compute.c	5 Dec 2006 06:36:56 -0000
@@ -206,7 +206,7 @@ compute_str_vec (void *compute_, struct 
 
       vr = compute->vector->var[rindx - 1];
       expr_evaluate_str (compute->rvalue, c, case_num,
-                         case_data_rw (c, vr->fv)->s, vr->width);
+                         case_data_rw (c, vr->fv)->s, var_get_width (vr));
     }
   
   return TRNS_CONTINUE;
@@ -379,8 +379,8 @@ static int
 lvalue_get_type (const struct lvalue *lvalue) 
 {
   return (lvalue->variable != NULL
-          ? lvalue->variable->type
-          : lvalue->vector->var[0]->type);
+          ? var_get_type (lvalue->variable)
+          : var_get_type (lvalue->vector->var[0]));
 }
 
 /* Returns true if LVALUE has a vector as its target. */
@@ -401,10 +401,10 @@ lvalue_finalize (struct lvalue *lvalue, 
     {
       compute->variable = lvalue->variable;
       compute->fv = compute->variable->fv;
-      compute->width = compute->variable->width;
+      compute->width = var_get_width (compute->variable);
 
       /* Goofy behavior, but compatible: Turn off LEAVE. */
-      if (dict_class_from_id (compute->variable->name) != DC_SCRATCH)
+      if (dict_class_from_id (var_get_name (compute->variable)) != DC_SCRATCH)
         compute->variable->leave = false;
 
       /* Prevent lvalue_destroy from deleting variable. */
Index: src/language/xforms/count.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/xforms/count.c,v
retrieving revision 1.11
diff -u -p -r1.11 count.c
--- src/language/xforms/count.c	11 Nov 2006 23:10:01 -0000	1.11
+++ src/language/xforms/count.c	5 Dec 2006 06:36:56 -0000
@@ -120,7 +120,7 @@ cmd_count (struct lexer *lexer, struct d
       dv->var = dict_lookup_var (dataset_dict (ds), lex_tokid (lexer));
       if (dv->var != NULL)
         {
-          if (dv->var->type == ALPHA)
+          if (var_is_alpha (dv->var))
             {
               msg (SE, _("Destination cannot be a string variable."));
               goto fail;
@@ -149,7 +149,7 @@ cmd_count (struct lexer *lexer, struct d
 	    goto fail;
 
           crit->value_cnt = 0;
-          if (crit->vars[0]->type == NUMERIC)
+          if (var_is_numeric (crit->vars[0]))
             ok = parse_numeric_criteria (lexer, trns->pool, crit);
           else
             ok = parse_string_criteria (lexer, trns->pool, crit);
@@ -239,8 +239,8 @@ parse_string_criteria (struct lexer *lex
   size_t i;
 
   for (i = 0; i < crit->var_cnt; i++)
-    if (crit->vars[i]->width > len)
-      len = crit->vars[i]->width;
+    if (var_get_width (crit->vars[i]) > len)
+      len = var_get_width (crit->vars[i]);
 
   crit->values.str = NULL;
   for (;;)
@@ -281,7 +281,7 @@ count_numeric (struct criteria *crit, st
       if (x == SYSMIS)
         counter += crit->count_system_missing;
       else if (crit->count_user_missing
-               && mv_is_num_user_missing (&crit->vars[i]->miss, x))
+               && var_is_num_user_missing (crit->vars[i], x))
         counter++;
       else 
         {
@@ -312,7 +312,7 @@ count_string (struct criteria *crit, str
       char **v;
       for (v = crit->values.str; v < crit->values.str + crit->value_cnt; v++)
         if (!memcmp (case_str (c, crit->vars[i]->fv), *v,
-                     crit->vars[i]->width))
+                     var_get_width (crit->vars[i])))
           {
 	    counter++;
             break;
@@ -337,7 +337,7 @@ count_trns_proc (void *trns_, struct cca
 
       counter = 0;
       for (crit = dv->crit; crit; crit = crit->next)
-	if (crit->vars[0]->type == NUMERIC)
+	if (var_is_numeric (crit->vars[0]))
 	  counter += count_numeric (crit, c);
 	else
 	  counter += count_string (crit, c);
Index: src/language/xforms/recode.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/xforms/recode.c,v
retrieving revision 1.14
diff -u -p -r1.14 recode.c
--- src/language/xforms/recode.c	22 Nov 2006 04:24:03 -0000	1.14
+++ src/language/xforms/recode.c	5 Dec 2006 06:36:56 -0000
@@ -186,7 +186,7 @@ parse_src_vars (struct lexer *lexer, 
                         PV_SAME_TYPE))
     return false;
   pool_register (trns->pool, free, trns->src_vars);
-  trns->src_type = trns->src_vars[0]->type;
+  trns->src_type = var_get_type (trns->src_vars[0]);
   return true;
 }
 
@@ -202,10 +202,10 @@ parse_mappings (struct lexer *lexer, str
   size_t i;
   
   /* Find length of longest source variable. */
-  max_src_width = trns->src_vars[0]->width;
+  max_src_width = var_get_width (trns->src_vars[0]);
   for (i = 1; i < trns->var_cnt; i++) 
     {
-      size_t var_width = trns->src_vars[i]->width;
+      size_t var_width = var_get_width (trns->src_vars[i]);
       if (var_width > max_src_width)
         max_src_width = var_width;
     }
@@ -474,13 +474,13 @@ parse_dst_vars (struct lexer *lexer, str
   for (i = 0; i < trns->var_cnt; i++)
     {
       struct variable *v = trns->dst_vars[i];
-      if (v != NULL && v->type != trns->dst_type)
+      if (v != NULL && var_get_type (v) != trns->dst_type)
         {
           msg (SE, _("Type mismatch.  Cannot store %s data in "
                      "%s variable %s."),
                trns->dst_type == ALPHA ? _("string") : _("numeric"),
-               v->type == ALPHA ? _("string") : _("numeric"),
-               v->name);
+               var_is_alpha (v) ? _("string") : _("numeric"),
+               var_get_name (v));
           return false;
         }
     }
@@ -500,8 +500,8 @@ enlarge_dst_widths (struct recode_trns *
   for (i = 0; i < trns->var_cnt; i++)
     {
       struct variable *v = trns->dst_vars[i];
-      if (v->width > max_dst_width)
-        max_dst_width = v->width;
+      if (var_get_width (v) > max_dst_width)
+        max_dst_width = var_get_width (v);
     }
 
   for (i = 0; i < trns->map_cnt; i++)
@@ -530,7 +530,7 @@ create_dst_vars (struct recode_trns *trn
       *var = dict_lookup_var (dict, name);
       if (*var == NULL)
         *var = dict_create_var_assert (dict, name, 0);
-      assert ((*var)->type == trns->dst_type);
+      assert (var_get_type (*var) == trns->dst_type);
     }
 }
 
@@ -555,7 +555,7 @@ find_src_numeric (struct recode_trns *tr
           match = value == in->x.f;
           break;
         case MAP_MISSING:
-          match = mv_is_num_user_missing (&v->miss, value);
+          match = var_is_num_user_missing (v, value);
           break;
         case MAP_RANGE:
           match = value >= in->x.f && value <= in->y.f;
@@ -636,7 +636,7 @@ recode_trns_proc (void *trns_, struct cc
       if (trns->src_type == NUMERIC) 
           out = find_src_numeric (trns, src_data->f, src_var);
       else
-          out = find_src_string (trns, src_data->s, src_var->width);
+          out = find_src_string (trns, src_data->s, var_get_width (src_var));
 
       if (trns->dst_type == NUMERIC) 
         {
@@ -650,13 +650,13 @@ recode_trns_proc (void *trns_, struct cc
           if (out != NULL)
             {
               if (!out->copy_input) 
-                memcpy (dst_data->s, out->value.c, dst_var->width); 
+                memcpy (dst_data->s, out->value.c, var_get_width (dst_var)); 
               else if (trns->src_vars != trns->dst_vars)
-                buf_copy_rpad (dst_data->s, dst_var->width,
-                               src_data->s, src_var->width); 
+                buf_copy_rpad (dst_data->s, var_get_width (dst_var),
+                               src_data->s, var_get_width (src_var)); 
             }
           else if (trns->src_vars != trns->dst_vars)
-            memset (dst_data->s, ' ', dst_var->width);
+            memset (dst_data->s, ' ', var_get_width (dst_var));
         }
     }
 
Index: src/language/xforms/select-if.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/language/xforms/select-if.c,v
retrieving revision 1.12
diff -u -p -r1.12 select-if.c
--- src/language/xforms/select-if.c	11 Nov 2006 23:10:01 -0000	1.12
+++ src/language/xforms/select-if.c	5 Dec 2006 06:36:56 -0000
@@ -112,13 +112,13 @@ cmd_filter (struct lexer *lexer, struct 
       if (!v)
 	return CMD_FAILURE;
 
-      if (v->type == ALPHA)
+      if (var_is_alpha (v))
 	{
 	  msg (SE, _("The filter variable must be numeric."));
 	  return CMD_FAILURE;
 	}
 
-      if (dict_class_from_id (v->name) == DC_SCRATCH)
+      if (dict_class_from_id (var_get_name (v)) == DC_SCRATCH)
 	{
 	  msg (SE, _("The filter variable may not be scratch."));
 	  return CMD_FAILURE;
Index: src/math/coefficient.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/math/coefficient.c,v
retrieving revision 1.4
diff -u -p -r1.4 coefficient.c
--- src/math/coefficient.c	15 Jul 2006 20:25:01 -0000	1.4
+++ src/math/coefficient.c	5 Dec 2006 06:36:56 -0000
@@ -71,7 +71,7 @@ pspp_coeff_init (struct pspp_coeff ** c,
       c[i]->v_info->v =
 	(const struct variable *) design_matrix_col_to_var (X, i);
 
-      if (c[i]->v_info->v->type == ALPHA)
+      if (var_is_alpha (c[i]->v_info->v))
 	{
 	  size_t k;
 	  k = design_matrix_var_to_column (X, c[i]->v_info->v);
@@ -162,7 +162,7 @@ pspp_coeff_get_value (struct pspp_coeff 
     {
       return NULL;
     }
-  if (v->type == NUMERIC)
+  if (var_is_numeric (v))
     {
       return NULL;
     }
@@ -211,7 +211,7 @@ pspp_linreg_get_coeff (const pspp_linreg
     {
       return NULL;
     }
-  if (v->type == NUMERIC)
+  if (var_is_numeric (v))
     {
       return result;
     }
@@ -223,7 +223,7 @@ pspp_linreg_get_coeff (const pspp_linreg
        */
       while (tmp->index != v->index && i < c->n_coeffs
 	     && compare_values (pspp_coeff_get_value (result, tmp),
-				val, v->width))
+				val, var_get_width (v)))
 	{			/* FIX THIS */
 	  i++;
 	  result = c->coeff[i];
Index: src/math/design-matrix.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/math/design-matrix.c,v
retrieving revision 1.3
diff -u -p -r1.3 design-matrix.c
--- src/math/design-matrix.c	8 Jul 2006 03:05:52 -0000	1.3
+++ src/math/design-matrix.c	5 Dec 2006 06:36:57 -0000
@@ -115,12 +115,12 @@ design_matrix_create (int n_variables,
       (dm->vars + i)->v = v;	/* Allows us to look up the variable from
 				   the design matrix. */
       (dm->vars + i)->first_column = n_cols;
-      if (v->type == NUMERIC)
+      if (var_is_numeric (v))
 	{
 	  (dm->vars + i)->last_column = n_cols;
 	  n_cols++;
 	}
-      else if (v->type == ALPHA)
+      else if (var_is_alpha (v))
 	{
 	  assert (v->obs_vals != NULL);
 	  (dm->vars + i)->last_column =
@@ -250,7 +250,7 @@ design_matrix_set_categorical (struct de
   size_t lc;
   double entry;
 
-  assert (var->type == ALPHA);
+  assert (var_is_alpha (var));
   fc = design_matrix_var_to_column (dm, var);
   lc = dm_var_to_last_column (dm, var);
   assert (lc != DM_COLUMN_NOT_FOUND);
@@ -268,7 +268,7 @@ design_matrix_set_numeric (struct design
 {
   size_t col;
 
-  assert (var->type == NUMERIC);
+  assert (var_is_numeric (var));
   col = design_matrix_var_to_column ((const struct design_matrix *) dm, var);
   assert (col != DM_COLUMN_NOT_FOUND);
   gsl_matrix_set (dm->m, row, col, val->f);
Index: src/math/linreg/predict.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/math/linreg/predict.c,v
retrieving revision 1.10
diff -u -p -r1.10 predict.c
--- src/math/linreg/predict.c	19 May 2006 21:08:20 -0000	1.10
+++ src/math/linreg/predict.c	5 Dec 2006 06:36:57 -0000
@@ -70,7 +70,7 @@ pspp_linreg_predict (const struct variab
 	{
 	  found[i] = coe;
 	  tmp = pspp_coeff_get_est (coe);
-	  if (predictors[j]->type == NUMERIC)
+	  if (var_is_numeric (predictors[j]))
 	    {
 	      tmp *= vals[j]->f;
 	    }
Index: src/ui/gui/psppire-dict.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/ui/gui/psppire-dict.c,v
retrieving revision 1.9
diff -u -p -r1.9 psppire-dict.c
--- src/ui/gui/psppire-dict.c	17 Jul 2006 10:45:43 -0000	1.9
+++ src/ui/gui/psppire-dict.c	5 Dec 2006 06:36:57 -0000
@@ -472,8 +472,6 @@ psppire_dict_resize_variable(PsppireDict
   if ( old_size == new_size ) 
     return ;
 
-  pv->v->nv = new_size;
-
   dict_compact_values(d->dict);
 
   fv = psppire_variable_get_fv(pv);
Index: src/ui/gui/psppire-variable.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/ui/gui/psppire-variable.c,v
retrieving revision 1.7
diff -u -p -r1.7 psppire-variable.c
--- src/ui/gui/psppire-variable.c	3 Nov 2006 04:53:52 -0000	1.7
+++ src/ui/gui/psppire-variable.c	5 Dec 2006 06:36:57 -0000
@@ -43,7 +43,7 @@ psppire_variable_set_name(struct Psppire
   if ( !text) 
     return FALSE;
 
-  if ( 0 == strcmp(pv->v->name, text))
+  if ( 0 == strcmp(var_get_name (pv->v), text))
     return FALSE;
 
   if ( ! psppire_dict_check_name(pv->dict, text, TRUE) )
@@ -64,7 +64,7 @@ psppire_variable_set_columns(struct Pspp
   g_return_val_if_fail(pv->dict, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  pv->v->display_width = columns;
+  var_set_display_width (pv->v, columns);
   
   psppire_dict_var_changed(pv->dict, pv->v->index);
 
@@ -78,8 +78,7 @@ psppire_variable_set_label(struct Psppir
   g_return_val_if_fail(pv->dict, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  g_free(pv->v->label);
-  pv->v->label = g_strdup(label);
+  var_set_label (pv->v, label);
 
   psppire_dict_var_changed(pv->dict, pv->v->index);
 
@@ -96,8 +95,7 @@ psppire_variable_set_decimals(struct Psp
   g_return_val_if_fail(pv->dict, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  fmt = pv->v->write;
-
+  fmt = *var_get_write_format (pv->v);
   fmt.d = decimals;
 
   return psppire_variable_set_format(pv, &fmt);
@@ -113,21 +111,20 @@ psppire_variable_set_width(struct Psppir
   g_return_val_if_fail(pv->dict, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  fmt = pv->v->write;
-
+  fmt = *var_get_write_format (pv->v);
   fmt.w = width;
 
-  if ( pv->v->type == ALPHA ) 
+  if (var_is_alpha (pv->v))
     {
       gint old_var_cnt , new_var_cnt ;
 
-      if ( pv->v->width == 0 ) 
+      if ( var_get_width (pv->v) == 0 ) 
 	old_var_cnt = 1;
       else
-	old_var_cnt = DIV_RND_UP(pv->v->width, MAX_SHORT_STRING);
+	old_var_cnt = DIV_RND_UP(var_get_width (pv->v), MAX_SHORT_STRING);
       
       new_var_cnt = DIV_RND_UP(width, MAX_SHORT_STRING);
-    pv->v->width = width;
+      pv->v->width = width;
 
       psppire_dict_resize_variable(pv->dict, pv,
 				   old_var_cnt, new_var_cnt);
@@ -146,20 +143,20 @@ psppire_variable_set_type(struct Psppire
   g_return_val_if_fail(pv->dict, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  pv->v->type = type; 
-
-  if ( pv->v->width == 0 ) 
+  if ( var_get_width (pv->v) ) 
     old_var_cnt = 1;
   else
-    old_var_cnt = DIV_RND_UP(pv->v->width, MAX_SHORT_STRING);
+    old_var_cnt = DIV_RND_UP (var_get_width (pv->v), MAX_SHORT_STRING);
 
   if ( type == NUMERIC ) 
     pv->v->width = 0;
+  else if (var_get_width (pv->v))
+    pv->v->width = 1;
 
-  if ( pv->v->width == 0 ) 
+  if ( var_get_width (pv->v) == 0 ) 
     new_var_cnt = 1;
   else
-    new_var_cnt = DIV_RND_UP(pv->v->width, MAX_SHORT_STRING);
+    new_var_cnt = DIV_RND_UP (var_get_width (pv->v), MAX_SHORT_STRING);
 
   psppire_dict_resize_variable(pv->dict, pv,
 			       old_var_cnt, new_var_cnt);
@@ -178,11 +175,11 @@ psppire_variable_set_format(struct Psppi
 
   msg_disable ();
   if ( fmt_check_output(fmt) 
-       && fmt_check_type_compat (fmt, pv->v->type)
-       && fmt_check_width_compat (fmt, pv->v->width)) 
+       && fmt_check_type_compat (fmt, var_get_type (pv->v))
+       && fmt_check_width_compat (fmt, var_get_width (pv->v))) 
     {
       msg_enable ();
-      pv->v->write = pv->v->print = *fmt;
+      var_set_both_formats (pv->v, fmt);
       psppire_dict_var_changed(pv->dict, pv->v->index);
       return TRUE;
     }
@@ -215,7 +212,7 @@ psppire_variable_set_missing(const struc
   g_return_val_if_fail(pv->dict, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  mv_copy(&pv->v->miss, miss);
+  var_set_missing_values (pv->v, miss);
 
   psppire_dict_var_changed(pv->dict, pv->v->index);
   return TRUE;
@@ -227,7 +224,7 @@ psppire_variable_set_write_spec(const st
   g_return_val_if_fail(pv, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  pv->v->write = fmt;
+  var_set_write_format (pv->v, &fmt);
 
   psppire_dict_var_changed(pv->dict, pv->v->index);
   return TRUE;
@@ -239,7 +236,7 @@ psppire_variable_set_print_spec(const st
   g_return_val_if_fail(pv, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  pv->v->print = fmt;
+  var_set_print_format (pv->v, &fmt);
 
   psppire_dict_var_changed(pv->dict, pv->v->index);
   return TRUE;
@@ -254,7 +251,7 @@ psppire_variable_set_alignment(struct Ps
   g_return_val_if_fail(pv->dict, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  pv->v->alignment = align;
+  var_set_alignment (pv->v, align);
 
   psppire_dict_var_changed(pv->dict, pv->v->index);
   return TRUE;
@@ -268,7 +265,7 @@ psppire_variable_set_measure(struct Pspp
   g_return_val_if_fail(pv->dict, FALSE);
   g_return_val_if_fail(pv->v, FALSE);
 
-  pv->v->measure = measure + 1;
+  var_set_measure (pv->v, measure + 1);
 
   psppire_dict_var_changed(pv->dict, pv->v->index);
   return TRUE;
@@ -281,8 +278,7 @@ psppire_variable_get_write_spec(const st
   g_return_val_if_fail(pv, NULL);
   g_return_val_if_fail(pv->v, NULL);
 
-
-  return &pv->v->write;
+  return var_get_write_format (pv->v);
 }
 
 
@@ -292,7 +288,7 @@ psppire_variable_get_name(const struct P
   g_return_val_if_fail(pv, NULL);
   g_return_val_if_fail(pv->v, NULL);
 
-  return pv->v->name;
+  return var_get_name (pv->v);
 }
 
 
@@ -302,7 +298,7 @@ psppire_variable_get_columns(const struc
   g_return_val_if_fail(pv, -1);
   g_return_val_if_fail(pv->v, -1);
 
-  return pv->v->display_width;
+  return var_get_display_width (pv->v);
 }
 
 
@@ -313,7 +309,7 @@ psppire_variable_get_label(const struct 
   g_return_val_if_fail(pv, NULL);
   g_return_val_if_fail(pv->v, NULL);
 
-  return pv->v->label;
+  return var_get_label (pv->v);
 }
 
 
@@ -323,7 +319,7 @@ psppire_variable_get_missing(const struc
   g_return_val_if_fail(pv, NULL);
   g_return_val_if_fail(pv->v, NULL);
 
-  return &pv->v->miss;
+  return var_get_missing_values (pv->v);
 }
 
 
@@ -343,7 +339,7 @@ psppire_variable_get_alignment(const str
   g_return_val_if_fail(pv, -1);
   g_return_val_if_fail(pv->v, -1);
 
-  return pv->v->alignment;
+  return var_get_alignment (pv->v);
 }
 
 
@@ -354,7 +350,7 @@ psppire_variable_get_measure(const struc
   g_return_val_if_fail(pv, -1);
   g_return_val_if_fail(pv->v, -1);
 
-  return pv->v->measure - 1;
+  return var_get_measure (pv->v) - 1;
 }
 
 gint
@@ -363,7 +359,7 @@ psppire_variable_get_type(const struct P
   g_return_val_if_fail(pv, -1);
   g_return_val_if_fail(pv->v, -1);
 
-  return pv->v->type;
+  return var_get_type (pv->v);
 }
 
 
@@ -373,7 +369,7 @@ psppire_variable_get_width(const struct 
   g_return_val_if_fail(pv, -1);
   g_return_val_if_fail(pv->v, -1);
 
-  return pv->v->width;
+  return var_get_width (pv->v);
 }
 
 
Index: tests/bugs/temp-freq.sh
===================================================================
RCS file: /cvsroot/pspp/pspp/tests/bugs/temp-freq.sh,v
retrieving revision 1.9
diff -u -p -r1.9 temp-freq.sh
--- tests/bugs/temp-freq.sh	27 May 2006 08:36:10 -0000	1.9
+++ tests/bugs/temp-freq.sh	5 Dec 2006 06:36:57 -0000
@@ -91,7 +91,7 @@ diff -b  -w $TEMPDIR/pspp.list - << EOF
 |SEX     |A1    |
 |X       |F8.0  |
 +--------+------+
-2.1 FREQUENCIES.  X: 
+2.1 FREQUENCIES.  X 
 +-----------+--------+---------+--------+--------+--------+
 |           |        |         |        |  Valid |   Cum  |
 |Value Label|  Value |Frequency| Percent| Percent| Percent|
Index: tests/command/weight.sh
===================================================================
RCS file: /cvsroot/pspp/pspp/tests/command/weight.sh,v
retrieving revision 1.18
diff -u -p -r1.18 weight.sh
--- tests/command/weight.sh	27 May 2006 08:36:10 -0000	1.18
+++ tests/command/weight.sh	5 Dec 2006 06:36:57 -0000
@@ -88,7 +88,7 @@ diff  -b $TEMPDIR/pspp.list - <<EOF
 #========#=======#=========#======#========#=======#========#========#========#========#========#======#=======#=======#=========#
 |AVAR    #    730|        0|31.515|    .405| 10.937| 119.608|   2.411|    .181|   1.345|    .090|76.000| 18.000| 94.000|23006.000|
 +--------#-------+---------+------+--------+-------+--------+--------+--------+--------+--------+------+-------+-------+---------+
-3.1 FREQUENCIES.  AVAR: 
+3.1 FREQUENCIES.  AVAR 
 +--------+--------+---+---+
 |        |        |   |Cum|
 |  Value |  Freq  |Pct|Pct|
Index: tests/stats/percentiles-compatible.sh
===================================================================
RCS file: /cvsroot/pspp/pspp/tests/stats/percentiles-compatible.sh,v
retrieving revision 1.9
diff -u -p -r1.9 percentiles-compatible.sh
--- tests/stats/percentiles-compatible.sh	27 May 2006 08:36:10 -0000	1.9
+++ tests/stats/percentiles-compatible.sh	5 Dec 2006 06:36:58 -0000
@@ -85,7 +85,7 @@ if [ $? -ne 0 ] ; then no_result ; fi
 activity="compare output $i"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 FREQUENCIES.  X: 
+1.1 FREQUENCIES.  X 
 +-----------+--------+---------+--------+--------+--------+
 |           |        |         |        |  Valid |   Cum  |
 |Value Label|  Value |Frequency| Percent| Percent| Percent|
Index: tests/stats/percentiles-enhanced.sh
===================================================================
RCS file: /cvsroot/pspp/pspp/tests/stats/percentiles-enhanced.sh,v
retrieving revision 1.9
diff -u -p -r1.9 percentiles-enhanced.sh
--- tests/stats/percentiles-enhanced.sh	27 May 2006 08:36:10 -0000	1.9
+++ tests/stats/percentiles-enhanced.sh	5 Dec 2006 06:36:58 -0000
@@ -84,7 +84,7 @@ if [ $? -ne 0 ] ; then no_result ; fi
 activity="compare output $i"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 FREQUENCIES.  X: 
+1.1 FREQUENCIES.  X 
 +-----------+--------+---------+--------+--------+--------+
 |           |        |         |        |  Valid |   Cum  |
 |Value Label|  Value |Frequency| Percent| Percent| Percent|
@@ -147,7 +147,7 @@ if [ $? -ne 0 ] ; then no_result ; fi
 activity="compare output $i"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 FREQUENCIES.  X: 
+1.1 FREQUENCIES.  X 
 +-----------+--------+---------+--------+--------+--------+
 |           |        |         |        |  Valid |   Cum  |
 |Value Label|  Value |Frequency| Percent| Percent| Percent|
@@ -208,7 +208,7 @@ if [ $? -ne 0 ] ; then no_result ; fi
 activity="compare output $i"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 FREQUENCIES.  X: 
+1.1 FREQUENCIES.  X 
 +-----------+--------+---------+--------+--------+--------+
 |           |        |         |        |  Valid |   Cum  |
 |Value Label|  Value |Frequency| Percent| Percent| Percent|
@@ -268,7 +268,7 @@ if [ $? -ne 0 ] ; then no_result ; fi
 activity="compare output $i"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b $TEMPDIR/pspp.list - <<EOF
-1.1 FREQUENCIES.  X: 
+1.1 FREQUENCIES.  X 
 +-----------+--------+---------+--------+--------+--------+
 |           |        |         |        |  Valid |   Cum  |
 |Value Label|  Value |Frequency| Percent| Percent| Percent|
