#include "data/dataset.h"
#include "data/variable.h"
+#include "libpspp/assertion.h"
#include "libpspp/cast.h"
#include "libpspp/compiler.h"
#include "libpspp/hash-functions.h"
return handle->encoding;
}
+/* Returns true if A and B refer to the same file or dataset, false
+ otherwise. */
+bool
+fh_equal (const struct file_handle *a, const struct file_handle *b)
+{
+ if (a->referent != b->referent)
+ return false;
+
+ switch (a->referent)
+ {
+ case FH_REF_FILE:
+ {
+ struct file_identity *a_id = fh_get_identity (a);
+ struct file_identity *b_id = fh_get_identity (b);
+
+ int cmp = fh_compare_file_identities (a_id, b_id);
+
+ fh_free_identity (a_id);
+ fh_free_identity (b_id);
+
+ return cmp == 0;
+ }
+
+ case FH_REF_INLINE:
+ return true;
+
+ case FH_REF_DATASET:
+ return a->ds == b->ds;
+
+ default:
+ NOT_REACHED ();
+ }
+}
+
/* Returns the dataset handle associated with HANDLE.
Applicable to only FH_REF_DATASET files. */
struct dataset *
enum fh_referent fh_get_referent (const struct file_handle *);
const char *fh_get_encoding (const struct file_handle *);
+bool fh_equal (const struct file_handle *, const struct file_handle *);
+
/* Properties of FH_REF_FILE file handles. */
const char *fh_get_file_name (const struct file_handle *);
const char *fh_get_file_name_encoding (const struct file_handle *handle);
for (size_t i = 0; i < s->n_save_files; i++)
{
struct save_file *sf = s->save_files[i];
- if (sf->file == fh)
+ if (fh_equal (sf->file, fh))
{
fh_unref (fh);
{
dataset_set_dict (sf->dataset, sf->dict);
dataset_set_source (sf->dataset, casewriter_make_reader (sf->writer));
- sf->dict = NULL;
- sf->writer = NULL;
}
-
+ else
+ {
+ casewriter_destroy (sf->writer);
+ dict_unref (sf->dict);
+ }
fh_unref (sf->file);
string_array_destroy (&sf->variables);
matrix_expr_destroy (sf->names);
stringi_set_destroy (&sf->strings);
- casewriter_destroy (sf->writer);
- dict_unref (sf->dict);
free (sf);
}
}
}
save->sf = save_file_create (s, fh, &variables, names, &strings);
- fh = NULL;
-
return cmd;
error:
1.00,abcd,3.00
4.00,xyzw,6.00
])
+AT_CLEANUP
+
+AT_SETUP([MATRIX - SAVE - negative])
+AT_DATA([matrix.sps], [dnl
+MATRIX.
+SAVE !.
+SAVE 1/OUTFILE=!.
+SAVE 1/VARIABLES=!.
+SAVE 1/NAMES=!.
+SAVE 1/!.
+SAVE 1.
+SAVE 1/OUTFILE='matrix.sav'/NAMES={'a'}/VARIABLES=a.
+SAVE 1/OUTFILE='matrix2.sav'.
+SAVE {1,2}/OUTFILE='matrix2.sav'.
+END MATRIX.
+])
+AT_CHECK([pspp matrix.sps], [1], [dnl
+matrix.sps:2.6: error: SAVE: Syntax error at `!'.
+
+matrix.sps:3.16: error: SAVE: Syntax error at `!': expecting a file name or
+handle name.
+
+matrix.sps:4.18: error: SAVE: Syntax error at `!': expecting variable name.
+
+matrix.sps:5.14: error: SAVE: Syntax error at `!'.
+
+matrix.sps:6.8: error: SAVE: Syntax error at `!': expecting OUTFILE, VARIABLES,
+NAMES, or STRINGS.
+
+matrix.sps:7: error: SAVE: Required subcommand OUTFILE was not specified.
+
+matrix.sps:8: warning: SAVE: VARIABLES and NAMES both specified; ignoring
+NAMES.
+
+error: The first SAVE to `matrix2.sav' within this matrix program had 1
+columns, so a 1×2 matrix cannot be saved to it.
+])
AT_CLEANUP
\ No newline at end of file