Delete trailing whitespace at end of lines.
[pspp-builds.git] / src / data / missing-values.c
index ba9ab53b98d58d9545c183695a86123ad14fa421..c8f6b7fe5e645fd5e9df931eefb168914acfa6ba 100644 (file)
 #include "variable.h"
 #include <libpspp/str.h>
 
+/* Types of user-missing values.
+   Invisible--use access functions defined below instead. */
+enum mv_type
+  {
+    MVT_NONE = 0,                /* No user-missing values. */
+    MVT_1 = 1,                   /* One user-missing value. */
+    MVT_2 = 2,                   /* Two user-missing values. */
+    MVT_3 = 3,                   /* Three user-missing values. */
+    MVT_RANGE = 4,               /* A range of user-missing values. */
+    MVT_RANGE_1 = 5              /* A range plus an individual value. */
+  };
 
 /* Initializes MV as a set of missing values for a variable of
    the given WIDTH.  Although only numeric variables and short
    string variables may have missing values, WIDTH may be any
    valid variable width. */
 void
-mv_init (struct missing_values *mv, int width) 
+mv_init (struct missing_values *mv, int width)
 {
   assert (width >= 0 && width <= MAX_STRING);
-  mv->type = MV_NONE;
+  mv->type = MVT_NONE;
   mv->width = width;
 }
 
-void 
-mv_set_type(struct missing_values *mv, enum mv_type type)
+/* Removes any missing values from MV. */
+void
+mv_clear (struct missing_values *mv)
 {
-  mv->type = type;
+  mv->type = MVT_NONE;
 }
 
-
 /* Copies SRC to MV. */
 void
