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