From 40271dcbfdecb01dfe808684741215eb2ddeb508 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 11 Dec 2005 02:48:44 +0000 Subject: [PATCH] Separate settings and the SET command, for modularity. --- doc/configuring.texi | 13 +- doc/utilities.texi | 85 +-- src/ChangeLog | 22 + src/Makefile.am | 1 + src/casefile.c | 2 +- src/cmdline.c | 26 +- src/command.c | 10 +- src/data-list.c | 2 +- src/data-out.c | 4 +- src/filename.c | 4 +- src/flip.c | 2 +- src/getl.c | 8 +- src/glob.c | 2 - src/glob.h | 2 - src/lexer.c | 2 +- src/output.c | 4 +- src/permissions.c | 2 +- src/q2c.c | 194 ------ src/set.q | 1375 ++++++++++-------------------------------- src/settings.c | 619 +++++++++++++++++++ src/settings.h | 283 +++------ src/sort.c | 6 +- 22 files changed, 1102 insertions(+), 1566 deletions(-) create mode 100644 src/settings.c diff --git a/doc/configuring.texi b/doc/configuring.texi index 44de42f9..3c1a4adc 100644 --- a/doc/configuring.texi +++ b/doc/configuring.texi @@ -166,10 +166,7 @@ Configuration file contents. @xref{Configuration files}. Fallback defaults. @end enumerate -Some of the above may not apply to a particular setting. For instance, -the current pager (such as @samp{more}, @samp{most}, or @samp{less}) -cannot be determined by configuration file contents because there is no -appropriate configuration file. +Some of the above may not apply to a particular setting. @node Configuration files, Environment variables, Configuration techniques, Configuration @section Configuration files @@ -1641,14 +1638,6 @@ across operating systems: No default path. @end table -@item STAT_PAGER -@itemx PAGER -@cindex pager - -When PSPP invokes an external pager, it uses the first of these that -is defined. There is a default pager only if the person who compiled -PSPP defined one. - @item TERM The terminal type @code{termcap} or @code{ncurses} will use, if such diff --git a/doc/utilities.texi b/doc/utilities.texi index ea1cfbb2..96341e9c 100644 --- a/doc/utilities.texi +++ b/doc/utilities.texi @@ -262,8 +262,6 @@ SET /MXERRS=max_errs /MXWARNS=max_warnings /PROMPT='prompt' - /VIEWLENGTH=@{MINIMUM,MEDIAN,MAXIMUM,n_lines@} - /VIEWWIDTH=n_characters (program execution) /MEXPAND=@{ON,OFF@} @@ -287,22 +285,15 @@ SET /PRINTBACK=@{ON,OFF@} /RESULTS=@{ON,OFF,TERMINAL,LISTING,BOTH,NONE@} -(output activation) - /LISTING=@{ON,OFF@} - /PRINTER=@{ON,OFF@} - /SCREEN=@{ON,OFF@} - (output driver options) /HEADERS=@{NO,YES,BLANK@} /LENGTH=@{NONE,length_in_lines@} - /LISTING=filename + /LISTING=@{ON,OFF,filename@} /MORE=@{ON,OFF@} - /PAGER=@{OFF,"pager_name"@} /WIDTH=@{NARROW,WIDTH,n_characters@} (logging) /JOURNAL=@{ON,OFF@} [filename] - /LOG=@{ON,OFF@} [filename] (system files) /COMPRESSION=@{ON,OFF@} @@ -312,29 +303,19 @@ SET /SAFER=ON (obsolete settings accepted for compatibility, but ignored) - /AUTOMENU=@{ON,OFF@} - /BEEP=@{ON,OFF@} - /BLOCK='c' /BOXSTRING=@{'xxx','xxxxxxxxxxx'@} /CASE=@{UPPER,UPLOW@} - /COLOR=@dots{} /CPI=cpi_value /DISK=@{ON,OFF@} - /EJECT=@{ON,OFF@} - /HELPWINDOWS=@{ON,OFF@} /HIGHRES=@{ON,OFF@} /HISTOGRAM='c' /LOWRES=@{AUTO,ON,OFF@} /LPI=lpi_value /MENUS=@{STANDARD,EXTENDED@} /MXMEMORY=max_memory - /PTRANSLATE=@{ON,OFF@} - /RCOLORS=@dots{} - /RUNREVIEW=@{AUTO,MANUAL@} /SCRIPTTAB='c' /TB1=@{'xxx','xxxxxxxxxxx'@} /TBFONTS='string' - /WORKDEV=drive_letter /WORKSPACE=workspace_size /XSORT=@{YES,NO@} @end display @@ -413,15 +394,6 @@ current command file. The default is 100. @item PROMPT The command prompt. The default is @samp{PSPP> }. - -@item VIEWLENGTH -The length of the screen in lines. MINIMUM means 25 lines, MEDIAN and -MAXIMUM mean 43 lines. Otherwise specify the number of lines. Normally -PSPP should auto-detect your screen size so this shouldn't have to be -used. - -@item VIEWWIDTH -The width of the screen in characters. Normally 80 or 132. @end table Program execution subcommands control the way that PSPP commands @@ -494,20 +466,6 @@ from command files. The default is OFF. Currently not used. @end table -Output activation subcommands affect whether output devices of -particular types are enabled. These subcommands are - -@table @asis -@item LISTING -Enable or disable listing devices. - -@item PRINTER -Enable or disable printer devices. - -@item SCREEN -Enable or disable screen devices. -@end table - Output driver option subcommands affect output drivers' settings. These subcommands are @@ -580,24 +538,47 @@ obvious security reasons. @display SHOW - /@var{subcommand} - + [ALL] + [BLANKS] + [CC] + [CCA] + [CCB] + [CCC] + [CCD] + [CCE] + [COPYING] + [DECIMALS] + [ENDCMD] + [FORMAT] + [LENGTH] + [MXERRS] + [MXLOOPS] + [MXWARNS] + [SCOMPRESSION] + [UNDEFINED] + [WARRANTY] + [WEIGHT] + [WIDTH] @end display -@cmd{SHOW} can be used to display the current state of PSPP's -execution parameters. All of the parameters which can be changed -using @code{SET} @xref{SET}, can be examined using @cmd{SHOW}, by -using a subcommand with the same name. -In addition, @code{SHOW} supports the following subcommands: +@cmd{SHOW} can be used to display the current state of PSPP's execution +parameters. Parameters that can be changed using @cmd{SET} +(@pxref{SET}), can be examined using @cmd{SHOW} using the subcommand +with the same name. @code{SHOW} supports the following additional +subcommands: @table @code +@item ALL +Show all settings. +@item CC +Show all custom currency settings (CCA through CCE). @item WARRANTY Show details of the lack of warranty for PSPP. @item COPYING -Display the terms of PSPP's copyright licence @ref{License}. +Display the terms of PSPP's copyright licence (@pxref{License}). @end table - +Specifying @cmd{SHOW} without any subcommands is equivalent to SHOW ALL. @node SUBTITLE, TITLE, SHOW, Utilities @section SUBTITLE diff --git a/src/ChangeLog b/src/ChangeLog index a99cdc8c..1fc5fef1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,25 @@ +Sat Dec 10 18:13:36 2005 Ben Pfaff + + Separate settings and the SET command, for modularity. + + * Makefile.am: Add settings.c to sources. + + * glob.c: (global variable test_mode) Removed. + + * set.q: Remove all the set_* variables. Remove a lot of obsolete + SPSS/PC+ settings. Remove the aux_*() routines. Moved the + get_*() functions into settings.c. Rewrite the settings code and + functions to call the new set_*() functions. Rewrite custom + currency parsing. Write new by-hand cmd_show(). + + * esttings.c: New file. Moved the get_*() functions here from + set.q. Created new set_*() functions to correspond with them. + Regularized the names and types of some functions and updated + their callers. Added static, file-scope variables to support the + settings. + + * q2c.c: Remove "aux" support, which was only needed by set.q. + Sun Nov 27 06:43:46 WST 2005 John Darrington * data-out.c format.h: Added return value to data_out function. diff --git a/src/Makefile.am b/src/Makefile.am index fbd3ef20..857dd8a5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -195,6 +195,7 @@ pspp_SOURCES = \ repeat.h \ sample.c \ sel-if.c \ + settings.c \ settings.h \ sfm-read.c \ sfm-read.h \ diff --git a/src/casefile.c b/src/casefile.c index aea4a147..a49db99d 100644 --- a/src/casefile.c +++ b/src/casefile.c @@ -331,7 +331,7 @@ casefile_append (struct casefile *cf, const struct ccase *c) /* Try memory first. */ if (cf->storage == MEMORY) { - if (case_bytes < get_max_workspace ()) + if (case_bytes < get_workspace ()) { size_t block_idx = cf->case_cnt / CASES_PER_BLOCK; size_t case_idx = cf->case_cnt % CASES_PER_BLOCK; diff --git a/src/cmdline.c b/src/cmdline.c index 50214db2..68df7b47 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -52,7 +52,6 @@ char *subst_vars (char *); void parse_command_line (int argc, char **argv) { - static int testing_mode = 0; static struct option long_options[] = { {"algorithm", required_argument, NULL, 'a'}, @@ -73,7 +72,7 @@ parse_command_line (int argc, char **argv) {"recon", no_argument, NULL, 'n'}, {"safer", no_argument, NULL, 's'}, {"syntax", required_argument, NULL, 'x'}, - {"testing-mode", no_argument, &testing_mode, 1}, + {"testing-mode", no_argument, NULL, 'T'}, {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {0, 0, 0, 0}, @@ -81,8 +80,8 @@ parse_command_line (int argc, char **argv) int c, i; - int cleared_device_defaults = 0; - int no_statrc = 0; + bool cleared_device_defaults = false; + bool no_statrc = false; for (;;) { @@ -168,7 +167,7 @@ parse_command_line (int argc, char **argv) if (!cleared_device_defaults) { outp_configure_clear (); - cleared_device_defaults = 1; + cleared_device_defaults = true; } outp_configure_add (optarg); break; @@ -177,10 +176,10 @@ parse_command_line (int argc, char **argv) putchar('\n'); break; case 'r': - no_statrc = 1; + no_statrc = true; break; case 's': - make_safe(); + set_safer_mode (); break; case 'v': err_verbosity++; @@ -189,6 +188,10 @@ parse_command_line (int argc, char **argv) puts (version); puts (legal); err_hcf (1); + case 'T': + force_long_view (); + set_testing_mode (true); + break; case '?': usage (); assert (0); @@ -199,15 +202,6 @@ parse_command_line (int argc, char **argv) } } - - if (testing_mode) - { - /* FIXME: Later this option should do some other things, too. */ - force_long_view(); - test_mode = 1; - } - - for (i = optind; i < argc; i++) { int separate = 1; diff --git a/src/command.c b/src/command.c index 4203ac32..0d557b20 100644 --- a/src/command.c +++ b/src/command.c @@ -108,7 +108,7 @@ pspp_completion_function (const char *text, int state) cmd = &commands[state + skip]; - if ( cmd->transition[pgm_state] == STATE_ERROR || ( cmd->debug && ! test_mode ) ) + if ( cmd->transition[pgm_state] == STATE_ERROR || ( cmd->debug && ! get_testing_mode () ) ) { skip++; continue; @@ -554,7 +554,7 @@ parse_command_name (void) { if (command->skip_entire_name) lex_get (); - if ( command->debug & !test_mode ) + if ( command->debug & !get_testing_mode () ) goto error; free_words (words, word_cnt); return command; @@ -599,7 +599,7 @@ parse_command_name (void) free (words[word_cnt]); } - if ( command->debug && !test_mode ) + if ( command->debug && !get_testing_mode () ) goto error; free_words (words, word_cnt); @@ -679,7 +679,7 @@ cmd_execute (void) int cmd_erase (void) { - if ( safer_mode() ) + if (get_safer_mode ()) { msg (SE, _("This command not allowed when the SAFER option is set.")); return CMD_FAILURE; @@ -810,7 +810,7 @@ cmd_host (void) { int code; - if ( safer_mode() ) + if (get_safer_mode ()) { msg (SE, _("This command not allowed when the SAFER option is set.")); return CMD_FAILURE; diff --git a/src/data-list.c b/src/data-list.c index b615beea..ab166f0d 100644 --- a/src/data-list.c +++ b/src/data-list.c @@ -844,7 +844,7 @@ parse_free (struct dls_var_spec **first, struct dls_var_spec **last) { lex_match ('*'); input = make_input_format (FMT_F, 8, 0); - output = get_format (); + output = *get_format (); } if (input.type == FMT_A || input.type == FMT_AHEX) diff --git a/src/data-out.c b/src/data-out.c index d26215a9..c9c17a5e 100644 --- a/src/data-out.c +++ b/src/data-out.c @@ -965,7 +965,7 @@ year4 (int year) static int try_CCx (char *dst, const struct fmt_spec *fp, double number) { - const struct set_cust_currency *cc = get_cc(fp->type - FMT_CCA); + const struct custom_currency *cc = get_cc(fp->type - FMT_CCA); struct fmt_spec f; @@ -975,7 +975,7 @@ try_CCx (char *dst, const struct fmt_spec *fp, double number) /* Determine length available, decimal character for number proper. */ - f.type = cc->decimal == get_decimal() ? FMT_COMMA : FMT_DOT; + f.type = cc->decimal == get_decimal () ? FMT_COMMA : FMT_DOT; f.w = fp->w - strlen (cc->prefix) - strlen (cc->suffix); if (number < 0) f.w -= strlen (cc->neg_prefix) + strlen (cc->neg_suffix) - 1; diff --git a/src/filename.c b/src/filename.c index b8f8332f..b78897e2 100644 --- a/src/filename.c +++ b/src/filename.c @@ -691,7 +691,7 @@ fn_open (const char *fn, const char *mode) #ifdef unix if (fn[0] == '|') { - if (safer_mode()) + if (get_safer_mode ()) return safety_violation (fn); return popen (&fn[1], mode); @@ -701,7 +701,7 @@ fn_open (const char *fn, const char *mode) char *s; FILE *f; - if (safer_mode()) + if (get_safer_mode ()) return safety_violation (fn); s = local_alloc (strlen (fn)); diff --git a/src/flip.c b/src/flip.c index 9fbea2a4..20498235 100644 --- a/src/flip.c +++ b/src/flip.c @@ -379,7 +379,7 @@ flip_file (struct flip_pgm *flip) /* Allocate memory for many cases. */ case_bytes = flip->var_cnt * sizeof *input_buf; - case_capacity = get_max_workspace() / case_bytes; + case_capacity = get_workspace () / case_bytes; if (case_capacity > flip->case_cnt * 2) case_capacity = flip->case_cnt * 2; if (case_capacity < 2) diff --git a/src/getl.c b/src/getl.c index 65ecb127..a02244d7 100644 --- a/src/getl.c +++ b/src/getl.c @@ -433,7 +433,7 @@ static int read_console (void) { char *line; - char *prompt; + const char *prompt; err_error_count = err_warning_count = 0; err_already_flagged = 0; @@ -453,15 +453,15 @@ read_console (void) switch (getl_prompt) { case GETL_PRPT_STANDARD: - prompt = get_prompt(); + prompt = get_prompt (); break; case GETL_PRPT_CONTINUATION: - prompt = get_cprompt(); + prompt = get_cprompt (); break; case GETL_PRPT_DATA: - prompt = get_dprompt(); + prompt = get_dprompt (); break; default: diff --git a/src/glob.c b/src/glob.c index a026ede6..47db10ea 100644 --- a/src/glob.c +++ b/src/glob.c @@ -86,8 +86,6 @@ struct expression *process_if_expr; struct transformation *t_trns; size_t n_trns, m_trns, f_trns; -short test_mode=0; - int FILTER_before_TEMPORARY; struct file_handle *default_handle; diff --git a/src/glob.h b/src/glob.h index 77d51f6e..dd5eb95c 100644 --- a/src/glob.h +++ b/src/glob.h @@ -23,6 +23,4 @@ void init_glob (int argc UNUSED, char **argv); void done_glob (void); -extern short test_mode; - #endif /* glob.h */ diff --git a/src/lexer.c b/src/lexer.c index 66324a25..fc6bf9d3 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -806,7 +806,7 @@ lex_preprocess_line (void) dot = 1; len--; } - else if (len == 0 && get_nullline() ) + else if (len == 0 && get_nulline ()) dot = 1; else dot = 0; diff --git a/src/output.c b/src/output.c index ba620e06..63e1f810 100644 --- a/src/output.c +++ b/src/output.c @@ -208,12 +208,12 @@ find_defn_value (const char *key) return d->value; if (!strcmp (key, "viewwidth")) { - sprintf (buf, "%d", get_viewwidth()); + sprintf (buf, "%d", get_viewwidth ()); return buf; } else if (!strcmp (key, "viewlength")) { - sprintf (buf, "%d", get_viewlength()); + sprintf (buf, "%d", get_viewlength ()); return buf; } else diff --git a/src/permissions.c b/src/permissions.c index 140c79ef..0d236921 100644 --- a/src/permissions.c +++ b/src/permissions.c @@ -97,7 +97,7 @@ change_permissions(const char *filename, enum PER per) struct stat buf; mode_t mode; - if ( safer_mode() ) + if (get_safer_mode ()) { msg (SE, _("This command not allowed when the SAFER option is set.")); return CMD_FAILURE; diff --git a/src/q2c.c b/src/q2c.c index 3bba2390..f771d466 100644 --- a/src/q2c.c +++ b/src/q2c.c @@ -557,16 +557,6 @@ struct subcommand int translatable; /* Error message is translatable */ }; -typedef struct aux_subcommand aux_subcommand; -struct aux_subcommand - { - aux_subcommand *next; /* Next in the chain. */ - char *name; /* Subcommand name. */ - char *value; /* Subcommand value */ - }; - -static aux_subcommand *aux_subcommands ; - /* Name of the command; i.e., DESCRIPTIVES. */ char *cmdname; @@ -1894,152 +1884,6 @@ dump_parser (int persistent) } -/* Write out the code to parse aux subcommand SBC. */ -static void -dump_aux_subcommand (const subcommand *sbc) -{ - if (sbc->type == SBC_PLAIN ) - { - specifier *spec; - - for (spec = sbc->spec; spec; spec = spec->next) - { - char buf[80]; - sprintf(buf,"p->%s%s",st_lower(sbc->prefix),spec->varname); - - dump (0, "msg(MM,\"%s is %%s\",",sbc->name); - dump (0, "(%s < 1000)?\"not set\":settings[%s - 1000]", buf, buf); - - dump (0, ");"); - } - } - else if (sbc->type == SBC_STRING) - { - dump (0, "msg(MM,\"%s is \\\"%%s\\\"\",p->s_%s);", sbc->name,st_lower(sbc->name) ); - } - else if (sbc->type == SBC_INT) - { - dump (1, "{"); - dump (0, "int i;"); - dump (1, "for (i = 0; i < MAXLISTS; ++i)"); - dump (0, "msg(MM,\"%s is %%ld\",p->n_%s[i]);", sbc->name,st_lower(sbc->name) ); - outdent(); - dump (-1, "}"); - } - else if (sbc->type == SBC_CUSTOM) - { - dump (0, "aux_%scustom_%s(p);",st_lower(prefix),make_identifier(sbc->name)); - } - else - assert(0); -} - - - -/* Write out auxilliary parser. */ -static void -dump_aux_parser (void) -{ - int f=0; - subcommand *sbc; - aux_subcommand *asbc; - - /* Write out English strings for all the identifiers in the symbol table. */ - { - int f, k; - symbol *sym; - char *buf = NULL; - - /* Note the squirmings necessary to make sure that the last string - is not followed by a comma (is it necessary to do that ?? ) */ - for (sym = symtab, f = k = 0; sym; sym = sym->next) - if (!sym->unique && !is_keyword (sym->name)) - { - if (!f) - { - dump (0, "/* Strings for subcommand specifiers. */"); - dump (1, "static const char *settings[]="); - dump (1, "{"); - f = 1; - } - - if (buf == NULL) - buf = xmalloc (1024); - else - dump (0, buf); - - sprintf (buf, "\"%s\",",sym->name); - } - if (buf) - { - buf[strlen (buf) - 1] = 0; - dump (0, buf); - free (buf); - } - if (f) - { - dump (-1, "};"); - dump (-1, nullstr); - } - } - - - indent = 0; - - dump (0, "static int"); - dump (0, "aux_parse_%s (struct cmd_%s *p)", make_identifier (cmdname), - make_identifier (cmdname)); - dump (1, "{"); - - dump (1, "for (;;)"); - dump (1, "{"); - - - for (sbc = subcommands; sbc; sbc = sbc->next) - { - dump (1, "%sif (%s)", f ? "else " : "", make_match (sbc->name)); - f = 1; - dump (1, "{"); - - dump_aux_subcommand (sbc); - - dump (-1, "}"); - outdent (); - } - - for (asbc = aux_subcommands ; asbc ; asbc = asbc->next) - { - dump (1, "%sif (%s)", f ? "else " : "", make_match (asbc->name)); - f = 1; - dump (1, "{"); - dump(0,"aux_%s();",make_identifier(asbc->value)); - dump (-1, "}"); - outdent (); - } - - dump (1, "if (!lex_match ('/'))"); - dump (0, "break;"); - dump (-2, "}"); - outdent (); - dump (0, nullstr); - dump (1, "if (token != '.')"); - dump (1, "{"); - dump (0, "lex_error (_(\"expecting end of command\"));"); - dump (0, "goto lossage;"); - dump (-1, "}"); - dump (0, nullstr); - dump (-1, "return 1;"); - dump (0, nullstr); - dump (-1, "lossage:"); - indent (); - dump (0, "free_%s (p);", make_identifier (cmdname)); - dump (0, "return 0;"); - dump (-1, "} /* aux_parse_%s (struct cmd_%s *p) */", - make_identifier (cmdname), make_identifier (cmdname)); - dump (0, nullstr); -} - - /* Write the output file header. */ static void dump_header (void) @@ -2145,8 +1989,6 @@ recognize_directive (void) return directive; } -static void aux_parse (void); - int main (int argc, char *argv[]) { @@ -2224,11 +2066,6 @@ main (int argc, char *argv[]) dump_parser (1); dump_free (1); } - else if (!strcmp (directive, "aux_functions")) - { - aux_parse(); - dump_aux_parser (); - } else error ("unknown directive `%s'", directive); indent = 0; @@ -2239,34 +2076,3 @@ main (int argc, char *argv[]) return EXIT_SUCCESS; } - -/* Parse an entire auxilliary specification. */ -static void -aux_parse (void) -{ - aux_subcommand *sbc; - aux_subcommand *prevsbc = 0 ; - get_line(); - lex_get(); - - for (;;) - { - sbc = xmalloc (sizeof *sbc); - sbc->next = prevsbc; - sbc->name = xstrdup (tokstr); - lex_get(); - skip_token('='); - sbc->value = xstrdup (tokstr); - lex_get(); - if (token == '.') - break; - skip_token(';'); - prevsbc = sbc; - - } - /* Skip trailing star-slash line. */ - get_line (); - aux_subcommands = sbc; -} - - diff --git a/src/set.q b/src/set.q index eb0a7331..9e045fb7 100644 --- a/src/set.q +++ b/src/set.q @@ -17,47 +17,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* - Categories of SET subcommands: - - data input: BLANKS, DECIMAL, FORMAT, EPOCH. - - program input: ENDCMD, NULLINE. - - interaction: CPROMPT, DPROMPT, ERRORBREAK, MXERRS, MXWARNS, PROMPT. - - program execution: MEXPAND, MITERATE, MNEST, MPRINT, - MXLOOPS, SEED, UNDEFINED. - - data output: CCA...CCE, DECIMAL, FORMAT, RESULTS-p. - - output routing: ECHO, ERRORS, INCLUDE, MESSAGES, PRINTBACK, ERRORS, - RESULTS-rw. - - output activation: LISTING (on/off), SCREEN, PRINTER. - - output driver options: HEADERS, MORE, PAGER, VIEWLENGTH, VIEWWIDTH, - LISTING (filename). - - logging: LOG, JOURNAL. - - system files: COMP/COMPRESSION, SCOMP/SCOMPRESSION. - - security: SAFER. -*/ - -/* - FIXME - - These subcommands remain to be implemented: - ECHO, PRINTBACK, INCLUDE - MORE, PAGER, VIEWLENGTH, VIEWWIDTH, HEADERS - - These subcommands are not complete: - MESSAGES, ERRORS, RESULTS - LISTING/DISK, LOG/JOURNAL -*/ - #include #include "settings.h" #include "error.h" @@ -67,6 +26,7 @@ #include #include "alloc.h" #include "command.h" +#include "dictionary.h" #include "lexer.h" #include "error.h" #include "magic.h" @@ -75,8 +35,8 @@ #include "var.h" #include "format.h" #include "copyleft.h" +#include "var.h" -#include "signal.h" #if HAVE_LIBTERMCAP #if HAVE_TERMCAP_H @@ -90,49 +50,8 @@ int tgetnum (const char *); #include "gettext.h" #define _(msgid) gettext (msgid) -static int set_errors; -static int set_messages; -static int set_results; - -static double set_blanks=SYSMIS; - -static int set_epoch = -1; - -static struct fmt_spec set_format={FMT_F,8,2}; - -static struct set_cust_currency set_cc[5]; - -static char *set_journal; -static int set_journaling; - -static int set_listing=1; - -#if !USE_INTERNAL_PAGER -static char *set_pager=0; -#endif /* !USE_INTERNAL_PAGER */ - -static gsl_rng *rng; - -static int long_view=0; -int set_testing_mode=0; -static int set_viewlength; -static int set_viewwidth; - -void aux_show_warranty(void); -void aux_show_copying(void); - -static const char *route_to_string(int routing); -static void set_routing (int q, int *setting); - -static int set_ccx (const char *cc_string, struct set_cust_currency * cc, - int cc_name); -static void set_rng (unsigned long); -static unsigned long random_seed (void); - /* (specification) "SET" (stc_): - automenu=automenu:on/off; - beep=beep:on/off; blanks=custom; block=string "x==1" "one character long"; boxstring=string "x==3 || x==11" "3 or 11 characters long"; @@ -142,7 +61,6 @@ static unsigned long random_seed (void); ccc=string; ccd=string; cce=string; - color=custom; compression=compress:on/off; cpi=integer "x>0" "%s must be greater than 0"; cprompt=string; @@ -150,21 +68,18 @@ static unsigned long random_seed (void); disk=custom; dprompt=string; echo=echo:on/off; - eject=eject:on/off; endcmd=string "x==1" "one character long"; epoch=custom; errorbreak=errbrk:on/off; errors=errors:on/off/terminal/listing/both/none; format=custom; headers=headers:no/yes/blank; - helpwindows=helpwin:on/off; highres=hires:on/off; histogram=string "x==1" "one character long"; include=inc:on/off; journal=custom; length=custom; listing=custom; - log=custom; lowres=lores:auto/on/off; lpi=integer "x>0" "%s must be greater than 0"; menus=menus:standard/extended; @@ -172,33 +87,23 @@ static unsigned long random_seed (void); mexpand=mexp:on/off; miterate=integer "x>0" "%s must be greater than 0"; mnest=integer "x>0" "%s must be greater than 0"; - more=more:on/off; mprint=mprint:on/off; mxerrs=integer "x >= 1" "%s must be at least 1"; mxloops=integer "x >=1" "%s must be at least 1"; mxmemory=integer; mxwarns=integer; nulline=null:on/off; - pager=custom; printback=prtbck:on/off; - printer=prtr:on/off; prompt=string; - ptranslate=ptrans:on/off; - rcolor=custom; - results=custom; - runreview=runrev:auto/manual; + results=res:on/off/terminal/listing/both/none; safer=safe:on; scompression=scompress:on/off; - screen=scrn:on/off; scripttab=string "x==1" "one character long"; seed=custom; tb1=string "x==3 || x==11" "3 or 11 characters long"; tbfonts=string; undefined=undef:warn/nowarn; - viewlength=custom; - viewwidth=custom; width=custom; - workdev=custom; workspace=integer "x>=1024" "%s must be at least 1 MB"; xsort=xsort:yes/no. */ @@ -207,439 +112,191 @@ static unsigned long random_seed (void); /* (_functions) */ -static int -aux_stc_custom_blanks(struct cmd_set *cmd UNUSED) -{ - if ( set_blanks == SYSMIS ) - msg(MM, "SYSMIS"); - else - msg(MM, "%g", set_blanks); - return 0; -} - - -static int -aux_stc_custom_color(struct cmd_set *cmd UNUSED) -{ - msg (MW, _("%s is obsolete."),"COLOR"); - return 0; -} - -static int -aux_stc_custom_listing(struct cmd_set *cmd UNUSED) -{ - if ( set_listing ) - msg(MM, _("LISTING is ON")); - else - msg(MM, _("LISTING is OFF")); - - return 0; -} - -static int -aux_stc_custom_disk(struct cmd_set *cmd UNUSED) -{ - return aux_stc_custom_listing(cmd); -} - -static int -aux_stc_custom_epoch(struct cmd_set *cmd UNUSED) -{ - msg (MM, _("EPOCH is %d"), get_epoch ()); - return 0; -} - -static int -aux_stc_custom_format(struct cmd_set *cmd UNUSED) -{ - msg(MM, fmt_to_string(&set_format)); - return 0; -} - - - -static int -aux_stc_custom_journal(struct cmd_set *cmd UNUSED) -{ - if (set_journaling) - msg(MM, set_journal); - else - msg(MM, _("Journalling is off") ); - - return 0; -} - -static int -aux_stc_custom_length(struct cmd_set *cmd UNUSED) -{ - msg(MM, "%d", set_viewlength); - return 0; -} - -static int -aux_stc_custom_log(struct cmd_set *cmd ) -{ - return aux_stc_custom_journal (cmd); -} - -static int -aux_stc_custom_pager(struct cmd_set *cmd UNUSED) -{ -#if !USE_INTERNAL_PAGER - if ( set_pager ) - msg(MM, set_pager); - else - msg(MM, "No pager"); -#else /* USE_INTERNAL_PAGER */ - msg (MM, "Internal pager."); -#endif /* USE_INTERNAL_PAGER */ - - return 0; -} - -static int -aux_stc_custom_rcolor(struct cmd_set *cmd UNUSED) -{ - msg (SW, _("%s is obsolete."),"RCOLOR"); - return 0; -} - -static int -aux_stc_custom_results(struct cmd_set *cmd UNUSED) -{ - - msg(MM, route_to_string(set_results) ); - - return 0; -} - -static int -aux_stc_custom_seed(struct cmd_set *cmd UNUSED) -{ - return 0; -} - -static int -aux_stc_custom_viewlength(struct cmd_set *cmd UNUSED) -{ - msg(MM, "%d", set_viewlength); - return 0; -} - -static int -aux_stc_custom_viewwidth(struct cmd_set *cmd UNUSED) -{ - msg(MM, "%d", set_viewwidth); - return 0; -} - -static int -aux_stc_custom_width(struct cmd_set *cmd UNUSED) -{ - msg(MM, "%d", set_viewwidth); - return 0; -} - -static int -aux_stc_custom_workdev(struct cmd_set *cmd UNUSED) -{ - msg (SW, _("%s is obsolete."),"WORKDEV"); - return 0; -} - - - -/* (aux_functions) - warranty=show_warranty; - copying=show_copying. -*/ - - -static struct cmd_set cmd; - -int -cmd_show (void) -{ - lex_match_id ("SHOW"); - - if (!aux_parse_set (&cmd)) - return CMD_FAILURE; - - return CMD_SUCCESS; -} +static bool do_cc (const char *cc_string, int idx); int cmd_set (void) { + struct cmd_set cmd; + bool ok = true; if (!parse_set (&cmd)) return CMD_FAILURE; if (cmd.sbc_cca) - set_ccx (cmd.s_cca, &set_cc[0], 'A'); + ok = ok && do_cc (cmd.s_cca, 0); if (cmd.sbc_ccb) - set_ccx (cmd.s_ccb, &set_cc[1], 'B'); + ok = ok && do_cc (cmd.s_ccb, 1); if (cmd.sbc_ccc) - set_ccx (cmd.s_ccc, &set_cc[2], 'C'); + ok = ok && do_cc (cmd.s_ccc, 2); if (cmd.sbc_ccd) - set_ccx (cmd.s_ccd, &set_cc[3], 'D'); + ok = ok && do_cc (cmd.s_ccd, 3); if (cmd.sbc_cce) - set_ccx (cmd.s_cce, &set_cc[4], 'E'); - - if (cmd.sbc_errors) - set_routing (cmd.errors, &set_errors); - if (cmd.sbc_messages) - set_routing (cmd.messages, &set_messages); - - /* PC+ compatible syntax. */ - if (cmd.sbc_screen) - outp_enable_device (cmd.scrn == STC_OFF ? 0 : 1, OUTP_DEV_SCREEN); - if (cmd.sbc_printer) - outp_enable_device (cmd.prtr == STC_OFF ? 0 : 1, OUTP_DEV_PRINTER); - - if (cmd.sbc_automenu ) - msg (SW, _("%s is obsolete."),"AUTOMENU"); - if (cmd.sbc_beep ) - msg (SW, _("%s is obsolete."),"BEEP"); + ok = ok && do_cc (cmd.s_cce, 4); + + if (cmd.sbc_prompt) + set_prompt (cmd.s_prompt); + if (cmd.sbc_cprompt) + set_prompt (cmd.s_cprompt); + if (cmd.sbc_dprompt) + set_prompt (cmd.s_dprompt); + + if (cmd.sbc_decimal) + set_decimal (cmd.dec == STC_DOT ? '.' : ','); + if (cmd.sbc_echo) + set_echo (cmd.echo == STC_ON); + if (cmd.sbc_endcmd) + set_endcmd (cmd.s_endcmd[0]); + if (cmd.sbc_errorbreak) + set_errorbreak (cmd.errbrk == STC_ON); + if (cmd.sbc_include) + set_include (cmd.inc == STC_ON); + if (cmd.sbc_mxerrs) + set_mxerrs (cmd.n_mxerrs[0]); + if (cmd.sbc_mxwarns) + set_mxwarns (cmd.n_mxwarns[0]); + if (cmd.sbc_nulline) + set_nulline (cmd.null == STC_ON); + if (cmd.sbc_safer) + set_safer_mode (); + if (cmd.sbc_scompression) + set_scompression (cmd.scompress == STC_ON); + if (cmd.sbc_undefined) + set_undefined (cmd.undef == STC_WARN); + if (cmd.sbc_workspace) + set_workspace (cmd.n_workspace[0] * 1024L); + if (cmd.sbc_block) msg (SW, _("%s is obsolete."),"BLOCK"); if (cmd.sbc_boxstring) msg (SW, _("%s is obsolete."),"BOXSTRING"); - if (cmd.sbc_eject ) - msg (SW, _("%s is obsolete."),"EJECT"); - if (cmd.sbc_helpwindows ) - msg (SW, _("%s is obsolete."),"HELPWINDOWS"); if (cmd.sbc_histogram) msg (MW, _("%s is obsolete."),"HISTOGRAM"); if (cmd.sbc_menus ) msg (MW, _("%s is obsolete."),"MENUS"); - if (cmd.sbc_ptranslate ) - msg (SW, _("%s is obsolete."),"PTRANSLATE"); - if (cmd.sbc_runreview ) - msg (SW, _("%s is obsolete."),"RUNREVIEW"); if (cmd.sbc_xsort ) msg (SW, _("%s is obsolete."),"XSORT"); if (cmd.sbc_mxmemory ) msg (SE, _("%s is obsolete."),"MXMEMORY"); if (cmd.sbc_scripttab) msg (SE, _("%s is obsolete."),"SCRIPTTAB"); - if (cmd.sbc_tbfonts) - msg (SW, _("%s is not yet implemented."),"TBFONTS"); + msg (SW, _("%s is obsolete."),"TBFONTS"); if (cmd.sbc_tb1 && cmd.s_tb1) - msg (SW, _("%s is not yet implemented."),"TB1"); + msg (SW, _("%s is obsolete."),"TB1"); - /* Windows compatible syntax. */ if (cmd.sbc_case) - msg (SW, _("CASE is not implemented and probably won't be. " - "If you care, complain about it.")); + msg (SW, _("%s is not implemented."), "CASE"); if (cmd.sbc_compression) - { - msg (MW, _("Active file compression is not yet implemented " - "(and probably won't be).")); - } + msg (MW, _("Active file compression is not implemented.")); return CMD_SUCCESS; } -/* Sets custom currency specifier CC having name CC_NAME ('A' through - 'E') to correspond to the settings in CC_STRING. */ -static int -set_ccx (const char *cc_string, struct set_cust_currency * cc, int cc_name) +/* Find the grouping characters in CC_STRING and set CC's + grouping and decimal members appropriately. Returns true if + successful, false otherwise. */ +static bool +find_cc_separators (const char *cc_string, struct custom_currency *cc) { - if (strlen (cc_string) > 16) - { - msg (SE, _("CC%c: Length of custom currency string `%s' (%d) " - "exceeds maximum length of 16."), - cc_name, cc_string, strlen (cc_string)); - return 0; - } - - /* Determine separators. */ - { - const char *sp; - int n_commas, n_periods; + const char *sp; + int comma_cnt, dot_cnt; - /* Count the number of commas and periods. There must be exactly - three of one or the other. */ - n_commas = n_periods = 0; - for (sp = cc_string; *sp; sp++) - if (*sp == ',') - n_commas++; - else if (*sp == '.') - n_periods++; + /* Count commas and periods. There must be exactly three of + one or the other, except that an apostrophe acts escapes a + following comma or period. */ + comma_cnt = dot_cnt = 0; + for (sp = cc_string; *sp; sp++) + if (*sp == ',') + comma_cnt++; + else if (*sp == '.') + dot_cnt++; + else if (*sp == '\'' && (sp[1] == '.' || sp[1] == ',' || sp[1] == '\'')) + sp++; - if (!((n_commas == 3) ^ (n_periods == 3))) - { - msg (SE, _("CC%c: Custom currency string `%s' does not contain " - "exactly three periods or commas (not both)."), - cc_name, cc_string); - return 0; - } - else if (n_commas == 3) - { - cc->decimal = '.'; - cc->grouping = ','; - } - else - { - cc->decimal = ','; - cc->grouping = '.'; - } - } - - /* Copy cc_string to cc, changing separators to nulls. */ - { - char *cp; - - strcpy (cc->buf, cc_string); - cp = cc->neg_prefix = cc->buf; - - while (*cp++ != cc->grouping) - ; - cp[-1] = '\0'; - cc->prefix = cp; - - while (*cp++ != cc->grouping) - ; - cp[-1] = '\0'; - cc->suffix = cp; - - while (*cp++ != cc->grouping) - ; - cp[-1] = '\0'; - cc->neg_suffix = cp; - } - - return 1; -} + if ((comma_cnt == 3) == (dot_cnt == 3)) + return false; - -const char * -route_to_string(int routing) -{ - static char s[255]; - - s[0]='\0'; - - if ( routing == 0 ) + if (comma_cnt == 3) { - strcpy(s, _("None")); - return s; + cc->decimal = '.'; + cc->grouping = ','; } - - if (routing & SET_ROUTE_DISABLE ) + else { - strcpy(s, _("Disabled") ); - return s; + cc->decimal = ','; + cc->grouping = '.'; } + return true; +} - if (routing & SET_ROUTE_SCREEN) - strcat(s, _("Screen") ); +/* Extracts a token from IN into TOKEn. Tokens are delimited by + GROUPING. The token is truncated to at most CC_WIDTH + characters (including null terminator). Returns the first + character following the token. */ +static const char * +extract_cc_token (const char *in, int grouping, char token[CC_WIDTH]) +{ + char *out = token; - if (routing & SET_ROUTE_LISTING) + for (; *in != '\0' && *in != grouping; in++) { - if(s[0] != '\0') - strcat(s,", "); - - strcat(s, _("Listing") ); + if (*in == '\'' && in[1] == grouping) + in++; + if (out < &token[CC_WIDTH - 1]) + *out++ = *in; } + *out = '\0'; - if (routing & SET_ROUTE_OTHER) - { - if(s[0] != '\0') - strcat(s,", "); - strcat(s, _("Other") ); - } - - - return s; - - + if (*in == grouping) + in++; + return in; } -/* Sets *SETTING, which is a combination of SET_ROUTE_* bits that - indicates what to do with some sort of output, to the value - indicated by Q, which is a value provided by the input parser. */ -static void -set_routing (int q, int *setting) +/* Sets custom currency specifier CC having name CC_NAME ('A' through + 'E') to correspond to the settings in CC_STRING. */ +static bool +do_cc (const char *cc_string, int idx) { - switch (q) + struct custom_currency cc; + + /* Determine separators. */ + if (!find_cc_separators (cc_string, &cc)) { - case STC_OFF: - *setting |= SET_ROUTE_DISABLE; - break; - case STC_ON: - *setting &= ~SET_ROUTE_DISABLE; - break; - case STC_TERMINAL: - *setting &= ~(SET_ROUTE_LISTING | SET_ROUTE_OTHER); - *setting |= SET_ROUTE_SCREEN; - break; - case STC_LISTING: - *setting &= ~SET_ROUTE_SCREEN; - *setting |= SET_ROUTE_LISTING | SET_ROUTE_OTHER; - break; - case STC_BOTH: - *setting |= SET_ROUTE_SCREEN | SET_ROUTE_LISTING | SET_ROUTE_OTHER; - break; - case STC_NONE: - *setting &= ~(SET_ROUTE_SCREEN | SET_ROUTE_LISTING | SET_ROUTE_OTHER); - break; - default: - assert (0); + msg (SE, _("CC%c: Custom currency string `%s' does not contain " + "exactly three periods or commas (not both)."), + "ABCDE"[idx], cc_string); + return false; } -} + + cc_string = extract_cc_token (cc_string, cc.grouping, cc.neg_prefix); + cc_string = extract_cc_token (cc_string, cc.grouping, cc.prefix); + cc_string = extract_cc_token (cc_string, cc.grouping, cc.suffix); + cc_string = extract_cc_token (cc_string, cc.grouping, cc.neg_suffix); -static int -stc_custom_pager (struct cmd_set *cmd UNUSED) -{ - lex_match ('='); -#if !USE_INTERNAL_PAGER - if (lex_match_id ("OFF")) - { - if (set_pager) - free (set_pager); - set_pager = NULL; - } - else - { - if (!lex_force_string ()) - return 0; - if (set_pager) - free (set_pager); - set_pager = xstrdup (ds_c_str (&tokstr)); - lex_get (); - } - return 1; -#else /* USE_INTERNAL_PAGER */ - if (lex_match_id ("OFF")) - return 1; - msg (SW, "External pagers not supported."); - return 0; -#endif /* USE_INTERNAL_PAGER */ + set_cc (idx, &cc); + + return true; } /* Parses the BLANKS subcommand, which controls the value that completely blank fields in numeric data imply. X, Wnd: Syntax is - SYSMIS or a numeric value; PC+: Syntax is '.', which is equivalent - to SYSMIS, or a numeric value. */ + SYSMIS or a numeric value. */ static int stc_custom_blanks (struct cmd_set *cmd UNUSED) { lex_match ('='); - if ((token == T_ID && lex_id_match ("SYSMIS", tokid)) - || (token == T_STRING && !strcmp (tokid, "."))) + if ((token == T_ID && lex_id_match ("SYSMIS", tokid))) { lex_get (); - set_blanks = SYSMIS; + set_blanks (SYSMIS); } else { if (!lex_force_num ()) return 0; - set_blanks = tokval; + set_blanks (lex_number ()); lex_get (); } return 1; @@ -652,7 +309,7 @@ stc_custom_epoch (struct cmd_set *cmd UNUSED) { lex_match ('='); if (lex_match_id ("AUTOMATIC")) - set_epoch = -1; + set_epoch (-1); else if (lex_is_integer ()) { int new_epoch = lex_integer (); @@ -662,7 +319,7 @@ stc_custom_epoch (struct cmd_set *cmd UNUSED) msg (SE, _("EPOCH must be 1500 or later.")); return 0; } - set_epoch = new_epoch; + set_epoch (new_epoch); } else { @@ -694,64 +351,23 @@ stc_custom_length (struct cmd_set *cmd UNUSED) lex_get (); } - if ( page_length != -1 ) - set_viewlength = page_length; + if (page_length != -1) + set_viewlength (page_length); return 1; } -static int -stc_custom_results (struct cmd_set *cmd UNUSED) -{ - struct tuple - { - const char *s; - int v; - }; - - static struct tuple tab[] = - { - {"ON", STC_ON}, - {"OFF", STC_OFF}, - {"TERMINAL", STC_TERMINAL}, - {"LISTING", STC_LISTING}, - {"BOTH", STC_BOTH}, - {"NONE", STC_NONE}, - {NULL, 0}, - }; - - struct tuple *t; - - lex_match ('='); - - if (token != T_ID) - { - msg (SE, _("Missing identifier in RESULTS subcommand.")); - return 0; - } - - for (t = tab; t->s; t++) - if (lex_id_match (t->s, tokid)) - { - lex_get (); - set_routing (t->v, &set_results); - return 1; - } - msg (SE, _("Unrecognized identifier in RESULTS subcommand.")); - return 0; -} - static int stc_custom_seed (struct cmd_set *cmd UNUSED) { lex_match ('='); if (lex_match_id ("RANDOM")) - set_rng (random_seed ()); + set_rng (time (0)); else { if (!lex_force_num ()) return 0; - set_rng (tokval); + set_rng (lex_number ()); lex_get (); } @@ -761,27 +377,24 @@ stc_custom_seed (struct cmd_set *cmd UNUSED) static int stc_custom_width (struct cmd_set *cmd UNUSED) { - int page_width; - lex_match ('='); if (lex_match_id ("NARROW")) - page_width = 79; + set_viewwidth (79); else if (lex_match_id ("WIDE")) - page_width = 131; + set_viewwidth (131); else { if (!lex_force_int ()) return 0; - if (lex_integer () < 1) + if (lex_integer () < 40) { - msg (SE, _("WIDTH must be at least 1.")); + msg (SE, _("WIDTH must be at least 40.")); return 0; } - page_width = lex_integer (); + set_viewwidth (lex_integer ()); lex_get (); } - set_viewwidth = page_width; return 1; } @@ -803,7 +416,7 @@ stc_custom_format (struct cmd_set *cmd UNUSED) return 0; } - set_format = fmt; + set_format (&fmt); return 1; } @@ -811,67 +424,15 @@ static int stc_custom_journal (struct cmd_set *cmd UNUSED) { lex_match ('='); - if (lex_match_id ("ON")) - set_journaling = 1; - else if (lex_match_id ("OFF")) - set_journaling = 0; - if (token == T_STRING) + if (!lex_match_id ("ON") && !lex_match_id ("OFF")) { - set_journal = xstrdup (ds_c_str (&tokstr)); - lex_get (); - } - return 1; -} - -/* Parses COLOR subcommand. PC+: either ON or OFF or two or three - comma-delimited numbers inside parentheses. */ -static int -stc_custom_color (struct cmd_set *cmd UNUSED) -{ - msg (MW, _("%s is obsolete."),"COLOR"); - - lex_match ('='); - if (!lex_match_id ("ON") && !lex_match_id ("YES") && !lex_match_id ("OFF") && !lex_match_id ("NO")) - { - if (!lex_force_match ('(')) - return 0; - if (!lex_match ('*')) - { - if (!lex_force_int ()) - return 0; - if (lex_integer () < 0 || lex_integer () > 15) - { - msg (SE, _("Text color must be in range 0-15.")); - return 0; - } - lex_get (); - } - if (!lex_force_match (',')) - return 0; - if (!lex_match ('*')) - { - if (!lex_force_int ()) - return 0; - if (lex_integer () < 0 || lex_integer () > 7) - { - msg (SE, _("Background color must be in range 0-7.")); - return 0; - } - lex_get (); - } - if (lex_match (',') && !lex_match ('*')) - { - if (!lex_force_int ()) - return 0; - if (lex_integer () < 0 || lex_integer () > 7) - { - msg (SE, _("Border color must be in range 0-7.")); - return 0; - } - lex_get (); - } - if (!lex_force_match (')')) - return 0; + if (token == T_STRING) + lex_get (); + else + { + lex_error (NULL); + return 0; + } } return 1; } @@ -879,17 +440,19 @@ stc_custom_color (struct cmd_set *cmd UNUSED) static int stc_custom_listing (struct cmd_set *cmd UNUSED) { + bool listing; + lex_match ('='); if (lex_match_id ("ON") || lex_match_id ("YES")) - set_listing = 1; + listing = true; else if (lex_match_id ("OFF") || lex_match_id ("NO")) - set_listing = 0; + listing = false; else { /* FIXME */ return 0; } - outp_enable_device (set_listing, OUTP_DEV_LISTING); + outp_enable_device (listing, OUTP_DEV_LISTING); return 1; } @@ -899,572 +462,258 @@ stc_custom_disk (struct cmd_set *cmd UNUSED) { return stc_custom_listing (cmd); } - -static int -stc_custom_log (struct cmd_set *cmd UNUSED) -{ - return stc_custom_journal (cmd); -} - -static int -stc_custom_rcolor (struct cmd_set *cmd UNUSED) -{ - msg (SW, _("%s is obsolete."),"RCOLOR"); - - lex_match ('='); - if (!lex_force_match ('(')) - return 0; - - if (!lex_match ('*')) - { - if (!lex_force_int ()) - return 0; - if (lex_integer () < 0 || lex_integer () > 6) - { - msg (SE, _("Lower window color must be between 0 and 6.")); - return 0; - } - lex_get (); - } - if (!lex_force_match (',')) - return 0; - - if (!lex_match ('*')) - { - if (!lex_force_int ()) - return 0; - if (lex_integer () < 0 || lex_integer () > 6) - { - msg (SE, _("Upper window color must be between 0 and 6.")); - return 0; - } - lex_get (); - } - - if (lex_match (',') && !lex_match ('*')) - { - if (!lex_force_int ()) - return 0; - if (lex_integer () < 0 || lex_integer () > 6) - { - msg (SE, _("Frame color must be between 0 and 6.")); - return 0; - } - lex_get (); - } - return 1; -} - -static int -stc_custom_viewwidth (struct cmd_set *cmd UNUSED) -{ - lex_match ('='); - - if ( !lex_force_int() ) - return 0; - - set_viewwidth = lex_integer(); - lex_get(); - - return 1; -} - -static int -stc_custom_viewlength (struct cmd_set *cmd UNUSED) + +static void +show_blanks (void) { - if (lex_match_id ("MINIMUM")) - set_viewlength = 25; - else if (lex_match_id ("MEDIAN")) - set_viewlength = 43; /* This is not correct for VGA displays. */ - else if (lex_match_id ("MAXIMUM")) - set_viewlength = 43; + if (get_blanks () == SYSMIS) + msg (MM, _("BLANKS is SYSMIS.")); else - { - if (!lex_force_int ()) - return 0; -#ifdef __MSDOS__ - if (lex_integer () >= (43 + 25) / 2) - set_viewlength = 43; - else - set_viewlength = 25; -#else /* not dos */ - set_viewlength = lex_integer (); -#endif /* not dos */ - lex_get (); - } - -#ifdef __MSDOS__ - msg (SW, _("%s is not yet implemented."),"VIEWLENGTH"); -#endif /* dos */ - return 1; -} - -static int -stc_custom_workdev (struct cmd_set *cmd UNUSED) -{ - char c[2]; - - msg (SW, _("%s is obsolete."),"WORKDEV"); - - c[1] = 0; - for (*c = 'A'; *c <= 'Z'; (*c)++) - if (token == T_ID && lex_id_match (c, tokid)) - { - lex_get (); - return 1; - } - msg (SE, _("Drive letter expected in WORKDEV subcommand.")); - return 0; -} - - - -static void -set_viewport(int sig_num UNUSED) -{ -#if HAVE_LIBTERMCAP - static char term_buffer[16384]; -#endif - - set_viewwidth = -1; - set_viewlength = -1; - -#if __DJGPP__ || __BORLANDC__ - { - struct text_info ti; - - gettextinfo (&ti); - set_viewlength = max (ti.screenheight, 25); - set_viewwidth = max (ti.screenwidth, 79); - } -#elif HAVE_LIBTERMCAP - { - char *termtype; - int success; - - /* This code stolen from termcap.info, though modified. */ - termtype = getenv ("TERM"); - if (!termtype) - msg (FE, _("Specify a terminal type with the TERM environment variable.")); - - success = tgetent (term_buffer, termtype); - if (success <= 0) - { - if (success < 0) - msg (IE, _("Could not access the termcap data base.")); - else - msg (IE, _("Terminal type `%s' is not defined."), termtype); - } - else - { - /* NOTE: Do not rely upon tgetnum returning -1 if the value is - not available. It's supposed to do it, but not all platforms - do (eg Cygwin) . - */ - if ( -1 != tgetnum("li")) - set_viewlength = tgetnum ("li"); - - if ( -1 != tgetnum("co")) - set_viewwidth = tgetnum ("co") - 1; - } - } -#endif /* HAVE_LIBTERMCAP */ - - /* Try the environment variables */ - if ( -1 == set_viewwidth ) - { - char *s = getenv("COLUMNS"); - if ( s ) set_viewwidth = atoi(s); - } - - if ( -1 == set_viewwidth ) - { - char *s = getenv("LINES"); - if ( s ) set_viewlength = atoi(s); - } - - - /* Last resort. Use hard coded values */ - if ( 0 > set_viewwidth ) set_viewwidth = 79; - if ( 0 > set_viewlength ) set_viewlength = 24; - -} - -/* Public functions */ - -void -done_settings(void) -{ - if ( rng ) - gsl_rng_free (rng); - free (set_pager); - free (set_journal); - - free (cmd.s_endcmd); - free (cmd.s_prompt); - free (cmd.s_cprompt); - free (cmd.s_dprompt); -} - - - -void -init_settings(void) -{ - cmd.s_dprompt = xstrdup (_("data> ")); - cmd.s_cprompt = xstrdup (" > "); - cmd.s_prompt = xstrdup ("PSPP> "); - cmd.s_endcmd = xstrdup ("."); - - assert(cmd.safe == 0 ); - cmd.safe = STC_OFF; - - cmd.dec = STC_DOT; - cmd.n_cpi[0] = 6; - cmd.n_lpi[0] = 10; - cmd.echo = STC_OFF; - cmd.more = STC_ON; - cmd.headers = STC_YES; - cmd.errbrk = STC_OFF; - - cmd.scompress = STC_OFF; - cmd.undef = STC_WARN; - cmd.mprint = STC_ON ; - cmd.prtbck = STC_ON ; - cmd.null = STC_ON ; - cmd.inc = STC_ON ; - - set_journal = xstrdup ("pspp.jnl"); - set_journaling = 1; - - cmd.n_mxwarns[0] = 100; - cmd.n_mxerrs[0] = 100; - cmd.n_mxloops[0] = 1; - cmd.n_workspace[0] = 4L * 1024 * 1024; - - -#if !USE_INTERNAL_PAGER - { - const char *pager = getenv ("STAT_PAGER"); - - if (!pager) - { - const char *p = getenv ("PAGER"); - - if ( p != NULL ) - set_pager = xstrdup (p); - else - set_pager = 0; - } - - - if (pager) - set_pager = xstrdup (pager); -#if DEFAULT_PAGER - else - set_pager = xstrdup (DEFAULT_PAGER); -#endif /* DEFAULT_PAGER */ - } -#endif /* !USE_INTERNAL_PAGER */ - - - { - int i; - - for (i = 0; i < 5; i++) - { - struct set_cust_currency *cc = &set_cc[i]; - strcpy (cc->buf, "-"); - cc->neg_prefix = cc->buf; - cc->prefix = &cc->buf[1]; - cc->suffix = &cc->buf[1]; - cc->neg_suffix = &cc->buf[1]; - cc->decimal = '.'; - cc->grouping = ','; - } - } - - if ( ! long_view ) - { - set_viewport (0); - signal (SIGWINCH, set_viewport); - } - -} - -void -force_long_view(void) -{ - long_view = 1; - set_viewwidth=9999; -} - -int -safer_mode(void) -{ - return !(cmd.safe != STC_ON) ; -} + msg (MM, _("BLANKS is %g."), get_blanks ()); - -/* Set safer mode */ -void -make_safe(void) -{ - cmd.safe = STC_ON; -} - - -char -get_decimal(void) -{ - return (cmd.dec == STC_DOT ? '.' : ','); } -int -get_epoch (void) +static char * +format_cc (const char *in, char grouping, char *out) { - if (set_epoch < 0) + while (*in != '\0') { - time_t t = time (0); - struct tm *tm = localtime (&t); - if (tm != NULL) - set_epoch = (tm->tm_year + 1900) - 69; - else - set_epoch = 2000 - 69; + if (*in == grouping || *in == '\'') + *out++ = '\''; + *out++ = *in++; } - - return set_epoch; + return out; } -char -get_grouping(void) -{ - return (cmd.dec == STC_DOT ? ',' : '.'); -} - - -char * -get_prompt(void) -{ - return cmd.s_prompt; -} - -char * -get_dprompt(void) -{ - return cmd.s_dprompt; -} - -char * -get_cprompt(void) -{ - return cmd.s_cprompt; -} - - -int -get_echo(void) -{ - return (cmd.echo != STC_OFF ); -} - - -int -get_errorbreak(void) -{ - return (cmd.errbrk != STC_OFF); +static void +show_cc (int idx) +{ + const struct custom_currency *cc = get_cc (idx); + char cc_string[CC_WIDTH * 4 * 2 + 3 + 1]; + char *out; + + out = format_cc (cc->neg_prefix, cc->grouping, cc_string); + *out++ = cc->grouping; + out = format_cc (cc->prefix, cc->grouping, out); + *out++ = cc->grouping; + out = format_cc (cc->suffix, cc->grouping, out); + *out++ = cc->grouping; + out = format_cc (cc->neg_suffix, cc->grouping, out); + *out = '\0'; + + msg (MM, _("CC%c is \"%s\"."), "ABCDE"[idx], cc_string); } -int -get_scompression(void) +static void +show_cca (void) { - return (cmd.scompress != STC_OFF ); + show_cc (0); } -int -get_undefined(void) +static void +show_ccb (void) { - return (cmd.undef != STC_NOWARN); -} - -int -get_mxwarns(void) -{ - return cmd.n_mxwarns[0]; + show_cc (1); } -int -get_mxerrs(void) +static void +show_ccc (void) { - return cmd.n_mxerrs[0]; + show_cc (2); } -int -get_mprint(void) +static void +show_ccd (void) { - return ( cmd.mprint != STC_OFF ); + show_cc (3); } -int -get_printback(void) +static void +show_cce (void) { - return (cmd.prtbck != STC_OFF ); + show_cc (4); } -int -get_mxloops(void) +static void +show_decimals (void) { - return cmd.n_mxloops[0]; + msg (MM, _("DECIMAL is \"%c\"."), get_decimal ()); } -int -get_nullline(void) +static void +show_endcmd (void) { - return (cmd.null != STC_OFF ); + msg (MM, _("ENDCMD is \"%c\"."), get_endcmd ()); } -int -get_include(void) +static void +show_format (void) { - return (cmd.inc != STC_OFF ); + msg (MM, _("FORMAT is %s."), fmt_to_string (get_format ())); } -char -get_endcmd(void) +static void +show_length (void) { - return cmd.s_endcmd[0]; + msg (MM, _("LENGTH is %d."), get_viewlength ()); } - -size_t -get_max_workspace(void) +static void +show_mxerrs (void) { - return cmd.n_workspace[0]; + msg (MM, _("MXERRS is %d."), get_mxerrs ()); } -double -get_blanks(void) +static void +show_mxloops (void) { - return set_blanks; -} - -struct fmt_spec -get_format(void) -{ - return set_format; + msg (MM, _("MXLOOPS is %d."), get_mxloops ()); } -/* CCA through CCE. */ -const struct set_cust_currency * -get_cc(int i) +static void +show_mxwarns (void) { - return &set_cc[i]; + msg (MM, _("MXWARNS is %d."), get_mxwarns ()); } -void -aux_show_warranty(void) +static void +show_scompression (void) { - msg(MM,lack_of_warranty); + if (get_scompression ()) + msg (MM, _("SCOMPRESSION is ON.")); + else + msg (MM, _("SCOMPRESSION is OFF.")); } -void -aux_show_copying(void) +static void +show_undefined (void) { - msg(MM,copyleft); + if (get_undefined ()) + msg (MM, _("UNDEFINED is WARN.")); + else + msg (MM, _("UNDEFINED is NOWARN.")); } - -int -get_viewlength(void) +static void +show_weight (void) { - return set_viewlength; + struct variable *var = dict_get_weight (default_dict); + if (var == NULL) + msg (MM, _("WEIGHT is off.")); + else + msg (MM, _("WEIGHT is variable %s."), var->name); } -int -get_viewwidth(void) +static void +show_width (void) { - return set_viewwidth; + msg (MM, _("WIDTH is %d."), get_viewwidth ()); } -const char * -get_pager(void) -{ - return set_pager; -} +struct show_sbc + { + const char *name; + void (*function) (void); + }; -gsl_rng * -get_rng (void) -{ - if (rng == NULL) - set_rng (random_seed ()); - return rng; -} +struct show_sbc show_table[] = + { + {"BLANKS", show_blanks}, + {"CCA", show_cca}, + {"CCB", show_ccb}, + {"CCC", show_ccc}, + {"CCD", show_ccd}, + {"CCE", show_cce}, + {"DECIMALS", show_decimals}, + {"ENDCMD", show_endcmd}, + {"FORMAT", show_format}, + {"LENGTH", show_length}, + {"MXERRS", show_mxerrs}, + {"MXLOOPS", show_mxloops}, + {"MXWARNS", show_mxwarns}, + {"SCOMPRESSION", show_scompression}, + {"UNDEFINED", show_undefined}, + {"WEIGHT", show_weight}, + {"WIDTH", show_width}, + }; static void -set_rng (unsigned long seed) +show_all (void) { - rng = gsl_rng_alloc (gsl_rng_mt19937); - if (rng == NULL) - xalloc_die (); - gsl_rng_set (rng, seed); + size_t i; + + for (i = 0; i < sizeof show_table / sizeof *show_table; i++) + show_table[i].function (); } -static unsigned long -random_seed (void) +static void +show_all_cc (void) { - return time (0); -} + int i; -static int global_algorithm = ENHANCED; -static int cmd_algorithm = ENHANCED; -static int *algorithm = &global_algorithm; - -static int syntax = ENHANCED; - -/* Set the algorithm option globally */ -void -set_algorithm(int x) -{ - global_algorithm = x; + for (i = 0; i < 5; i++) + show_cc (i); } -/* Set the algorithm option for this command only */ -void -set_cmd_algorithm(int x) +static void +show_warranty (void) { - cmd_algorithm = x; - algorithm = &cmd_algorithm; + msg (MM, lack_of_warranty); } -/* Unset the algorithm option for this command */ -void -unset_cmd_algorithm(void) +static void +show_copying (void) { - algorithm = &global_algorithm; + msg (MM, copyleft); } -/* Return the current algorithm setting */ int -get_algorithm(void) +cmd_show (void) { - return *algorithm; -} + if (token == '.') + { + show_all (); + return CMD_SUCCESS; + } -/* Set the syntax option */ -void -set_syntax(int x) -{ - syntax = x; -} + do + { + if (lex_match (T_ALL)) + show_all (); + else if (lex_match_id ("CC")) + show_all_cc (); + else if (lex_match_id ("WARRANTY")) + show_warranty (); + else if (lex_match_id ("COPYING")) + show_copying (); + else if (token == T_ID) + { + int i; + + for (i = 0; i < sizeof show_table / sizeof *show_table; i++) + if (lex_match_id (show_table[i].name)) + { + show_table[i].function (); + goto found; + } + lex_error (NULL); + return CMD_PART_SUCCESS_MAYBE; + + found: ; + } + else + { + lex_error (NULL); + return CMD_PART_SUCCESS_MAYBE; + } -/* Get the current syntax setting */ -int -get_syntax(void) -{ - return syntax; -} + lex_match ('/'); + } + while (token != '.'); + return CMD_SUCCESS; +} /* Local Variables: diff --git a/src/settings.c b/src/settings.c new file mode 100644 index 00000000..749757bc --- /dev/null +++ b/src/settings.c @@ -0,0 +1,619 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + Written by Ben Pfaff . + + 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 the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include "settings.h" +#include +#include +#include "format.h" +#include "val.h" +#include "xalloc.h" + +static int viewlength = 24; +static int viewwidth = 79; +static bool long_view = false; + +static bool safer_mode = false; + +static char decimal = '.'; +static char grouping = ','; + +static char *prompt = NULL; +static char *cprompt = NULL; +static char *dprompt = NULL; + +static bool echo = false; +static bool include = true; + +static int epoch = -1; + +static bool errorbreak = false; + +static bool scompress = false; + +static bool undefined = true; +static double blanks = SYSMIS; + +static int mxwarns = 100; +static int mxerrs = 100; + +static bool printback = true; +static bool mprint = true; + +static int mxloops = 1; + +static bool nulline = true; + +static char endcmd = '.'; + +static size_t workspace = 4L * 1024 * 1024; + +static struct fmt_spec default_format = {FMT_F, 8, 2}; + +#define CC_CNT 5 +#define CC_INITIALIZER {"-", "", "", "", '.', ','} +static struct custom_currency cc[CC_CNT] = + { + CC_INITIALIZER, + CC_INITIALIZER, + CC_INITIALIZER, + CC_INITIALIZER, + CC_INITIALIZER, + }; + +static gsl_rng *rng; + +static bool testing_mode = false; + +static int global_algorithm = ENHANCED; +static int cmd_algorithm = ENHANCED; +static int *algorithm = &global_algorithm; + +static int syntax = ENHANCED; + +static void init_viewport (void); + +void +done_settings (void) +{ + if (rng != NULL) + gsl_rng_free (rng); + + free (prompt); + free (cprompt); + free (dprompt); +} + +void +init_settings (void) +{ + init_viewport (); +} + +/* Screen length in lines. */ +int +get_viewlength (void) +{ + return viewlength; +} + +/* Sets the view length. */ +void +set_viewlength (int viewlength_) +{ + viewlength = viewlength_; +} + +/* Set view width to a very long value, and prevent it from ever + changing. */ +void +force_long_view (void) +{ + long_view = true; + viewwidth = 9999; +} + +/* Screen width. */ +int +get_viewwidth(void) +{ + return viewwidth; +} + +/* Sets the screen width. */ +void +set_viewwidth (int viewwidth_) +{ + viewwidth = viewwidth_; +} + +#if HAVE_LIBTERMCAP +static void +get_termcap_viewport (void) +{ + char term_buffer[16384]; + if (getenv ("TERM") == NULL) + return; + else if (tgetent (term_buffer, getenv ("TERM")) <= 0) + { + msg (IE, _("Could not access definition for terminal `%s'."), termtype); + return; + } + + if (tgetnum ("li") > 0) + viewlength = tgetnum ("li"); + + if (tgetnum ("co") > 1) + viewwidth = tgetnum ("co") - 1; +} +#endif /* HAVE_LIBTERMCAP */ + +static void +init_viewport (void) +{ + if (long_view) + return; + + viewwidth = viewlength = -1; + +#if HAVE_LIBTERMCAP + get_termcap_viewport (); +#endif /* HAVE_LIBTERMCAP */ + + if (viewwidth < 0 && getenv ("COLUMNS") != NULL) + viewwidth = atoi (getenv ("COLUMNS")); + if (viewlength < 0 && getenv ("LINES") != NULL) + viewlength = atoi (getenv ("LINES")); + + if (viewwidth < 0) + viewwidth = 79; + if (viewlength < 0) + viewlength = 24; +} + +/* Whether PSPP can erase and overwrite files. */ +bool +get_safer_mode (void) +{ + return safer_mode; +} + +/* Set safer mode. */ +void +set_safer_mode (void) +{ + safer_mode = true; +} + +/* The character used for a decimal point: ',' or '.'. Only + respected for data input and output. */ +char +get_decimal (void) +{ + return decimal; +} + +/* Sets the character used for a decimal point, which must be + either ',' or '.'. */ +void +set_decimal (char decimal_) +{ + assert (decimal_ == '.' || decimal_ == ','); + decimal = decimal_; +} + +/* The character used for grouping in numbers: '.' or ','; the + opposite of set_decimal. Only used in COMMA data input and + output. */ +char +get_grouping (void) +{ + return grouping; +} + +/* Sets the character used for grouping, which must be either ',' + or '.'. */ +void +set_grouping (char grouping_) +{ + assert (grouping_ == '.' || grouping_ == ','); + grouping = grouping_; +} + +/* Gets the normal command prompt. */ +const char * +get_prompt (void) +{ + return prompt != NULL ? prompt : "PSPP> "; +} + +/* Sets the normal command prompt. */ +void +set_prompt (const char *prompt_) +{ + free (prompt); + prompt = xstrdup (prompt_); +} + +/* Gets the prompt used for data (after BEGIN DATA and before END + DATA). */ +const char * +get_dprompt (void) +{ + return dprompt != NULL ? dprompt : "data> "; +} + +/* Sets the prompt used for data (after BEGIN DATA and before END + DATA). */ +void +set_dprompt (const char *dprompt_) +{ + free (dprompt); + dprompt = xstrdup (dprompt_); +} + +/* Gets the continuation prompt used for second and subsequent + lines of commands. */ +const char * +get_cprompt (void) +{ + return cprompt != NULL ? cprompt : " > "; +} + +/* Sets the continuation prompt used for second and subsequent + lines of commands. */ +void +set_cprompt (const char *cprompt_) +{ + free (cprompt); + cprompt = xstrdup (cprompt_); +} + +/* Echo commands to the listing file/printer? */ +bool +get_echo (void) +{ + return echo; +} + +/* Set echo. */ +void +set_echo (bool echo_) +{ + echo = echo_; +} + +/* If echo is on, whether commands from include files are echoed. */ +bool +get_include (void) +{ + return include; +} + +/* Set include file echo. */ +void +set_include (bool include_) +{ + include = include_; +} + +/* What year to use as the start of the epoch. */ +int +get_epoch (void) +{ + if (epoch < 0) + { + time_t t = time (0); + struct tm *tm = localtime (&t); + epoch = (tm != NULL ? tm->tm_year + 1900 : 2000) - 69; + } + + return epoch; +} + +/* Sets the year that starts the epoch. */ +void +set_epoch (int epoch_) +{ + epoch = epoch_; +} + +/* Does an error stop execution? */ +bool +get_errorbreak (void) +{ + return errorbreak; +} + +/* Sets whether an error stops execution. */ +void +set_errorbreak (bool errorbreak_) +{ + errorbreak = errorbreak_; +} + +/* Compress system files by default? */ +bool +get_scompression (void) +{ + return scompress; +} + +/* Set system file default compression. */ +void +set_scompression (bool scompress_) +{ + scompress = scompress_; +} + +/* Whether to warn on undefined values in numeric data. */ +bool +get_undefined (void) +{ + return undefined; +} + +/* Set whether to warn on undefined values. */ +void +set_undefined (bool undefined_) +{ + undefined = undefined_; +} + +/* The value that blank numeric fields are set to when read in. */ +double +get_blanks (void) +{ + return blanks; +} + +/* Set the value that blank numeric fields are set to when read + in. */ +void +set_blanks (double blanks_) +{ + blanks = blanks_; +} + +/* Maximum number of warnings + errors. */ +int +get_mxwarns (void) +{ + return mxwarns; +} + +/* Sets maximum number of warnings + errors. */ +void +set_mxwarns (int mxwarns_) +{ + mxwarns = mxwarns_; +} + +/* Maximum number of errors. */ +int +get_mxerrs (void) +{ + return mxerrs; +} + +/* Sets maximum number of errors. */ +void +set_mxerrs (int mxerrs_) +{ + mxerrs = mxerrs_; +} + +/* Whether commands are written to the display. */ +bool +get_printback (void) +{ + return printback; +} + +/* Sets whether commands are written to the display. */ +void +set_printback (bool printback_) +{ + printback = printback_; +} + +/* Independent of get_printback, controls whether the commands + generated by macro invocations are displayed. */ +bool +get_mprint (void) +{ + return mprint; +} + +/* Sets whether the commands generated by macro invocations are + displayed. */ +void +set_mprint (bool mprint_) +{ + mprint = mprint_; +} + +/* Implied limit of unbounded loop. */ +int +get_mxloops (void) +{ + return mxloops; +} + +/* Set implied limit of unbounded loop. */ +void +set_mxloops (int mxloops_) +{ + mxloops = mxloops_; +} + +/* Whether a blank line is a command terminator. */ +bool +get_nulline (void) +{ + return nulline; +} + +/* Set whether a blank line is a command terminator. */ +void +set_nulline (bool nulline_) +{ + nulline = nulline_; +} + +/* The character used to terminate commands. */ +char +get_endcmd (void) +{ + return endcmd; +} + +/* Set the character used to terminate commands. */ +void +set_endcmd (char endcmd_) +{ + endcmd = endcmd_; +} + +/* Approximate maximum amount of memory to use for cases, in + bytes. */ +size_t +get_workspace(void) +{ + return workspace; +} + +/* Set approximate maximum amount of memory to use for cases, in + bytes. */ + +void +set_workspace (size_t workspace_) +{ + workspace = workspace_; +} + +/* Default format for variables created by transformations and by + DATA LIST {FREE,LIST}. */ +const struct fmt_spec * +get_format (void) +{ + return &default_format; +} + +/* Set default format for variables created by transformations + and by DATA LIST {FREE,LIST}. */ +void +set_format (const struct fmt_spec *default_format_) +{ + default_format = *default_format_; +} + +/* Gets the custom currency specification with the given IDX. */ +const struct custom_currency * +get_cc (int idx) +{ + assert (idx >= 0 && idx < CC_CNT); + return &cc[idx]; +} + +/* Gets custom currency specification IDX to CC. */ +void +set_cc (int idx, const struct custom_currency *cc_) +{ + assert (idx >= 0 && idx < CC_CNT); + cc[idx] = *cc_; +} + +/* Returns the current random number generator. */ +gsl_rng * +get_rng (void) +{ + if (rng == NULL) + set_rng (time (0)); + return rng; +} + +/* Initializes or reinitializes the random number generator with + the given SEED. */ +void +set_rng (unsigned long seed) +{ + rng = gsl_rng_alloc (gsl_rng_mt19937); + if (rng == NULL) + xalloc_die (); + gsl_rng_set (rng, seed); +} + +/* Are we in testing mode? (e.g. --testing-mode command line + option) */ +bool +get_testing_mode (void) +{ + return testing_mode; +} + +/* Set testing mode. */ +void +set_testing_mode (bool testing_mode_) +{ + testing_mode = testing_mode_; +} + +/* Return the current algorithm setting */ +enum behavior_mode +get_algorithm (void) +{ + return *algorithm; +} + +/* Set the algorithm option globally. */ +void +set_algorithm (enum behavior_mode mode) +{ + global_algorithm = mode; +} + +/* Set the algorithm option for this command only */ +void +set_cmd_algorithm (enum behavior_mode mode) +{ + cmd_algorithm = mode; + algorithm = &cmd_algorithm; +} + +/* Unset the algorithm option for this command */ +void +unset_cmd_algorithm (void) +{ + algorithm = &global_algorithm; +} + +/* Get the current syntax setting */ +enum behavior_mode +get_syntax (void) +{ + return syntax; +} + +/* Set the syntax option */ +void +set_syntax (enum behavior_mode mode) +{ + syntax = mode; +} diff --git a/src/settings.h b/src/settings.h index 8cff528e..9e620925 100644 --- a/src/settings.h +++ b/src/settings.h @@ -20,102 +20,8 @@ #if !settings_h #define settings_h 1 -/* Table of mode settings (x=X, w=Windows, p=PC+, f=has relevance for - PSPP): - - AUTOMENU: p - BEEP: p - BLANKS: xwpf - BLKSIZE: x (only on SHOW, not on SET) - BLOCK: xwp - BOX/BOXSTRING: xwp - BUFNO: x (only on SHOW, not on SET) - CASE: xw - CCA...CCE: xwf - COLOR: p - COMP/COMPRESSION: xwpf (meaning varies between p and xw) - CPI: xwp - CPROMPT: pf - DECIMAL: wf - DPROMPT: f - ECHO: pf - EJECT: p - EMULATION: f - ENDCMD: xpf - ERRORBREAK: pf - ERRORS: wf - FORMAT: xwf - HEADERS: xwf - HELPWINDOWS: p - HIGHRES: w - HISTOGRAM: xp - INCLUDE: pf - JOURNAL: wf (equivalent to LOG) - LENGTH: xwp - LISTING: xpf - LOG: pf (equivalent to JOURNAL) - LOWRES: w - LPI: xwp - MENUS: p - MESSAGES: wf - MEXPAND: xwf - MITERATE: xwf - MNEST: xwf - MORE: pf - MPRINT: xwf - MXERRS: xf - MXLOOPS: xwf - MXMEMORY: w - MXWARNS: xwf - N: xw (only on SHOW, not on SET) - NULLINE: xpf - NUMBERED: x (only on SHOW, not on SET) - PAGER: f - PRINTBACK: xwf - PRINTER: pf - PROMPT: pf - PTRANSLATE: p - RCOLOR: p - RESULTS: wpf (semantics differ) - RUNREVIEW: p - SCOMP/SCOMPRESSION: xwf - SCREEN: pf - SCRIPTTAB: xw - SEED: xwpf (semantics differ) - SYSMIS: xwf (only on SHOW, not on SET) - TBFONTS: xw - TB1: xw - TB2: x - UNDEFINED: xwf - VIEWLENGTH: pf - VIEWWIDTH: f - WEIGHT: xwf (only on SHOW, not on SET) - WIDTH: xwp - WORKDEV: p - WORKSPACE: w - XSORT: x - $VARS: wf (only on SHOW, not on SET) - - */ - +#include #include -#include - - -/* Describes one custom currency specification. */ -struct set_cust_currency - { - char buf[32]; /* Buffer for strings. */ - char *neg_prefix; /* Negative prefix. */ - char *prefix; /* Prefix. */ - char *suffix; /* Suffix. */ - char *neg_suffix; /* Negative suffix. */ - int decimal; /* Decimal point. */ - int grouping; /* Grouping character. */ - }; - - - /* Types of routing. */ enum @@ -126,135 +32,108 @@ enum SET_ROUTE_DISABLE = 010 /* Disable output--overrides all other bits. */ }; +void init_settings (void); +void done_settings (void); -/* Set view width to a very long value, and prevent it from - ever changing */ -void force_long_view(void); - - -/* Requested "view length" in lines. */ -int get_viewlength(void); +void force_long_view (void); +int get_viewlength (void); +void set_viewlength (int); -/* Screen width. */ -int get_viewwidth(void); +int get_viewwidth (void); +void set_viewwidth (int); -void init_settings(void) ; -void done_settings(void) ; +bool get_safer_mode (void); +void set_safer_mode (void); -/* Whether pspp can erase and overwrite files */ -int safer_mode(void); +char get_decimal (void); +void set_decimal (char); +char get_grouping (void); +void set_grouping (char); -/* Put into safer mode */ -void make_safe(void); +const char *get_prompt (void); +void set_prompt (const char *); +const char *get_cprompt (void); +void set_cprompt (const char *); +const char *get_dprompt (void); +void set_dprompt (const char *); -/* The character used for a decimal point: ',' or '.'. Only respected - for data input and output. */ -char get_decimal(void); +bool get_echo (void); +void set_echo (bool); +bool get_include (void); +void set_include (bool); -/* The character used for grouping in numbers: '.' or ','; the - opposite of set_decimal. Only used in COMMA data input and - output. */ - -char get_grouping(void); - -char *get_prompt(void); - -/* Prompt used for lines between BEGIN DATA and END DATA. */ -char *get_dprompt(void); - -/* Continuation prompt. */ -char *get_cprompt(void); - - -/* Whether we echo commands to the listing file/printer;*/ -int get_echo(void); - -/* What year to use as the start of the epoch. */ int get_epoch (void); +void set_epoch (int); -/* If echo is on, whether commands from include files are echoed */ -int get_include(void); - -/* Whether an error stops execution; */ -int get_errorbreak(void); - -/* Whether save files should be compressed by default. */ -int get_scompression(void); +bool get_errorbreak (void); +void set_errorbreak (bool); -/* Whether to warn on undefined values in numeric data. */ -int get_undefined(void); +bool get_scompression (void); +void set_scompression (bool); -/* Maximum number of warnings + errors. */ -int get_mxwarns(void); +bool get_undefined (void); +void set_undefined (bool); +double get_blanks (void); +void set_blanks (double); -/* Maximum number of errors. */ -int get_mxerrs(void); +int get_mxwarns (void); +void set_mxwarns (int); +int get_mxerrs (void); +void set_mxerrs (int); -/* 0=macro expansion is disabled, 1=macro expansion is enabled. */ -int get_mexpand(void); +bool get_printback (void); +void set_printback (bool); +bool get_mprint (void); +void set_mprint (bool); -/* Whether commands are written to the display */ -int get_printback(void); +int get_mxloops (void); +void set_mxloops (int); -/* Independent of get_printback, controls whether the commands - generated by macro invocations are displayed. */ -int get_mprint(void); +bool get_nulline (void); +void set_nulline (bool); -/* Implied limit of unbounded loop. */ -int get_mxloops(void); +char get_endcmd (void); +void set_endcmd (char); -/* Whether a blank line is a command terminator */ -int get_nullline(void); +size_t get_workspace (void); +void set_workspace (size_t); -/* The character used to terminate commands. */ -char get_endcmd(void); +const struct fmt_spec *get_format (void); +void set_format (const struct fmt_spec *); -/* Approximate maximum amount of memory to use for cases, in - bytes. */ -size_t get_max_workspace(void); - -/* The value that blank numeric fields are set to when read in; - normally SYSMIS. */ -double get_blanks(void); - - -/* Default format for variables created by transformations and by DATA - LIST {FREE,LIST}. */ -struct fmt_spec get_format(void); - -/* CCA through CCE. */ -const struct set_cust_currency *get_cc(int i); - -#if !USE_INTERNAL_PAGER -/* Name of the pager program. */ -const char *get_pager(void); -#endif /* !USE_INTERNAL_PAGER */ +/* One custom currency specification. */ +#define CC_WIDTH 16 +struct custom_currency + { + char neg_prefix[CC_WIDTH]; /* Negative prefix. */ + char prefix[CC_WIDTH]; /* Prefix. */ + char suffix[CC_WIDTH]; /* Suffix. */ + char neg_suffix[CC_WIDTH]; /* Negative suffix. */ + char decimal; /* Decimal point. */ + char grouping; /* Grouping character. */ + }; +const struct custom_currency *get_cc (int idx); +void set_cc (int idx, const struct custom_currency *); #include -gsl_rng *get_rng (void); - - -enum {ENHANCED,COMPATIBLE}; - - -/* Set the algorithm option globally */ -void set_algorithm(int x); - -/* Set the algorithm option for this command only */ -void set_cmd_algorithm(int x); - -/* Unset the algorithm option for this command */ -void unset_cmd_algorithm(void); - -/* Return the current algorithm setting */ -int get_algorithm(void); - -/* Set the syntax option */ -void set_syntax(int x); - -/* Get the current syntax setting */ -int get_syntax(void); +gsl_rng *get_rng (void); +void set_rng (unsigned long seed); + +bool get_testing_mode (void); +void set_testing_mode (bool); + +enum behavior_mode { + ENHANCED, /* Use improved PSPP behavior. */ + COMPATIBLE /* Be as compatible as possible. */ +}; + +enum behavior_mode get_algorithm (void); +void set_algorithm (enum behavior_mode); +enum behavior_mode get_syntax (void); +void set_syntax(enum behavior_mode); +void set_cmd_algorithm (enum behavior_mode); +void unset_cmd_algorithm (void); #endif /* !settings_h */ diff --git a/src/sort.c b/src/sort.c index 47cd6a09..8dad3566 100644 --- a/src/sort.c +++ b/src/sort.c @@ -72,7 +72,7 @@ cmd_sort_cases (void) if (criteria == NULL) return CMD_FAILURE; - if (test_mode && lex_match ('/')) + if (get_testing_mode () && lex_match ('/')) { if (!lex_force_match_id ("BUFFERS") || !lex_match ('=') || !lex_force_int ()) @@ -443,7 +443,7 @@ allocate_cases (struct initial_run_state *irs) approx_case_cost = (sizeof *irs->records + irs->xsrt->value_cnt * sizeof (union value) + 4 * sizeof (void *)); - max_cases = get_max_workspace() / approx_case_cost; + max_cases = get_workspace() / approx_case_cost; if (max_cases > max_buffers) max_cases = max_buffers; irs->records = nmalloc (sizeof *irs->records, max_cases); @@ -462,7 +462,7 @@ allocate_cases (struct initial_run_state *irs) msg (SE, _("Out of memory. Could not allocate room for minimum of %d " "cases of %d bytes each. (PSPP workspace is currently " "restricted to a maximum of %d KB.)"), - min_buffers, approx_case_cost, get_max_workspace() / 1024); + min_buffers, approx_case_cost, get_workspace() / 1024); return 0; } return 1; -- 2.30.2