Changed a lot of ints to bools.
[pspp-builds.git] / src / language / data-io / matrix-data.c
index d5b489c34cd1dac103bd7fc492d8b89949aa9a19..401360de164382d7abdd5a66bed6d6a72c17d328 100644 (file)
 #include <language/data-io/data-reader.h>
 #include <language/data-io/file-handle.h>
 #include <language/lexer/lexer.h>
+#include <language/lexer/variable-parser.h>
 #include <libpspp/alloc.h>
 #include <libpspp/array.h>
+#include <libpspp/assertion.h>
 #include <libpspp/compiler.h>
 #include <libpspp/message.h>
 #include <libpspp/message.h>
@@ -42,6 +44,8 @@
 #include <libpspp/pool.h>
 #include <libpspp/str.h>
 
+#include "size_max.h"
+
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
@@ -751,7 +755,7 @@ mdump_token (const struct matrix_token *token)
       printf (" '%.*s'", token->length, token->string);
       break;
     default:
-      assert (0);
+      NOT_REACHED ();
     }
   fflush (stdout);
 }
@@ -769,138 +773,115 @@ mget_token_dump (struct matrix_token *token, struct dfm_reader *reader)
 static const char *
 context (struct dfm_reader *reader)
 {
-  static char buf[32];
+  static struct string buf = DS_EMPTY_INITIALIZER;
 
+  ds_clear (&buf);
   if (dfm_eof (reader))
-    strcpy (buf, "at end of file");
+    ds_assign_cstr (&buf, "at end of file");
   else 
     {
-      struct fixed_string line;
-      const char *sp;
+      struct substring p;
       
-      dfm_get_record (reader, &line);
-      sp = ls_c_str (&line);
-      while (sp < ls_end (&line) && isspace ((unsigned char) *sp))
-        sp++;
-      if (sp >= ls_end (&line))
-        strcpy (buf, "at end of line");
+      p = dfm_get_record (reader);
+      ss_ltrim (&p, ss_cstr (CC_SPACES));
+      if (ss_is_empty (p))
+        ds_assign_cstr (&buf, "at end of line");
       else
-        {
-          char *dp;
-          size_t copy_cnt = 0;
-
-          dp = stpcpy (buf, "before `");
-          while (sp < ls_end (&line) && !isspace ((unsigned char) *sp)
-                 && copy_cnt < 10) 
-            {
-              *dp++ = *sp++;
-              copy_cnt++; 
-            }
-          strcpy (dp, "'");
-        }
+        ds_put_format (&buf, "before `%.*s'",
+                       (int) ss_cspan (p, ss_cstr (CC_SPACES)), ss_data (p));
     }
   
-  return buf;
+  return ds_cstr (&buf);
 }
 
 /* Is there at least one token left in the data file? */
