Subcommand to export a model as a C function
[pspp-builds.git] / src / missing-values.c
index 09192179f1f69da6e9008884659f5b4ac37a998d..6940c6cf124d37ff5f0d674578da55ab32dc8c0a 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include "str.h"
 
+
 /* 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
@@ -35,10 +36,19 @@ mv_init (struct missing_values *mv, int width)
   mv->width = width;
 }
 
+void 
+mv_set_type(struct missing_values *mv, enum mv_type type)
+{
+  mv->type = type;
+}
+
+
 /* Copies SRC to MV. */
 void
 mv_copy (struct missing_values *mv, const struct missing_values *src) 
 {
+  assert(src);
+
   *mv = *src;
 }
 
@@ -89,7 +99,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 unsigned char s[]) 
+mv_add_str (struct missing_values *mv, const char s[]) 
 {
   assert (mv->width > 0);
   return mv_add_value (mv, (union value *) s);
@@ -107,11 +117,13 @@ mv_add_num (struct missing_values *mv, double d)
 
 /* Attempts to add range [LOW, HIGH] to the set of numeric
    missing values MV.  Returns true if successful, false if MV
-   has no room for a range. */
+   has no room for a range, or if LOW > HIGH. */
 bool
 mv_add_num_range (struct missing_values *mv, double low, double high) 
 {
   assert (mv->width == 0);
+  if (low > high)
+    return false;
   switch (mv->type) 
     {
     case MV_NONE:
@@ -133,7 +145,7 @@ mv_add_num_range (struct missing_values *mv, double low, double high)
 /* Returns true if MV contains an individual value,
    false if MV is empty (or contains only a range). */
 bool
-mv_has_value (struct missing_values *mv)
+mv_has_value (const struct missing_values *mv)
 {
   switch (mv->type) 
     {
@@ -161,10 +173,44 @@ mv_pop_value (struct missing_values *mv, union value *v)
   *v = mv->values[mv->type & 3];
 }
 
+/* Stores  a value  in *V.
+   MV must contain an individual value (as determined by
+   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) 
+{
+  assert (idx >= 0 ) ;
+  assert (idx < 3);
+
+  assert (mv_has_value (mv));
+  *v = mv->values[idx];
+}
+
+void 
+mv_replace_value (struct missing_values *mv, const union value *v, int idx)
+{
+  assert (idx >= 0) ;
+  assert (idx < mv_n_values(mv));
+
+  mv->values[idx] = *v;
+}
+
+
+
+int  
+mv_n_values (const struct missing_values *mv)
+{
+  assert(mv_has_value(mv));
+  return mv->type & 3;
+}
+
+
 /* Returns true if MV contains a numeric range,
    false if MV is empty (or contains only individual values). */
 bool
-mv_has_range (struct missing_values *mv) 
+mv_has_range (const struct missing_values *mv) 
 {
   switch (mv->type) 
     {
@@ -193,6 +239,19 @@ mv_pop_range (struct missing_values *mv, double *low, double *high)
   mv->type &= 3;
 }
 
+
+/* Returns the numeric range from MV  into *LOW and
+   *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) 
+{
+  assert (mv_has_range (mv));
+  *low = mv->values[1].f;
+  *high = mv->values[2].f;
+}
+
+
 /* Returns true if values[IDX] is in use when the `type' member
    is set to TYPE (in struct missing_values),
    false otherwise. */
@@ -223,7 +282,7 @@ using_element (unsigned type, int idx)
    NEW_WIDTH (inclusive) and OLD_WIDTH (exclusive),
    false otherwise. */
 static bool
-can_resize_string (const unsigned char *s, int old_width, int new_width) 
+can_resize_string (const char *s, int old_width, int new_width) 
 {
   int i;
 
@@ -302,8 +361,7 @@ mv_is_num_missing (const struct missing_values *mv, double d)
    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 unsigned char s[])
+mv_is_str_missing (const struct missing_values *mv, const char s[])
 {
   return mv_is_str_user_missing (mv, s);
 }
@@ -348,7 +406,7 @@ mv_is_num_user_missing (const struct missing_values *mv, double d)
    S[] must contain exactly as many characters as MV's width. */
 bool
 mv_is_str_user_missing (const struct missing_values *mv,
-                        const unsigned char s[])
+                        const char s[])
 {
   const union value *v = mv->values;
   assert (mv->width > 0);