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