X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdictionary%2Fmrsets.c;h=3b96da3a6ceab28a7177416386bcef1d22ca87fa;hb=037d8f6e7932459b5d0fb479a2c5030a8088f3d1;hp=6e8a050849e3290c095cbdca36ef1d187f7d70f8;hpb=f550aee00a62fe1d8baf62d83cd7efef6cc2ee92;p=pspp diff --git a/src/language/dictionary/mrsets.c b/src/language/dictionary/mrsets.c index 6e8a050849..3b96da3a6c 100644 --- a/src/language/dictionary/mrsets.c +++ b/src/language/dictionary/mrsets.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2010 Free Software Foundation, Inc. + Copyright (C) 2010, 2011, 2012 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 @@ -17,9 +17,9 @@ #include #include "data/data-out.h" +#include "data/dataset.h" #include "data/dictionary.h" #include "data/mrset.h" -#include "data/procedure.h" #include "data/value-labels.h" #include "data/variable.h" #include "language/command.h" @@ -27,15 +27,17 @@ #include "language/lexer/variable-parser.h" #include "libpspp/assertion.h" #include "libpspp/hmap.h" +#include "libpspp/i18n.h" #include "libpspp/message.h" #include "libpspp/str.h" #include "libpspp/stringi-map.h" #include "libpspp/stringi-set.h" -#include "output/tab.h" +#include "output/pivot-table.h" #include "gl/xalloc.h" #include "gettext.h" +#define N_(msgid) msgid #define _(msgid) gettext (msgid) static bool parse_group (struct lexer *, struct dictionary *, enum mrset_type); @@ -47,7 +49,7 @@ cmd_mrsets (struct lexer *lexer, struct dataset *ds) { struct dictionary *dict = dataset_dict (ds); - while (lex_match (lexer, '/')) + while (lex_match (lexer, T_SLASH)) { bool ok; @@ -69,7 +71,7 @@ cmd_mrsets (struct lexer *lexer, struct dataset *ds) return CMD_FAILURE; } - return lex_end_of_command (lexer); + return CMD_SUCCESS; } static bool @@ -77,37 +79,31 @@ parse_group (struct lexer *lexer, struct dictionary *dict, enum mrset_type type) { const char *subcommand_name = type == MRSET_MD ? "MDGROUP" : "MCGROUP"; - struct mrset *mrset; bool labelsource_varlabel; bool has_value; - mrset = xzalloc (sizeof *mrset); + struct mrset *mrset = XZALLOC (struct mrset); mrset->type = type; mrset->cat_source = MRSET_VARLABELS; labelsource_varlabel = false; has_value = false; - while (lex_token (lexer) != '/' && lex_token (lexer) != '.') + while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD) { if (lex_match_id (lexer, "NAME")) { - if (!lex_force_match (lexer, '=') || !lex_force_id (lexer)) + if (!lex_force_match (lexer, T_EQUALS) || !lex_force_id (lexer) + || !mrset_is_valid_name (lex_tokcstr (lexer), + dict_get_encoding (dict), true)) goto error; - if (lex_tokid (lexer)[0] != '$') - { - msg (SE, _("%s is not a valid name for a multiple response " - "set. Multiple response set names must begin with " - "`$'."), lex_tokid (lexer)); - goto error; - } free (mrset->name); - mrset->name = xstrdup (lex_tokid (lexer)); + mrset->name = xstrdup (lex_tokcstr (lexer)); lex_get (lexer); } else if (lex_match_id (lexer, "VARIABLES")) { - if (!lex_force_match (lexer, '=')) + if (!lex_force_match (lexer, T_EQUALS)) goto error; free (mrset->vars); @@ -125,16 +121,16 @@ parse_group (struct lexer *lexer, struct dictionary *dict, } else if (lex_match_id (lexer, "LABEL")) { - if (!lex_force_match (lexer, '=') || !lex_force_string (lexer)) + if (!lex_force_match (lexer, T_EQUALS) || !lex_force_string (lexer)) goto error; free (mrset->label); - mrset->label = ds_xstrdup (lex_tokstr (lexer)); + mrset->label = ss_xstrdup (lex_tokss (lexer)); lex_get (lexer); } else if (type == MRSET_MD && lex_match_id (lexer, "LABELSOURCE")) { - if (!lex_force_match (lexer, '=') + if (!lex_force_match (lexer, T_EQUALS) || !lex_force_match_id (lexer, "VARLABEL")) goto error; @@ -142,7 +138,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict, } else if (type == MRSET_MD && lex_match_id (lexer, "VALUE")) { - if (!lex_force_match (lexer, '=')) + if (!lex_force_match (lexer, T_EQUALS)) goto error; has_value = true; @@ -159,19 +155,24 @@ parse_group (struct lexer *lexer, struct dictionary *dict, } else if (lex_is_string (lexer)) { - const char *s = ds_cstr (lex_tokstr (lexer)); - int width; + size_t width; + char *s; + + s = recode_string (dict_get_encoding (dict), "UTF-8", + lex_tokcstr (lexer), -1); + width = strlen (s); /* Trim off trailing spaces, but don't trim the string until it's empty because a width of 0 is a numeric type. */ - width = strlen (s); while (width > 1 && s[width - 1] == ' ') width--; value_destroy (&mrset->counted, mrset->width); value_init (&mrset->counted, width); - memcpy (value_str_rw (&mrset->counted, width), s, width); + memcpy (mrset->counted.s, s, width); mrset->width = width; + + free (s); } else { @@ -182,7 +183,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict, } else if (type == MRSET_MD && lex_match_id (lexer, "CATEGORYLABELS")) { - if (!lex_force_match (lexer, '=')) + if (!lex_force_match (lexer, T_EQUALS)) goto error; if (lex_match_id (lexer, "VARLABELS")) @@ -204,14 +205,12 @@ parse_group (struct lexer *lexer, struct dictionary *dict, if (mrset->name == NULL) { - msg (SE, _("Required %s specification missing from %s subcommand."), - "NAME", subcommand_name); + lex_spec_missing (lexer, subcommand_name, "NAME"); goto error; } else if (mrset->n_vars == 0) { - msg (SE, _("Required %s specification missing from %s subcommand."), - "VARIABLES", subcommand_name); + lex_spec_missing (lexer, subcommand_name, "VARIABLES"); goto error; } @@ -220,8 +219,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict, /* Check that VALUE is specified and is valid for the VARIABLES. */ if (!has_value) { - msg (SE, _("Required %s specification missing from %s subcommand."), - "VALUE", subcommand_name); + lex_spec_missing (lexer, subcommand_name, "VALUE"); goto error; } else if (var_is_alpha (mrset->vars[0])) @@ -370,7 +368,7 @@ parse_group (struct lexer *lexer, struct dictionary *dict, msg (SW, _("Variables %s and %s specified as part of " "multiple dichotomy group %s (which has " "CATEGORYLABELS=COUNTEDVALUES) have the same " - "value label for the the group's counted " + "value label for the group's counted " "value. These categories will not be " "distinguishable in output."), other_name, name, mrset->name); @@ -419,10 +417,11 @@ parse_group (struct lexer *lexer, struct dictionary *dict, if (width == c->width && value_equal (value, &c->value, width)) { - if (!c->warned && strcasecmp (c->label, label)) + if (!c->warned && utf8_strcasecmp (c->label, label)) { char *s = data_out (value, var_get_encoding (var), - var_get_print_format (var)); + var_get_print_format (var), + settings_get_fmt_settings ()); c->warned = true; msg (SW, _("Variables specified on MCGROUP should " "have the same categories, but %s and %s " @@ -469,24 +468,25 @@ static bool parse_mrset_names (struct lexer *lexer, struct dictionary *dict, struct stringi_set *mrset_names) { - if (!lex_force_match_id (lexer, "NAME") || !lex_force_match (lexer, '=')) + if (!lex_force_match_id (lexer, "NAME") + || !lex_force_match (lexer, T_EQUALS)) return false; stringi_set_init (mrset_names); - if (lex_match (lexer, '[')) + if (lex_match (lexer, T_LBRACK)) { - while (!lex_match (lexer, ']')) + while (!lex_match (lexer, T_RBRACK)) { if (!lex_force_id (lexer)) return false; - if (dict_lookup_mrset (dict, lex_tokid (lexer)) == NULL) + if (dict_lookup_mrset (dict, lex_tokcstr (lexer)) == NULL) { msg (SE, _("No multiple response set named %s."), - lex_tokid (lexer)); + lex_tokcstr (lexer)); stringi_set_destroy (mrset_names); return false; } - stringi_set_insert (mrset_names, lex_tokid (lexer)); + stringi_set_insert (mrset_names, lex_tokcstr (lexer)); lex_get (lexer); } } @@ -522,84 +522,67 @@ parse_delete (struct lexer *lexer, struct dictionary *dict) static bool parse_display (struct lexer *lexer, struct dictionary *dict) { - struct string details, var_names; struct stringi_set mrset_names_set; - char **mrset_names; - struct tab_table *table; - size_t i, n; - if (!parse_mrset_names (lexer, dict, &mrset_names_set)) return false; - n = stringi_set_count (&mrset_names_set); + size_t n = stringi_set_count (&mrset_names_set); if (n == 0) { if (dict_get_n_mrsets (dict) == 0) - msg (SN, _("The active file dictionary does not contain any multiple " - "response sets.")); + msg (SN, _("The active dataset dictionary does not contain any " + "multiple response sets.")); stringi_set_destroy (&mrset_names_set); return true; } - table = tab_create (3, n + 1); - tab_headers (table, 0, 0, 1, 0); - tab_box (table, TAL_1, TAL_1, TAL_1, TAL_1, 0, 0, 2, n); - tab_hline (table, TAL_2, 0, 2, 1); - tab_title (table, "%s", _("Multiple Response Sets")); - tab_text (table, 0, 0, TAB_EMPH | TAB_LEFT, _("Name")); - tab_text (table, 1, 0, TAB_EMPH | TAB_LEFT, _("Variables")); - tab_text (table, 2, 0, TAB_EMPH | TAB_LEFT, _("Details")); - - ds_init_empty (&details); - ds_init_empty (&var_names); - mrset_names = stringi_set_get_sorted_array (&mrset_names_set); - for (i = 0; i < n; i++) + struct pivot_table *table = pivot_table_create ( + N_("Multiple Response Sets")); + + pivot_dimension_create ( + table, PIVOT_AXIS_COLUMN, N_("Attributes"), + N_("Label"), N_("Encoding"), N_("Counted Value"), N_("Member Variables")); + + struct pivot_dimension *mrsets = pivot_dimension_create ( + table, PIVOT_AXIS_ROW, N_("Name")); + mrsets->root->show_label = true; + + char **mrset_names = stringi_set_get_sorted_array (&mrset_names_set); + for (size_t i = 0; i < n; i++) { const struct mrset *mrset = dict_lookup_mrset (dict, mrset_names[i]); - const int row = i + 1; - size_t j; - - /* Details. */ - ds_clear (&details); - ds_put_format (&details, "%s\n", (mrset->type == MRSET_MD - ? _("Multiple dichotomy set") - : _("Multiple category set"))); + + int row = pivot_category_create_leaf ( + mrsets->root, pivot_value_new_user_text (mrset->name, -1)); + if (mrset->label != NULL) - ds_put_format (&details, "%s: %s\n", _("Label"), mrset->label); + pivot_table_put2 (table, 0, row, + pivot_value_new_user_text (mrset->label, -1)); + + pivot_table_put2 (table, 1, row, + pivot_value_new_text (mrset->type == MRSET_MD + ? _("Dichotomies") + : _("Categories"))); + if (mrset->type == MRSET_MD) - { - if (mrset->label != NULL || mrset->label_from_var_label) - ds_put_format (&details, "%s: %s\n", _("Label source"), - (mrset->label_from_var_label - ? _("First variable label among variables") - : _("Provided by user"))); - ds_put_format (&details, "%s: ", _("Counted value")); - if (mrset->width == 0) - ds_put_format (&details, "%.0f\n", mrset->counted.f); - else - ds_put_format (&details, "\"%.*s\"\n", mrset->width, - value_str (&mrset->counted, mrset->width)); - ds_put_format (&details, "%s: %s\n", _("Category label source"), - (mrset->cat_source == MRSET_VARLABELS - ? _("Variable labels") - : _("Value labels of counted value"))); - } + pivot_table_put2 (table, 2, row, + pivot_value_new_value ( + &mrset->counted, mrset->width, + &F_8_0, dict_get_encoding (dict))); /* Variable names. */ - ds_clear (&var_names); - for (j = 0; j < mrset->n_vars; j++) + struct string var_names = DS_EMPTY_INITIALIZER; + for (size_t j = 0; j < mrset->n_vars; j++) ds_put_format (&var_names, "%s\n", var_get_name (mrset->vars[j])); - - tab_text (table, 0, row, TAB_LEFT, mrset_names[i]); - tab_text (table, 1, row, TAB_LEFT, ds_cstr (&var_names)); - tab_text (table, 2, row, TAB_LEFT, ds_cstr (&details)); + ds_chomp_byte (&var_names, '\n'); + pivot_table_put2 (table, 3, row, + pivot_value_new_user_text_nocopy ( + ds_steal_cstr (&var_names))); } free (mrset_names); - ds_destroy (&var_names); - ds_destroy (&details); stringi_set_destroy (&mrset_names_set); - tab_submit (table); + pivot_table_submit (table); return true; }