-mv_copy (struct missing_values *mv, const struct missing_values *src) 
+mv_copy (struct missing_values *mv, const struct missing_values *src)
 {
   assert(src);
 
@@ -55,9 +66,9 @@ mv_copy (struct missing_values *mv, const struct missing_values *src)
 
 /* Returns true if MV is an empty set of missing values. */
 bool
-mv_is_empty (const struct missing_values *mv) 
+mv_is_empty (const struct missing_values *mv)
 {
-  return mv->type == MV_NONE;
+  return mv->type == MVT_NONE;
 }
 
 /* Returns the width of the missing values that MV may
@@ -77,18 +88,18 @@ mv_add_value (struct missing_values *mv, const union value *v)
 {
   if (mv->width > MAX_SHORT_STRING)
     return false;
-  switch (mv->type) 
+  switch (mv->type)
     {
-    case MV_NONE:
-    case MV_1:
-    case MV_2:
-    case MV_RANGE:
+    case MVT_NONE:
+    case MVT_1:
+    case MVT_2:
+    case MVT_RANGE:
       mv->values[mv->type & 3] = *v;
       mv->type++;
       return true;
 
-    case MV_3:
-    case MV_RANGE_1:
+    case MVT_3:
+    case MVT_RANGE_1:
       return false;
     }
   NOT_REACHED ();
@@ -100,7 +111,7 @@ mv_add_value (struct missing_values *mv, const union value *v)
    missing values.  (Long string variables never accept missing
    values.) */
 bool
-mv_add_str (struct missing_values *mv, const char s[]) 
+mv_add_str (struct missing_values *mv, const char s[])
 {
   assert (mv->width > 0);
   return mv_add_value (mv, (union value *) s);
@@ -110,7 +121,7 @@ mv_add_str (struct missing_values *mv, const char s[])
    Returns true if successful, false if MV has no more room for
    missing values.  */
 bool
-mv_add_num (struct missing_values *mv, double d) 
+mv_add_num (struct missing_values *mv, double d)
 {
   assert (mv->width == 0);
   return mv_add_value (mv, (union value *) &d);
@@ -120,24 +131,24 @@ mv_add_num (struct missing_values *mv, double d)
    missing values MV.  Returns true if successful, false if MV
    has no room for a range, or if LOW > HIGH. */
 bool
-mv_add_num_range (struct missing_values *mv, double low, double high) 
+mv_add_num_range (struct missing_values *mv, double low, double high)
 {
   assert (mv->width == 0);
   if (low > high)
     return false;
-  switch (mv->type) 
+  switch (mv->type)
     {
-    case MV_NONE:
-    case MV_1:
+    case MVT_NONE:
+    case MVT_1:
       mv->values[1].f = low;
       mv->values[2].f = high;
       mv->type |= 4;
       return true;
 
-    case MV_2:
-    case MV_3:
-    case MV_RANGE:
-    case MV_RANGE_1:
+    case MVT_2:
+    case MVT_3:
+    case MVT_RANGE:
+    case MVT_RANGE_1:
       return false;
     }
   NOT_REACHED ();
@@ -148,16 +159,16 @@ mv_add_num_range (struct missing_values *mv, double low, double high)
 bool
 mv_has_value (const struct missing_values *mv)
 {
-  switch (mv->type) 
+  switch (mv->type)
     {
-    case MV_1:
-    case MV_2:
-    case MV_3:
-    case MV_RANGE_1:
+    case MVT_1:
+    case MVT_2:
+    case MVT_3:
+    case MVT_RANGE_1:
       return true;
-      
-    case MV_NONE:
-    case MV_RANGE:
+
+    case MVT_NONE:
+    case MVT_RANGE:
       return false;
     }
   NOT_REACHED ();
@@ -167,7 +178,7 @@ mv_has_value (const struct missing_values *mv)
    MV must contain an individual value (as determined by
    mv_has_value()). */
 void
-mv_pop_value (struct missing_values *mv, union value *v) 
+mv_pop_value (struct missing_values *mv, union value *v)
 {
   assert (mv_has_value (mv));
   mv->type--;
@@ -176,11 +187,11 @@ mv_pop_value (struct missing_values *mv, union value *v)
 
 /* Stores  a value  in *V.
    MV must contain an individual value (as determined by
-   mv_has_value()). 
+   mv_has_value()).
    IDX is the zero based index of the value to get
 */
 void
-mv_peek_value (const struct missing_values *mv, union value *v, int idx) 
+mv_peek_value (const struct missing_values *mv, union value *v, int idx)
 {
   assert (idx >= 0 ) ;
   assert (idx < 3);
@@ -189,7 +200,7 @@ mv_peek_value (const struct missing_values *mv, union value *v, int idx)
   *v = mv->values[idx];
 }
 
-void 
+void
 mv_replace_value (struct missing_values *mv, const union value *v, int idx)
 {
   assert (idx >= 0) ;
@@ -200,7 +211,7 @@ mv_replace_value (struct missing_values *mv, const union value *v, int idx)
 
 
 
-int  
+int
 mv_n_values (const struct missing_values *mv)
 {
   assert(mv_has_value(mv));
@@ -211,18 +222,18 @@ mv_n_values (const struct missing_values *mv)
 /* Returns true if MV contains a numeric range,
    false if MV is empty (or contains only individual values). */
 bool
-mv_has_range (const struct missing_values *mv) 
+mv_has_range (const struct missing_values *mv)
 {
-  switch (mv->type) 
+  switch (mv->type)
     {
-    case MV_RANGE:
-    case MV_RANGE_1:
+    case MVT_RANGE:
+    case MVT_RANGE_1:
       return true;
-      
-    case MV_NONE:
-    case MV_1:
-    case MV_2:
-    case MV_3:
+
+    case MVT_NONE:
+    case MVT_1:
+    case MVT_2:
+    case MVT_3:
       return false;
     }
   NOT_REACHED ();
@@ -232,7 +243,7 @@ mv_has_range (const struct missing_values *mv)
    *HIGH.  MV must contain a individual range (as determined by
    mv_has_range()). */
 void
-mv_pop_range (struct missing_values *mv, double *low, double *high) 
+mv_pop_range (struct missing_values *mv, double *low, double *high)
 {
   assert (mv_has_range (mv));
   *low = mv->values[1].f;
@@ -245,7 +256,7 @@ mv_pop_range (struct missing_values *mv, double *low, double *high)
    *HIGH.  MV must contain a individual range (as determined by
    mv_has_range()). */
 void
-mv_peek_range (const struct missing_values *mv, double *low, double *high) 
+mv_peek_range (const struct missing_values *mv, double *low, double *high)
 {
   assert (mv_has_range (mv));
   *low = mv->values[1].f;
@@ -257,23 +268,23 @@ mv_peek_range (const struct missing_values *mv, double *low, double *high)
    is set to TYPE (in struct missing_values),
    false otherwise. */
 static bool
-using_element (unsigned type, int idx) 
+using_element (unsigned type, int idx)
 {
   assert (idx >= 0 && idx < 3);
-  
-  switch (type) 
+
+  switch (type)
     {
-    case MV_NONE:
+    case MVT_NONE:
       return false;
-    case MV_1:
+    case MVT_1:
       return idx < 1;
-    case MV_2:
+    case MVT_2:
       return idx < 2;
-    case MV_3:
+    case MVT_3:
       return true;
-    case MV_RANGE:
+    case MVT_RANGE:
       return idx > 0;
-    case MV_RANGE_1:
+    case MVT_RANGE_1:
       return true;
     }
   NOT_REACHED ();
@@ -283,7 +294,7 @@ using_element (unsigned type, int idx)
    NEW_WIDTH (inclusive) and OLD_WIDTH (exclusive),
    false otherwise. */
 static bool
-can_resize_string (const char *s, int old_width, int new_width) 
+can_resize_string (const char *s, int old_width, int new_width)
 {
   int i;
 
@@ -308,7 +319,7 @@ mv_is_resizable (const struct missing_values *mv, int width)
   if ( var_type_from_width (width) != var_type_from_width (mv->width) )
     return false;
 
-  if (width > MAX_SHORT_STRING && mv->type != MV_NONE)
+  if (width > MAX_SHORT_STRING && mv->type != MVT_NONE)
     return false;
 
   if (width >= mv->width)
@@ -328,117 +339,104 @@ mv_is_resizable (const struct missing_values *mv, int width)
 /* Resizes MV to the given WIDTH.  WIDTH must fit the constraints
    explained for mv_is_resizable(). */
 void
-mv_resize (struct missing_values *mv, int width) 
+mv_resize (struct missing_values *mv, int width)
 {
   assert (mv_is_resizable (mv, width));
-  if (width > mv->width && mv->type != MV_NONE) 
+  if (width > mv->width && mv->type != MVT_NONE)
     {
       int i;
-      
+
       for (i = 0; i < 3; i++)
         memset (mv->values[i].s + mv->width, ' ', width - mv->width);
     }
   mv->width = width;
 }
 
-/* Returns true if V is system missing or a missing value in MV,
-   false otherwise. */
-bool
-mv_is_value_missing (const struct missing_values *mv, const union value *v)
-{
-  return (mv->width == 0
-          ? mv_is_num_missing (mv, v->f)
-          : mv_is_str_missing (mv, v->s));
-}
-
-/* Returns true if D is system missing or a missing value in MV,
-   false otherwise.
-   MV must be a set of numeric missing values. */
-bool
-mv_is_num_missing (const struct missing_values *mv, double d)
-{
-  assert (mv->width == 0);
-  return d == SYSMIS || mv_is_num_user_missing (mv, d);
-}
-
-/* Returns true if S[] is a missing value in MV, false otherwise.
-   MV must be a set of string missing values. 
-   S[] must contain exactly as many characters as MV's width. */
-bool
-mv_is_str_missing (const struct missing_values *mv, const char s[])
-{
-  return mv_is_str_user_missing (mv, s);
-}
-
-/* Returns true if V is a missing value in MV, false otherwise. */
-bool
-mv_is_value_user_missing (const struct missing_values *mv,
-                          const union value *v)
-{
-  return (mv->width == 0
-          ? mv_is_num_user_missing (mv, v->f)
-          : mv_is_str_user_missing (mv, v->s));
-}
-
 /* Returns true if D is a missing value in MV, false otherwise.
    MV must be a set of numeric missing values. */
-bool
-mv_is_num_user_missing (const struct missing_values *mv, double d)
+static bool
+is_num_user_missing (const struct missing_values *mv, double d)
 {
   const union value *v = mv->values;
   assert (mv->width == 0);
-  switch (mv->type) 
+  switch (mv->type)
     {
-    case MV_NONE:
+    case MVT_NONE:
       return false;
-    case MV_1:
+    case MVT_1:
       return v[0].f == d;
-    case MV_2:
+    case MVT_2:
       return v[0].f == d || v[1].f == d;
-    case MV_3:
+    case MVT_3:
       return v[0].f == d || v[1].f == d || v[2].f == d;
-    case MV_RANGE:
+    case MVT_RANGE:
       return v[1].f <= d && d <= v[2].f;
-    case MV_RANGE_1:
+    case MVT_RANGE_1:
       return v[0].f == d || (v[1].f <= d && d <= v[2].f);
     }
   NOT_REACHED ();
 }
 
 /* Returns true if S[] is a missing value in MV, false otherwise.
-   MV must be a set of string missing values. 
+   MV must be a set of string missing values.
    S[] must contain exactly as many characters as MV's width. */
-bool
-mv_is_str_user_missing (const struct missing_values *mv,
+static bool
+is_str_user_missing (const struct missing_values *mv,
                         const char s[])
 {
   const union value *v = mv->values;
   assert (mv->width > 0);
-  switch (mv->type) 
+  switch (mv->type)
     {
-    case MV_NONE:
+    case MVT_NONE:
       return false;
-    case MV_1:
+    case MVT_1:
       return !memcmp (v[0].s, s, mv->width);
-    case MV_2:
+    case MVT_2:
       return (!memcmp (v[0].s, s, mv->width)
               || !memcmp (v[1].s, s, mv->width));
-    case MV_3:
+    case MVT_3:
       return (!memcmp (v[0].s, s, mv->width)
               || !memcmp (v[1].s, s, mv->width)
               || !memcmp (v[2].s, s, mv->width));
-    case MV_RANGE:
-    case MV_RANGE_1:
+    case MVT_RANGE:
+    case MVT_RANGE_1:
       NOT_REACHED ();
     }
   NOT_REACHED ();
 }
 
-/* Returns true if MV is a set of numeric missing values and V is
-   the system missing value. */
+/* Returns true if V is a missing value in the given CLASS in MV,
+   false otherwise. */
 bool
-mv_is_value_system_missing (const struct missing_values *mv,
-                            const union value *v)
+mv_is_value_missing (const struct missing_values *mv, const union value *v,
+                     enum mv_class class)
 {
-  return mv->width == 0 && v->f == SYSMIS;
+  return (mv->width == 0
+          ? mv_is_num_missing (mv, v->f, class)
+          : mv_is_str_missing (mv, v->s, class));
+}
+
+/* Returns true if D is a missing value in the given CLASS in MV,
+   false otherwise.
+   MV must be a set of numeric missing values. */
+bool
+mv_is_num_missing (const struct missing_values *mv, double d,
+                   enum mv_class class)
+{
+  assert (mv->width == 0);
+  return ((class & MV_SYSTEM && d == SYSMIS)
+          || (class & MV_USER && is_num_user_missing (mv, d)));
+}
+
+/* Returns true if S[] is a missing value in the given CLASS in
+   MV, false otherwise.
+   MV must be a set of string missing values.
+   S[] must contain exactly as many characters as MV's width. */
+bool
+mv_is_str_missing (const struct missing_values *mv, const char s[],
+                   enum mv_class class)
+{
+  assert (mv->width > 0);
+  return class & MV_USER && is_str_user_missing (mv, s);
 }