X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fflip.c;h=68152b1b190b4c90d8754205279f45e623ab75c3;hb=eb06da6a334bc37108cdce9bfc7f26cfcb2003ee;hp=3ca2413fcf35f2d56bba7b2200cde2934bb92985;hpb=5c3291dc396b795696e94f47780308fd7ace6fc4;p=pspp diff --git a/src/language/stats/flip.c b/src/language/stats/flip.c index 3ca2413fcf..68152b1b19 100644 --- a/src/language/stats/flip.c +++ b/src/language/stats/flip.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "config.h" +#include #include #include @@ -22,28 +22,30 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "intprops.h" -#include "minmax.h" -#include "xalloc.h" +#include "data/case.h" +#include "data/casereader.h" +#include "data/casereader-provider.h" +#include "data/dataset.h" +#include "data/dictionary.h" +#include "data/settings.h" +#include "data/short-names.h" +#include "data/value.h" +#include "data/variable.h" +#include "language/command.h" +#include "language/lexer/lexer.h" +#include "language/lexer/variable-parser.h" +#include "libpspp/array.h" +#include "libpspp/assertion.h" +#include "libpspp/message.h" +#include "libpspp/misc.h" +#include "libpspp/pool.h" +#include "libpspp/str.h" +#include "data/data-in.h" +#include "data/data-out.h" + +#include "gl/intprops.h" +#include "gl/minmax.h" +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -66,6 +68,7 @@ struct flip_pgm int n_cases; /* Pre-flip number of cases. */ struct variable *new_names_var; /* Variable with new variable names. */ + const char *encoding; /* Variable names' encoding. */ struct var_names old_names; /* Variable names before FLIP. */ struct var_names new_names; /* Variable names after FLIP. */ @@ -84,7 +87,8 @@ static void make_new_var (struct dictionary *, const char *name); int cmd_flip (struct lexer *lexer, struct dataset *ds) { - struct dictionary *dict = dataset_dict (ds); + struct dictionary *old_dict = dataset_dict (ds); + struct dictionary *new_dict = NULL; const struct variable **vars; struct flip_pgm *flip; struct casereader *input, *reader; @@ -93,8 +97,8 @@ cmd_flip (struct lexer *lexer, struct dataset *ds) bool ok; if (proc_make_temporary_transformations_permanent (ds)) - msg (SW, _("FLIP ignores TEMPORARY. " - "Temporary transformations will be made permanent.")); + msg (SW, _("%s ignores %s. " + "Temporary transformations will be made permanent."), "FLIP", "TEMPORARY"); flip = pool_create_container (struct flip_pgm, pool); flip->n_vars = 0; @@ -106,29 +110,29 @@ cmd_flip (struct lexer *lexer, struct dataset *ds) flip->cases_read = 0; flip->error = false; - lex_match (lexer, '/'); + lex_match (lexer, T_SLASH); if (lex_match_id (lexer, "VARIABLES")) { - lex_match (lexer, '='); - if (!parse_variables_const (lexer, dict, &vars, &flip->n_vars, + lex_match (lexer, T_EQUALS); + if (!parse_variables_const (lexer, old_dict, &vars, &flip->n_vars, PV_NO_DUPLICATE)) goto error; - lex_match (lexer, '/'); + lex_match (lexer, T_SLASH); } else - dict_get_vars (dict, &vars, &flip->n_vars, DC_SYSTEM); + dict_get_vars (old_dict, &vars, &flip->n_vars, DC_SYSTEM); pool_register (flip->pool, free, vars); - lex_match (lexer, '/'); + lex_match (lexer, T_SLASH); if (lex_match_id (lexer, "NEWNAMES")) { - lex_match (lexer, '='); - flip->new_names_var = parse_variable (lexer, dict); + lex_match (lexer, T_EQUALS); + flip->new_names_var = parse_variable (lexer, old_dict); if (!flip->new_names_var) goto error; } else - flip->new_names_var = dict_lookup_var (dict, "CASE_LBL"); + flip->new_names_var = dict_lookup_var (old_dict, "CASE_LBL"); if (flip->new_names_var) { @@ -141,10 +145,10 @@ cmd_flip (struct lexer *lexer, struct dataset *ds) } } - flip->file = pool_tmpfile (flip->pool); + flip->file = pool_create_temp_file (flip->pool); if (flip->file == NULL) { - msg (SE, _("Could not create temporary file for FLIP.")); + msg (SE, _("Could not create temporary file for %s."), "FLIP"); goto error; } @@ -154,10 +158,15 @@ cmd_flip (struct lexer *lexer, struct dataset *ds) var_names_add (flip->pool, &flip->old_names, pool_strdup (flip->pool, var_get_name (vars[i]))); - /* Read the active file into a flip_sink. */ + /* Read the active dataset into a flip_sink. */ proc_discard_output (ds); - input = proc_open (ds); + /* Save old dictionary. */ + new_dict = dict_clone (old_dict); + flip->encoding = dict_get_encoding (new_dict); + dict_clear (new_dict); + + input = proc_open_filtering (ds, false); while ((c = casereader_read (input)) != NULL) { flip->n_cases++; @@ -181,9 +190,9 @@ cmd_flip (struct lexer *lexer, struct dataset *ds) } else { - int width = var_get_width (flip->new_names_var); - name = pool_strdup0 (flip->pool, - value_str (value, width), width); + name = data_out_pool (value, dict_get_encoding (old_dict), + var_get_write_format (flip->new_names_var), + flip->pool); } var_names_add (flip->pool, &flip->new_names, name); } @@ -195,31 +204,32 @@ cmd_flip (struct lexer *lexer, struct dataset *ds) /* Flip the data we read. */ if (!ok || !flip_file (flip)) { - proc_discard_active_file (ds); + dataset_clear (ds); goto error; } /* Flip the dictionary. */ - dict_clear (dict); - dict_create_var_assert (dict, "CASE_LBL", 8); + dict_create_var_assert (new_dict, "CASE_LBL", 8); for (i = 0; i < flip->n_cases; i++) if (flip->new_names.n_names) - make_new_var (dict, flip->new_names.names[i]); + make_new_var (new_dict, flip->new_names.names[i]); else { - char s[VAR_NAME_LEN + 1]; - sprintf (s, "VAR%03d", i); - dict_create_var_assert (dict, s, 0); + char s[3 + INT_STRLEN_BOUND (i) + 1]; + sprintf (s, "VAR%03zu", i); + dict_create_var_assert (new_dict, s, 0); } /* Set up flipped data for reading. */ - reader = casereader_create_sequential (NULL, dict_get_proto (dict), + reader = casereader_create_sequential (NULL, dict_get_proto (new_dict), flip->n_vars, &flip_casereader_class, flip); - proc_set_active_file_data (ds, reader); - return lex_end_of_command (lexer); + dataset_set_dict (ds, new_dict); + dataset_set_source (ds, reader); + return CMD_SUCCESS; error: + dict_destroy (new_dict); destroy_flip_pgm (flip); return CMD_CASCADING_FAILURE; } @@ -246,7 +256,7 @@ make_new_var (struct dictionary *dict, const char *name_) *--cp = '\0'; /* Fix invalid characters. */ - for (cp = name; *cp && cp < name + VAR_NAME_LEN; cp++) + for (cp = name; *cp && cp < name + ID_MAX_LEN; cp++) if (cp == name) { if (!lex_is_id1 (*cp) || *cp == '$') @@ -258,7 +268,6 @@ make_new_var (struct dictionary *dict, const char *name_) *cp = '_'; } *cp = '\0'; - str_uppercase (name); /* Use the mangled name, if it is available, or add numeric extensions until we find one that is. */ @@ -268,9 +277,9 @@ make_new_var (struct dictionary *dict, const char *name_) int i; for (i = 1; ; i++) { - char n[VAR_NAME_LEN + 1]; - int ofs = MIN (VAR_NAME_LEN - 1 - intlog10 (i), len); - memcpy (n, name, ofs); + char n[ID_MAX_LEN + 1]; + int ofs = MIN (ID_MAX_LEN - 1 - intlog10 (i), len); + strncpy (n, name, ofs); sprintf (&n[ofs], "%d", i); if (dict_create_var (dict, n, 0)) @@ -319,16 +328,16 @@ flip_file (struct flip_pgm *flip) output_buf = input_buf + flip->n_vars * case_capacity; input_file = flip->file; - if (fseek (input_file, 0, SEEK_SET) != 0) + if (fseeko (input_file, 0, SEEK_SET) != 0) { - msg (SE, _("Error rewinding FLIP file: %s."), strerror (errno)); + msg (SE, _("Error rewinding %s file: %s."), "FLIP", strerror (errno)); return false; } - output_file = pool_tmpfile (flip->pool); + output_file = pool_create_temp_file (flip->pool); if (output_file == NULL) { - msg (SE, _("Error creating FLIP source file.")); + msg (SE, _("Error creating %s source file."), "FLIP"); return false; } @@ -341,9 +350,9 @@ flip_file (struct flip_pgm *flip) if (read_cases != fread (input_buf, case_bytes, read_cases, input_file)) { if (ferror (input_file)) - msg (SE, _("Error reading FLIP file: %s."), strerror (errno)); + msg (SE, _("Error reading %s file: %s."), "FLIP", strerror (errno)); else - msg (SE, _("Unexpected end of file reading FLIP file.")); + msg (SE, _("Unexpected end of file reading %s file."), "FLIP"); return false; } @@ -359,7 +368,7 @@ flip_file (struct flip_pgm *flip) + (off_t) i * flip->n_cases), SEEK_SET) != 0) { - msg (SE, _("Error seeking FLIP source file: %s."), + msg (SE, _("Error seeking %s source file: %s."), "FLIP", strerror (errno)); return false; } @@ -367,7 +376,7 @@ flip_file (struct flip_pgm *flip) if (fwrite (output_buf, sizeof *output_buf, read_cases, output_file) != read_cases) { - msg (SE, _("Error writing FLIP source file: %s."), + msg (SE, _("Error writing %s source file: %s."), "FLIP", strerror (errno)); return false; } @@ -376,17 +385,13 @@ flip_file (struct flip_pgm *flip) case_idx += read_cases; } - if (pool_fclose (flip->pool, input_file) == EOF) - { - msg (SE, _("Error closing FLIP source file: %s."), strerror (errno)); - return false; - } + pool_fclose_temp_file (flip->pool, input_file); pool_unregister (flip->pool, input_buf); free (input_buf); - if (fseek (output_file, 0, SEEK_SET) != 0) + if (fseeko (output_file, 0, SEEK_SET) != 0) { - msg (SE, _("Error rewinding FLIP source file: %s."), strerror (errno)); + msg (SE, _("Error rewinding %s source file: %s."), "FLIP", strerror (errno)); return false; } flip->file = output_file; @@ -407,8 +412,9 @@ flip_casereader_read (struct casereader *reader, void *flip_) return false; c = case_create (casereader_get_proto (reader)); - value_copy_str_rpad (case_data_rw_idx (c, 0), 8, - flip->old_names.names[flip->cases_read], ' '); + data_in (ss_cstr (flip->old_names.names[flip->cases_read]), flip->encoding, + FMT_A, case_data_rw_idx (c, 0), 8, flip->encoding); + for (i = 0; i < flip->n_cases; i++) { double in; @@ -416,10 +422,10 @@ flip_casereader_read (struct casereader *reader, void *flip_) { case_unref (c); if (ferror (flip->file)) - msg (SE, _("Error reading FLIP temporary file: %s."), + msg (SE, _("Error reading %s temporary file: %s."), "FLIP", strerror (errno)); else if (feof (flip->file)) - msg (SE, _("Unexpected end of file reading FLIP temporary file.")); + msg (SE, _("Unexpected end of file reading %s temporary file."), "FLIP"); else NOT_REACHED (); flip->error = true;