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