int cmd_variable_labels (struct lexer *lexer, struct dataset *ds) { struct dictionary *dict = dataset_dict (ds); do { struct variable **v; size_t nv; size_t i; if (!parse_variables (lexer, dict, &v, &nv, PV_NONE)) return CMD_FAILURE; if (!lex_force_string (lexer)) { free (v); return CMD_FAILURE; } for (i = 0; i < nv; i++) var_set_label (v[i], lex_tokcstr (lexer)); lex_get (lexer); while (lex_token (lexer) == T_SLASH) lex_get (lexer); free (v); } while (lex_token (lexer) != T_ENDCMD); return CMD_SUCCESS; }
/* Parse all the labels for the VAR_CNT variables in VARS and add the specified labels to those variables. */ static int get_label (struct lexer *lexer, struct variable **vars, size_t var_cnt, const char *dict_encoding) { /* Parse all the labels and add them to the variables. */ do { enum { MAX_LABEL_LEN = 255 }; int width = var_get_width (vars[0]); union value value; struct string label; size_t trunc_len; size_t i; /* Set value. */ value_init (&value, width); if (!parse_value (lexer, &value, vars[0])) { value_destroy (&value, width); return 0; } lex_match (lexer, T_COMMA); /* Set label. */ if (lex_token (lexer) != T_ID && !lex_force_string (lexer)) { value_destroy (&value, width); return 0; } ds_init_substring (&label, lex_tokss (lexer)); trunc_len = utf8_encoding_trunc_len (ds_cstr (&label), dict_encoding, MAX_LABEL_LEN); if (ds_length (&label) > trunc_len) { msg (SW, _("Truncating value label to %d bytes."), MAX_LABEL_LEN); ds_truncate (&label, trunc_len); } for (i = 0; i < var_cnt; i++) var_replace_value_label (vars[i], &value, ds_cstr (&label)); ds_destroy (&label); value_destroy (&value, width); lex_get (lexer); lex_match (lexer, T_COMMA); } while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD); return 1; }
int cmd_missing_values (struct lexer *lexer, struct dataset *ds) { struct dictionary *dict = dataset_dict (ds); struct variable **v = NULL; size_t nv; bool ok = true; while (lex_token (lexer) != T_ENDCMD) { size_t i; if (!parse_variables (lexer, dict, &v, &nv, PV_NONE)) goto error; if (!lex_force_match (lexer, T_LPAREN)) goto error; for (i = 0; i < nv; i++) var_clear_missing_values (v[i]); if (!lex_match (lexer, T_RPAREN)) { struct missing_values mv; for (i = 0; i < nv; i++) if (var_get_type (v[i]) != var_get_type (v[0])) { const struct variable *n = var_is_numeric (v[0]) ? v[0] : v[i]; const struct variable *s = var_is_numeric (v[0]) ? v[i] : v[0]; msg (SE, _("Cannot mix numeric variables (e.g. %s) and " "string variables (e.g. %s) within a single list."), var_get_name (n), var_get_name (s)); goto error; } if (var_is_numeric (v[0])) { mv_init (&mv, 0); while (!lex_match (lexer, T_RPAREN)) { enum fmt_type type = var_get_print_format (v[0])->type; double x, y; bool ok; if (!parse_num_range (lexer, &x, &y, &type)) goto error; ok = (x == y ? mv_add_num (&mv, x) : mv_add_range (&mv, x, y)); if (!ok) ok = false; lex_match (lexer, T_COMMA); } } else { mv_init (&mv, MV_MAX_STRING); while (!lex_match (lexer, T_RPAREN)) { uint8_t value[MV_MAX_STRING]; char *dict_mv; size_t length; if (!lex_force_string (lexer)) { ok = false; break; } dict_mv = recode_string (dict_get_encoding (dict), "UTF-8", lex_tokcstr (lexer), ss_length (lex_tokss (lexer))); length = strlen (dict_mv); if (length > MV_MAX_STRING) { /* XXX truncate graphemes not bytes */ msg (SE, _("Truncating missing value to maximum " "acceptable length (%d bytes)."), MV_MAX_STRING); length = MV_MAX_STRING; } memset (value, ' ', MV_MAX_STRING); memcpy (value, dict_mv, length); free (dict_mv); if (!mv_add_str (&mv, value)) ok = false; lex_get (lexer); lex_match (lexer, T_COMMA); } } for (i = 0; i < nv; i++) { if (mv_is_resizable (&mv, var_get_width (v[i]))) var_set_missing_values (v[i], &mv); else { msg (SE, _("Missing values provided are too long to assign " "to variable of width %d."), var_get_width (v[i])); ok = false; } } mv_destroy (&mv); } lex_match (lexer, T_SLASH); free (v); v = NULL; } free (v); return ok ? CMD_SUCCESS : CMD_FAILURE; error: free (v); return CMD_FAILURE; }
int cmd_save_translate (struct lexer *lexer, struct dataset *ds) { enum { CSV_FILE = 1, TAB_FILE } type; struct dictionary *dict; struct case_map *map; struct casewriter *writer; struct file_handle *handle; struct csv_writer_options csv_opts; bool replace; bool retain_unselected; bool recode_user_missing; bool include_var_names; bool use_value_labels; bool use_print_formats; char decimal; char delimiter; char qualifier; bool ok; type = 0; dict = dict_clone (dataset_dict (ds)); map = NULL; handle = NULL; replace = false; retain_unselected = true; recode_user_missing = false; include_var_names = false; use_value_labels = false; use_print_formats = false; decimal = settings_get_decimal_char (FMT_F); delimiter = 0; qualifier = '"'; case_map_prepare_dict (dict); dict_delete_scratch_vars (dict); while (lex_match (lexer, T_SLASH)) { if (lex_match_id (lexer, "OUTFILE")) { if (handle != NULL) { lex_sbc_only_once ("OUTFILE"); goto error; } lex_match (lexer, T_EQUALS); handle = fh_parse (lexer, FH_REF_FILE, NULL); if (handle == NULL) goto error; } else if (lex_match_id (lexer, "TYPE")) { if (type != 0) { lex_sbc_only_once ("TYPE"); goto error; } lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "CSV")) type = CSV_FILE; else if (lex_match_id (lexer, "TAB")) type = TAB_FILE; else { lex_error_expecting (lexer, "CSV", "TAB", NULL_SENTINEL); goto error; } } else if (lex_match_id (lexer, "REPLACE")) replace = true; else if (lex_match_id (lexer, "FIELDNAMES")) include_var_names = true; else if (lex_match_id (lexer, "MISSING")) { lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "IGNORE")) recode_user_missing = false; else if (lex_match_id (lexer, "RECODE")) recode_user_missing = true; else { lex_error_expecting (lexer, "IGNORE", "RECODE", NULL_SENTINEL); goto error; } } else if (lex_match_id (lexer, "CELLS")) { lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "VALUES")) use_value_labels = false; else if (lex_match_id (lexer, "LABELS")) use_value_labels = true; else { lex_error_expecting (lexer, "VALUES", "LABELS", NULL_SENTINEL); goto error; } } else if (lex_match_id (lexer, "TEXTOPTIONS")) { lex_match (lexer, T_EQUALS); for (;;) { if (lex_match_id (lexer, "DELIMITER")) { lex_match (lexer, T_EQUALS); if (!lex_force_string (lexer)) goto error; /* XXX should support multibyte UTF-8 delimiters */ if (ss_length (lex_tokss (lexer)) != 1) { msg (SE, _("The %s string must contain exactly one " "character."), "DELIMITER"); goto error; } delimiter = ss_first (lex_tokss (lexer)); lex_get (lexer); } else if (lex_match_id (lexer, "QUALIFIER")) { lex_match (lexer, T_EQUALS); if (!lex_force_string (lexer)) goto error; /* XXX should support multibyte UTF-8 qualifiers */ if (ss_length (lex_tokss (lexer)) != 1) { msg (SE, _("The %s string must contain exactly one " "character."), "QUALIFIER"); goto error; } qualifier = ss_first (lex_tokss (lexer)); lex_get (lexer); } else if (lex_match_id (lexer, "DECIMAL")) { lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "DOT")) decimal = '.'; else if (lex_match_id (lexer, "COMMA")) decimal = ','; else { lex_error_expecting (lexer, "DOT", "COMMA", NULL_SENTINEL); goto error; } } else if (lex_match_id (lexer, "FORMAT")) { lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "PLAIN")) use_print_formats = false; else if (lex_match_id (lexer, "VARIABLE")) use_print_formats = true; else { lex_error_expecting (lexer, "PLAIN", "VARIABLE", NULL_SENTINEL); goto error; } } else break; } } else if (lex_match_id (lexer, "UNSELECTED")) { lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "RETAIN")) retain_unselected = true; else if (lex_match_id (lexer, "DELETE")) retain_unselected = false; else { lex_error_expecting (lexer, "RETAIN", "DELETE", NULL_SENTINEL); goto error; } } else if (!parse_dict_trim (lexer, dict)) goto error; } if (lex_end_of_command (lexer) != CMD_SUCCESS) goto error; if (type == 0) { lex_sbc_missing ("TYPE"); goto error; } else if (handle == NULL) { lex_sbc_missing ("OUTFILE"); goto error; } else if (!replace && fn_exists (fh_get_file_name (handle))) { msg (SE, _("Output file `%s' exists but REPLACE was not specified."), fh_get_file_name (handle)); goto error; } dict_delete_scratch_vars (dict); dict_compact_values (dict); csv_opts.recode_user_missing = recode_user_missing; csv_opts.include_var_names = include_var_names; csv_opts.use_value_labels = use_value_labels; csv_opts.use_print_formats = use_print_formats; csv_opts.decimal = decimal; csv_opts.delimiter = (delimiter ? delimiter : type == TAB_FILE ? '\t' : decimal == '.' ? ',' : ';'); csv_opts.qualifier = qualifier; writer = csv_writer_open (handle, dict, &csv_opts); if (writer == NULL) goto error; fh_unref (handle); map = case_map_from_dict (dict); if (map != NULL) writer = case_map_create_output_translator (map, writer); dict_destroy (dict); casereader_transfer (proc_open_filtering (ds, !retain_unselected), writer); ok = casewriter_destroy (writer); ok = proc_commit (ds) && ok; return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE; error: fh_unref (handle); dict_destroy (dict); case_map_destroy (map); return CMD_FAILURE; }
int cmd_reliability (struct lexer *lexer, struct dataset *ds) { const struct dictionary *dict = dataset_dict (ds); struct reliability reliability; reliability.n_variables = 0; reliability.variables = NULL; reliability.model = MODEL_ALPHA; reliability.exclude = MV_ANY; reliability.summary = 0; reliability.wv = dict_get_weight (dict); reliability.total_start = 0; lex_match (lexer, T_SLASH); if (!lex_force_match_id (lexer, "VARIABLES")) { goto error; } lex_match (lexer, T_EQUALS); if (!parse_variables_const (lexer, dict, &reliability.variables, &reliability.n_variables, PV_NO_DUPLICATE | PV_NUMERIC)) goto error; if (reliability.n_variables < 2) msg (MW, _("Reliability on a single variable is not useful.")); { int i; struct cronbach *c; /* Create a default Scale */ reliability.n_sc = 1; reliability.sc = xzalloc (sizeof (struct cronbach) * reliability.n_sc); ds_init_cstr (&reliability.scale_name, "ANY"); c = &reliability.sc[0]; c->n_items = reliability.n_variables; c->items = xzalloc (sizeof (struct variable*) * c->n_items); for (i = 0 ; i < c->n_items ; ++i) c->items[i] = reliability.variables[i]; } while (lex_token (lexer) != T_ENDCMD) { lex_match (lexer, T_SLASH); if (lex_match_id (lexer, "SCALE")) { struct const_var_set *vs; if ( ! lex_force_match (lexer, T_LPAREN)) goto error; if ( ! lex_force_string (lexer) ) goto error; ds_init_substring (&reliability.scale_name, lex_tokss (lexer)); lex_get (lexer); if ( ! lex_force_match (lexer, T_RPAREN)) goto error; lex_match (lexer, T_EQUALS); vs = const_var_set_create_from_array (reliability.variables, reliability.n_variables); if (!parse_const_var_set_vars (lexer, vs, &reliability.sc->items, &reliability.sc->n_items, 0)) { const_var_set_destroy (vs); goto error; } const_var_set_destroy (vs); } else if (lex_match_id (lexer, "MODEL")) { lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "ALPHA")) { reliability.model = MODEL_ALPHA; } else if (lex_match_id (lexer, "SPLIT")) { reliability.model = MODEL_SPLIT; reliability.split_point = -1; if ( lex_match (lexer, T_LPAREN)) { lex_force_num (lexer); reliability.split_point = lex_number (lexer); lex_get (lexer); lex_force_match (lexer, T_RPAREN); } } else goto error; } else if (lex_match_id (lexer, "SUMMARY")) { lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "TOTAL")) { reliability.summary |= SUMMARY_TOTAL; } else if (lex_match (lexer, T_ALL)) { reliability.summary = 0xFFFF; } else goto error; } else if (lex_match_id (lexer, "MISSING")) { lex_match (lexer, T_EQUALS); while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH) { if (lex_match_id (lexer, "INCLUDE")) { reliability.exclude = MV_SYSTEM; } else if (lex_match_id (lexer, "EXCLUDE")) { reliability.exclude = MV_ANY; } else { lex_error (lexer, NULL); goto error; } } } else { lex_error (lexer, NULL); goto error; } } if ( reliability.model == MODEL_SPLIT) { int i; const struct cronbach *s; if ( reliability.split_point >= reliability.n_variables) { msg (ME, _("The split point must be less than the number of variables")); goto error; } reliability.n_sc += 2 ; reliability.sc = xrealloc (reliability.sc, sizeof (struct cronbach) * reliability.n_sc); s = &reliability.sc[0]; reliability.sc[1].n_items = (reliability.split_point == -1) ? s->n_items / 2 : reliability.split_point; reliability.sc[2].n_items = s->n_items - reliability.sc[1].n_items; reliability.sc[1].items = xzalloc (sizeof (struct variable *) * reliability.sc[1].n_items); reliability.sc[2].items = xzalloc (sizeof (struct variable *) * reliability.sc[2].n_items); for (i = 0; i < reliability.sc[1].n_items ; ++i) reliability.sc[1].items[i] = s->items[i]; while (i < s->n_items) { reliability.sc[2].items[i - reliability.sc[1].n_items] = s->items[i]; i++; } } if ( reliability.summary & SUMMARY_TOTAL) { int i; const int base_sc = reliability.n_sc; reliability.total_start = base_sc; reliability.n_sc += reliability.sc[0].n_items ; reliability.sc = xrealloc (reliability.sc, sizeof (struct cronbach) * reliability.n_sc); for (i = 0 ; i < reliability.sc[0].n_items; ++i ) { int v_src; int v_dest = 0; struct cronbach *s = &reliability.sc[i + base_sc]; s->n_items = reliability.sc[0].n_items - 1; s->items = xzalloc (sizeof (struct variable *) * s->n_items); for (v_src = 0 ; v_src < reliability.sc[0].n_items ; ++v_src) { if ( v_src != i) s->items[v_dest++] = reliability.sc[0].items[v_src]; } } } if ( ! run_reliability (ds, &reliability)) goto error; free (reliability.variables); return CMD_SUCCESS; error: free (reliability.variables); return CMD_FAILURE; }