-static int
+static bool
 another_token (struct dfm_reader *reader)
 {
   for (;;)
     {
-      struct fixed_string line;
-      const char *cp;
+      struct substring p;
+      size_t space_cnt;
       
       if (dfm_eof (reader))
-        return 0;
-      dfm_get_record (reader, &line);
-
-      cp = ls_c_str (&line);
-      while (isspace ((unsigned char) *cp) && cp < ls_end (&line))
-       cp++;
+        return false;
 
-      if (cp < ls_end (&line)) 
+      p = dfm_get_record (reader);
+      space_cnt = ss_span (p, ss_cstr (CC_SPACES));
+      if (space_cnt < ss_length (p)) 
         {
-          dfm_forward_columns (reader, cp - ls_c_str (&line));
-          return 1;
+          dfm_forward_columns (reader, space_cnt);
+          return true;
         }
 
       dfm_forward_record (reader);
     }
+  NOT_REACHED();
 }
 
 /* Parse a MATRIX DATA token from READER into TOKEN. */
 static int
 (mget_token) (struct matrix_token *token, struct dfm_reader *reader)
 {
-  struct fixed_string line;
-  int first_column;
-  char *cp;
+  struct substring line, p;
+  struct substring s;
+  int c;
 
   if (!another_token (reader))
     return 0;
 
-  dfm_get_record (reader, &line);
-  first_column = dfm_column_start (reader);
+  line = p = dfm_get_record (reader);
 
   /* Three types of fields: quoted with ', quoted with ", unquoted. */
-  cp = ls_c_str (&line);
-  if (*cp == '\'' || *cp == '"')
+  c = ss_first (p);
+  if (c == '\'' || c == '"')
     {
-      int quote = *cp;
-
-      token->type = MSTR;
-      token->string = ++cp;
-      while (cp < ls_end (&line) && *cp != quote)
-       cp++;
-      token->length = cp - token->string;
-      if (cp < ls_end (&line))
-       cp++;
-      else
-       msg (SW, _("Scope of string exceeds line."));
+      ss_get_char (&p);
+      if (!ss_get_until (&p, c, &s))
+        msg (SW, _("Scope of string exceeds line."));
     }
   else
     {
-      int is_num = isdigit ((unsigned char) *cp) || *cp == '.';
-
-      token->string = cp++;
-      while (cp < ls_end (&line)
-             && !isspace ((unsigned char) *cp) && *cp != ','
-            && *cp != '-' && *cp != '+')
-       {
-         if (isdigit ((unsigned char) *cp))
-           is_num = 1;
-         
-         if ((tolower ((unsigned char) *cp) == 'd'
-              || tolower ((unsigned char) *cp) == 'e')
-             && (cp[1] == '+' || cp[1] == '-'))
-           cp += 2;
-         else
-           cp++;
-       }
+      bool is_num = isdigit (c) || c == '.';
+      const char *start = ss_data (p);
       
-      token->length = cp - token->string;
-      assert (token->length);
+      for (;;) 
+        {
+          c = ss_first (p);
+          if (strchr (CC_SPACES ",-+", c) != NULL)
+            break;
+
+          if (isdigit (c))
+            is_num = true;
+          if (strchr ("deDE", c) && strchr ("+-", ss_at (p, 1)))
+            {
+              is_num = true;
+              ss_advance (&p, 2);
+            }
+          else
+            ss_advance (&p, 1);
+        }
+      s = ss_buffer (start, ss_data (p) - start);
 
       if (is_num)
        {
          struct data_in di;
 
-         di.s = token->string;
-         di.e = token->string + token->length;
+         di.s = ss_data (s);
+         di.e = ss_end (s);
          di.v = (union value *) &token->number;
-         di.f1 = first_column;
+         di.f1 = dfm_get_column (reader, di.s);
          di.format = make_output_format (FMT_F, token->length, 0);
 
-         if (!data_in (&di))
-           return 0;
+         data_in (&di);
        }
       else
        token->type = MSTR;
     }
-
-  dfm_forward_columns (reader, cp - ls_c_str (&line));
+  token->string = ss_data (s);
+  token->length = ss_length (s);
+  
+  dfm_reread_record (reader, dfm_get_column (reader, ss_end (s)));
     
   return 1;
 }
