X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fsave.c;h=88f3c75ee59a23d66a628995843d3b6dbaf23f27;hb=c8adc6783134063d4ada34a58f9e7abf6a039bb2;hp=be746742f380403036c021b7a626d2b21bc4bbca;hpb=8d6bfdd2a100bf8166b3b0b3f006d46f3e7a59e9;p=pspp diff --git a/src/language/data-io/save.c b/src/language/data-io/save.c index be746742f3..88f3c75ee5 100644 --- a/src/language/data-io/save.c +++ b/src/language/data-io/save.c @@ -36,6 +36,7 @@ #include "language/lexer/lexer.h" #include "libpspp/assertion.h" #include "libpspp/compiler.h" +#include "libpspp/message.h" #include "gl/xalloc.h" @@ -98,8 +99,7 @@ struct output_trns struct casewriter *writer; /* Writer. */ }; -static trns_proc_func output_trns_proc; -static trns_free_func output_trns_free; +static const struct trns_class output_trns_class; static struct casewriter *parse_write_command (struct lexer *, struct dataset *, enum writer_type, @@ -139,7 +139,7 @@ parse_output_trns (struct lexer *lexer, struct dataset *ds, enum writer_type wri return CMD_CASCADING_FAILURE; } - add_transformation (ds, output_trns_proc, output_trns_free, t); + add_transformation (ds, &output_trns_class, t); return CMD_SUCCESS; } @@ -166,6 +166,7 @@ parse_write_command (struct lexer *lexer, struct dataset *ds, struct casewriter *writer; /* Writer. */ struct case_map_stage *stage; /* Preparation for 'map'. */ struct case_map *map; /* Map from input data to data for writer. */ + const char *sav_name = ""; /* Common options. */ struct sfm_write_options sysfile_opts; @@ -236,8 +237,7 @@ parse_write_command (struct lexer *lexer, struct dataset *ds, cw = true; else { - lex_error_expecting (lexer, "READONLY", "WRITEABLE", - NULL_SENTINEL); + lex_error_expecting (lexer, "READONLY", "WRITEABLE"); goto error; } sysfile_opts.create_writeable = porfile_opts.create_writeable = cw; @@ -251,7 +251,7 @@ parse_write_command (struct lexer *lexer, struct dataset *ds, *retain_unselected = false; else { - lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL); + lex_error_expecting (lexer, "RETAIN", "DELETE"); goto error; } } @@ -268,7 +268,7 @@ parse_write_command (struct lexer *lexer, struct dataset *ds, && lex_match_id (lexer, "VERSION")) { lex_match (lexer, T_EQUALS); - if (!lex_force_int (lexer)) + if (!lex_force_int_range (lexer, "VERSION", 2, 3)) goto error; sysfile_opts.version = lex_integer (lexer); lex_get (lexer); @@ -282,19 +282,19 @@ parse_write_command (struct lexer *lexer, struct dataset *ds, porfile_opts.type = PFM_TAPE; else { - lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL); + lex_error_expecting (lexer, "COMM", "TAPE"); goto error; } } else if (writer_type == PORFILE_WRITER && lex_match_id (lexer, "DIGITS")) { lex_match (lexer, T_EQUALS); - if (!lex_force_int (lexer)) + if (!lex_force_int_range (lexer, "DIGITS", 1, INT_MAX)) goto error; porfile_opts.digits = lex_integer (lexer); lex_get (lexer); } - else if (!parse_dict_trim (lexer, dict)) + else if (!parse_dict_trim (lexer, dict, false)) goto error; if (!lex_match (lexer, T_SLASH)) @@ -303,37 +303,41 @@ parse_write_command (struct lexer *lexer, struct dataset *ds, if (lex_end_of_command (lexer) != CMD_SUCCESS) goto error; - if (handle == NULL) + if (!handle && !metadata) { - lex_sbc_missing ("OUTFILE"); + msg (SE, _("The OUTFILE or METADATA subcommand is required.")); goto error; } dict_delete_scratch_vars (dict); dict_compact_values (dict); - if (fh_get_referent (handle) == FH_REF_FILE) + if (handle) { - switch (writer_type) + if (metadata) + sav_name = (fh_get_referent (handle) == FH_REF_FILE + ? fh_get_file_name (handle) + : fh_get_name (handle)); + if (fh_get_referent (handle) == FH_REF_FILE) { - case SYSFILE_WRITER: - writer = sfm_open_writer (handle, dict, sysfile_opts); - break; - case PORFILE_WRITER: - writer = pfm_open_writer (handle, dict, porfile_opts); - break; + switch (writer_type) + { + case SYSFILE_WRITER: + writer = sfm_open_writer (handle, dict, sysfile_opts); + break; + case PORFILE_WRITER: + writer = pfm_open_writer (handle, dict, porfile_opts); + break; + } } + else + writer = any_writer_open (handle, dict); + if (writer == NULL) + goto error; } - else - writer = any_writer_open (handle, dict); - if (writer == NULL) - goto error; if (metadata) { - const char *sav_name = (fh_get_referent (handle) == FH_REF_FILE - ? fh_get_file_name (handle) - : fh_get_name (handle)); if (!mdd_write (metadata, dict, sav_name)) goto error; } @@ -359,7 +363,7 @@ parse_write_command (struct lexer *lexer, struct dataset *ds, } /* Writes case *C to the system file specified on XSAVE or XEXPORT. */ -static int +static enum trns_result output_trns_proc (void *trns_, struct ccase **c, casenumber case_num UNUSED) { struct output_trns *t = trns_; @@ -377,3 +381,9 @@ output_trns_free (void *trns_) free (t); return ok; } + +static const struct trns_class output_trns_class = { + .name = "XSAVE/XEXPORT", + .execute = output_trns_proc, + .destroy = output_trns_free, +};