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