@@ -910,18 +891,13 @@ static int
 static int
 force_eol (struct dfm_reader *reader, const char *content)
 {
-  struct fixed_string line;
-  const char *cp;
+  struct substring p;
 
   if (dfm_eof (reader))
     return 0;
-  dfm_get_record (reader, &line);
 
-  cp = ls_c_str (&line);
-  while (isspace ((unsigned char) *cp) && cp < ls_end (&line))
-    cp++;
-  
-  if (cp < ls_end (&line))
+  p = dfm_get_record (reader);
+  if (ss_span (p, ss_cstr (CC_SPACES)) != ss_length (p))
     {
       msg (SE, _("End of line expected %s while reading %s."),
           context (reader), content);
@@ -944,8 +920,8 @@ struct nr_aux_data
     double *split_values;       /* SPLIT FILE variable values. */
   };
 
-static int nr_read_splits (struct nr_aux_data *, int compare);
-static int nr_read_factors (struct nr_aux_data *, int cell);
+static bool nr_read_splits (struct nr_aux_data *, int compare);
+static bool nr_read_factors (struct nr_aux_data *, int cell);
 static bool nr_output_data (struct nr_aux_data *, struct ccase *,
                             write_case_func *, write_case_data);
 static bool matrix_data_read_without_rowtype (struct case_source *source,
@@ -1092,16 +1068,14 @@ nr_read_data_lines (struct nr_aux_data *nr,
              n_cols = mx->n_continuous;
              break;
            default:
-             assert (0);
-              abort ();
+              NOT_REACHED ();
            }
          break;
        case 2:
          n_cols = 1;
          break;
        default:
-         assert (0);
-          abort ();
+          NOT_REACHED ();
        }
 
       {
@@ -1239,9 +1213,9 @@ matrix_data_read_without_rowtype (struct case_source *source,
 }
 
 /* Read the split file variables.  If COMPARE is 1, compares the
-   values read to the last values read and returns 1 if they're equal,
-   0 otherwise. */
-static int
+   values read to the last values read and returns true if they're equal,
+   false otherwise. */
+static bool
 nr_read_splits (struct nr_aux_data *nr, int compare)
 {
   struct matrix_data_pgm *mx = nr->mx;
@@ -1252,11 +1226,11 @@ nr_read_splits (struct nr_aux_data *nr, int compare)
   if (compare && just_read)
     {
       just_read = 0;
-      return 1;
+      return true;
     }
   
   if (dict_get_split_vars (default_dict) == NULL)
-    return 1;
+    return true;
 
   if (mx->single_split)
     {
@@ -1265,7 +1239,7 @@ nr_read_splits (struct nr_aux_data *nr, int compare)
           struct mxd_var *mv = dict_get_split_vars (default_dict)[0]->aux;
           nr->split_values[0] = ++mv->sub_type; 
         }
-      return 1;
+      return true;
     }
 
   if (!compare)
@@ -1276,12 +1250,12 @@ nr_read_splits (struct nr_aux_data *nr, int compare)
     {
       struct matrix_token token;
       if (!mget_token (&token, mx->reader))
-        return 0;
+        return false;
       if (token.type != MNUM)
         {
           msg (SE, _("Syntax error expecting SPLIT FILE value %s."),
                context (mx->reader));
-          return 0;
+          return false;
         }
 
       if (!compare)
@@ -1291,31 +1265,31 @@ nr_read_splits (struct nr_aux_data *nr, int compare)
           msg (SE, _("Expecting value %g for %s."),
                nr->split_values[i],
                dict_get_split_vars (default_dict)[i]->name);
-          return 0;
+          return false;
         }
     }
 
-  return 1;
+  return true;
 }
 
 /* Read the factors for cell CELL.  If COMPARE is 1, compares the
-   values read to the last values read and returns 1 if they're equal,
-   0 otherwise. */
-static int
+   values read to the last values read and returns true if they're equal,
+   false otherwise. */
+static bool
 nr_read_factors (struct nr_aux_data *nr, int cell)
 {
   struct matrix_data_pgm *mx = nr->mx;
-  int compare;
+  bool compare;
   
   if (mx->n_factors == 0)
-    return 1;
+    return true;
 
   assert (nr->max_cell_idx >= cell);
   if (cell != nr->max_cell_idx)
-    compare = 1;
+    compare = true;
   else
     {
-      compare = 0;
+      compare = false;
       nr->max_cell_idx++;
     }
       
@@ -1326,12 +1300,12 @@ nr_read_factors (struct nr_aux_data *nr, int cell)
       {
         struct matrix_token token;
        if (!mget_token (&token, mx->reader))
-         return 0;
+         return false;
        if (token.type != MNUM)
          {
            msg (SE, _("Syntax error expecting factor value %s."),
                 context (mx->reader));
-           return 0;
+           return false;
          }
        
        if (!compare)
@@ -1341,12 +1315,12 @@ nr_read_factors (struct nr_aux_data *nr, int cell)
            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));
-           return 0;
+           return false;
          }
       }
   }
 
-  return 1;
+  return true;
 }
 
 /* Write the contents of a cell having content type CONTENT and data
@@ -1484,14 +1458,14 @@ struct wr_aux_data
     struct factor_data *current;        /* Current factor. */
   };
 
