Rewrite formatted data input routines to conform to SPSS data formats
[pspp-builds.git] / src / language / data-io / matrix-data.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #include <config.h>
21
22 #include <stdlib.h>
23 #include <ctype.h>
24 #include <float.h>
25
26 #include <data/case-source.h>
27 #include <data/case.h>
28 #include <data/data-in.h>
29 #include <data/dictionary.h>
30 #include <data/procedure.h>
31 #include <data/variable.h>
32 #include <language/command.h>
33 #include <language/data-io/data-reader.h>
34 #include <language/data-io/file-handle.h>
35 #include <language/lexer/lexer.h>
36 #include <language/lexer/variable-parser.h>
37 #include <libpspp/alloc.h>
38 #include <libpspp/array.h>
39 #include <libpspp/assertion.h>
40 #include <libpspp/compiler.h>
41 #include <libpspp/message.h>
42 #include <libpspp/message.h>
43 #include <libpspp/misc.h>
44 #include <libpspp/pool.h>
45 #include <libpspp/str.h>
46
47 #include "size_max.h"
48
49 #include "gettext.h"
50 #define _(msgid) gettext (msgid)
51
52 /* FIXME: /N subcommand not implemented.  It should be pretty simple,
53    too. */
54
55 /* Different types of variables for MATRIX DATA procedure.  Order is
56    important: these are used for sort keys. */
57 enum
58   {
59     MXD_SPLIT,                  /* SPLIT FILE variables. */
60     MXD_ROWTYPE,                /* ROWTYPE_. */
61     MXD_FACTOR,                 /* Factor variables. */
62     MXD_VARNAME,                /* VARNAME_. */
63     MXD_CONTINUOUS,             /* Continuous variables. */
64
65     MXD_COUNT
66   };
67
68 /* Format type enums. */
69 enum format_type
70   {
71     LIST,
72     FREE
73   };
74
75 /* Matrix section enums. */
76 enum matrix_section
77   {
78     LOWER,
79     UPPER,
80     FULL
81   };
82
83 /* Diagonal inclusion enums. */
84 enum include_diagonal
85   {
86     DIAGONAL,
87     NODIAGONAL
88   };
89
90 /* CONTENTS types. */
91 enum content_type
92   {
93     N_VECTOR,
94     N_SCALAR,
95     N_MATRIX,
96     MEAN,
97     STDDEV,
98     COUNT,
99     MSE,
100     DFE,
101     MAT,
102     COV,
103     CORR,
104     PROX,
105     
106     LPAREN,
107     RPAREN,
108     EOC
109   };
110
111 /* 0=vector, 1=matrix, 2=scalar. */
112 static const int content_type[PROX + 1] = 
113   {
114     0, 2, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1,
115   };
116
117 /* Name of each content type. */
118 static const char *const content_names[PROX + 1] =
119   {
120     "N", "N", "N_MATRIX", "MEAN", "STDDEV", "COUNT", "MSE",
121     "DFE", "MAT", "COV", "CORR", "PROX",
122   };
123
124 /* A MATRIX DATA input program. */
125 struct matrix_data_pgm 
126   {
127     struct pool *container;     /* Arena used for all allocations. */
128     struct dfm_reader *reader;  /* Data file to read. */
129
130     /* Format. */
131     enum format_type fmt;       /* LIST or FREE. */
132     enum matrix_section section;/* LOWER or UPPER or FULL. */
133     enum include_diagonal diag; /* DIAGONAL or NODIAGONAL. */
134
135     int explicit_rowtype;       /* ROWTYPE_ specified explicitly in data? */
136     struct variable *rowtype_, *varname_; /* ROWTYPE_, VARNAME_ variables. */
137     
138     struct variable *single_split; /* Single SPLIT FILE variable. */
139
140     /* Factor variables.  */
141     size_t n_factors;           /* Number of factor variables. */
142     struct variable **factors;  /* Factor variables. */
143     int is_per_factor[PROX + 1]; /* Is there per-factor data? */
144
145     int cells;                  /* Number of cells, or -1 if none. */
146
147     int pop_n;                  /* Population N specified by user. */
148
149     /* CONTENTS subcommand. */
150     int contents[EOC * 3 + 1];  /* Contents. */
151     int n_contents;             /* Number of entries. */
152
153     /* Continuous variables. */
154     int n_continuous;           /* Number of continuous variables. */
155     int first_continuous;       /* Index into dictionary of
156                                    first continuous variable. */
157   };
158
159 /* Auxiliary data attached to MATRIX DATA variables. */
160 struct mxd_var 
161   {
162     int var_type;               /* Variable type. */
163     int sub_type;               /* Subtype. */
164   };
165
166 static const struct case_source_class matrix_data_with_rowtype_source_class;
167 static const struct case_source_class matrix_data_without_rowtype_source_class;
168
169 static int compare_variables_by_mxd_var_type (const void *pa,
170                                              const void *pb);
171 static bool read_matrices_without_rowtype (struct dataset *ds, struct matrix_data_pgm *);
172 static bool read_matrices_with_rowtype (struct dataset *ds, struct matrix_data_pgm *);
173 static int string_to_content_type (const char *, int *);
174 static void attach_mxd_aux (struct variable *, int var_type, int sub_type);
175
176 int
177 cmd_matrix_data (struct lexer *lexer, struct dataset *ds)
178 {
179   struct pool *pool;
180   struct matrix_data_pgm *mx;
181   struct file_handle *fh = fh_inline_file ();
182   bool ok;
183     
184   unsigned seen = 0;
185   
186   discard_variables (ds);
187
188   pool = pool_create ();
189   mx = pool_alloc (pool, sizeof *mx);
190   mx->container = pool;
191   mx->reader = NULL;
192   mx->fmt = LIST;
193   mx->section = LOWER;
194   mx->diag = DIAGONAL;
195   mx->explicit_rowtype = 0;
196   mx->rowtype_ = NULL;
197   mx->varname_ = NULL;
198   mx->single_split = NULL;
199   mx->n_factors = 0;
200   mx->factors = NULL;
201   memset (mx->is_per_factor, 0, sizeof mx->is_per_factor);
202   mx->cells = -1;
203   mx->pop_n = -1;
204   mx->n_contents = 0;
205   mx->n_continuous = 0;
206   mx->first_continuous = 0;
207   while (lex_token (lexer) != '.')
208     {
209       lex_match (lexer, '/');
210
211       if (lex_match_id (lexer, "VARIABLES"))
212         {
213           char **v;
214           size_t nv;
215
216           if (seen & 1)
217             {
218               msg (SE, _("VARIABLES subcommand multiply specified."));
219               goto lossage;
220             }
221           seen |= 1;
222           
223           lex_match (lexer, '=');
224           if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NO_DUPLICATE))
225             goto lossage;
226           
227           {
228             size_t i;
229
230             for (i = 0; i < nv; i++)
231               if (!strcasecmp (v[i], "VARNAME_"))
232                 {
233                   msg (SE, _("VARNAME_ cannot be explicitly specified on "
234                              "VARIABLES."));
235                   for (i = 0; i < nv; i++)
236                     free (v[i]);
237                   free (v);
238                   goto lossage;
239                 }
240           }
241           
242           {
243             size_t i;
244
245             for (i = 0; i < nv; i++)
246               {
247                 struct variable *new_var;
248                 
249                 if (strcasecmp (v[i], "ROWTYPE_"))
250                   {
251                     new_var = dict_create_var_assert (dataset_dict (ds), v[i], 0);
252                     attach_mxd_aux (new_var, MXD_CONTINUOUS, i);
253                   }
254                 else
255                   mx->explicit_rowtype = 1;
256                 free (v[i]);
257               }
258             free (v);
259           }
260           
261           mx->rowtype_ = dict_create_var_assert (dataset_dict (ds),
262                                                  "ROWTYPE_", 8);
263           attach_mxd_aux (mx->rowtype_, MXD_ROWTYPE, 0);
264         }
265       else if (lex_match_id (lexer, "FILE"))
266         {
267           lex_match (lexer, '=');
268           fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
269           if (fh == NULL)
270             goto lossage;
271         }
272       else if (lex_match_id (lexer, "FORMAT"))
273         {
274           lex_match (lexer, '=');
275
276           while (lex_token (lexer) == T_ID)
277             {
278               if (lex_match_id (lexer, "LIST"))
279                 mx->fmt = LIST;
280               else if (lex_match_id (lexer, "FREE"))
281                 mx->fmt = FREE;
282               else if (lex_match_id (lexer, "LOWER"))
283                 mx->section = LOWER;
284               else if (lex_match_id (lexer, "UPPER"))
285                 mx->section = UPPER;
286               else if (lex_match_id (lexer, "FULL"))
287                 mx->section = FULL;
288               else if (lex_match_id (lexer, "DIAGONAL"))
289                 mx->diag = DIAGONAL;
290               else if (lex_match_id (lexer, "NODIAGONAL"))
291                 mx->diag = NODIAGONAL;
292               else 
293                 {
294                   lex_error (lexer, _("in FORMAT subcommand"));
295                   goto lossage;
296                 }
297             }
298         }
299       else if (lex_match_id (lexer, "SPLIT"))
300         {
301           lex_match (lexer, '=');
302
303           if (seen & 2)
304             {
305               msg (SE, _("SPLIT subcommand multiply specified."));
306               goto lossage;
307             }
308           seen |= 2;
309           
310           if (lex_token (lexer) != T_ID)
311             {
312               lex_error (lexer, _("in SPLIT subcommand"));
313               goto lossage;
314             }
315           
316           if (dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL
317               && (lex_look_ahead (lexer) == '.' || lex_look_ahead (lexer) == '/'))
318             {
319               if (!strcasecmp (lex_tokid (lexer), "ROWTYPE_")
320                   || !strcasecmp (lex_tokid (lexer), "VARNAME_"))
321                 {
322                   msg (SE, _("Split variable may not be named ROWTYPE_ "
323                              "or VARNAME_."));
324                   goto lossage;
325                 }
326
327               mx->single_split = dict_create_var_assert (dataset_dict (ds),
328                                                          lex_tokid (lexer), 0);
329               attach_mxd_aux (mx->single_split, MXD_CONTINUOUS, 0);
330               lex_get (lexer);
331
332               dict_set_split_vars (dataset_dict (ds), &mx->single_split, 1);
333             }
334           else
335             {
336               struct variable **split;
337               size_t n;
338
339               if (!parse_variables (lexer, dataset_dict (ds), 
340                                     &split, &n, PV_NO_DUPLICATE))
341                 goto lossage;
342
343               dict_set_split_vars (dataset_dict (ds), split, n);
344             }
345           
346           {
347             struct variable *const *split = dict_get_split_vars (dataset_dict (ds));
348             size_t split_cnt = dict_get_split_cnt (dataset_dict (ds));
349             int i;
350
351             for (i = 0; i < split_cnt; i++)
352               {
353                 struct mxd_var *mv = split[i]->aux;
354                 assert (mv != NULL);
355                 if (mv->var_type != MXD_CONTINUOUS)
356                   {
357                     msg (SE, _("Split variable %s is already another type."),
358                          lex_tokid (lexer));
359                     goto lossage;
360                   }
361                 var_clear_aux (split[i]);
362                 attach_mxd_aux (split[i], MXD_SPLIT, i);
363               }
364           }
365         }
366       else if (lex_match_id (lexer, "FACTORS"))
367         {
368           lex_match (lexer, '=');
369           
370           if (seen & 4)
371             {
372               msg (SE, _("FACTORS subcommand multiply specified."));
373               goto lossage;
374             }
375           seen |= 4;
376
377           if (!parse_variables (lexer, dataset_dict (ds), &mx->factors, &mx->n_factors,
378                                 PV_NONE))
379             goto lossage;
380           
381           {
382             size_t i;
383             
384             for (i = 0; i < mx->n_factors; i++)
385               {
386                 struct variable *v = mx->factors[i];
387                 struct mxd_var *mv = v->aux;
388                 assert (mv != NULL);
389                 if (mv->var_type != MXD_CONTINUOUS)
390                   {
391                     msg (SE, _("Factor variable %s is already another type."),
392                          lex_tokid (lexer));
393                     goto lossage;
394                   }
395                 var_clear_aux (v);
396                 attach_mxd_aux (v, MXD_FACTOR, i);
397               }
398           }
399         }
400       else if (lex_match_id (lexer, "CELLS"))
401         {
402           lex_match (lexer, '=');
403           
404           if (mx->cells != -1)
405             {
406               msg (SE, _("CELLS subcommand multiply specified."));
407               goto lossage;
408             }
409
410           if (!lex_is_integer (lexer) || lex_integer (lexer) < 1)
411             {
412               lex_error (lexer, _("expecting positive integer"));
413               goto lossage;
414             }
415
416           mx->cells = lex_integer (lexer);
417           lex_get (lexer);
418         }
419       else if (lex_match_id (lexer, "N"))
420         {
421           lex_match (lexer, '=');
422
423           if (mx->pop_n != -1)
424             {
425               msg (SE, _("N subcommand multiply specified."));
426               goto lossage;
427             }
428
429           if (!lex_is_integer (lexer) || lex_integer (lexer) < 1)
430             {
431               lex_error (lexer, _("expecting positive integer"));
432               goto lossage;
433             }
434
435           mx->pop_n = lex_integer (lexer);
436           lex_get (lexer);
437         }
438       else if (lex_match_id (lexer, "CONTENTS"))
439         {
440           int inside_parens = 0;
441           unsigned collide = 0;
442           int item;
443           
444           if (seen & 8)
445             {
446               msg (SE, _("CONTENTS subcommand multiply specified."));
447               goto lossage;
448             }
449           seen |= 8;
450
451           lex_match (lexer, '=');
452           
453           {
454             int i;
455             
456             for (i = 0; i <= PROX; i++)
457               mx->is_per_factor[i] = 0;
458           }
459
460           for (;;)
461             {
462               if (lex_match (lexer, '('))
463                 {
464                   if (inside_parens)
465                     {
466                       msg (SE, _("Nested parentheses not allowed."));
467                       goto lossage;
468                     }
469                   inside_parens = 1;
470                   item = LPAREN;
471                 }
472               else if (lex_match (lexer, ')'))
473                 {
474                   if (!inside_parens)
475                     {
476                       msg (SE, _("Mismatched right parenthesis (`(')."));
477                       goto lossage;
478                     }
479                   if (mx->contents[mx->n_contents - 1] == LPAREN)
480                     {
481                       msg (SE, _("Empty parentheses not allowed."));
482                       goto lossage;
483                     }
484                   inside_parens = 0;
485                   item = RPAREN;
486                 }
487               else 
488                 {
489                   int content_type;
490                   int collide_index;
491                   
492                   if (lex_token (lexer) != T_ID)
493                     {
494                       lex_error (lexer, _("in CONTENTS subcommand"));
495                       goto lossage;
496                     }
497
498                   content_type = string_to_content_type (lex_tokid (lexer),
499                                                          &collide_index);
500                   if (content_type == -1)
501                     {
502                       lex_error (lexer, _("in CONTENTS subcommand"));
503                       goto lossage;
504                     }
505                   lex_get (lexer);
506
507                   if (collide & (1 << collide_index))
508                     {
509                       msg (SE, _("Content multiply specified for %s."),
510                            content_names[content_type]);
511                       goto lossage;
512                     }
513                   collide |= (1 << collide_index);
514                   
515                   item = content_type;
516                   mx->is_per_factor[item] = inside_parens;
517                 }
518               mx->contents[mx->n_contents++] = item;
519
520               if (lex_token (lexer) == '/' || lex_token (lexer) == '.')
521                 break;
522             }
523
524           if (inside_parens)
525             {
526               msg (SE, _("Missing right parenthesis."));
527               goto lossage;
528             }
529           mx->contents[mx->n_contents] = EOC;
530         }
531       else 
532         {
533           lex_error (lexer, NULL);
534           goto lossage;
535         }
536     }
537   
538   if (lex_token (lexer) != '.')
539     {
540       lex_error (lexer, _("expecting end of command"));
541       goto lossage;
542     }
543   
544   if (!(seen & 1))
545     {
546       msg (SE, _("Missing VARIABLES subcommand."));
547       goto lossage;
548     }
549   
550   if (!mx->n_contents && !mx->explicit_rowtype)
551     {
552       msg (SW, _("CONTENTS subcommand not specified: assuming file "
553                  "contains only CORR matrix."));
554
555       mx->contents[0] = CORR;
556       mx->contents[1] = EOC;
557       mx->n_contents = 0;
558     }
559
560   if (mx->n_factors && !mx->explicit_rowtype && mx->cells == -1)
561     {
562       msg (SE, _("Missing CELLS subcommand.  CELLS is required "
563                  "when ROWTYPE_ is not given in the data and "
564                  "factors are present."));
565       goto lossage;
566     }
567
568   if (mx->explicit_rowtype && mx->single_split)
569     {
570       msg (SE, _("Split file values must be present in the data when "
571                  "ROWTYPE_ is present."));
572       goto lossage;
573     }
574       
575   /* Create VARNAME_. */
576   mx->varname_ = dict_create_var_assert (dataset_dict (ds), "VARNAME_", 8);
577   attach_mxd_aux (mx->varname_, MXD_VARNAME, 0);
578   
579   /* Sort the dictionary variables into the desired order for the
580      system file output. */
581   {
582     struct variable **v;
583     size_t nv;
584
585     dict_get_vars (dataset_dict (ds), &v, &nv, 0);
586     qsort (v, nv, sizeof *v, compare_variables_by_mxd_var_type);
587     dict_reorder_vars (dataset_dict (ds), v, nv);
588     free (v);
589   }
590
591   /* Set formats. */
592   {
593     static const struct fmt_spec fmt_tab[MXD_COUNT] =
594       {
595         {FMT_F, 4, 0},
596         {FMT_A, 8, 0},
597         {FMT_F, 4, 0},
598         {FMT_A, 8, 0},
599         {FMT_F, 10, 4},
600       };
601     
602     int i;
603
604     mx->first_continuous = -1;
605     for (i = 0; i < dict_get_var_cnt (dataset_dict (ds)); i++)
606       {
607         struct variable *v = dict_get_var (dataset_dict (ds), i);
608         struct mxd_var *mv = v->aux;
609         int type = mv->var_type;
610         
611         assert (type >= 0 && type < MXD_COUNT);
612         v->print = v->write = fmt_tab[type];
613
614         if (type == MXD_CONTINUOUS)
615           mx->n_continuous++;
616         if (mx->first_continuous == -1 && type == MXD_CONTINUOUS)
617           mx->first_continuous = i;
618       }
619   }
620
621   if (mx->n_continuous == 0)
622     {
623       msg (SE, _("No continuous variables specified."));
624       goto lossage;
625     }
626
627   mx->reader = dfm_open_reader (fh, lexer);
628   if (mx->reader == NULL)
629     goto lossage;
630
631   if (mx->explicit_rowtype)
632     ok = read_matrices_with_rowtype (ds, mx);
633   else
634     ok = read_matrices_without_rowtype (ds, mx);
635
636   dfm_close_reader (mx->reader);
637
638   pool_destroy (mx->container);
639
640   return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
641
642 lossage:
643   discard_variables (ds);
644   free (mx->factors);
645   pool_destroy (mx->container);
646   return CMD_CASCADING_FAILURE;
647 }
648
649 /* Look up string S as a content-type name and return the
650    corresponding enumerated value, or -1 if there is no match.  If
651    COLLIDE is non-NULL then *COLLIDE returns a value (suitable for use
652    as a bit-index) which can be used for determining whether a related
653    statistic has already been used. */
654 static int
655 string_to_content_type (const char *s, int *collide)
656 {
657   static const struct
658     {
659       int value;
660       int collide;
661       const char *string;
662     }
663   *tp,
664   tab[] = 
665     {
666       {N_VECTOR, 0, "N_VECTOR"},
667       {N_VECTOR, 0, "N"},
668       {N_SCALAR, 0, "N_SCALAR"},
669       {N_MATRIX, 1, "N_MATRIX"},
670       {MEAN, 2, "MEAN"},
671       {STDDEV, 3, "STDDEV"},
672       {STDDEV, 3, "SD"},
673       {COUNT, 4, "COUNT"},
674       {MSE, 5, "MSE"},
675       {DFE, 6, "DFE"},
676       {MAT, 7, "MAT"},
677       {COV, 8, "COV"},
678       {CORR, 9, "CORR"},
679       {PROX, 10, "PROX"},
680       {-1, -1, NULL},
681     };
682
683   for (tp = tab; tp->value != -1; tp++)
684     if (!strcasecmp (s, tp->string))
685       {
686         if (collide)
687           *collide = tp->collide;
688         
689         return tp->value;
690       }
691   return -1;
692 }
693
694 /* Compare two variables using p.mxd.var_type and p.mxd.sub_type
695    fields. */
696 static int
697 compare_variables_by_mxd_var_type (const void *a_, const void *b_)
698 {
699   struct variable *const *pa = a_;
700   struct variable *const *pb = b_;
701   const struct mxd_var *a = (*pa)->aux;
702   const struct mxd_var *b = (*pb)->aux;
703   
704   if (a->var_type != b->var_type)
705     return a->var_type > b->var_type ? 1 : -1;
706   else
707     return a->sub_type < b->sub_type ? -1 : a->sub_type > b->sub_type;
708 }
709
710 /* Attaches a struct mxd_var with the specific member values to
711    V. */
712 static void
713 attach_mxd_aux (struct variable *v, int var_type, int sub_type) 
714 {
715   struct mxd_var *mv;
716   
717   assert (v->aux == NULL);
718   mv = xmalloc (sizeof *mv);
719   mv->var_type = var_type;
720   mv->sub_type = sub_type;
721   var_attach_aux (v, mv, var_dtor_free);
722 }
723 \f
724 /* Matrix tokenizer. */
725
726 /* Matrix token types. */
727 enum matrix_token_type
728   {
729     MNUM,               /* Number. */
730     MSTR                /* String. */
731   };
732
733 /* A MATRIX DATA parsing token. */
734 struct matrix_token
735   {
736     enum matrix_token_type type; 
737     double number;       /* MNUM: token value. */
738     char *string;        /* MSTR: token string; not null-terminated. */
739     int length;          /* MSTR: tokstr length. */
740   };
741
742 static int mget_token (struct matrix_token *, struct dfm_reader *);
743
744 #if DEBUGGING
745 #define mget_token(TOKEN, READER) mget_token_dump(TOKEN, READER)
746
747 static void
748 mdump_token (const struct matrix_token *token)
749 {
750   switch (token->type)
751     {
752     case MNUM:
753       printf (" #%g", token->number);
754       break;
755     case MSTR:
756       printf (" '%.*s'", token->length, token->string);
757       break;
758     default:
759       NOT_REACHED ();
760     }
761   fflush (stdout);
762 }
763
764 static int
765 mget_token_dump (struct matrix_token *token, struct dfm_reader *reader)
766 {
767   int result = (mget_token) (token, reader);
768   mdump_token (token);
769   return result;
770 }
771 #endif
772
773 /* Return the current position in READER. */
774 static const char *
775 context (struct dfm_reader *reader)
776 {
777   static struct string buf = DS_EMPTY_INITIALIZER;
778
779   ds_clear (&buf);
780   if (dfm_eof (reader))
781     ds_assign_cstr (&buf, "at end of file");
782   else 
783     {
784       struct substring p;
785       
786       p = dfm_get_record (reader);
787       ss_ltrim (&p, ss_cstr (CC_SPACES));
788       if (ss_is_empty (p))
789         ds_assign_cstr (&buf, "at end of line");
790       else
791         ds_put_format (&buf, "before `%.*s'",
792                        (int) ss_cspan (p, ss_cstr (CC_SPACES)), ss_data (p));
793     }
794   
795   return ds_cstr (&buf);
796 }
797
798 /* Is there at least one token left in the data file? */
799 static bool
800 another_token (struct dfm_reader *reader)
801 {
802   for (;;)
803     {
804       struct substring p;
805       size_t space_cnt;
806       
807       if (dfm_eof (reader))
808         return false;
809
810       p = dfm_get_record (reader);
811       space_cnt = ss_span (p, ss_cstr (CC_SPACES));
812       if (space_cnt < ss_length (p)) 
813         {
814           dfm_forward_columns (reader, space_cnt);
815           return true;
816         }
817
818       dfm_forward_record (reader);
819     }
820   NOT_REACHED();
821 }
822
823 /* Parse a MATRIX DATA token from READER into TOKEN. */
824 static int
825 (mget_token) (struct matrix_token *token, struct dfm_reader *reader)
826 {
827   struct substring line, p;
828   struct substring s;
829   int c;
830
831   if (!another_token (reader))
832     return 0;
833
834   line = p = dfm_get_record (reader);
835
836   /* Three types of fields: quoted with ', quoted with ", unquoted. */
837   c = ss_first (p);
838   if (c == '\'' || c == '"')
839     {
840       ss_get_char (&p);
841       if (!ss_get_until (&p, c, &s))
842         msg (SW, _("Scope of string exceeds line."));
843     }
844   else
845     {
846       bool is_num = isdigit (c) || c == '.';
847       const char *start = ss_data (p);
848       
849       for (;;) 
850         {
851           c = ss_first (p);
852           if (strchr (CC_SPACES ",-+", c) != NULL)
853             break;
854
855           if (isdigit (c))
856             is_num = true;
857           if (strchr ("deDE", c) && strchr ("+-", ss_at (p, 1)))
858             {
859               is_num = true;
860               ss_advance (&p, 2);
861             }
862           else
863             ss_advance (&p, 1);
864         }
865       s = ss_buffer (start, ss_data (p) - start);
866
867       if (is_num)
868         data_in (s, FMT_F, 0,
869                  dfm_get_column (reader, ss_data (s)),
870                  (union value *) &token->number, 0);
871       else
872         token->type = MSTR;
873     }
874   token->string = ss_data (s);
875   token->length = ss_length (s);
876   
877   dfm_reread_record (reader, dfm_get_column (reader, ss_end (s)));
878     
879   return 1;
880 }
881
882 /* Forcibly skip the end of a line for content type CONTENT in
883    READER. */
884 static int
885 force_eol (struct dfm_reader *reader, const char *content)
886 {
887   struct substring p;
888
889   if (dfm_eof (reader))
890     return 0;
891
892   p = dfm_get_record (reader);
893   if (ss_span (p, ss_cstr (CC_SPACES)) != ss_length (p))
894     {
895       msg (SE, _("End of line expected %s while reading %s."),
896            context (reader), content);
897       return 0;
898     }
899   
900   dfm_forward_record (reader);
901   return 1;
902 }
903 \f
904 /* Back end, omitting ROWTYPE_. */
905
906 struct nr_aux_data 
907   {
908     const struct dictionary *dict; /* The dictionary */
909     struct matrix_data_pgm *mx; /* MATRIX DATA program. */
910     double ***data;             /* MATRIX DATA data. */
911     double *factor_values;      /* Factor values. */
912     int max_cell_idx;           /* Max-numbered cell that we have
913                                    read so far, plus one. */
914     double *split_values;       /* SPLIT FILE variable values. */
915   };
916
917 static bool nr_read_splits (struct nr_aux_data *, int compare);
918 static bool nr_read_factors (struct nr_aux_data *, int cell);
919 static bool nr_output_data (struct nr_aux_data *, struct ccase *,
920                             write_case_func *, write_case_data);
921 static bool matrix_data_read_without_rowtype (struct case_source *source,
922                                               struct ccase *,
923                                               write_case_func *,
924                                               write_case_data);
925
926 /* Read from the data file and write it to the active file.
927    Returns true if successful, false if an I/O error occurred. */
928 static bool
929 read_matrices_without_rowtype (struct dataset *ds, struct matrix_data_pgm *mx)
930 {
931   struct nr_aux_data nr;
932   bool ok;
933   
934   if (mx->cells == -1)
935     mx->cells = 1;
936
937   nr.mx = mx;
938   nr.dict = dataset_dict (ds);
939   nr.data = NULL;
940   nr.factor_values = xnmalloc (mx->n_factors * mx->cells,
941                                sizeof *nr.factor_values);
942   nr.max_cell_idx = 0;
943   nr.split_values = xnmalloc (dict_get_split_cnt (dataset_dict (ds)),
944                               sizeof *nr.split_values);
945
946   proc_set_source (ds, create_case_source (
947                      &matrix_data_without_rowtype_source_class, &nr));
948   
949   ok = procedure (ds, NULL, NULL);
950
951   free (nr.split_values);
952   free (nr.factor_values);
953
954   return ok;
955 }
956
957 /* Mirror data across the diagonal of matrix CP which contains
958    CONTENT type data. */
959 static void
960 fill_matrix (struct matrix_data_pgm *mx, int content, double *cp)
961 {
962   int type = content_type[content];
963
964   if (type == 1 && mx->section != FULL)
965     {
966       if (mx->diag == NODIAGONAL)
967         {
968           const double fill = content == CORR ? 1.0 : SYSMIS;
969           int i;
970
971           for (i = 0; i < mx->n_continuous; i++)
972             cp[i * (1 + mx->n_continuous)] = fill;
973         }
974       
975       {
976         int c, r;
977         
978         if (mx->section == LOWER)
979           {
980             int n_lines = mx->n_continuous;
981             if (mx->section != FULL && mx->diag == NODIAGONAL)
982               n_lines--;
983             
984             for (r = 1; r < n_lines; r++)
985               for (c = 0; c < r; c++)
986                 cp[r + c * mx->n_continuous] = cp[c + r * mx->n_continuous];
987           }
988         else 
989           {
990             assert (mx->section == UPPER);
991             for (r = 1; r < mx->n_continuous; r++)
992               for (c = 0; c < r; c++)
993                 cp[c + r * mx->n_continuous] = cp[r + c * mx->n_continuous];
994           }
995       }
996     }
997   else if (type == 2)
998     {
999       int c;
1000
1001       for (c = 1; c < mx->n_continuous; c++)
1002         cp[c] = cp[0];
1003     }
1004 }
1005
1006 /* Read data lines for content type CONTENT from the data file.
1007    If PER_FACTOR is nonzero, then factor information is read from
1008    the data file.  Data is for cell number CELL. */
1009 static int
1010 nr_read_data_lines (struct nr_aux_data *nr,
1011                     int per_factor, int cell, int content, int compare)
1012 {
1013   struct matrix_data_pgm *mx = nr->mx;
1014   const int type = content_type[content];               /* Content type. */
1015   int n_lines; /* Number of lines to parse from data file for this type. */
1016   double *cp;                   /* Current position in vector or matrix. */
1017   int i;
1018
1019   if (type != 1)
1020     n_lines = 1;
1021   else
1022     {
1023       n_lines = mx->n_continuous;
1024       if (mx->section != FULL && mx->diag == NODIAGONAL)
1025         n_lines--;
1026     }
1027
1028   cp = nr->data[content][cell];
1029   if (type == 1 && mx->section == LOWER && mx->diag == NODIAGONAL)
1030     cp += mx->n_continuous;
1031
1032   for (i = 0; i < n_lines; i++)
1033     {
1034       int n_cols;
1035       
1036       if (!nr_read_splits (nr, 1))
1037         return 0;
1038       if (per_factor && !nr_read_factors (nr, cell))
1039         return 0;
1040       compare = 1;
1041
1042       switch (type)
1043         {
1044         case 0:
1045           n_cols = mx->n_continuous;
1046           break;
1047         case 1:
1048           switch (mx->section)
1049             {
1050             case LOWER:
1051               n_cols = i + 1;
1052               break;
1053             case UPPER:
1054               cp += i;
1055               n_cols = mx->n_continuous - i;
1056               if (mx->diag == NODIAGONAL)
1057                 {
1058                   n_cols--;
1059                   cp++;
1060                 }
1061               break;
1062             case FULL:
1063               n_cols = mx->n_continuous;
1064               break;
1065             default:
1066               NOT_REACHED ();
1067             }
1068           break;
1069         case 2:
1070           n_cols = 1;
1071           break;
1072         default:
1073           NOT_REACHED ();
1074         }
1075
1076       {
1077         int j;
1078         
1079         for (j = 0; j < n_cols; j++)
1080           {
1081             struct matrix_token token;
1082             if (!mget_token (&token, mx->reader))
1083               return 0;
1084             if (token.type != MNUM)
1085               {
1086                 msg (SE, _("expecting value for %s %s"),
1087                      dict_get_var (nr->dict, j)->name,
1088                      context (mx->reader));
1089                 return 0;
1090               }
1091
1092             *cp++ = token.number;
1093           }
1094         if (mx->fmt != FREE
1095             && !force_eol (mx->reader, content_names[content]))
1096           return 0;
1097       }
1098
1099       if (mx->section == LOWER)
1100         cp += mx->n_continuous - n_cols;
1101     }
1102
1103   fill_matrix (mx, content, nr->data[content][cell]);
1104
1105   return 1;
1106 }
1107
1108 /* When ROWTYPE_ does not appear in the data, reads the matrices and
1109    writes them to the output file.
1110    Returns true if successful, false if an I/O error occurred. */
1111 static bool
1112 matrix_data_read_without_rowtype (struct case_source *source,
1113                                   struct ccase *c,
1114                                   write_case_func *write_case,
1115                                   write_case_data wc_data)
1116 {
1117   struct nr_aux_data *nr = source->aux;
1118   struct matrix_data_pgm *mx = nr->mx;
1119
1120   {
1121     int *cp;
1122
1123     nr->data = pool_nalloc (mx->container, PROX + 1, sizeof *nr->data);
1124     
1125     {
1126       int i;
1127
1128       for (i = 0; i <= PROX; i++)
1129         nr->data[i] = NULL;
1130     }
1131     
1132     for (cp = mx->contents; *cp != EOC; cp++)
1133       if (*cp != LPAREN && *cp != RPAREN)
1134         {
1135           int per_factor = mx->is_per_factor[*cp];
1136           int n_entries;
1137           
1138           n_entries = mx->n_continuous;
1139           if (content_type[*cp] == 1)
1140             n_entries *= mx->n_continuous;
1141           
1142           {
1143             int n_vectors = per_factor ? mx->cells : 1;
1144             int i;
1145             
1146             nr->data[*cp] = pool_nalloc (mx->container,
1147                                          n_vectors, sizeof **nr->data);
1148             
1149             for (i = 0; i < n_vectors; i++)
1150               nr->data[*cp][i] = pool_nalloc (mx->container,
1151                                               n_entries, sizeof ***nr->data);
1152           }
1153         }
1154   }
1155   
1156   for (;;)
1157     {
1158       int *bp, *ep, *np;
1159       
1160       if (!nr_read_splits (nr, 0))
1161         return true;
1162       
1163       for (bp = mx->contents; *bp != EOC; bp = np)
1164         {
1165           int per_factor;
1166
1167           /* Trap the CONTENTS that we should parse in this pass
1168              between bp and ep.  Set np to the starting bp for next
1169              iteration. */
1170           if (*bp == LPAREN)
1171             {
1172               ep = ++bp;
1173               while (*ep != RPAREN)
1174                 ep++;
1175               np = &ep[1];
1176               per_factor = 1;
1177             }
1178           else
1179             {
1180               ep = &bp[1];
1181               while (*ep != EOC && *ep != LPAREN)
1182                 ep++;
1183               np = ep;
1184               per_factor = 0;
1185             }
1186           
1187           {
1188             int i;
1189               
1190             for (i = 0; i < (per_factor ? mx->cells : 1); i++)
1191               {
1192                 int *cp;
1193
1194                 for (cp = bp; cp < ep; cp++) 
1195                   if (!nr_read_data_lines (nr, per_factor, i, *cp, cp != bp))
1196                     return true;
1197               }
1198           }
1199         }
1200
1201       if (!nr_output_data (nr, c, write_case, wc_data))
1202         return false;
1203
1204       if (dict_get_split_cnt (nr->dict) == 0
1205           || !another_token (mx->reader))
1206         return true;
1207     }
1208 }
1209
1210 /* Read the split file variables.  If COMPARE is 1, compares the
1211    values read to the last values read and returns true if they're equal,
1212    false otherwise. */
1213 static bool
1214 nr_read_splits (struct nr_aux_data *nr, int compare)
1215 {
1216   struct matrix_data_pgm *mx = nr->mx;
1217   static int just_read = 0; /* FIXME: WTF? */
1218   size_t split_cnt;
1219   size_t i;
1220
1221   if (compare && just_read)
1222     {
1223       just_read = 0;
1224       return true;
1225     }
1226   
1227   if (dict_get_split_vars (nr->dict) == NULL)
1228     return true;
1229
1230   if (mx->single_split)
1231     {
1232       if (!compare) 
1233         {
1234           struct mxd_var *mv = dict_get_split_vars (nr->dict)[0]->aux;
1235           nr->split_values[0] = ++mv->sub_type; 
1236         }
1237       return true;
1238     }
1239
1240   if (!compare)
1241     just_read = 1;
1242
1243   split_cnt = dict_get_split_cnt (nr->dict);
1244   for (i = 0; i < split_cnt; i++) 
1245     {
1246       struct matrix_token token;
1247       if (!mget_token (&token, mx->reader))
1248         return false;
1249       if (token.type != MNUM)
1250         {
1251           msg (SE, _("Syntax error expecting SPLIT FILE value %s."),
1252                context (mx->reader));
1253           return false;
1254         }
1255
1256       if (!compare)
1257         nr->split_values[i] = token.number;
1258       else if (nr->split_values[i] != token.number)
1259         {
1260           msg (SE, _("Expecting value %g for %s."),
1261                nr->split_values[i],
1262                dict_get_split_vars (nr->dict)[i]->name);
1263           return false;
1264         }
1265     }
1266
1267   return true;
1268 }
1269
1270 /* Read the factors for cell CELL.  If COMPARE is 1, compares the
1271    values read to the last values read and returns true if they're equal,
1272    false otherwise. */
1273 static bool
1274 nr_read_factors (struct nr_aux_data *nr, int cell)
1275 {
1276   struct matrix_data_pgm *mx = nr->mx;
1277   bool compare;
1278   
1279   if (mx->n_factors == 0)
1280     return true;
1281
1282   assert (nr->max_cell_idx >= cell);
1283   if (cell != nr->max_cell_idx)
1284     compare = true;
1285   else
1286     {
1287       compare = false;
1288       nr->max_cell_idx++;
1289     }
1290       
1291   {
1292     size_t i;
1293     
1294     for (i = 0; i < mx->n_factors; i++)
1295       {
1296         struct matrix_token token;
1297         if (!mget_token (&token, mx->reader))
1298           return false;
1299         if (token.type != MNUM)
1300           {
1301             msg (SE, _("Syntax error expecting factor value %s."),
1302                  context (mx->reader));
1303             return false;
1304           }
1305         
1306         if (!compare)
1307           nr->factor_values[i + mx->n_factors * cell] = token.number;
1308         else if (nr->factor_values[i + mx->n_factors * cell] != token.number)
1309           {
1310             msg (SE, _("Syntax error expecting value %g for %s %s."),
1311                  nr->factor_values[i + mx->n_factors * cell],
1312                  mx->factors[i]->name, context (mx->reader));
1313             return false;
1314           }
1315       }
1316   }
1317
1318   return true;
1319 }
1320
1321 /* Write the contents of a cell having content type CONTENT and data
1322    CP to the active file.
1323    Returns true if successful, false if an I/O error occurred. */
1324 static bool
1325 dump_cell_content (const struct dictionary *dict, 
1326                    struct matrix_data_pgm *mx, int content, double *cp,
1327                    struct ccase *c,
1328                    write_case_func *write_case, write_case_data wc_data)
1329 {
1330   int type = content_type[content];
1331
1332   {
1333     buf_copy_str_rpad (case_data_rw (c, mx->rowtype_->fv)->s, 8,
1334                        content_names[content]);
1335     
1336     if (type != 1)
1337       memset (case_data_rw (c, mx->varname_->fv)->s, ' ', 8);
1338   }
1339
1340   {
1341     int n_lines = (type == 1) ? mx->n_continuous : 1;
1342     int i;
1343                 
1344     for (i = 0; i < n_lines; i++)
1345       {
1346         int j;
1347
1348         for (j = 0; j < mx->n_continuous; j++)
1349           {
1350             int fv = dict_get_var (dict, mx->first_continuous + j)->fv;
1351             case_data_rw (c, fv)->f = *cp;
1352             cp++;
1353           }
1354         if (type == 1)
1355           buf_copy_str_rpad (case_data_rw (c, mx->varname_->fv)->s, 8,
1356                              dict_get_var (dict,
1357                                            mx->first_continuous + i)->name);
1358         if (!write_case (wc_data))
1359           return false;
1360       }
1361   }
1362   return true;
1363 }
1364
1365 /* Finally dump out everything from nr_data[] to the output file. */
1366 static bool
1367 nr_output_data (struct nr_aux_data *nr, struct ccase *c,
1368                 write_case_func *write_case, write_case_data wc_data)
1369 {
1370   struct matrix_data_pgm *mx = nr->mx;
1371   
1372   {
1373     struct variable *const *split;
1374     size_t split_cnt;
1375     size_t i;
1376
1377     split_cnt = dict_get_split_cnt (nr->dict);
1378     split = dict_get_split_vars (nr->dict);
1379     for (i = 0; i < split_cnt; i++)
1380       case_data_rw (c, split[i]->fv)->f = nr->split_values[i];
1381   }
1382
1383   if (mx->n_factors)
1384     {
1385       int cell;
1386
1387       for (cell = 0; cell < mx->cells; cell++)
1388         {
1389           {
1390             size_t factor;
1391
1392             for (factor = 0; factor < mx->n_factors; factor++)
1393               case_data_rw (c, mx->factors[factor]->fv)->f
1394                 = nr->factor_values[factor + cell * mx->n_factors];
1395           }
1396           
1397           {
1398             int content;
1399             
1400             for (content = 0; content <= PROX; content++)
1401               if (mx->is_per_factor[content])
1402                 {
1403                   assert (nr->data[content] != NULL
1404                           && nr->data[content][cell] != NULL);
1405
1406                   if (!dump_cell_content (nr->dict, mx, 
1407                                           content, nr->data[content][cell],
1408                                           c, write_case, wc_data))
1409                     return false;
1410                 }
1411           }
1412         }
1413     }
1414
1415   {
1416     int content;
1417     
1418     {
1419       size_t factor;
1420
1421       for (factor = 0; factor < mx->n_factors; factor++)
1422         case_data_rw (c, mx->factors[factor]->fv)->f = SYSMIS;
1423     }
1424     
1425     for (content = 0; content <= PROX; content++)
1426       if (!mx->is_per_factor[content] && nr->data[content] != NULL) 
1427         {
1428           if (!dump_cell_content (nr->dict, mx, content, nr->data[content][0],
1429                                   c, write_case, wc_data))
1430             return false; 
1431         }
1432   }
1433
1434   return true;
1435 }
1436 \f
1437 /* Back end, with ROWTYPE_. */
1438
1439 /* All the data for one set of factor values. */
1440 struct factor_data
1441   {
1442     double *factors;
1443     int n_rows[PROX + 1];
1444     double *data[PROX + 1];
1445     struct factor_data *next;
1446   };
1447
1448 /* With ROWTYPE_ auxiliary data. */
1449 struct wr_aux_data 
1450   {
1451     const struct dictionary *dict;            /* The dictionary */
1452     struct matrix_data_pgm *mx;         /* MATRIX DATA program. */
1453     int content;                        /* Type of current row. */
1454     double *split_values;               /* SPLIT FILE variable values. */
1455     struct factor_data *data;           /* All the data. */
1456     struct factor_data *current;        /* Current factor. */
1457   };
1458
1459 static bool wr_read_splits (struct wr_aux_data *, struct ccase *,
1460                            write_case_func *, write_case_data);
1461 static bool wr_output_data (struct wr_aux_data *, struct ccase *,
1462                            write_case_func *, write_case_data);
1463 static bool wr_read_rowtype (struct wr_aux_data *, 
1464                             const struct matrix_token *, struct dfm_reader *);
1465 static bool wr_read_factors (struct wr_aux_data *);
1466 static bool wr_read_indeps (struct wr_aux_data *);
1467 static bool matrix_data_read_with_rowtype (struct case_source *,
1468                                            struct ccase *,
1469                                            write_case_func *,
1470                                            write_case_data);
1471
1472 /* When ROWTYPE_ appears in the data, reads the matrices and writes
1473    them to the output file.
1474    Returns true if successful, false if an I/O error occurred. */
1475 static bool
1476 read_matrices_with_rowtype (struct dataset *ds, struct matrix_data_pgm *mx)
1477 {
1478   struct wr_aux_data wr;
1479   bool ok;
1480
1481   wr.mx = mx;
1482   wr.content = -1;
1483   wr.split_values = NULL;
1484   wr.data = NULL;
1485   wr.current = NULL;
1486   wr.dict = dataset_dict (ds);
1487   mx->cells = 0;
1488
1489   proc_set_source (ds, 
1490                    create_case_source (&matrix_data_with_rowtype_source_class,
1491                                        &wr));
1492   ok = procedure (ds, NULL, NULL);
1493
1494   free (wr.split_values);
1495   return ok;
1496 }
1497
1498 /* Read from the data file and write it to the active file.
1499    Returns true if successful, false if an I/O error occurred. */
1500 static bool
1501 matrix_data_read_with_rowtype (struct case_source *source,
1502                                struct ccase *c,
1503                                write_case_func *write_case,
1504                                write_case_data wc_data)
1505 {
1506   struct wr_aux_data *wr = source->aux;
1507   struct matrix_data_pgm *mx = wr->mx;
1508
1509   do
1510     {
1511       if (!wr_read_splits (wr, c, write_case, wc_data))
1512         return true;
1513
1514       if (!wr_read_factors (wr))
1515         return true;
1516
1517       if (!wr_read_indeps (wr))
1518         return true;
1519     }
1520   while (another_token (mx->reader));
1521
1522   return wr_output_data (wr, c, write_case, wc_data);
1523 }
1524
1525 /* Read the split file variables.  If they differ from the previous
1526    set of split variables then output the data.  Returns success. */
1527 static bool 
1528 wr_read_splits (struct wr_aux_data *wr,
1529                 struct ccase *c,
1530                 write_case_func *write_case, write_case_data wc_data)
1531 {
1532   struct matrix_data_pgm *mx = wr->mx;
1533   bool compare;
1534   size_t split_cnt;
1535
1536   split_cnt = dict_get_split_cnt (wr->dict);
1537   if (split_cnt == 0)
1538     return true;
1539
1540   if (wr->split_values)
1541     compare = true;
1542   else
1543     {
1544       compare = false;
1545       wr->split_values = xnmalloc (split_cnt, sizeof *wr->split_values);
1546     }
1547   
1548   {
1549     bool different = false;
1550     int i;
1551
1552     for (i = 0; i < split_cnt; i++)
1553       {
1554         struct matrix_token token;
1555         if (!mget_token (&token, mx->reader))
1556           return false;
1557         if (token.type != MNUM)
1558           {
1559             msg (SE, _("Syntax error %s expecting SPLIT FILE value."),
1560                  context (mx->reader));
1561             return false;
1562           }
1563
1564         if (compare && wr->split_values[i] != token.number && !different)
1565           {
1566             if (!wr_output_data (wr, c, write_case, wc_data))
1567               return 0;
1568             different = true;
1569             mx->cells = 0;
1570           }
1571         wr->split_values[i] = token.number;
1572       }
1573   }
1574
1575   return true;
1576 }
1577
1578 /* Compares doubles A and B, treating SYSMIS as greatest. */
1579 static int
1580 compare_doubles (const void *a_, const void *b_, const void *aux UNUSED)
1581 {
1582   const double *a = a_;
1583   const double *b = b_;
1584
1585   if (*a == *b)
1586     return 0;
1587   else if (*a == SYSMIS)
1588     return 1;
1589   else if (*b == SYSMIS)
1590     return -1;
1591   else if (*a > *b)
1592     return 1;
1593   else
1594     return -1;
1595 }
1596
1597 /* Return strcmp()-type comparison of the MX->n_factors factors at _A and
1598    _B.  Sort missing values toward the end. */
1599 static int
1600 compare_factors (const void *a_, const void *b_, const void *mx_)
1601 {
1602   const struct matrix_data_pgm *mx = mx_;
1603   struct factor_data *const *pa = a_;
1604   struct factor_data *const *pb = b_;
1605   const double *a = (*pa)->factors;
1606   const double *b = (*pb)->factors;
1607
1608   return lexicographical_compare_3way (a, mx->n_factors,
1609                                        b, mx->n_factors,
1610                                        sizeof *a,
1611                                        compare_doubles, NULL);
1612 }
1613
1614 /* Write out the data for the current split file to the active
1615    file.
1616    Returns true if successful, false if an I/O error occurred. */
1617 static bool
1618 wr_output_data (struct wr_aux_data *wr,
1619                 struct ccase *c,
1620                 write_case_func *write_case, write_case_data wc_data)
1621 {
1622   struct matrix_data_pgm *mx = wr->mx;
1623   bool ok = true;
1624
1625   {
1626     struct variable *const *split;
1627     size_t split_cnt;
1628     size_t i;
1629
1630     split_cnt = dict_get_split_cnt (wr->dict);
1631     split = dict_get_split_vars (wr->dict);
1632     for (i = 0; i < split_cnt; i++)
1633       case_data_rw (c, split[i]->fv)->f = wr->split_values[i];
1634   }
1635
1636   /* Sort the wr->data list. */
1637   {
1638     struct factor_data **factors;
1639     struct factor_data *iter;
1640     int i;
1641
1642     factors = xnmalloc (mx->cells, sizeof *factors);
1643
1644     for (i = 0, iter = wr->data; iter; iter = iter->next, i++)
1645       factors[i] = iter;
1646
1647     sort (factors, mx->cells, sizeof *factors, compare_factors, mx);
1648
1649     wr->data = factors[0];
1650     for (i = 0; i < mx->cells - 1; i++)
1651       factors[i]->next = factors[i + 1];
1652     factors[mx->cells - 1]->next = NULL;
1653
1654     free (factors);
1655   }
1656
1657   /* Write out records for every set of factor values. */
1658   {
1659     struct factor_data *iter;
1660     
1661     for (iter = wr->data; iter; iter = iter->next)
1662       {
1663         {
1664           size_t factor;
1665
1666           for (factor = 0; factor < mx->n_factors; factor++)
1667             case_data_rw (c, mx->factors[factor]->fv)->f
1668               = iter->factors[factor];
1669         }
1670         
1671         {
1672           int content;
1673
1674           for (content = 0; content <= PROX; content++)
1675             {
1676               if (!iter->n_rows[content])
1677                 continue;
1678               
1679               {
1680                 int type = content_type[content];
1681                 int n_lines = (type == 1
1682                                ? (mx->n_continuous
1683                                   - (mx->section != FULL && mx->diag == NODIAGONAL))
1684                                : 1);
1685                 
1686                 if (n_lines != iter->n_rows[content])
1687                   {
1688                     msg (SE, _("Expected %d lines of data for %s content; "
1689                                "actually saw %d lines.  No data will be "
1690                                "output for this content."),
1691                          n_lines, content_names[content],
1692                          iter->n_rows[content]);
1693                     continue;
1694                   }
1695               }
1696
1697               fill_matrix (mx, content, iter->data[content]);
1698
1699               ok = dump_cell_content (wr->dict, mx, content, 
1700                                       iter->data[content],
1701                                       c, write_case, wc_data);
1702               if (!ok)
1703                 break;
1704             }
1705         }
1706       }
1707   }
1708   
1709   pool_destroy (mx->container);
1710   mx->container = pool_create ();
1711   
1712   wr->data = wr->current = NULL;
1713   
1714   return ok;
1715 }
1716
1717 /* Sets ROWTYPE_ based on the given TOKEN read from READER.
1718    Return success. */
1719 static bool 
1720 wr_read_rowtype (struct wr_aux_data *wr,
1721                  const struct matrix_token *token,
1722                  struct dfm_reader *reader)
1723 {
1724   if (wr->content != -1)
1725     {
1726       msg (SE, _("Multiply specified ROWTYPE_ %s."), context (reader));
1727       return false;
1728     }
1729   if (token->type != MSTR)
1730     {
1731       msg (SE, _("Syntax error %s expecting ROWTYPE_ string."),
1732            context (reader));
1733       return false;
1734     }
1735   
1736   {
1737     char s[16];
1738     char *cp;
1739     
1740     memcpy (s, token->string, min (15, token->length));
1741     s[min (15, token->length)] = 0;
1742
1743     for (cp = s; *cp; cp++)
1744       *cp = toupper ((unsigned char) *cp);
1745
1746     wr->content = string_to_content_type (s, NULL);
1747   }
1748
1749   if (wr->content == -1)
1750     {
1751       msg (SE, _("Syntax error %s."), context (reader));
1752       return 0;
1753     }
1754
1755   return true;
1756 }
1757
1758 /* Read the factors for the current row.  Select a set of factors and
1759    point wr_current to it. */
1760 static bool 
1761 wr_read_factors (struct wr_aux_data *wr)
1762 {
1763   struct matrix_data_pgm *mx = wr->mx;
1764   double *factor_values = local_alloc (sizeof *factor_values * mx->n_factors);
1765
1766   wr->content = -1;
1767   {
1768     size_t i;
1769   
1770     for (i = 0; i < mx->n_factors; i++)
1771       {
1772         struct matrix_token token;
1773         if (!mget_token (&token, mx->reader))
1774           goto lossage;
1775         if (token.type == MSTR)
1776           {
1777             if (!wr_read_rowtype (wr, &token, mx->reader))
1778               goto lossage;
1779             if (!mget_token (&token, mx->reader))
1780               goto lossage;
1781           }
1782         if (token.type != MNUM)
1783           {
1784             msg (SE, _("Syntax error expecting factor value %s."),
1785                  context (mx->reader));
1786             goto lossage;
1787           }
1788         
1789         factor_values[i] = token.number;
1790       }
1791   }
1792   if (wr->content == -1)
1793     {
1794       struct matrix_token token;
1795       if (!mget_token (&token, mx->reader))
1796         goto lossage;
1797       if (!wr_read_rowtype (wr, &token, mx->reader))
1798         goto lossage;
1799     }
1800   
1801   /* Try the most recent factor first as a simple caching
1802      mechanism. */
1803   if (wr->current)
1804     {
1805       size_t i;
1806       
1807       for (i = 0; i < mx->n_factors; i++)
1808         if (factor_values[i] != wr->current->factors[i])
1809           goto cache_miss;
1810       goto winnage;
1811     }
1812
1813   /* Linear search through the list. */
1814 cache_miss:
1815   {
1816     struct factor_data *iter;
1817
1818     for (iter = wr->data; iter; iter = iter->next)
1819       {
1820         size_t i;
1821
1822         for (i = 0; i < mx->n_factors; i++)
1823           if (factor_values[i] != iter->factors[i])
1824             goto next_item;
1825         
1826         wr->current = iter;
1827         goto winnage;
1828         
1829       next_item: ;
1830       }
1831   }
1832
1833   /* Not found.  Make a new item. */
1834   {
1835     struct factor_data *new = pool_alloc (mx->container, sizeof *new);
1836
1837     new->factors = pool_nalloc (mx->container,
1838                                 mx->n_factors, sizeof *new->factors);
1839     
1840     {
1841       size_t i;
1842
1843       for (i = 0; i < mx->n_factors; i++)
1844         new->factors[i] = factor_values[i];
1845     }
1846     
1847     {
1848       int i;
1849
1850       for (i = 0; i <= PROX; i++)
1851         {
1852           new->n_rows[i] = 0;
1853           new->data[i] = NULL;
1854         }
1855     }
1856
1857     new->next = wr->data;
1858     wr->data = wr->current = new;
1859     mx->cells++;
1860   }
1861
1862 winnage:
1863   local_free (factor_values);
1864   return true;
1865
1866 lossage:
1867   local_free (factor_values);
1868   return false;
1869 }
1870
1871 /* Read the independent variables into wr->current. */
1872 static bool 
1873 wr_read_indeps (struct wr_aux_data *wr)
1874 {
1875   struct matrix_data_pgm *mx = wr->mx;
1876   struct factor_data *c = wr->current;
1877   const int type = content_type[wr->content];
1878   const int n_rows = c->n_rows[wr->content];
1879   double *cp;
1880   int n_cols;
1881
1882   /* Allocate room for data if necessary. */
1883   if (c->data[wr->content] == NULL)
1884     {
1885       int n_items = mx->n_continuous;
1886       if (type == 1)
1887         n_items *= mx->n_continuous;
1888       
1889       c->data[wr->content] = pool_nalloc (mx->container,
1890                                           n_items, sizeof **c->data);
1891     }
1892
1893   cp = &c->data[wr->content][n_rows * mx->n_continuous];
1894
1895   /* Figure out how much to read from this line. */
1896   switch (type)
1897     {
1898     case 0:
1899     case 2:
1900       if (n_rows > 0)
1901         {
1902           msg (SE, _("Duplicate specification for %s."),
1903                content_names[wr->content]);
1904           return false;
1905         }
1906       if (type == 0)
1907         n_cols = mx->n_continuous;
1908       else
1909         n_cols = 1;
1910       break;
1911     case 1:
1912       if (n_rows >= mx->n_continuous - (mx->section != FULL && mx->diag == NODIAGONAL))
1913         {
1914           msg (SE, _("Too many rows of matrix data for %s."),
1915                content_names[wr->content]);
1916           return false;
1917         }
1918       
1919       switch (mx->section)
1920         {
1921         case LOWER:
1922           n_cols = n_rows + 1;
1923           if (mx->diag == NODIAGONAL)
1924             cp += mx->n_continuous;
1925           break;
1926         case UPPER:
1927           cp += n_rows;
1928           n_cols = mx->n_continuous - n_rows;
1929           if (mx->diag == NODIAGONAL)
1930             {
1931               n_cols--;
1932               cp++;
1933             }
1934           break;
1935         case FULL:
1936           n_cols = mx->n_continuous;
1937           break;
1938         default:
1939           NOT_REACHED ();
1940         }
1941       break;
1942     default:
1943       NOT_REACHED ();
1944     }
1945   c->n_rows[wr->content]++;
1946
1947   /* Read N_COLS items at CP. */
1948   {
1949     int j;
1950         
1951     for (j = 0; j < n_cols; j++)
1952       {
1953         struct matrix_token token;
1954         if (!mget_token (&token, mx->reader))
1955           return false;
1956         if (token.type != MNUM)
1957           {
1958             msg (SE, _("Syntax error expecting value for %s %s."),
1959                  dict_get_var (wr->dict, mx->first_continuous + j)->name,
1960                  context (mx->reader));
1961             return false;
1962           }
1963
1964         *cp++ = token.number;
1965       }
1966     if (mx->fmt != FREE
1967         && !force_eol (mx->reader, content_names[wr->content]))
1968       return false;
1969   }
1970
1971   return true;
1972 }
1973 \f
1974 /* Matrix source. */
1975
1976 static const struct case_source_class matrix_data_with_rowtype_source_class = 
1977   {
1978     "MATRIX DATA",
1979     NULL,
1980     matrix_data_read_with_rowtype,
1981     NULL,
1982   };
1983
1984 static const struct case_source_class 
1985 matrix_data_without_rowtype_source_class =
1986   {
1987     "MATRIX DATA",
1988     NULL,
1989     matrix_data_read_without_rowtype,
1990     NULL,
1991   };
1992