X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fterminal%2Fterminal-opts.c;h=eeb10356d8ecf7f971dc82f7c280b12231c1e504;hb=3b03678858485b01277d7488323613fb28691834;hp=d2ddc6eeffa2b611f9d524d5b13fb8453d4dcb9e;hpb=bd17d2af982332ee1791998361b1ac6731fe14fa;p=pspp diff --git a/src/ui/terminal/terminal-opts.c b/src/ui/terminal/terminal-opts.c index d2ddc6eeff..eeb10356d8 100644 --- a/src/ui/terminal/terminal-opts.c +++ b/src/ui/terminal/terminal-opts.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2008 Free Software Foundation + Copyright (C) 2008, 2010 Free Software Foundation 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 @@ -15,184 +15,299 @@ along with this program. If not, see . */ #include -#include + +#include "terminal-opts.h" + #include -#include #include -#include -#include -#include "msg-ui.h" -#include -#include -#include -#include -#include "terminal-opts.h" -#include -#include -#include "read-line.h" +#include + +#include "data/settings.h" +#include "language/lexer/include-path.h" +#include "libpspp/argv-parser.h" +#include "libpspp/assertion.h" +#include "libpspp/cast.h" +#include "libpspp/compiler.h" +#include "libpspp/llx.h" +#include "libpspp/str.h" +#include "libpspp/string-array.h" +#include "libpspp/string-map.h" +#include "libpspp/string-set.h" +#include "libpspp/version.h" +#include "output/driver.h" +#include "output/driver-provider.h" +#include "output/msglog.h" +#include "output/pivot-table.h" + +#include "gl/error.h" +#include "gl/localcharset.h" +#include "gl/progname.h" +#include "gl/version-etc.h" +#include "gl/xmemdup0.h" +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) #define N_(msgid) msgid +struct terminal_opts + { + struct string_map options; /* Output driver options. */ + bool has_output_driver; + bool has_terminal_driver; + bool has_error_file; + enum lex_syntax_mode *syntax_mode; + bool *process_statrc; + char **syntax_encoding; + char *table_look; + }; -static const struct argp_option test_options [] = +enum { - {"verbose", 'v', 0, 0, N_("Increase diagnostic verbosity level"), 0}, - {"testing-mode", 'T', 0, OPTION_HIDDEN, 0, 0}, + OPT_TESTING_MODE, + OPT_ERROR_FILE, + OPT_OUTPUT, + OPT_OUTPUT_OPTION, + OPT_NO_OUTPUT, + OPT_BATCH, + OPT_INTERACTIVE, + OPT_SYNTAX_ENCODING, + OPT_NO_STATRC, + OPT_TABLE_LOOK, + OPT_HELP, + OPT_VERSION, + N_TERMINAL_OPTIONS + }; - { 0, 0, 0, 0, 0, 0 } +static struct argv_option terminal_argv_options[N_TERMINAL_OPTIONS] = + { + {"testing-mode", 0, no_argument, OPT_TESTING_MODE}, + {"error-file", 'e', required_argument, OPT_ERROR_FILE}, + {"output", 'o', required_argument, OPT_OUTPUT}, + {NULL, 'O', required_argument, OPT_OUTPUT_OPTION}, + {"no-output", 0, no_argument, OPT_NO_OUTPUT}, + {"batch", 'b', no_argument, OPT_BATCH}, + {"interactive", 'i', no_argument, OPT_INTERACTIVE}, + {"syntax-encoding", 0, required_argument, OPT_SYNTAX_ENCODING}, + {"no-statrc", 'r', no_argument, OPT_NO_STATRC}, + {"table-look", 0, required_argument, OPT_TABLE_LOOK}, + {"help", 'h', no_argument, OPT_HELP}, + {"version", 'V', no_argument, OPT_VERSION}, }; -static error_t -parse_test_opts (int key, char *arg, struct argp_state *state) +static void +register_output_driver (struct terminal_opts *to) { - switch (key) + if (!string_map_is_empty (&to->options)) { - case 'T': - settings_set_testing_mode (true); - break; - case 'v': - verbose_increment_level (); - break; - default: - return ARGP_ERR_UNKNOWN; + struct output_driver *driver; + + driver = output_driver_create (&to->options); + if (driver != NULL) + { + output_driver_register (driver); + + to->has_output_driver = true; + if (driver->device_type == SETTINGS_DEVICE_TERMINAL) + to->has_terminal_driver = true; + } + string_map_clear (&to->options); } - - return 0; } -static const struct argp_option io_options [] = - { - {"error-file", 'e', "FILE", 0, - N_("Send error messages to FILE (appended)"), 0}, - - {"device", 'o', "DEVICE", 0, - N_("Select output driver DEVICE and disable defaults"), 0}, - - {"list", 'l', 0, 0, - N_("Print a list of known driver classes, then exit"), 0}, - - {"interactive", 'i', 0, 0, N_("Start an interactive session"), 0}, - - { 0, 0, 0, 0, 0, 0 } - }; - - -static error_t -parse_io_opts (int key, char *arg, struct argp_state *state) +static char * +get_supported_formats (void) { - struct source_init - { - struct llx_list file_list; - bool cleared_device_defaults; - bool interactive; - }; + const struct string_set_node *node; + struct string_array format_array; + struct string_set format_set; + char *format_string; + const char *format; + + /* Get supported formats as unordered set. */ + string_set_init (&format_set); + output_get_supported_formats (&format_set); + + /* Converted supported formats to sorted array. */ + string_array_init (&format_array); + STRING_SET_FOR_EACH (format, node, &format_set) + string_array_append (&format_array, format); + string_array_sort (&format_array); + string_set_destroy (&format_set); + + /* Converted supported formats to string. */ + format_string = string_array_join (&format_array, " "); + string_array_destroy (&format_array); + return format_string; +} - struct fn_element { - struct ll ll; - const char *fn; - }; +static void +usage (void) +{ + char *supported_formats = get_supported_formats (); + char *inc_path = string_array_join (include_path_default (), " "); + + printf (_("\ +PSPP, a program for statistical analysis of sampled data.\n\ +Usage: %s [OPTION]... FILE...\n\ +\n\ +Arguments to long options also apply to equivalent short options.\n\ +\n\ +Output options:\n\ + -o, --output=FILE output to FILE, default format from FILE's name\n\ + -O format=FORMAT override format for previous -o\n\ + -O OPTION=VALUE set output option to customize previous -o\n\ + -O device={terminal|listing} override device type for previous -o\n\ + -e, --error-file=FILE append errors, warnings, and notes to FILE\n\ + --no-output disable default output driver\n\ + --table-look=FILE use output style read from FILE\n\ +Supported output formats: %s\n\ +\n\ +Language options:\n\ + -I, --include=DIR append DIR to search path\n\ + -I-, --no-include clear search path\n\ + -r, --no-statrc disable running rc file at startup\n\ + -a, --algorithm={compatible|enhanced}\n\ + set to `compatible' if you want output\n\ + calculated from broken algorithms\n\ + -x, --syntax={compatible|enhanced}\n\ + set to `compatible' to disable PSPP extensions\n\ + -b, --batch interpret syntax in batch mode\n\ + -i, --interactive interpret syntax in interactive mode\n\ + --syntax-encoding=ENCODING specify encoding for syntax files\n\ + -s, --safer don't allow some unsafe operations\n\ +Default search path: %s\n\ +\n\ +Informative output:\n\ + -h, --help display this help and exit\n\ + -V, --version output version information and exit\n\ +\n\ +Non-option arguments are interpreted as syntax files to execute.\n"), + program_name, supported_formats, inc_path); + + free (supported_formats); + free (inc_path); + + emit_bug_reporting_address (); + exit (EXIT_SUCCESS); +} - struct source_init *sip = state->hook; +static void +terminal_option_callback (int id, void *to_) +{ + struct terminal_opts *to = to_; - struct source_stream *ss = state->input; + switch (id) + { + case OPT_TESTING_MODE: + settings_set_testing_mode (true); + break; - struct command_line_processor *clp = get_subject (state); + case OPT_ERROR_FILE: + if (!strcmp (optarg, "none") || msglog_create (optarg)) + to->has_error_file = true; + break; - switch (key) - { - case ARGP_KEY_INIT: - state->hook = sip = xzalloc (sizeof (struct source_init)); - llx_init (&sip->file_list); + case OPT_OUTPUT: + register_output_driver (to); + string_map_insert (&to->options, "output-file", optarg); break; - case ARGP_KEY_ARG: - if (strchr (arg, '=')) - outp_configure_macro (arg); - else - { - llx_push_tail (&sip->file_list, arg, &llx_malloc_mgr); - } + + case OPT_OUTPUT_OPTION: + output_driver_parse_option (optarg, &to->options); break; - case ARGP_KEY_SUCCESS: - { - struct llx *llx = llx_null (&sip->file_list); - while ((llx = llx_next (llx)) != llx_null (&sip->file_list)) - { - const char *fn = llx_data (llx); - /* Assume it's a syntax file */ - getl_append_source (ss, - create_syntax_file_source (fn), - GETL_BATCH, - ERRMODE_CONTINUE - ); - - } - - if (sip->interactive || llx_is_empty (&sip->file_list)) - { - getl_append_source (ss, create_readln_source (), - GETL_INTERACTIVE, - ERRMODE_CONTINUE - ); - - if (!sip->cleared_device_defaults) - outp_configure_add ("interactive"); - } - } + + case OPT_NO_OUTPUT: + /* Pretend that we already have an output driver, which disables adding + one in terminal_opts_done() when we don't already have one. */ + to->has_output_driver = true; break; - case ARGP_KEY_FINI: - free (sip); + + case OPT_BATCH: + *to->syntax_mode = LEX_SYNTAX_BATCH; break; - case 'e': - msg_ui_set_error_file (arg); + + case OPT_INTERACTIVE: + *to->syntax_mode = LEX_SYNTAX_INTERACTIVE; break; - case 'i': - sip->interactive = true; + + case OPT_SYNTAX_ENCODING: + *to->syntax_encoding = optarg; break; - case 'l': - outp_list_classes (); + + case OPT_NO_STATRC: + *to->process_statrc = false; break; - case 'o': - if (! sip->cleared_device_defaults) - { - outp_configure_clear (); - sip->cleared_device_defaults = true; - } - outp_configure_add (arg); + + case OPT_TABLE_LOOK: + to->table_look = optarg; break; + + case OPT_HELP: + usage (); + exit (EXIT_SUCCESS); + + case OPT_VERSION: + version_etc (stdout, "pspp", PACKAGE_NAME, PACKAGE_VERSION, + "Ben Pfaff", "John Darrington", "Jason Stover", + NULL_SENTINEL); + exit (EXIT_SUCCESS); + default: - return ARGP_ERR_UNKNOWN; + NOT_REACHED (); } +} - return 0; +struct terminal_opts * +terminal_opts_init (struct argv_parser *ap, + enum lex_syntax_mode *syntax_mode, bool *process_statrc, + char **syntax_encoding) +{ + struct terminal_opts *to; + + *syntax_mode = LEX_SYNTAX_AUTO; + *process_statrc = true; + *syntax_encoding = "Auto"; + + to = xzalloc (sizeof *to); + to->syntax_mode = syntax_mode; + string_map_init (&to->options); + to->has_output_driver = false; + to->has_error_file = false; + to->syntax_mode = syntax_mode; + to->process_statrc = process_statrc; + to->syntax_encoding = syntax_encoding; + + argv_parser_add_options (ap, terminal_argv_options, N_TERMINAL_OPTIONS, + terminal_option_callback, to); + return to; } -const struct argp io_argp = {io_options, parse_io_opts, 0, 0, 0, 0, 0}; -const struct argp test_argp = {test_options, parse_test_opts, 0, 0, 0, 0, 0}; +void +terminal_opts_done (struct terminal_opts *to, int argc, char *argv[]) +{ + register_output_driver (to); + if (!to->has_output_driver) + { + string_map_insert (&to->options, "output-file", "-"); + string_map_insert (&to->options, "format", "txt"); + register_output_driver (to); + } -#if 0 -static const struct argp_child children [] = - { - {&io_argp, 0, N_("Options affecting input and output locations:"), 0}, - {&test_argp, 0, N_("Diagnostic options:"), 0}, - {0, 0, 0, 0} - }; + if (!to->has_terminal_driver && !to->has_error_file) + msglog_create ("-"); + string_map_destroy (&to->options); -static error_t -propagate_aux (int key, char *arg, struct argp_state *state) -{ - if ( key == ARGP_KEY_INIT) + if (to->table_look) { - int i; - for (i = 0 ; i < sizeof (children) / sizeof (children[0]) - 1 ; ++i) - state->child_inputs[i] = state->input; + struct pivot_table_look *look; + char *s = pivot_table_look_read (to->table_look, &look); + if (s) + error (1, 0, "%s", s); + pivot_table_look_set_default (look); + pivot_table_look_unref (look); } - return ARGP_ERR_UNKNOWN; + free (to); } - -const struct argp terminal_argp = {NULL, propagate_aux, 0, 0, children, 0, 0}; - -#endif