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