-static int wr_read_splits (struct wr_aux_data *, struct ccase *,
+static bool wr_read_splits (struct wr_aux_data *, struct ccase *,
                            write_case_func *, write_case_data);
 static bool wr_output_data (struct wr_aux_data *, struct ccase *,
                            write_case_func *, write_case_data);
-static int wr_read_rowtype (struct wr_aux_data *, 
+static bool wr_read_rowtype (struct wr_aux_data *, 
                             const struct matrix_token *, struct dfm_reader *);
-static int wr_read_factors (struct wr_aux_data *);
-static int wr_read_indeps (struct wr_aux_data *);
+static bool wr_read_factors (struct wr_aux_data *);
+static bool wr_read_indeps (struct wr_aux_data *);
 static bool matrix_data_read_with_rowtype (struct case_source *,
                                            struct ccase *,
                                            write_case_func *,
@@ -1550,55 +1524,55 @@ matrix_data_read_with_rowtype (struct case_source *source,
 
 /* Read the split file variables.  If they differ from the previous
    set of split variables then output the data.  Returns success. */
-static int 
+static bool 
 wr_read_splits (struct wr_aux_data *wr,
                 struct ccase *c,
                 write_case_func *write_case, write_case_data wc_data)
 {
   struct matrix_data_pgm *mx = wr->mx;
-  int compare;
+  bool compare;
   size_t split_cnt;
 
   split_cnt = dict_get_split_cnt (default_dict);
   if (split_cnt == 0)
-    return 1;
+    return true;
 
   if (wr->split_values)
-    compare = 1;
+    compare = true;
   else
     {
-      compare = 0;
+      compare = false;
       wr->split_values = xnmalloc (split_cnt, sizeof *wr->split_values);
     }
   
   {
-    int different = 0;
+    bool different = false;
     int i;
 
     for (i = 0; i < split_cnt; i++)
       {
         struct matrix_token token;
        if (!mget_token (&token, mx->reader))
-         return 0;
+         return false;
        if (token.type != MNUM)
          {
            msg (SE, _("Syntax error %s expecting SPLIT FILE value."),
                 context (mx->reader));
-           return 0;
+           return false;
          }
 
        if (compare && wr->split_values[i] != token.number && !different)
          {
            if (!wr_output_data (wr, c, write_case, wc_data))
              return 0;
-           different = 1;
+           different = true;
            mx->cells = 0;
          }
        wr->split_values[i] = token.number;
       }
   }
 
-  return 1;
+  return true;
 }
 
 /* Compares doubles A and B, treating SYSMIS as greatest. */
@@ -1741,7 +1715,7 @@ wr_output_data (struct wr_aux_data *wr,
 
 /* Sets ROWTYPE_ based on the given TOKEN read from READER.
    Return success. */
-static int 
+static bool 
 wr_read_rowtype (struct wr_aux_data *wr,
                  const struct matrix_token *token,
                  struct dfm_reader *reader)
@@ -1749,13 +1723,13 @@ wr_read_rowtype (struct wr_aux_data *wr,
   if (wr->content != -1)
     {
       msg (SE, _("Multiply specified ROWTYPE_ %s."), context (reader));
-      return 0;
+      return false;
     }
   if (token->type != MSTR)
     {
       msg (SE, _("Syntax error %s expecting ROWTYPE_ string."),
            context (reader));
-      return 0;
+      return false;
     }
   
   {
@@ -1777,12 +1751,12 @@ wr_read_rowtype (struct wr_aux_data *wr,
       return 0;
     }
 
-  return 1;
+  return true;
 }
 
 /* Read the factors for the current row.  Select a set of factors and
    point wr_current to it. */
-static int 
+static bool 
 wr_read_factors (struct wr_aux_data *wr)
 {
   struct matrix_data_pgm *mx = wr->mx;
@@ -1886,15 +1860,15 @@ cache_miss:
 
 winnage:
   local_free (factor_values);
-  return 1;
+  return true;
 
 lossage:
   local_free (factor_values);
-  return 0;
+  return false;
 }
 
 /* Read the independent variables into wr->current. */
-static int 
+static bool 
 wr_read_indeps (struct wr_aux_data *wr)
 {
   struct matrix_data_pgm *mx = wr->mx;
@@ -1926,7 +1900,7 @@ wr_read_indeps (struct wr_aux_data *wr)
        {
          msg (SE, _("Duplicate specification for %s."),
               content_names[wr->content]);
-         return 0;
+         return false;
        }
       if (type == 0)
        n_cols = mx->n_continuous;
@@ -1938,7 +1912,7 @@ wr_read_indeps (struct wr_aux_data *wr)
        {
          msg (SE, _("Too many rows of matrix data for %s."),
               content_names[wr->content]);
-         return 0;
+         return false;
        }
       
       switch (mx->section)
@@ -1961,13 +1935,11 @@ wr_read_indeps (struct wr_aux_data *wr)
          n_cols = mx->n_continuous;
          break;
        default:
-         assert (0);
-          abort ();
+          NOT_REACHED ();
        }
       break;
     default:
-      assert (0);
-      abort ();
+      NOT_REACHED ();
     }
   c->n_rows[wr->content]++;
 
@@ -1979,23 +1951,23 @@ wr_read_indeps (struct wr_aux_data *wr)
       {
         struct matrix_token token;
        if (!mget_token (&token, mx->reader))
-         return 0;
+         return false;
        if (token.type != MNUM)
          {
            msg (SE, _("Syntax error expecting value for %s %s."),
                  dict_get_var (default_dict, mx->first_continuous + j)->name,
                  context (mx->reader));
-           return 0;
+           return false;
          }
 
        *cp++ = token.number;
       }
     if (mx->fmt != FREE
         && !force_eol (mx->reader, content_names[wr->content]))
-      return 0;
+      return false;
   }
 
-  return 1;
+  return true;
 }
 \f
 /* Matrix source. */