X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fset.q;h=8df84654710ac041d282ceecf59bb5ea6b653e0f;hb=6d2a8977cc6a54e9e2278467f2af3d5ae277cd43;hp=c4f80326b905f95507e34a65eb19cd8f961a03f1;hpb=f61e279fa8d35fa2f9c5ef6d5d0e628147ccde60;p=pspp diff --git a/src/set.q b/src/set.q index c4f80326b9..8df8465471 100644 --- a/src/set.q +++ b/src/set.q @@ -14,119 +14,44 @@ 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., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ -/* - Categories of SET subcommands: - - data input: BLANKS, DECIMAL, FORMAT. - - 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 +#include "error.h" #include #include #include +#include #include "alloc.h" #include "command.h" +#include "dictionary.h" #include "lexer.h" #include "error.h" #include "magic.h" -#include "log.h" #include "output.h" +#include "random.h" #include "var.h" #include "format.h" +#include "copyleft.h" +#include "var.h" + + +#if HAVE_LIBTERMCAP +#if HAVE_TERMCAP_H +#include +#else /* !HAVE_TERMCAP_H */ +int tgetent (char *, const char *); +int tgetnum (const char *); +#endif /* !HAVE_TERMCAP_H */ +#endif /* !HAVE_LIBTERMCAP */ -double set_blanks; -int set_compression; -struct set_cust_currency set_cc[5]; -int set_cpi; -char *set_cprompt; -int set_decimal; -int set_grouping; -char *set_dprompt; -int set_echo; -int set_endcmd; -int set_errorbreak; -int set_errors, set_messages, set_results; -struct fmt_spec set_format; -int set_headers; -int set_include; -char *set_journal; -int set_journaling; -int set_lpi; -int set_messages; -int set_mexpand; -int set_miterate; -int set_mnest; -int set_more; -int set_mprint; -int set_mxerrs; -int set_mxloops; -int set_mxwarns; -int set_nullline; -int set_printback; -int set_output = 1; -#if !USE_INTERNAL_PAGER -char *set_pager; -#endif /* !USE_INTERNAL_PAGER */ -int set_printer; -char *set_prompt; -char *set_results_file; -int set_safer; -int set_scompression; -int set_screen; -long set_seed; -int set_testing_mode; -int set_undefined; -int set_viewlength; -int set_viewwidth; - -static void set_routing (int q, int *setting); -static int set_ccx (const char *cc_string, struct set_cust_currency * cc, - int cc_name); +#include "gettext.h" +#define _(msgid) gettext (msgid) /* (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"; @@ -136,409 +61,277 @@ static int set_ccx (const char *cc_string, struct set_cust_currency * cc, ccc=string; ccd=string; cce=string; - color=custom; compression=compress:on/off; - cpi=integer; + cpi=integer "x>0" "%s must be greater than 0"; cprompt=string; - decimal=dec:dot/_comma; + decimal=dec:dot/comma; 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; + lpi=integer "x>0" "%s must be greater than 0"; menus=menus:standard/extended; messages=messages:on/off/terminal/listing/both/none; mexpand=mexp:on/off; - miterate=integer; - mnest=integer; - more=more:on/off; + miterate=integer "x>0" "%s must be greater than 0"; + mnest=integer "x>0" "%s must be greater than 0"; mprint=mprint:on/off; - mxerrs=integer; - mxloops=integer; + 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=integer; width=custom; - workdev=custom; - workspace=integer; + workspace=integer "x>=1024" "%s must be at least 1 MB"; xsort=xsort:yes/no. */ /* (declarations) */ -/* (functions) */ -int internal_cmd_set (void); +/* (_functions) */ + +static bool do_cc (const char *cc_string, int idx); int cmd_set (void) { struct cmd_set cmd; - - lex_match_id ("SET"); + bool ok = true; if (!parse_set (&cmd)) return CMD_FAILURE; + if (cmd.sbc_cca) + ok = ok && do_cc (cmd.s_cca, 0); + if (cmd.sbc_ccb) + ok = ok && do_cc (cmd.s_ccb, 1); + if (cmd.sbc_ccc) + ok = ok && do_cc (cmd.s_ccc, 2); + if (cmd.sbc_ccd) + ok = ok && do_cc (cmd.s_ccd, 3); + if (cmd.sbc_cce) + 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.compress != -1) - { - msg (MW, _("Active file compression is not yet implemented " - "(and probably won't be).")); - set_compression = cmd.compress == STC_OFF ? 0 : 1; - } - if (cmd.scompress != -1) - set_scompression = cmd.scompress == STC_OFF ? 0 : 1; - if (cmd.n_cpi != NOT_LONG) - { - if (cmd.n_cpi <= 0) - msg (SE, _("CPI must be greater than 0.")); - else - set_cpi = cmd.n_cpi; - } if (cmd.sbc_histogram) msg (MW, _("%s is obsolete."),"HISTOGRAM"); - if (cmd.n_lpi != NOT_LONG) - { - if (cmd.n_lpi <= 0) - msg (SE, _("LPI must be greater than 0.")); - else - set_lpi = cmd.n_lpi; - } - - /* Windows compatible syntax. */ - if (cmd.sbc_case) - msg (SW, _("CASE is not implemented and probably won't be. If you care, " - "complain about it.")); - if (cmd.sbc_cca) - set_ccx (cmd.s_cca, &set_cc[0], 'A'); - if (cmd.sbc_ccb) - set_ccx (cmd.s_ccb, &set_cc[1], 'B'); - if (cmd.sbc_ccc) - set_ccx (cmd.s_ccc, &set_cc[2], 'C'); - if (cmd.sbc_ccd) - set_ccx (cmd.s_ccd, &set_cc[3], 'D'); - if (cmd.sbc_cce) - set_ccx (cmd.s_cce, &set_cc[4], 'E'); - if (cmd.dec != -1) - { - set_decimal = cmd.dec == STC_DOT ? '.' : ','; - set_grouping = cmd.dec == STC_DOT ? ',' : '.'; - } - if (cmd.errors != -1) - set_routing (cmd.errors, &set_errors); - if (cmd.headers != -1) - set_headers = cmd.headers == STC_NO ? 0 : (cmd.headers == STC_YES ? 1 : 2); - if (cmd.messages != -1) - set_routing (cmd.messages, &set_messages); - if (cmd.mexp != -1) - set_mexpand = cmd.mexp == STC_OFF ? 0 : 1; - if (cmd.n_miterate != NOT_LONG) - { - if (cmd.n_miterate > 0) - set_miterate = cmd.n_miterate; - else - msg (SE, _("Value for MITERATE (%ld) must be greater than 0."), - cmd.n_miterate); - } - if (cmd.n_mnest != NOT_LONG) - { - if (cmd.n_mnest > 0) - set_mnest = cmd.n_mnest; - else - msg (SE, _("Value for MNEST (%ld) must be greater than 0."), - cmd.n_mnest); - } - if (cmd.mprint != -1) - set_mprint = cmd.mprint == STC_OFF ? 0 : 1; - if (cmd.n_mxerrs != NOT_LONG) - { - if (set_mxerrs < 1) - msg (SE, _("MXERRS must be at least 1.")); - else - set_mxerrs = cmd.n_mxerrs; - } - if (cmd.n_mxloops != NOT_LONG) - { - if (set_mxloops < 1) - msg (SE, _("MXLOOPS must be at least 1.")); - else - set_mxloops = cmd.n_mxloops; - } - if (cmd.n_mxmemory != NOT_LONG) + if (cmd.sbc_menus ) + msg (MW, _("%s is obsolete."),"MENUS"); + if (cmd.sbc_xsort ) + msg (SW, _("%s is obsolete."),"XSORT"); + if (cmd.sbc_mxmemory ) msg (SE, _("%s is obsolete."),"MXMEMORY"); - if (cmd.n_mxwarns != NOT_LONG) - set_mxwarns = cmd.n_mxwarns; - if (cmd.prtbck != -1) - set_printback = cmd.prtbck == STC_OFF ? 0 : 1; - if (cmd.s_scripttab) + if (cmd.sbc_scripttab) msg (SE, _("%s is obsolete."),"SCRIPTTAB"); - if (cmd.s_tbfonts) - msg (SW, _("TBFONTS not implemented.")); - if (cmd.s_tb1) - msg (SW, _("TB1 not implemented.")); - if (cmd.undef != -1) - set_undefined = cmd.undef == STC_NOWARN ? 0 : 1; - if (cmd.n_workspace != NOT_LONG) - msg (SE, _("%s is obsolete."),"WORKSPACE"); - - /* PC+ compatible syntax. */ - if (cmd.scrn != -1) - outp_enable_device (cmd.scrn == STC_OFF ? 0 : 1, OUTP_DEV_SCREEN); - - if (cmd.automenu != -1) - msg (SW, _("%s is obsolete."),"AUTOMENU"); - if (cmd.beep != -1) - msg (SW, _("%s is obsolete."),"BEEP"); - - if (cmd.s_cprompt) + if (cmd.sbc_tbfonts) + msg (SW, _("%s is obsolete."),"TBFONTS"); + if (cmd.sbc_tb1 && cmd.s_tb1) + msg (SW, _("%s is obsolete."),"TB1"); + + if (cmd.sbc_case) + msg (SW, _("%s is not implemented."), "CASE"); + + if (cmd.sbc_compression) + msg (MW, _("Active file compression is not implemented.")); + + return CMD_SUCCESS; +} + +/* 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) +{ + const char *sp; + int comma_cnt, dot_cnt; + + /* 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 ((comma_cnt == 3) == (dot_cnt == 3)) + return false; + + if (comma_cnt == 3) { - free (set_cprompt); - set_cprompt = cmd.s_cprompt; - cmd.s_cprompt = NULL; + cc->decimal = '.'; + cc->grouping = ','; } - if (cmd.s_dprompt) + else { - free (set_dprompt); - set_dprompt = cmd.s_dprompt; - cmd.s_dprompt = NULL; + cc->decimal = ','; + cc->grouping = '.'; } - if (cmd.echo != -1) - set_echo = cmd.echo == STC_OFF ? 0 : 1; - if (cmd.s_endcmd) - set_endcmd = cmd.s_endcmd[0]; - if (cmd.eject != -1) - msg (SW, _("%s is obsolete."),"EJECT"); - if (cmd.errbrk != -1) - set_errorbreak = cmd.errbrk == STC_OFF ? 0 : 1; - if (cmd.helpwin != -1) - msg (SW, _("%s is obsolete."),"HELPWINDOWS"); - if (cmd.inc != -1) - set_include = cmd.inc == STC_OFF ? 0 : 1; - if (cmd.menus != -1) - msg (MW, _("%s is obsolete."),"MENUS"); - if (cmd.null != -1) - set_nullline = cmd.null == STC_OFF ? 0 : 1; - if (cmd.more != -1) - set_more = cmd.more == STC_OFF ? 0 : 1; - if (cmd.prtr != -1) - outp_enable_device (cmd.prtr == STC_OFF ? 0 : 1, OUTP_DEV_PRINTER); - if (cmd.s_prompt) + return true; +} + +/* 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; + + for (; *in != '\0' && *in != grouping; in++) { - free (set_prompt); - set_prompt = cmd.s_prompt; - cmd.s_prompt = NULL; + if (*in == '\'' && in[1] == grouping) + in++; + if (out < &token[CC_WIDTH - 1]) + *out++ = *in; } - if (cmd.ptrans != -1) - msg (SW, _("%s is obsolete."),"PTRANSLATE"); - if (cmd.runrev != -1) - msg (SW, _("%s is obsolete."),"RUNREVIEW"); - if (cmd.safe == STC_ON) - set_safer = 1; - if (cmd.xsort != -1) - msg (SW, _("%s is obsolete."),"XSORT"); + *out = '\0'; - free_set (&cmd); - - return CMD_SUCCESS; + if (*in == grouping) + in++; + return in; } /* 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) +static bool +do_cc (const char *cc_string, int idx) { - if (strlen (cc_string) > 16) + struct custom_currency cc; + + /* Determine separators. */ + if (!find_cc_separators (cc_string, &cc)) { - 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; + msg (SE, _("CC%c: Custom currency string `%s' does not contain " + "exactly three periods or commas (not both)."), + "ABCDE"[idx], cc_string); + return false; } - - /* Determine separators. */ - { - const char *sp; - int n_commas, n_periods; - /* 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++; - - 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; -} + 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); -/* 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) -{ - switch (q) - { - case STC_ON: - *setting |= SET_ROUTE_DISABLE; - break; - case STC_OFF: - *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); - } + 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. */ static int -stc_custom_pager (struct cmd_set *cmd unused) +stc_custom_blanks (struct cmd_set *cmd UNUSED) { lex_match ('='); -#if !USE_INTERNAL_PAGER - if (lex_match_id ("OFF")) + if ((token == T_ID && lex_id_match ("SYSMIS", tokid))) { - if (set_pager) - free (set_pager); - set_pager = NULL; + lex_get (); + set_blanks (SYSMIS); } else { - if (!lex_force_string ()) + if (!lex_force_num ()) return 0; - if (set_pager) - free (set_pager); - set_pager = xstrdup (ds_value (&tokstr)); + set_blanks (lex_number ()); lex_get (); } return 1; -#else /* USE_INTERNAL_PAGER */ - if (match_id (OFF)) - return 1; - msg (SW, "External pagers not supported."); - return 0; -#endif /* USE_INTERNAL_PAGER */ } -/* 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. */ +/* Parses the EPOCH subcommand, which controls the epoch used for + parsing 2-digit years. */ static int -stc_custom_blanks (struct cmd_set *cmd unused) +stc_custom_epoch (struct cmd_set *cmd UNUSED) { lex_match ('='); - if ((token == T_ID && lex_id_match ("SYSMIS", tokid)) - || (token == T_STRING && !strcmp (tokid, "."))) + if (lex_match_id ("AUTOMATIC")) + set_epoch (-1); + else if (lex_is_integer ()) { + int new_epoch = lex_integer (); lex_get (); - set_blanks = SYSMIS; + if (new_epoch < 1500) + { + msg (SE, _("EPOCH must be 1500 or later.")); + return 0; + } + set_epoch (new_epoch); } - else + else { - if (!lex_force_num ()) - return 0; - set_blanks = tokval; - lex_get (); + lex_error (_("expecting AUTOMATIC or year")); + return 0; } + return 1; } static int -stc_custom_length (struct cmd_set *cmd unused) +stc_custom_length (struct cmd_set *cmd UNUSED) { int page_length; @@ -558,98 +351,57 @@ stc_custom_length (struct cmd_set *cmd unused) lex_get (); } - /* FIXME: Set 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}, - }; + if (page_length != -1) + set_viewlength (page_length); - 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; + return 1; } static int -stc_custom_seed (struct cmd_set *cmd unused) +stc_custom_seed (struct cmd_set *cmd UNUSED) { lex_match ('='); if (lex_match_id ("RANDOM")) - set_seed = NOT_LONG; + set_rng (time (0)); else { if (!lex_force_num ()) return 0; - set_seed = tokval; + set_rng (lex_number ()); lex_get (); } + return 1; } static int -stc_custom_width (struct cmd_set *cmd unused) +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 (); } - /* FIXME: Set page width. */ return 1; } /* Parses FORMAT subcommand, which consists of a numeric format specifier. */ static int -stc_custom_format (struct cmd_set *cmd unused) +stc_custom_format (struct cmd_set *cmd UNUSED) { struct fmt_spec fmt; @@ -664,204 +416,303 @@ stc_custom_format (struct cmd_set *cmd unused) return 0; } - set_format = fmt; + set_format (&fmt); return 1; } static int -stc_custom_journal (struct cmd_set *cmd unused) +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_value (&tokstr)); - lex_get (); + if (token == T_STRING) + lex_get (); + else + { + lex_error (NULL); + return 0; + } } 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) +stc_custom_listing (struct cmd_set *cmd UNUSED) { - msg (MW, _("%s is obsolete."),"COLOR"); + bool listing; lex_match ('='); - if (!lex_match_id ("ON") && !lex_match_id ("YES") && !lex_match_id ("OFF") && !lex_match_id ("NO")) + if (lex_match_id ("ON") || lex_match_id ("YES")) + listing = true; + else if (lex_match_id ("OFF") || lex_match_id ("NO")) + listing = false; + else { - 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; + /* FIXME */ + return 0; } + outp_enable_device (listing, OUTP_DEV_LISTING); + return 1; } static int -stc_custom_listing (struct cmd_set *cmd unused) +stc_custom_disk (struct cmd_set *cmd UNUSED) { - lex_match ('='); - if (lex_match_id ("ON") || lex_match_id ("YES")) - outp_enable_device (1, OUTP_DEV_LISTING); - else if (lex_match_id ("OFF") || lex_match_id ("NO")) - outp_enable_device (0, OUTP_DEV_LISTING); + return stc_custom_listing (cmd); +} + +static void +show_blanks (void) +{ + if (get_blanks () == SYSMIS) + msg (MM, _("BLANKS is SYSMIS.")); else + msg (MM, _("BLANKS is %g."), get_blanks ()); + +} + +static char * +format_cc (const char *in, char grouping, char *out) +{ + while (*in != '\0') { - /* FIXME */ + if (*in == grouping || *in == '\'') + *out++ = '\''; + *out++ = *in++; } + return out; +} - return 0; +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); } -static int -stc_custom_disk (struct cmd_set *cmd unused) + +static void +show_cca (void) { - stc_custom_listing (cmd); - return 0; + show_cc (0); } -static int -stc_custom_log (struct cmd_set *cmd unused) -{ - stc_custom_journal (cmd); - return 0; +static void +show_ccb (void) +{ + show_cc (1); } -static int -stc_custom_rcolor (struct cmd_set *cmd unused) +static void +show_ccc (void) { - msg (SW, _("%s is obsolete."),"RCOLOR"); + show_cc (2); +} - lex_match ('='); - if (!lex_force_match ('(')) - return 0; +static void +show_ccd (void) +{ + show_cc (3); +} - 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; +static void +show_cce (void) +{ + show_cc (4); +} - 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 (); - } +static void +show_decimals (void) +{ + msg (MM, _("DECIMAL is \"%c\"."), get_decimal ()); +} - 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 void +show_endcmd (void) +{ + msg (MM, _("ENDCMD is \"%c\"."), get_endcmd ()); } -static int -stc_custom_viewlength (struct cmd_set *cmd unused) -{ - 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; +static void +show_format (void) +{ + msg (MM, _("FORMAT is %s."), fmt_to_string (get_format ())); +} + +static void +show_length (void) +{ + msg (MM, _("LENGTH is %d."), get_viewlength ()); +} + +static void +show_mxerrs (void) +{ + msg (MM, _("MXERRS is %d."), get_mxerrs ()); +} + +static void +show_mxloops (void) +{ + msg (MM, _("MXLOOPS is %d."), get_mxloops ()); +} + +static void +show_mxwarns (void) +{ + msg (MM, _("MXWARNS is %d."), get_mxwarns ()); +} + +static void +show_scompression (void) +{ + if (get_scompression ()) + msg (MM, _("SCOMPRESSION is ON.")); else - { - if (!lex_force_int ()) - return 0; -#if __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 (); - } + msg (MM, _("SCOMPRESSION is OFF.")); +} -#if __MSDOS__ - msg (SW, _("VIEWLENGTH not implemented.")); -#endif /* dos */ - return 1; +static void +show_undefined (void) +{ + if (get_undefined ()) + msg (MM, _("UNDEFINED is WARN.")); + else + msg (MM, _("UNDEFINED is NOWARN.")); } -static int -stc_custom_workdev (struct cmd_set *cmd unused) +static void +show_weight (void) +{ + 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); +} + +static void +show_width (void) +{ + msg (MM, _("WIDTH is %d."), get_viewwidth ()); +} + +struct show_sbc + { + const char *name; + void (*function) (void); + }; + +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 +show_all (void) { - char c[2]; + size_t i; + + for (i = 0; i < sizeof show_table / sizeof *show_table; i++) + show_table[i].function (); +} - msg (SW, _("%s is obsolete."),"WORKDEV"); +static void +show_all_cc (void) +{ + int i; + + for (i = 0; i < 5; i++) + show_cc (i); +} - 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 +show_warranty (void) +{ + msg (MM, lack_of_warranty); +} + +static void +show_copying (void) +{ + msg (MM, copyleft); +} + +int +cmd_show (void) +{ + if (token == '.') + { + show_all (); + return CMD_SUCCESS; + } + + 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; + } + + lex_match ('/'); + } + while (token != '.'); + + return CMD_SUCCESS; } /*