Miscellaneous cleanup to categorical values, linreg and design matrix code.
[pspp-builds.git] / src / data / variable.c
index 5513e5ef89a27a8dad7f8c16814a6384e07c4a85..f890746ac051c12adf355b9824c53939a0c5e1e1 100644 (file)
@@ -1,6 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
 
 #include <stdlib.h>
 
-#include "cat-routines.h"
+
 #include "category.h"
 #include "data-out.h"
-#include "dictionary.h"
 #include "format.h"
+#include "dictionary.h"
 #include "identifier.h"
 #include "missing-values.h"
-#include "value.h"
 #include "value-labels.h"
 #include "vardict.h"
 
 #include <libpspp/compiler.h>
 #include <libpspp/hash.h>
 #include <libpspp/message.h>
-#include <libpspp/misc.h>
 #include <libpspp/str.h>
 
-#include "minmax.h"
-
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
@@ -70,10 +65,9 @@ struct variable
     struct vardict_info vardict;    
 
     /* Short name, used only for system and portable file input
-       and output.  Upper case only.  There is no index for short
-       names.  Short names are not necessarily unique.  Any
-       variable may have no short name, indicated by an empty
-       string. */
+       and output.  Upper case only. Short names are not necessarily
+       unique.  Any variable may have no short name, indicated by an
+       empty string. */
     char short_name[SHORT_NAME_LEN + 1];
 
     /* Each command may use these fields as needed. */
@@ -208,6 +202,7 @@ var_set_name (struct variable *v, const char *name)
   assert (var_is_plausible_name (name, false));
 
   str_copy_trunc (v->name, sizeof v->name, name);
+  dict_var_changed (v);
 }
 
 /* Returns true if NAME is an acceptable name for a variable,
@@ -234,7 +229,7 @@ var_is_valid_name (const char *name, bool issue_error)
   if (!lex_is_id1 (name[0]))
     {
       if (issue_error)
-        msg (SE, _("Character `%c' (in %s), may not appear "
+        msg (SE, _("Character `%c' (in %s) may not appear "
                    "as the first character in a variable name."),
              name[0], name);
       return false;
@@ -354,27 +349,27 @@ var_get_width (const struct variable *v)
 
 /* Sets the width of V to WIDTH. */
 void
-var_set_width (struct variable *v, int new_width) 
+var_set_width (struct variable *v, int new_width)
 {
   enum var_type new_type = var_type_from_width (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 (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 
+      else
         {
           val_labs_destroy (v->val_labs);
           v->val_labs = NULL;
         }
     }
-  
-  if (var_get_type (v) != new_type) 
+
+  if (var_get_type (v) != new_type)
     {
       v->print = (new_type == VAR_NUMERIC
                   ? fmt_for_output (FMT_F, 8, 2)
@@ -388,6 +383,8 @@ var_set_width (struct variable *v, int new_width)
     }
 
   v->width = new_width;
+
+  dict_var_changed (v);
 }
 
 /* Returns true if variable V is numeric, false otherwise. */
@@ -451,6 +448,8 @@ var_set_missing_values (struct variable *v, const struct missing_values *miss)
     }
   else
     mv_init (&v->miss, v->width);
+
+  dict_var_changed (v);
 }
 
 /* Sets variable V to have no user-missing values. */
@@ -468,64 +467,32 @@ 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. */
+/* Returns true if VALUE is in the given CLASS of missing values
+   in V, false otherwise. */
 bool
-var_is_value_missing (const struct variable *v, const union value *value) 
+var_is_value_missing (const struct variable *v, const union value *value,
+                      enum mv_class class) 
 {
-  return mv_is_value_missing (&v->miss, value);
+  return mv_is_value_missing (&v->miss, value, class);
 }
 
-/* Returns true if D is system missing or a missing value in V,
-   false otherwise.
+/* Returns true if D is in the given CLASS of missing values in
+   V, false otherwise.
    V must be a numeric variable. */
 bool
