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