From ae93a402dec5c3b8c6115dcc9f048a45745944ed Mon Sep 17 00:00:00 2001 From: John Darrington Date: Tue, 17 Nov 2020 18:27:38 +0100 Subject: [PATCH] Move syntax generation to the psppire-import-textfile module --- src/ui/gui/psppire-import-assistant.c | 191 +------------------------ src/ui/gui/psppire-import-textfile.c | 196 ++++++++++++++++++++++++++ src/ui/gui/psppire-import-textfile.h | 2 + 3 files changed, 199 insertions(+), 190 deletions(-) diff --git a/src/ui/gui/psppire-import-assistant.c b/src/ui/gui/psppire-import-assistant.c index 47744909db..f111d10c52 100644 --- a/src/ui/gui/psppire-import-assistant.c +++ b/src/ui/gui/psppire-import-assistant.c @@ -547,168 +547,6 @@ formats_page_create (PsppireImportAssistant *ia) -static void -separators_append_syntax (const PsppireImportAssistant *ia, struct string *s) -{ - int i; - - ds_put_cstr (s, " /DELIMITERS=\""); - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (get_widget_assert (ia->text_builder, "tab")))) - ds_put_cstr (s, "\\t"); - for (i = 0; i < SEPARATOR_CNT; i++) - { - const struct separator *seps = &separators[i]; - GtkWidget *button = get_widget_assert (ia->text_builder, seps->name); - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) - { - if (seps->c == '\t') - continue; - - ds_put_byte (s, seps->c); - } - } - ds_put_cstr (s, "\"\n"); - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->quote_cb))) - { - GtkComboBoxText *cbt = GTK_COMBO_BOX_TEXT (ia->quote_combo); - gchar *quotes = gtk_combo_box_text_get_active_text (cbt); - if (quotes && *quotes) - syntax_gen_pspp (s, " /QUALIFIER=%sq\n", quotes); - free (quotes); - } -} - -static void -formats_append_syntax (const PsppireImportAssistant *ia, struct string *s) -{ - int i; - int var_cnt; - - g_return_if_fail (ia->dict); - - ds_put_cstr (s, " /VARIABLES=\n"); - - var_cnt = dict_get_var_cnt (ia->dict); - for (i = 0; i < var_cnt; i++) - { - struct variable *var = dict_get_var (ia->dict, i); - char format_string[FMT_STRING_LEN_MAX + 1]; - fmt_to_string (var_get_print_format (var), format_string); - ds_put_format (s, " %s %s%s\n", - var_get_name (var), format_string, - i == var_cnt - 1 ? "." : ""); - } -} - -static void -first_line_append_syntax (const PsppireImportAssistant *ia, struct string *s) -{ - gint first_case = 0; - g_object_get (ia->delimiters_model, "first-line", &first_case, NULL); - - if (first_case > 0) - ds_put_format (s, " /FIRSTCASE=%d\n", first_case + 1); -} - -static void -intro_append_syntax (const PsppireImportAssistant *ia, struct string *s) -{ - gint first_line = 0; - g_object_get (ia->delimiters_model, "first-line", &first_line, NULL); - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->n_cases_button))) - ds_put_format (s, "SELECT IF ($CASENUM <= %d).\n", - gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ia->n_cases_spin)) - first_line); - else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->percent_button))) - ds_put_format (s, "SAMPLE %.4g.\n", - gtk_spin_button_get_value (GTK_SPIN_BUTTON (ia->percent_spin)) / 100.0); -} - - -/* Emits PSPP syntax to S that applies the dictionary attributes - (such as missing values and value labels) of the variables in - DICT. */ -static void -apply_dict (const struct dictionary *dict, struct string *s) -{ - size_t var_cnt = dict_get_var_cnt (dict); - size_t i; - - for (i = 0; i < var_cnt; i++) - { - struct variable *var = dict_get_var (dict, i); - const char *name = var_get_name (var); - enum val_type type = var_get_type (var); - int width = var_get_width (var); - enum measure measure = var_get_measure (var); - enum var_role role = var_get_role (var); - enum alignment alignment = var_get_alignment (var); - const struct fmt_spec *format = var_get_print_format (var); - - if (var_has_missing_values (var)) - { - const struct missing_values *mv = var_get_missing_values (var); - size_t j; - - syntax_gen_pspp (s, "MISSING VALUES %ss (", name); - for (j = 0; j < mv_n_values (mv); j++) - { - if (j) - ds_put_cstr (s, ", "); - syntax_gen_value (s, mv_get_value (mv, j), width, format); - } - - if (mv_has_range (mv)) - { - double low, high; - if (mv_has_value (mv)) - ds_put_cstr (s, ", "); - mv_get_range (mv, &low, &high); - syntax_gen_num_range (s, low, high, format); - } - ds_put_cstr (s, ").\n"); - } - if (var_has_value_labels (var)) - { - const struct val_labs *vls = var_get_value_labels (var); - const struct val_lab **labels = val_labs_sorted (vls); - size_t n_labels = val_labs_count (vls); - size_t i; - - syntax_gen_pspp (s, "VALUE LABELS %ss", name); - for (i = 0; i < n_labels; i++) - { - const struct val_lab *vl = labels[i]; - ds_put_cstr (s, "\n "); - syntax_gen_value (s, &vl->value, width, format); - ds_put_byte (s, ' '); - syntax_gen_string (s, ss_cstr (val_lab_get_escaped_label (vl))); - } - free (labels); - ds_put_cstr (s, ".\n"); - } - if (var_has_label (var)) - syntax_gen_pspp (s, "VARIABLE LABELS %ss %sq.\n", - name, var_get_label (var)); - if (measure != var_default_measure (type)) - syntax_gen_pspp (s, "VARIABLE LEVEL %ss (%ss).\n", - name, measure_to_syntax (measure)); - if (role != ROLE_INPUT) - syntax_gen_pspp (s, "VARIABLE ROLE /%ss %ss.\n", - var_role_to_syntax (role), name); - if (alignment != var_default_alignment (type)) - syntax_gen_pspp (s, "VARIABLE ALIGNMENT %ss (%ss).\n", - name, alignment_to_syntax (alignment)); - if (var_get_display_width (var) != var_default_display_width (width)) - syntax_gen_pspp (s, "VARIABLE WIDTH %ss (%d).\n", - name, var_get_display_width (var)); - } -} - - - static void sheet_spec_gen_syntax (PsppireImportAssistant *ia, struct string *s) { @@ -760,34 +598,7 @@ psppire_import_assistant_generate_syntax (PsppireImportAssistant *ia) if (!ia->spreadsheet) { - gchar *file_name = NULL; - gchar *encoding = NULL; - g_object_get (ia->text_file, - "file-name", &file_name, - "encoding", &encoding, - NULL); - - if (file_name == NULL) - return NULL; - - syntax_gen_pspp (&s, - "GET DATA" - "\n /TYPE=TXT" - "\n /FILE=%sq\n", - file_name); - if (encoding && strcmp (encoding, "Auto")) - syntax_gen_pspp (&s, " /ENCODING=%sq\n", encoding); - - ds_put_cstr (&s, - " /ARRANGEMENT=DELIMITED\n" - " /DELCASE=LINE\n"); - - first_line_append_syntax (ia, &s); - separators_append_syntax (ia, &s); - - formats_append_syntax (ia, &s); - apply_dict (ia->dict, &s); - intro_append_syntax (ia, &s); + text_spec_gen_syntax (ia, &s); } else { diff --git a/src/ui/gui/psppire-import-textfile.c b/src/ui/gui/psppire-import-textfile.c index d293dc0e39..0d9562a54f 100644 --- a/src/ui/gui/psppire-import-textfile.c +++ b/src/ui/gui/psppire-import-textfile.c @@ -31,6 +31,7 @@ #include "data/casereader-provider.h" #include "data/data-in.h" #include "data/format-guesser.h" +#include "data/value-labels.h" #include "builder-wrapper.h" @@ -860,3 +861,198 @@ textfile_set_data_models (PsppireImportAssistant *ia) g_object_set (ia->data_sheet, "data-model", store, NULL); g_object_set (ia->var_sheet, "data-model", dict, NULL); } + +static void +first_line_append_syntax (const PsppireImportAssistant *ia, struct string *s) +{ + gint first_case = 0; + g_object_get (ia->delimiters_model, "first-line", &first_case, NULL); + + if (first_case > 0) + ds_put_format (s, " /FIRSTCASE=%d\n", first_case + 1); +} + +/* Emits PSPP syntax to S that applies the dictionary attributes + (such as missing values and value labels) of the variables in + DICT. */ +static void +apply_dict (const struct dictionary *dict, struct string *s) +{ + size_t var_cnt = dict_get_var_cnt (dict); + size_t i; + + for (i = 0; i < var_cnt; i++) + { + struct variable *var = dict_get_var (dict, i); + const char *name = var_get_name (var); + enum val_type type = var_get_type (var); + int width = var_get_width (var); + enum measure measure = var_get_measure (var); + enum var_role role = var_get_role (var); + enum alignment alignment = var_get_alignment (var); + const struct fmt_spec *format = var_get_print_format (var); + + if (var_has_missing_values (var)) + { + const struct missing_values *mv = var_get_missing_values (var); + size_t j; + + syntax_gen_pspp (s, "MISSING VALUES %ss (", name); + for (j = 0; j < mv_n_values (mv); j++) + { + if (j) + ds_put_cstr (s, ", "); + syntax_gen_value (s, mv_get_value (mv, j), width, format); + } + + if (mv_has_range (mv)) + { + double low, high; + if (mv_has_value (mv)) + ds_put_cstr (s, ", "); + mv_get_range (mv, &low, &high); + syntax_gen_num_range (s, low, high, format); + } + ds_put_cstr (s, ").\n"); + } + if (var_has_value_labels (var)) + { + const struct val_labs *vls = var_get_value_labels (var); + const struct val_lab **labels = val_labs_sorted (vls); + size_t n_labels = val_labs_count (vls); + size_t i; + + syntax_gen_pspp (s, "VALUE LABELS %ss", name); + for (i = 0; i < n_labels; i++) + { + const struct val_lab *vl = labels[i]; + ds_put_cstr (s, "\n "); + syntax_gen_value (s, &vl->value, width, format); + ds_put_byte (s, ' '); + syntax_gen_string (s, ss_cstr (val_lab_get_escaped_label (vl))); + } + free (labels); + ds_put_cstr (s, ".\n"); + } + if (var_has_label (var)) + syntax_gen_pspp (s, "VARIABLE LABELS %ss %sq.\n", + name, var_get_label (var)); + if (measure != var_default_measure (type)) + syntax_gen_pspp (s, "VARIABLE LEVEL %ss (%ss).\n", + name, measure_to_syntax (measure)); + if (role != ROLE_INPUT) + syntax_gen_pspp (s, "VARIABLE ROLE /%ss %ss.\n", + var_role_to_syntax (role), name); + if (alignment != var_default_alignment (type)) + syntax_gen_pspp (s, "VARIABLE ALIGNMENT %ss (%ss).\n", + name, alignment_to_syntax (alignment)); + if (var_get_display_width (var) != var_default_display_width (width)) + syntax_gen_pspp (s, "VARIABLE WIDTH %ss (%d).\n", + name, var_get_display_width (var)); + } +} + + +static void +intro_append_syntax (const PsppireImportAssistant *ia, struct string *s) +{ + gint first_line = 0; + g_object_get (ia->delimiters_model, "first-line", &first_line, NULL); + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->n_cases_button))) + ds_put_format (s, "SELECT IF ($CASENUM <= %d).\n", + gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ia->n_cases_spin)) - first_line); + else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->percent_button))) + ds_put_format (s, "SAMPLE %.4g.\n", + gtk_spin_button_get_value (GTK_SPIN_BUTTON (ia->percent_spin)) / 100.0); +} + + +static void +formats_append_syntax (const PsppireImportAssistant *ia, struct string *s) +{ + int i; + int var_cnt; + + g_return_if_fail (ia->dict); + + ds_put_cstr (s, " /VARIABLES=\n"); + + var_cnt = dict_get_var_cnt (ia->dict); + for (i = 0; i < var_cnt; i++) + { + struct variable *var = dict_get_var (ia->dict, i); + char format_string[FMT_STRING_LEN_MAX + 1]; + fmt_to_string (var_get_print_format (var), format_string); + ds_put_format (s, " %s %s%s\n", + var_get_name (var), format_string, + i == var_cnt - 1 ? "." : ""); + } +} + +static void +separators_append_syntax (const PsppireImportAssistant *ia, struct string *s) +{ + int i; + + ds_put_cstr (s, " /DELIMITERS=\""); + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (get_widget_assert (ia->text_builder, "tab")))) + ds_put_cstr (s, "\\t"); + for (i = 0; i < SEPARATOR_CNT; i++) + { + const struct separator *seps = &separators[i]; + GtkWidget *button = get_widget_assert (ia->text_builder, seps->name); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) + { + if (seps->c == '\t') + continue; + + ds_put_byte (s, seps->c); + } + } + ds_put_cstr (s, "\"\n"); + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ia->quote_cb))) + { + GtkComboBoxText *cbt = GTK_COMBO_BOX_TEXT (ia->quote_combo); + gchar *quotes = gtk_combo_box_text_get_active_text (cbt); + if (quotes && *quotes) + syntax_gen_pspp (s, " /QUALIFIER=%sq\n", quotes); + free (quotes); + } +} + + +void +text_spec_gen_syntax (PsppireImportAssistant *ia, struct string *s) +{ + gchar *file_name = NULL; + gchar *encoding = NULL; + g_object_get (ia->text_file, + "file-name", &file_name, + "encoding", &encoding, + NULL); + + if (file_name == NULL) + return; + + syntax_gen_pspp (s, + "GET DATA" + "\n /TYPE=TXT" + "\n /FILE=%sq\n", + file_name); + if (encoding && strcmp (encoding, "Auto")) + syntax_gen_pspp (s, " /ENCODING=%sq\n", encoding); + + ds_put_cstr (s, + " /ARRANGEMENT=DELIMITED\n" + " /DELCASE=LINE\n"); + + first_line_append_syntax (ia, s); + separators_append_syntax (ia, s); + + formats_append_syntax (ia, s); + apply_dict (ia->dict, s); + intro_append_syntax (ia, s); +} diff --git a/src/ui/gui/psppire-import-textfile.h b/src/ui/gui/psppire-import-textfile.h index 7a3c0f6fd4..f9c982f43c 100644 --- a/src/ui/gui/psppire-import-textfile.h +++ b/src/ui/gui/psppire-import-textfile.h @@ -33,5 +33,7 @@ void separators_page_create (PsppireImportAssistant *ia); /* Set the data model for both the data sheet and the variable sheet. */ void textfile_set_data_models (PsppireImportAssistant *ia); +void text_spec_gen_syntax (PsppireImportAssistant *ia, struct string *s); + #endif -- 2.30.2