-var_is_num_missing (const struct variable *v, double d) 
+var_is_num_missing (const struct variable *v, double d, enum mv_class class
 {
-  return mv_is_num_missing (&v->miss, d);
+  return mv_is_num_missing (&v->miss, d, class);
 }
 
 /* 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) 
+var_is_str_missing (const struct variable *v, const char s[],
+                    enum mv_class class) 
 {
-  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);
+  return mv_is_str_missing (&v->miss, s, class);
 }
 \f
 /* Returns variable V's value labels,
@@ -558,6 +525,7 @@ var_set_value_labels (struct variable *v, const struct val_labs *vls)
       assert (val_labs_can_set_width (vls, v->width));
       v->val_labs = val_labs_copy (vls);
       val_labs_set_width (v->val_labs, v->width);
+      dict_var_changed (v);
     }
 }
 
@@ -643,6 +611,7 @@ var_set_print_format (struct variable *v, const struct fmt_spec *print)
 {
   assert (fmt_check_width_compat (print, v->width));
   v->print = *print;
+  dict_var_changed (v);
 }
 
 /* Returns V's write format specification. */
@@ -660,6 +629,7 @@ var_set_write_format (struct variable *v, const struct fmt_spec *write)
 {
   assert (fmt_check_width_compat (write, v->width));
   v->write = *write;
+  dict_var_changed (v);
 }
 
 /* Sets V's print and write format specifications to FORMAT,
@@ -706,6 +676,7 @@ var_set_label (struct variable *v, const char *label)
       ss_truncate (&s, 255);
       if (!ss_is_empty (s)) 
         v->label = ss_xstrdup (s);
+      dict_var_changed (v);
     }
 }
 
@@ -745,6 +716,7 @@ var_set_measure (struct variable *v, enum measure measure)
 {
   assert (measure_is_valid (measure));
   v->measure = measure;
+  dict_var_changed (v);
 }
 \f
 /* Returns V's display width, which applies only to GUIs. */
@@ -754,11 +726,15 @@ 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;
+  dict_var_changed (v);
 }
 \f
 /* Returns true if A is a valid alignment,
@@ -782,6 +758,7 @@ var_set_alignment (struct variable *v, enum alignment alignment)
 {
   assert (alignment_is_valid (alignment));
   v->alignment = alignment;
+  dict_var_changed (v);
 }
 \f
 /* Whether variables' values should be preserved from case to
@@ -801,6 +778,7 @@ var_set_leave (struct variable *v, bool leave)
 {
   assert (leave || !var_must_leave (v));
   v->leave = leave;
+  dict_var_changed (v);
 }
 
 /* Returns true if V must be left from case to case,
@@ -842,6 +820,7 @@ var_set_short_name (struct variable *v, const char *short_name)
     }
   else
     v->short_name[0] = '\0';
+  dict_var_changed (v);
 }
 
 /* Clears V's short name. */
@@ -889,9 +868,10 @@ var_get_aux (const struct variable *v)
    cleared, AUX_DTOR(V) will be called.  (var_dtor_free, below,
    may be appropriate for use as AUX_DTOR.) */
 void *
-var_attach_aux (struct variable *v,
+var_attach_aux (const struct variable *v_,
                 void *aux, void (*aux_dtor) (struct variable *)) 
 {
+  struct variable *v = (struct variable *) v_ ; /* cast away const  */
   assert (v->aux == NULL);
   assert (aux != NULL);
   v->aux = aux;
@@ -946,8 +926,9 @@ var_get_obs_vals (const struct variable *v)
 
 /* Sets V's observed categorical values to CAT_VALS. */
 void
-var_set_obs_vals (struct variable *v, struct cat_vals *cat_vals) 
+var_set_obs_vals (const struct variable *v_, struct cat_vals *cat_vals) 
 {
+  struct variable *v = (struct variable *) v_ ; /* cast away const */ 
   cat_stored_values_destroy (v->obs_vals);
   v->obs_vals = cat_vals;
 }