Start work on fixing MATCH FILES.
[pspp-builds.git] / src / get.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 "error.h"
22 #include <stdlib.h>
23 #include "alloc.h"
24 #include "case.h"
25 #include "command.h"
26 #include "dictionary.h"
27 #include "error.h"
28 #include "file-handle.h"
29 #include "hash.h"
30 #include "lexer.h"
31 #include "misc.h"
32 #include "pfm-read.h"
33 #include "pfm-write.h"
34 #include "settings.h"
35 #include "sfm-read.h"
36 #include "sfm-write.h"
37 #include "str.h"
38 #include "value-labels.h"
39 #include "var.h"
40 #include "vfm.h"
41 #include "vfmP.h"
42
43 #include "debug-print.h"
44
45 /* Rearranging and reducing a dictionary. */
46 static void start_case_map (struct dictionary *);
47 static struct case_map *finish_case_map (struct dictionary *);
48 static void map_case (const struct case_map *,
49                       const struct ccase *, struct ccase *);
50 static void destroy_case_map (struct case_map *);
51
52 /* Operation type. */
53 enum operation 
54   {
55     OP_READ,    /* GET or IMPORT. */
56     OP_SAVE,    /* SAVE or XSAVE. */
57     OP_EXPORT   /* EXPORT. */
58   };
59
60 static bool trim_dictionary (struct dictionary *,
61                              enum operation, int *compress);
62 \f
63 /* GET input program. */
64 struct get_pgm 
65   {
66     struct sfm_reader *reader;  /* System file reader. */
67     struct case_map *map;       /* Map from system file to active file dict. */
68     struct ccase bounce;        /* Bounce buffer. */
69   };
70
71 static void get_pgm_free (struct get_pgm *);
72
73 /* Parses the GET command. */
74 int
75 cmd_get (void)
76 {
77   struct get_pgm *pgm = NULL;
78   struct file_handle *fh;
79   struct dictionary *dict = NULL;
80
81   pgm = xmalloc (sizeof *pgm);
82   pgm->reader = NULL;
83   pgm->map = NULL;
84   case_nullify (&pgm->bounce);
85
86   discard_variables ();
87
88   lex_match ('/');
89   if (lex_match_id ("FILE"))
90     lex_match ('=');
91   fh = fh_parse ();
92   if (fh == NULL)
93     goto error;
94
95   pgm->reader = sfm_open_reader (fh, &dict, NULL);
96   if (pgm->reader == NULL)
97     goto error;
98   case_create (&pgm->bounce, dict_get_next_value_idx (dict));
99
100   start_case_map (dict);
101   if (!trim_dictionary (dict, OP_READ, NULL))
102     goto error;
103   pgm->map = finish_case_map (dict);
104
105   dict_destroy (default_dict);
106   default_dict = dict;
107
108   vfm_source = create_case_source (&get_source_class, pgm);
109
110   return CMD_SUCCESS;
111
112  error:
113   get_pgm_free (pgm);
114   if (dict != NULL)
115     dict_destroy (dict);
116   return CMD_FAILURE;
117 }
118
119 /* Frees a struct get_pgm. */
120 static void
121 get_pgm_free (struct get_pgm *pgm) 
122 {
123   if (pgm != NULL) 
124     {
125       sfm_close_reader (pgm->reader);
126       destroy_case_map (pgm->map);
127       case_destroy (&pgm->bounce);
128       free (pgm);
129     }
130 }
131
132 /* Clears internal state related to GET input procedure. */
133 static void
134 get_source_destroy (struct case_source *source)
135 {
136   struct get_pgm *pgm = source->aux;
137   get_pgm_free (pgm);
138 }
139
140 /* Reads all the cases from the data file into C and passes them
141    to WRITE_CASE one by one, passing WC_DATA. */
142 static void
143 get_source_read (struct case_source *source,
144                  struct ccase *c,
145                  write_case_func *write_case, write_case_data wc_data)
146 {
147   struct get_pgm *pgm = source->aux;
148   int ok;
149
150   do
151     {
152       if (pgm->map == NULL)
153         ok = sfm_read_case (pgm->reader, c);
154       else
155         {
156           ok = sfm_read_case (pgm->reader, &pgm->bounce);
157           if (ok)
158             map_case (pgm->map, &pgm->bounce, c);
159         }
160
161       if (ok)
162         ok = write_case (wc_data);
163     }
164   while (ok);
165 }
166
167 const struct case_source_class get_source_class =
168   {
169     "GET",
170     NULL,
171     get_source_read,
172     get_source_destroy,
173   };
174 \f
175 /* XSAVE transformation and SAVE procedure. */
176 struct save_trns
177   {
178     struct trns_header h;
179     struct sfm_writer *writer;  /* System file writer. */
180     struct case_map *map;       /* Map from active file to system file dict. */
181     struct ccase bounce;        /* Bounce buffer. */
182   };
183
184 static int save_write_case_func (struct ccase *, void *);
185 static trns_proc_func save_trns_proc;
186 static trns_free_func save_trns_free;
187
188 /* Parses the SAVE or XSAVE command
189    and returns the parsed transformation. */
190 static struct save_trns *
191 cmd_save_internal (void)
192 {
193   struct file_handle *fh = NULL;
194   struct dictionary *dict = NULL;
195   struct save_trns *t = NULL;
196   int compress = get_scompression ();
197   const int default_version = 3;
198   int version = default_version;
199   short no_name_table = 0;
200
201   t = xmalloc (sizeof *t);
202   t->h.proc = save_trns_proc;
203   t->h.free = save_trns_free;
204   t->writer = NULL;
205   t->map = NULL;
206   case_nullify (&t->bounce);
207   
208
209   /* Read most of the subcommands. */
210   for (;;)
211     {
212       if (lex_match_id ("VERSION"))
213         {
214           lex_match ('=');
215           if ( lex_force_num() ) 
216             {
217               lex_get();
218               version = tokval;
219               
220               if ( 0 == strncasecmp (tokid,"x", 1) ) 
221                 {
222                   lex_get();
223                   no_name_table = 1;
224                 }
225
226             }
227         }
228       else if (lex_match_id ("OUTFILE"))
229         {
230           lex_match ('=');
231       
232           fh = fh_parse ();
233           if (fh == NULL)
234             goto error;
235
236         }
237       if ( ! lex_match('/')  ) 
238         break;
239
240     }
241
242   if (token != '.')
243     {
244       lex_error (_("expecting end of command"));
245       goto error;
246     }
247
248   if ( fh == NULL ) 
249     {
250       msg ( ME, _("The required %s subcommand was not present"), "OUTFILE");
251       goto error;
252     }
253
254   if ( version != default_version )
255     {
256       msg (MW, _("Unsupported sysfile version: %d. Using version %d instead."),
257            version, default_version);
258
259       version = default_version;
260     }
261
262   dict = dict_clone (default_dict);
263   start_case_map (dict);
264   if (!trim_dictionary (dict, OP_SAVE, &compress))
265     goto error;
266   t->map = finish_case_map (dict);
267   if (t->map != NULL)
268     case_create (&t->bounce, dict_get_next_value_idx (dict));
269
270   t->writer = sfm_open_writer (fh, dict, compress, no_name_table);
271   if (t->writer == NULL)
272     goto error;
273
274   dict_destroy (dict);
275
276   return t;
277
278  error:
279   assert (t != NULL);
280   dict_destroy (dict);
281   save_trns_free (&t->h);
282   return NULL;
283 }
284
285 /* Parses and performs the SAVE procedure. */
286 int
287 cmd_save (void)
288 {
289   struct save_trns *t = cmd_save_internal ();
290   if (t != NULL) 
291     {
292       procedure (save_write_case_func, t);
293       save_trns_free (&t->h);
294       free(t);
295       return CMD_SUCCESS;
296     }
297   else
298     return CMD_FAILURE;
299 }
300
301 /* Parses the XSAVE transformation command. */
302 int
303 cmd_xsave (void)
304 {
305   struct save_trns *t = cmd_save_internal ();
306   if (t != NULL) 
307     {
308       add_transformation (&t->h);
309       return CMD_SUCCESS; 
310     }
311   else
312     return CMD_FAILURE;
313 }
314
315 /* Writes the given C to the file specified by T. */
316 static void
317 do_write_case (struct save_trns *t, struct ccase *c) 
318 {
319   if (t->map == NULL)
320     sfm_write_case (t->writer, c);
321   else 
322     {
323       map_case (t->map, c, &t->bounce);
324       sfm_write_case (t->writer, &t->bounce);
325     }
326 }
327
328 /* Writes case C to the system file specified on SAVE. */
329 static int
330 save_write_case_func (struct ccase *c, void *aux UNUSED)
331 {
332   do_write_case (aux, c);
333   return 1;
334 }
335
336 /* Writes case C to the system file specified on XSAVE. */
337 static int
338 save_trns_proc (struct trns_header *h, struct ccase *c, int case_num UNUSED)
339 {
340   struct save_trns *t = (struct save_trns *) h;
341   do_write_case (t, c);
342   return -1;
343 }
344
345 /* Frees a SAVE transformation. */
346 static void
347 save_trns_free (struct trns_header *t_)
348 {
349   struct save_trns *t = (struct save_trns *) t_;
350
351   if (t != NULL) 
352     {
353       sfm_close_writer (t->writer);
354       destroy_case_map (t->map);
355       case_destroy (&t->bounce);
356     }
357 }
358
359 static int rename_variables (struct dictionary *dict);
360
361 /* Commands that read and write system files share a great deal
362    of common syntactic structure for rearranging and dropping
363    variables.  This function parses this syntax and modifies DICT
364    appropriately.
365
366    OP is the operation being performed.  For operations that
367    write a system file, *COMPRESS is set to 1 if the system file
368    should be compressed, 0 otherwise.
369    
370    Returns true on success, false on failure. */
371 static bool
372 trim_dictionary (struct dictionary *dict, enum operation op, int *compress)
373 {
374   assert ((compress != NULL) == (op == OP_SAVE));
375   if (get_scompression())
376     *compress = 1;
377
378   if (op == OP_SAVE || op == OP_EXPORT)
379     {
380       /* Delete all the scratch variables. */
381       struct variable **v;
382       size_t nv;
383       size_t i;
384
385       v = xmalloc (sizeof *v * dict_get_var_cnt (dict));
386       nv = 0;
387       for (i = 0; i < dict_get_var_cnt (dict); i++) 
388         if (dict_class_from_id (dict_get_var (dict, i)->name) == DC_SCRATCH)
389           v[nv++] = dict_get_var (dict, i);
390       dict_delete_vars (dict, v, nv);
391       free (v);
392     }
393   
394   while (lex_match ('/'))
395     {
396       if (op == OP_SAVE && lex_match_id ("COMPRESSED"))
397         *compress = 1;
398       else if (op == OP_SAVE && lex_match_id ("UNCOMPRESSED"))
399         *compress = 0;
400       else if (lex_match_id ("DROP"))
401         {
402           struct variable **v;
403           int nv;
404
405           lex_match ('=');
406           if (!parse_variables (dict, &v, &nv, PV_NONE))
407             return false;
408           dict_delete_vars (dict, v, nv);
409           free (v);
410         }
411       else if (lex_match_id ("KEEP"))
412         {
413           struct variable **v;
414           int nv;
415           int i;
416
417           lex_match ('=');
418           if (!parse_variables (dict, &v, &nv, PV_NONE))
419             return false;
420
421           /* Move the specified variables to the beginning. */
422           dict_reorder_vars (dict, v, nv);
423           
424           /* Delete the remaining variables. */
425           v = xrealloc (v, (dict_get_var_cnt (dict) - nv) * sizeof *v);
426           for (i = nv; i < dict_get_var_cnt (dict); i++)
427             v[i - nv] = dict_get_var (dict, i);
428           dict_delete_vars (dict, v, dict_get_var_cnt (dict) - nv);
429           free (v);
430         }
431       else if (lex_match_id ("RENAME"))
432         {
433           if (!rename_variables (dict))
434             return false;
435         }
436       else
437         {
438           lex_error (_("while expecting a valid subcommand"));
439           return false;
440         }
441
442       if (dict_get_var_cnt (dict) == 0)
443         {
444           msg (SE, _("All variables deleted from system file dictionary."));
445           return false;
446         }
447     }
448
449   if (!lex_end_of_command ())
450     return false;
451
452   dict_compact_values (dict);
453   return true;
454 }
455
456 /* Parses and performs the RENAME subcommand of GET and SAVE. */
457 static int
458 rename_variables (struct dictionary *dict)
459 {
460   int i;
461
462   int success = 0;
463
464   struct variable **v;
465   char **new_names;
466   int nv, nn;
467   char *err_name;
468
469   int group;
470
471   lex_match ('=');
472   if (token != '(')
473     {
474       struct variable *v;
475
476       v = parse_dict_variable (dict);
477       if (v == NULL)
478         return 0;
479       if (!lex_force_match ('=')
480           || !lex_force_id ())
481         return 0;
482       if (!strncmp (tokid, v->name, SHORT_NAME_LEN))
483         return 1;
484       if (dict_lookup_var (dict, tokid) != NULL)
485         {
486           msg (SE, _("Cannot rename %s as %s because there already exists "
487                      "a variable named %s.  To rename variables with "
488                      "overlapping names, use a single RENAME subcommand "
489                      "such as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, "
490                      "\"/RENAME (A B C=B C A)\"."), v->name, tokid, tokid);
491           return 0;
492         }
493       
494       dict_rename_var (dict, v, tokid);
495       lex_get ();
496       return 1;
497     }
498
499   nv = nn = 0;
500   v = NULL;
501   new_names = 0;
502   group = 1;
503   while (lex_match ('('))
504     {
505       int old_nv = nv;
506
507       if (!parse_variables (dict, &v, &nv, PV_NO_DUPLICATE | PV_APPEND))
508         goto done;
509       if (!lex_match ('='))
510         {
511           msg (SE, _("`=' expected after variable list."));
512           goto done;
513         }
514       if (!parse_DATA_LIST_vars (&new_names, &nn, PV_APPEND | PV_NO_SCRATCH))
515         goto done;
516       if (nn != nv)
517         {
518           msg (SE, _("Number of variables on left side of `=' (%d) does not "
519                "match number of variables on right side (%d), in "
520                "parenthesized group %d of RENAME subcommand."),
521                nv - old_nv, nn - old_nv, group);
522           goto done;
523         }
524       if (!lex_force_match (')'))
525         goto done;
526       group++;
527     }
528
529   if (!dict_rename_vars (dict, v, new_names, nv, &err_name)) 
530     {
531       msg (SE, _("Requested renaming duplicates variable name %s."), err_name);
532       goto done;
533     }
534   success = 1;
535
536 done:
537   for (i = 0; i < nn; i++)
538     free (new_names[i]);
539   free (new_names);
540   free (v);
541
542   return success;
543 }
544 \f
545 /* EXPORT procedure. */
546 struct export_proc 
547   {
548     struct pfm_writer *writer;  /* System file writer. */
549     struct case_map *map;       /* Map from active file to system file dict. */
550     struct ccase bounce;        /* Bounce buffer. */
551   };
552
553 static int export_write_case_func (struct ccase *, void *);
554 static void export_proc_free (struct export_proc *);
555      
556 /* Parses the EXPORT command.  */
557 /* FIXME: same as cmd_save_internal(). */
558 int
559 cmd_export (void)
560 {
561   struct file_handle *fh;
562   struct dictionary *dict;
563   struct export_proc *proc;
564
565   proc = xmalloc (sizeof *proc);
566   proc->writer = NULL;
567   proc->map = NULL;
568   case_nullify (&proc->bounce);
569
570   lex_match ('/');
571   if (lex_match_id ("OUTFILE"))
572     lex_match ('=');
573   fh = fh_parse ();
574   if (fh == NULL)
575     return CMD_FAILURE;
576
577   dict = dict_clone (default_dict);
578   start_case_map (dict);
579   if (!trim_dictionary (dict, OP_EXPORT, NULL))
580     goto error;
581   proc->map = finish_case_map (dict);
582   if (proc->map != NULL)
583     case_create (&proc->bounce, dict_get_next_value_idx (dict));
584
585   proc->writer = pfm_open_writer (fh, dict);
586   if (proc->writer == NULL)
587     goto error;
588   
589   dict_destroy (dict);
590
591   procedure (export_write_case_func, proc);
592   export_proc_free (proc);
593   free (proc);
594
595   return CMD_SUCCESS;
596
597  error:
598   dict_destroy (dict);
599   export_proc_free (proc);
600   free (proc);
601   return CMD_FAILURE;
602 }
603
604 /* Writes case C to the EXPORT file. */
605 static int
606 export_write_case_func (struct ccase *c, void *aux) 
607 {
608   struct export_proc *proc = aux;
609   if (proc->map == NULL)
610     pfm_write_case (proc->writer, c);
611   else 
612     {
613       map_case (proc->map, c, &proc->bounce);
614       pfm_write_case (proc->writer, &proc->bounce);
615     }
616   return 1;
617 }
618
619 static void
620 export_proc_free (struct export_proc *proc) 
621 {
622   if (proc != NULL) 
623     {
624       pfm_close_writer (proc->writer);
625       destroy_case_map (proc->map);
626       case_destroy (&proc->bounce);
627     }
628 }
629 \f
630 /* MATCH FILES. */
631
632 #include "debug-print.h"
633
634 /* File types. */
635 enum
636   {
637     MTF_FILE,                   /* Specified on FILE= subcommand. */
638     MTF_TABLE                   /* Specified on TABLE= subcommand. */
639   };
640
641 /* One of the files on MATCH FILES. */
642 struct mtf_file
643   {
644     struct mtf_file *next, *prev;
645                                 /* Next, previous in the list of files. */
646     struct mtf_file *next_min;  /* Next in the chain of minimums. */
647     
648     int type;                   /* One of MTF_*. */
649     struct variable **by;       /* List of BY variables for this file. */
650     struct file_handle *handle; /* File handle. */
651     struct sfm_reader *reader;  /* System file reader. */
652     struct dictionary *dict;    /* Dictionary from system file. */
653     char in[SHORT_NAME_LEN + 1]; /* Name of the variable from IN=. */
654
655     struct ccase input;         /* Input record. */
656   };
657
658 /* MATCH FILES procedure. */
659 struct mtf_proc 
660   {
661     struct mtf_file *head;      /* First file mentioned on FILE or TABLE. */
662     struct mtf_file *tail;      /* Last file mentioned on FILE or TABLE. */
663     
664     size_t by_cnt;              /* Number of variables on BY subcommand. */
665
666     /* Names of FIRST, LAST variables. */
667     char first[SHORT_NAME_LEN + 1], last[SHORT_NAME_LEN + 1];
668     
669     struct dictionary *dict;    /* Dictionary of output file. */
670     struct case_sink *sink;     /* Sink to receive output. */
671     struct ccase mtf_case;      /* Case used for output. */
672
673     unsigned seq_num;           /* Have we initialized this variable? */
674     unsigned *seq_nums;         /* Sequence numbers for each var in dict. */
675   };
676
677 static void mtf_free (struct mtf_proc *);
678 static void mtf_free_file (struct mtf_file *);
679 static int mtf_merge_dictionary (struct dictionary *const, struct mtf_file *);
680 static void mtf_delete_file_in_place (struct mtf_proc *, struct mtf_file **);
681
682 static void mtf_read_nonactive_records (void *);
683 static void mtf_processing_finish (void *);
684 static int mtf_processing (struct ccase *, void *);
685
686 static char *var_type_description (struct variable *);
687
688 static void set_master (struct variable *, struct variable *master);
689 static struct variable *get_master (struct variable *);
690
691 /* Parse and execute the MATCH FILES command. */
692 int
693 cmd_match_files (void)
694 {
695   struct mtf_proc mtf;
696   struct mtf_file *first_table = NULL;
697   
698   bool used_active_file = false;
699   bool saw_table = false;
700   
701   mtf.head = mtf.tail = NULL;
702   mtf.by_cnt = 0;
703   mtf.first[0] = '\0';
704   mtf.last[0] = '\0';
705   mtf.dict = dict_create ();
706   mtf.sink = NULL;
707   case_nullify (&mtf.mtf_case);
708   mtf.seq_num = 0;
709   mtf.seq_nums = NULL;
710   dict_set_case_limit (mtf.dict, dict_get_case_limit (default_dict));
711
712   lex_match ('/');
713   while (lex_id_match ("FILE", tokid) || lex_id_match ("TABLE", tokid)) 
714     {
715       struct mtf_file *file = xmalloc (sizeof *file);
716
717       if (lex_match_id ("FILE"))
718         file->type = MTF_FILE;
719       else if (lex_match_id ("TABLE"))
720         {
721           file->type = MTF_TABLE;
722           saw_table = true;
723         }
724       else
725         assert (0);
726
727       file->by = NULL;
728       file->handle = NULL;
729       file->reader = NULL;
730       file->dict = NULL;
731       file->in[0] = '\0';
732       case_nullify (&file->input);
733
734       /* FILEs go first, then TABLEs. */
735       if (file->type == MTF_TABLE || first_table == NULL)
736         {
737           file->next = NULL;
738           file->prev = mtf.tail;
739           if (mtf.tail)
740             mtf.tail->next = file;
741           mtf.tail = file;
742           if (mtf.head == NULL)
743             mtf.head = file;
744           if (file->type == MTF_TABLE && first_table == NULL)
745             first_table = file;
746         }
747       else 
748         {
749           assert (file->type == MTF_FILE);
750           file->next = first_table;
751           file->prev = first_table->prev;
752           if (first_table->prev)
753             first_table->prev->next = file;
754           else
755             mtf.head = file;
756           first_table->prev = file;
757         }
758           
759       lex_match ('=');
760           
761       if (lex_match ('*'))
762         {
763           file->handle = NULL;
764           file->reader = NULL;
765               
766           if (used_active_file)
767             {
768               msg (SE, _("The active file may not be specified more "
769                          "than once."));
770               goto error;
771             }
772           used_active_file = true;
773
774           assert (pgm_state != STATE_INPUT);
775           if (pgm_state == STATE_INIT)
776             {
777               msg (SE, _("Cannot specify the active file since no active "
778                          "file has been defined."));
779               goto error;
780             }
781
782           if (temporary != 0)
783             {
784               msg (SE,
785                    _("MATCH FILES may not be used after TEMPORARY when "
786                      "the active file is an input source.  "
787                      "Temporary transformations will be made permanent."));
788               cancel_temporary (); 
789             }
790
791           file->dict = default_dict;
792         }
793       else
794         {
795           file->handle = fh_parse ();
796           if (file->handle == NULL)
797             goto error;
798
799           file->reader = sfm_open_reader (file->handle, &file->dict, NULL);
800           if (file->reader == NULL)
801             goto error;
802
803           case_create (&file->input, dict_get_next_value_idx (file->dict));
804         }
805
806       while (lex_match ('/'))
807         if (lex_match_id ("RENAME")) 
808           {
809             if (!rename_variables (file->dict))
810               goto error; 
811           }
812         else if (lex_match_id ("IN"))
813           {
814             lex_match ('=');
815             if (token != T_ID)
816               {
817                 lex_error (NULL);
818                 goto error;
819               }
820
821             if (file->in[0])
822               {
823                 msg (SE, _("Multiple IN subcommands for a single FILE or "
824                            "TABLE."));
825                 goto error;
826               }
827             strcpy (file->in, tokid);
828             lex_get ();
829           }
830
831       mtf_merge_dictionary (mtf.dict, file);
832     }
833       
834   while (token != '.')
835     {
836       if (lex_match (T_BY))
837         {
838           struct variable **by;
839           struct mtf_file *iter;
840           
841           if (mtf.by_cnt)
842             {
843               msg (SE, _("BY may appear at most once."));
844               goto error;
845             }
846               
847           lex_match ('=');
848           if (!parse_variables (mtf.dict, &by, &mtf.by_cnt,
849                                 PV_NO_DUPLICATE | PV_NO_SCRATCH))
850             goto error;
851
852           for (iter = mtf.head; iter != NULL; iter = iter->next)
853             {
854               int i;
855           
856               iter->by = xmalloc (sizeof *iter->by * mtf.by_cnt);
857
858               for (i = 0; i < mtf.by_cnt; i++)
859                 {
860                   iter->by[i] = dict_lookup_var (iter->dict, by[i]->name);
861                   if (iter->by[i] == NULL)
862                     {
863                       msg (SE, _("File %s lacks BY variable %s."),
864                            iter->handle ? handle_get_name (iter->handle) : "*",
865                            by[i]->name);
866                       free (by);
867                       goto error;
868                     }
869                 }
870             }
871         }
872       else if (lex_match_id ("FIRST")) 
873         {
874           if (mtf.first[0] != '\0')
875             {
876               msg (SE, _("FIRST may appear at most once."));
877               goto error;
878             }
879               
880           lex_match ('=');
881           if (!lex_force_id ())
882             goto error;
883           strcpy (mtf.first, tokid);
884           lex_get ();
885         }
886       else if (lex_match_id ("LAST")) 
887         {
888           if (mtf.last[0] != '\0')
889             {
890               msg (SE, _("LAST may appear at most once."));
891               goto error;
892             }
893               
894           lex_match ('=');
895           if (!lex_force_id ())
896             goto error;
897           strcpy (mtf.last, tokid);
898           lex_get ();
899         }
900       else if (lex_match_id ("MAP"))
901         {
902           /* FIXME. */
903         }
904       else
905         {
906           lex_error (NULL);
907           goto error;
908         }
909
910       if (!lex_match ('/') && token != '.') 
911         {
912           lex_end_of_command ();
913           goto error;
914         }
915     }
916
917   if (mtf.by_cnt == 0 && saw_table)
918     {
919       msg (SE, _("BY is required when TABLE is specified."));
920       goto error;
921     }
922
923   /* MATCH FILES performs an n-way merge on all its input files.
924      Abstract algorithm:
925
926      1. Read one input record from every input FILE.
927
928      2. If no FILEs are left, stop.  Otherwise, proceed to step 3.
929
930      3. Find the FILE input record with minimum BY values.  Store all
931      the values from this input record into the output record.
932
933      4. Find all the FILE input records with BY values identical to
934      the minimums.  Store all the values from these input records into
935      the output record.
936
937      5. For every TABLE, read another record as long as the BY values
938      on the TABLE's input record are less than the FILEs' BY values.
939      If an exact match is found, store all the values from the TABLE
940      input record into the output record.
941
942      6. Write the output record.
943
944      7. Read another record from each input file FILE and TABLE that
945      we stored values from above.  If we come to the end of one of the
946      input files, remove it from the list of input files.
947
948      8. Repeat from step 2.
949
950      Unfortunately, this algorithm can't be directly implemented
951      because there's no function to read a record from the active
952      file; instead, it has to be done using callbacks.
953
954      FIXME: For merging large numbers of files (more than 10?) a
955      better algorithm would use a heap for finding minimum
956      values. */
957
958   if (!used_active_file)
959     discard_variables ();
960
961   mtf.sink = create_case_sink (&storage_sink_class, mtf.dict, NULL);
962   if (mtf.sink->class->open != NULL)
963     mtf.sink->class->open (mtf.sink);
964
965   mtf.seq_nums = xmalloc (dict_get_var_cnt (mtf.dict) * sizeof *mtf.seq_nums);
966   memset (mtf.seq_nums, 0,
967           dict_get_var_cnt (mtf.dict) * sizeof *mtf.seq_nums);
968   case_create (&mtf.mtf_case, dict_get_next_value_idx (mtf.dict));
969
970   mtf_read_nonactive_records (&mtf);
971   if (used_active_file)
972     procedure (mtf_processing, &mtf);
973   mtf_processing_finish (&mtf);
974
975   dict_destroy (default_dict);
976   default_dict = mtf.dict;
977   mtf.dict = NULL;
978   vfm_source = mtf.sink->class->make_source (mtf.sink);
979   free_case_sink (mtf.sink);
980   
981   mtf_free (&mtf);
982   return CMD_SUCCESS;
983   
984 error:
985   mtf_free (&mtf);
986   return CMD_FAILURE;
987 }
988
989 /* Repeats 2...8 an arbitrary number of times. */
990 static void
991 mtf_processing_finish (void *mtf_)
992 {
993   struct mtf_proc *mtf = mtf_;
994   struct mtf_file *iter;
995
996   /* Find the active file and delete it. */
997   for (iter = mtf->head; iter; iter = iter->next)
998     if (iter->handle == NULL)
999       {
1000         mtf_delete_file_in_place (mtf, &iter);
1001         break;
1002       }
1003   
1004   while (mtf->head && mtf->head->type == MTF_FILE)
1005     if (!mtf_processing (NULL, mtf))
1006       break;
1007 }
1008
1009 /* Return a string in a static buffer describing V's variable type and
1010    width. */
1011 static char *
1012 var_type_description (struct variable *v)
1013 {
1014   static char buf[2][32];
1015   static int x = 0;
1016   char *s;
1017
1018   x ^= 1;
1019   s = buf[x];
1020
1021   if (v->type == NUMERIC)
1022     strcpy (s, "numeric");
1023   else
1024     {
1025       assert (v->type == ALPHA);
1026       sprintf (s, "string with width %d", v->width);
1027     }
1028   return s;
1029 }
1030
1031 /* Free FILE and associated data. */
1032 static void
1033 mtf_free_file (struct mtf_file *file)
1034 {
1035   free (file->by);
1036   sfm_close_reader (file->reader);
1037   if (file->dict != default_dict)
1038     dict_destroy (file->dict);
1039   case_destroy (&file->input);
1040   free (file);
1041 }
1042
1043 /* Free all the data for the MATCH FILES procedure. */
1044 static void
1045 mtf_free (struct mtf_proc *mtf)
1046 {
1047   struct mtf_file *iter, *next;
1048
1049   for (iter = mtf->head; iter; iter = next)
1050     {
1051       next = iter->next;
1052
1053       mtf_free_file (iter);
1054     }
1055   
1056   if (mtf->dict)
1057     dict_destroy (mtf->dict);
1058   case_destroy (&mtf->mtf_case);
1059   free (mtf->seq_nums);
1060 }
1061
1062 /* Remove *FILE from the mtf_file chain.  Make *FILE point to the next
1063    file in the chain, or to NULL if was the last in the chain. */
1064 static void
1065 mtf_delete_file_in_place (struct mtf_proc *mtf, struct mtf_file **file)
1066 {
1067   struct mtf_file *f = *file;
1068
1069   if (f->prev)
1070     f->prev->next = f->next;
1071   if (f->next)
1072     f->next->prev = f->prev;
1073   if (f == mtf->head)
1074     mtf->head = f->next;
1075   if (f == mtf->tail)
1076     mtf->tail = f->prev;
1077   *file = f->next;
1078
1079   {
1080     int i;
1081
1082     for (i = 0; i < dict_get_var_cnt (f->dict); i++)
1083       {
1084         struct variable *v = dict_get_var (f->dict, i);
1085         union value *out = case_data_rw (&mtf->mtf_case, get_master (v)->fv);
1086           
1087         if (v->type == NUMERIC)
1088           out->f = SYSMIS;
1089         else
1090           memset (out->s, ' ', v->width);
1091       }
1092   }
1093
1094   mtf_free_file (f);
1095 }
1096
1097 /* Read a record from every input file except the active file. */
1098 static void
1099 mtf_read_nonactive_records (void *mtf_)
1100 {
1101   struct mtf_proc *mtf = mtf_;
1102   struct mtf_file *iter;
1103
1104   for (iter = mtf->head; iter; )
1105     {
1106       if (iter->handle)
1107         {
1108           if (!sfm_read_case (iter->reader, &iter->input))
1109             mtf_delete_file_in_place (mtf, &iter);
1110           else
1111             iter = iter->next;
1112         }
1113       else
1114         iter = iter->next;
1115     }
1116 }
1117
1118 /* Compare the BY variables for files A and B; return -1 if A < B, 0
1119    if A == B, 1 if A > B. */
1120 static inline int
1121 mtf_compare_BY_values (struct mtf_proc *mtf,
1122                        struct mtf_file *a, struct mtf_file *b,
1123                        struct ccase *c)
1124 {
1125   struct ccase *a_input, *b_input;
1126   int i;
1127
1128   assert ((a == NULL) + (b == NULL) + (c == NULL) <= 1);
1129   a_input = case_is_null (&a->input) ? c : &a->input;
1130   b_input = case_is_null (&b->input) ? c : &b->input;
1131   for (i = 0; i < mtf->by_cnt; i++)
1132     {
1133       assert (a->by[i]->type == b->by[i]->type);
1134       assert (a->by[i]->width == b->by[i]->width);
1135       
1136       if (a->by[i]->type == NUMERIC)
1137         {
1138           double af = case_num (a_input, a->by[i]->fv);
1139           double bf = case_num (b_input, b->by[i]->fv);
1140
1141           if (af < bf)
1142             return -1;
1143           else if (af > bf)
1144             return 1;
1145         }
1146       else 
1147         {
1148           int result;
1149           
1150           assert (a->by[i]->type == ALPHA);
1151           result = memcmp (case_str (a_input, a->by[i]->fv),
1152                            case_str (b_input, b->by[i]->fv),
1153                            a->by[i]->width);
1154           if (result < 0)
1155             return -1;
1156           else if (result > 0)
1157             return 1;
1158         }
1159     }
1160   return 0;
1161 }
1162
1163 /* Perform one iteration of steps 3...7 above. */
1164 static int
1165 mtf_processing (struct ccase *c, void *mtf_)
1166 {
1167   struct mtf_proc *mtf = mtf_;
1168   struct mtf_file *min_head, *min_tail; /* Files with minimum BY values. */
1169   struct mtf_file *max_head, *max_tail; /* Files with non-minimum BY values. */
1170   struct mtf_file *iter;                /* Iterator. */
1171
1172   for (;;)
1173     {
1174       /* If the active file doesn't have the minimum BY values, don't
1175          return because that would cause a record to be skipped. */
1176       bool advance = true;
1177
1178       if (mtf->head->type == MTF_TABLE)
1179         return 0;
1180       
1181       /* 3. Find the FILE input record with minimum BY values.  Store
1182          all the values from this input record into the output record.
1183
1184          4. Find all the FILE input records with BY values identical
1185          to the minimums.  Store all the values from these input
1186          records into the output record. */
1187       min_head = min_tail = mtf->head;
1188       max_head = max_tail = NULL;
1189       for (iter = mtf->head->next; iter && iter->type == MTF_FILE;
1190            iter = iter->next)
1191         switch (mtf_compare_BY_values (mtf, min_head, iter, c))
1192           {
1193           case -1:
1194             if (max_head)
1195               max_tail = max_tail->next_min = iter;
1196             else
1197               max_head = max_tail = iter;
1198             break;
1199
1200           case 0:
1201             min_tail = min_tail->next_min = iter;
1202             break;
1203
1204           case 1:
1205             if (max_head)
1206               {
1207                 max_tail->next_min = min_head;
1208                 max_tail = min_tail;
1209               }
1210             else
1211               {
1212                 max_head = min_head;
1213                 max_tail = min_tail;
1214               }
1215             min_head = min_tail = iter;
1216             break;
1217
1218           default:
1219             assert (0);
1220           }
1221
1222       /* 5. For every TABLE, read another record as long as the BY
1223          values on the TABLE's input record are less than the FILEs'
1224          BY values.  If an exact match is found, store all the values
1225          from the TABLE input record into the output record. */
1226       while (iter)
1227         {
1228           struct mtf_file *next = iter->next;
1229           
1230           assert (iter->type == MTF_TABLE);
1231       
1232           if (iter->handle == NULL)
1233             advance = false;
1234
1235         again:
1236           switch (mtf_compare_BY_values (mtf, min_head, iter, c))
1237             {
1238             case -1:
1239               if (max_head)
1240                 max_tail = max_tail->next_min = iter;
1241               else
1242                 max_head = max_tail = iter;
1243               break;
1244
1245             case 0:
1246               min_tail = min_tail->next_min = iter;
1247               break;
1248
1249             case 1:
1250               if (iter->handle == NULL)
1251                 return 1;
1252               if (sfm_read_case (iter->reader, &iter->input))
1253                 goto again;
1254               mtf_delete_file_in_place (mtf, &iter);
1255               break;
1256
1257             default:
1258               assert (0);
1259             }
1260
1261           iter = next;
1262         }
1263
1264       /* Next sequence number. */
1265       mtf->seq_num++;
1266   
1267       /* Store data to all the records we are using. */
1268       if (min_tail)
1269         min_tail->next_min = NULL;
1270       for (iter = min_head; iter; iter = iter->next_min)
1271         {
1272           int i;
1273
1274           for (i = 0; i < dict_get_var_cnt (iter->dict); i++)
1275             {
1276               struct variable *v = dict_get_var (iter->dict, i);
1277               struct variable *mv = get_master (v);
1278           
1279               if (mtf->seq_nums[mv->index] != mtf->seq_num) 
1280                 {
1281                   struct ccase *record
1282                     = case_is_null (&iter->input) ? c : &iter->input;
1283                   union value *out = case_data_rw (&mtf->mtf_case, mv->fv);
1284
1285                   mtf->seq_nums[mv->index] = mtf->seq_num;
1286                   if (v->type == NUMERIC)
1287                     out->f = case_num (record, v->fv);
1288                   else
1289                     memcpy (out->s, case_str (record, v->fv), v->width);
1290                 } 
1291             }
1292         }
1293
1294       /* Store missing values to all the records we're not using. */
1295       if (max_tail)
1296         max_tail->next_min = NULL;
1297       for (iter = max_head; iter; iter = iter->next_min)
1298         {
1299           int i;
1300
1301           for (i = 0; i < dict_get_var_cnt (iter->dict); i++)
1302             {
1303               struct variable *v = dict_get_var (iter->dict, i);
1304               struct variable *mv = get_master (v);
1305           
1306               if (mtf->seq_nums[mv->index] != mtf->seq_num) 
1307                 {
1308                   union value *out = case_data_rw (&mtf->mtf_case, mv->fv);
1309                   mtf->seq_nums[mv->index] = mtf->seq_num;
1310
1311                   if (v->type == NUMERIC)
1312                     out->f = SYSMIS;
1313                   else
1314                     memset (out->s, ' ', v->width);
1315                 }
1316             }
1317
1318           if (iter->handle == NULL)
1319             advance = false;
1320         }
1321
1322       /* 6. Write the output record. */
1323       mtf->sink->class->write (mtf->sink, &mtf->mtf_case);
1324
1325       /* 7. Read another record from each input file FILE and TABLE
1326          that we stored values from above.  If we come to the end of
1327          one of the input files, remove it from the list of input
1328          files. */
1329       for (iter = min_head; iter && iter->type == MTF_FILE; )
1330         {
1331           struct mtf_file *next = iter->next_min;
1332           
1333           if (iter->reader != NULL)
1334             {
1335               if (!sfm_read_case (iter->reader, &iter->input))
1336                 mtf_delete_file_in_place (mtf, &iter);
1337             }
1338
1339           iter = next;
1340         }
1341       
1342       if (advance)
1343         break;
1344     }
1345
1346   return (mtf->head && mtf->head->type != MTF_TABLE);
1347 }
1348
1349 /* Merge the dictionary for file F into master dictionary M. */
1350 static int
1351 mtf_merge_dictionary (struct dictionary *const m, struct mtf_file *f)
1352 {
1353   struct dictionary *d = f->dict;
1354   const char *d_docs, *m_docs;
1355   int i;
1356
1357   if (dict_get_label (m) == NULL)
1358     dict_set_label (m, dict_get_label (d));
1359
1360   d_docs = dict_get_documents (d);
1361   m_docs = dict_get_documents (m);
1362   if (d_docs != NULL) 
1363     {
1364       if (m_docs == NULL)
1365         dict_set_documents (m, d_docs);
1366       else
1367         {
1368           char *new_docs;
1369           size_t new_len;
1370
1371           new_len = strlen (m_docs) + strlen (d_docs);
1372           new_docs = xmalloc (new_len + 1);
1373           strcpy (new_docs, m_docs);
1374           strcat (new_docs, d_docs);
1375           dict_set_documents (m, new_docs);
1376           free (new_docs);
1377         }
1378     }
1379   
1380   dict_compact_values (d);
1381
1382   for (i = 0; i < dict_get_var_cnt (d); i++)
1383     {
1384       struct variable *dv = dict_get_var (d, i);
1385       struct variable *mv = dict_lookup_var (m, dv->name);
1386
1387       if (mv != NULL)
1388         {
1389           if (mv->width != dv->width) 
1390             {
1391               msg (SE, _("Variable %s in file %s (%s) has different "
1392                          "type or width from the same variable in "
1393                          "earlier file (%s)."),
1394                    dv->name, handle_get_name (f->handle),
1395                    var_type_description (dv), var_type_description (mv));
1396               return 0;
1397             }
1398         
1399           if (dv->width == mv->width)
1400             {
1401               if (val_labs_count (dv->val_labs)
1402                   && !val_labs_count (mv->val_labs))
1403                 mv->val_labs = val_labs_copy (dv->val_labs);
1404               if (dv->miss_type != MISSING_NONE
1405                   && mv->miss_type == MISSING_NONE)
1406                 copy_missing_values (mv, dv);
1407             }
1408
1409           if (dv->label && !mv->label)
1410             mv->label = xstrdup (dv->label);
1411         }
1412       else
1413         {
1414           mv = dict_clone_var (m, dv, dv->name, dv->longname);
1415           assert (mv != NULL);
1416         }
1417         
1418       set_master (dv, mv);
1419     }
1420
1421   return 1;
1422 }
1423
1424 /* Marks V's master variable as MASTER. */
1425 static void
1426 set_master (struct variable *v, struct variable *master) 
1427 {
1428   var_attach_aux (v, master, NULL);
1429 }
1430
1431 /* Returns the master variable corresponding to V,
1432    as set with set_master(). */
1433 static struct variable *
1434 get_master (struct variable *v) 
1435 {
1436   assert (v->aux != NULL);
1437   return v->aux;
1438 }
1439 \f
1440 /* IMPORT command. */
1441
1442 /* IMPORT input program. */
1443 struct import_pgm 
1444   {
1445     struct pfm_reader *reader;  /* Portable file reader. */
1446     struct case_map *map;       /* Map from system file to active file dict. */
1447     struct ccase bounce;        /* Bounce buffer. */
1448   };
1449
1450 static void import_pgm_free (struct import_pgm *);
1451
1452 /* Parses the IMPORT command. */
1453 int
1454 cmd_import (void)
1455 {
1456   struct import_pgm *pgm = NULL;
1457   struct file_handle *fh = NULL;
1458   struct dictionary *dict = NULL;
1459   int type;
1460
1461   pgm = xmalloc (sizeof *pgm);
1462   pgm->reader = NULL;
1463   pgm->map = NULL;
1464   case_nullify (&pgm->bounce);
1465
1466   for (;;)
1467     {
1468       lex_match ('/');
1469       
1470       if (lex_match_id ("FILE") || token == T_STRING)
1471         {
1472           lex_match ('=');
1473
1474           fh = fh_parse ();
1475           if (fh == NULL)
1476             return CMD_FAILURE;
1477         }
1478       else if (lex_match_id ("TYPE"))
1479         {
1480           lex_match ('=');
1481
1482           if (lex_match_id ("COMM"))
1483             type = PFM_COMM;
1484           else if (lex_match_id ("TAPE"))
1485             type = PFM_TAPE;
1486           else
1487             {
1488               lex_error (_("expecting COMM or TAPE"));
1489               return CMD_FAILURE;
1490             }
1491         }
1492       else break;
1493     }
1494   if (!lex_match ('/') && token != '.')
1495     {
1496       lex_error (NULL);
1497       return CMD_FAILURE;
1498     }
1499
1500   discard_variables ();
1501
1502   pgm->reader = pfm_open_reader (fh, &dict, NULL);
1503   if (pgm->reader == NULL)
1504     return CMD_FAILURE;
1505   case_create (&pgm->bounce, dict_get_next_value_idx (dict));
1506   
1507   start_case_map (dict);
1508   if (!trim_dictionary (dict, OP_READ, NULL))
1509     goto error;
1510   pgm->map = finish_case_map (dict);
1511   
1512   dict_destroy (default_dict);
1513   default_dict = dict;
1514
1515   vfm_source = create_case_source (&import_source_class, pgm);
1516
1517   return CMD_SUCCESS;
1518
1519  error:
1520   import_pgm_free (pgm);
1521   if (dict != NULL)
1522     dict_destroy (dict);
1523   return CMD_FAILURE;
1524 }
1525
1526 /* Frees a struct import_pgm. */
1527 static void
1528 import_pgm_free (struct import_pgm *pgm) 
1529 {
1530   if (pgm != NULL) 
1531     {
1532       pfm_close_reader (pgm->reader);
1533       destroy_case_map (pgm->map);
1534       case_destroy (&pgm->bounce);
1535       free (pgm);
1536     }
1537 }
1538
1539 /* Clears internal state related to IMPORT input procedure. */
1540 static void
1541 import_source_destroy (struct case_source *source)
1542 {
1543   struct import_pgm *pgm = source->aux;
1544   import_pgm_free (pgm);
1545 }
1546
1547 /* Reads all the cases from the data file into C and passes them
1548    to WRITE_CASE one by one, passing WC_DATA. */
1549 static void
1550 import_source_read (struct case_source *source,
1551                  struct ccase *c,
1552                  write_case_func *write_case, write_case_data wc_data)
1553 {
1554   struct import_pgm *pgm = source->aux;
1555   int ok;
1556
1557   do
1558     {
1559       if (pgm->map == NULL)
1560         ok = pfm_read_case (pgm->reader, c);
1561       else
1562         {
1563           ok = pfm_read_case (pgm->reader, &pgm->bounce);
1564           if (ok)
1565             map_case (pgm->map, &pgm->bounce, c);
1566         }
1567
1568       if (ok)
1569         ok = write_case (wc_data);
1570     }
1571   while (ok);
1572 }
1573
1574 const struct case_source_class import_source_class =
1575   {
1576     "IMPORT",
1577     NULL,
1578     import_source_read,
1579     import_source_destroy,
1580   };
1581
1582 \f
1583 /* Case map.
1584
1585    A case map copies data from a case that corresponds for one
1586    dictionary to a case that corresponds to a second dictionary
1587    derived from the first by, optionally, deleting, reordering,
1588    or renaming variables.  (No new variables may be created.)
1589    */
1590
1591 /* A case map. */
1592 struct case_map
1593   {
1594     size_t value_cnt;   /* Number of values in map. */
1595     int *map;           /* For each destination index, the
1596                            corresponding source index. */
1597   };
1598
1599 /* Prepares dictionary D for producing a case map.  Afterward,
1600    the caller may delete, reorder, or rename variables within D
1601    at will before using finish_case_map() to produce the case
1602    map.
1603
1604    Uses D's aux members, which may not otherwise be in use. */
1605 static void
1606 start_case_map (struct dictionary *d) 
1607 {
1608   size_t var_cnt = dict_get_var_cnt (d);
1609   size_t i;
1610   
1611   for (i = 0; i < var_cnt; i++)
1612     {
1613       struct variable *v = dict_get_var (d, i);
1614       int *src_fv = xmalloc (sizeof *src_fv);
1615       *src_fv = v->fv;
1616       var_attach_aux (v, src_fv, var_dtor_free);
1617     }
1618 }
1619
1620 /* Produces a case map from dictionary D, which must have been
1621    previously prepared with start_case_map().
1622
1623    Does not retain any reference to D, and clears the aux members
1624    set up by start_case_map().
1625
1626    Returns the new case map, or a null pointer if no mapping is
1627    required (that is, no data has changed position). */
1628 static struct case_map *
1629 finish_case_map (struct dictionary *d) 
1630 {
1631   struct case_map *map;
1632   size_t var_cnt = dict_get_var_cnt (d);
1633   size_t i;
1634   int identity_map;
1635
1636   map = xmalloc (sizeof *map);
1637   map->value_cnt = dict_get_next_value_idx (d);
1638   map->map = xmalloc (sizeof *map->map * map->value_cnt);
1639   for (i = 0; i < map->value_cnt; i++)
1640     map->map[i] = -1;
1641
1642   identity_map = 1;
1643   for (i = 0; i < var_cnt; i++) 
1644     {
1645       struct variable *v = dict_get_var (d, i);
1646       int *src_fv = (int *) var_detach_aux (v);
1647       size_t idx;
1648
1649       if (v->fv != *src_fv)
1650         identity_map = 0;
1651       
1652       for (idx = 0; idx < v->nv; idx++)
1653         {
1654           int src_idx = *src_fv + idx;
1655           int dst_idx = v->fv + idx;
1656           
1657           assert (map->map[dst_idx] == -1);
1658           map->map[dst_idx] = src_idx;
1659         }
1660       free (src_fv);
1661     }
1662
1663   if (identity_map) 
1664     {
1665       destroy_case_map (map);
1666       return NULL;
1667     }
1668
1669   while (map->value_cnt > 0 && map->map[map->value_cnt - 1] == -1)
1670     map->value_cnt--;
1671
1672   return map;
1673 }
1674
1675 /* Maps from SRC to DST, applying case map MAP. */
1676 static void
1677 map_case (const struct case_map *map,
1678           const struct ccase *src, struct ccase *dst) 
1679 {
1680   size_t dst_idx;
1681
1682   assert (map != NULL);
1683   assert (src != NULL);
1684   assert (dst != NULL);
1685   assert (src != dst);
1686
1687   for (dst_idx = 0; dst_idx < map->value_cnt; dst_idx++)
1688     {
1689       int src_idx = map->map[dst_idx];
1690       if (src_idx != -1)
1691         *case_data_rw (dst, dst_idx) = *case_data (src, src_idx);
1692     }
1693 }
1694
1695 /* Destroys case map MAP. */
1696 static void
1697 destroy_case_map (struct case_map *map) 
1698 {
1699   if (map != NULL) 
1700     {
1701       free (map->map);
1702       free (map);
1703     }
1704 }