::= ( setting-value-2 )
::= setting-value-2
setting-value-2 ::= setting-value-options setting-value-type : ID
- setting-value-restriction
setting-value-options ::=
::= *
setting-value-type ::= N
::= D
::= S
-setting-value-restriction ::=
- ::= , STRING
@end example
Settings may have values. If the value must be enclosed in parentheses,
or string type, respectively. The given @code{ID} is used to
construct a variable name.
If option @samp{*} is given, then the value is optional; otherwise it
-must be specified whenever the corresponding setting is specified. A
-``restriction'' can also be specified which is a string giving a C
-expression limiting the valid range of the value. The special escape
-@code{%s} should be used within the restriction to refer to the
-setting's value variable.
+must be specified whenever the corresponding setting is specified.
@example
sbc-special-form ::= VAR
::= INTEGER opt-list
::= DOUBLE opt-list
::= PINT
- ::= STRING @r{(the literal word STRING)} string-options
+ ::= STRING @r{(the literal word STRING)}
::= CUSTOM
varlist-options ::=
::= ( STRING )
opt-list ::=
::= LIST
-string-options ::=
- ::= ( STRING STRING )
@end example
The special forms are of the following types:
@item STRING
-A string value. If the options are given then the first string is an
-expression giving a restriction on the value of the string; the second
-string is an error message to display when the restriction is violated.
+A string value.
@item CUSTOM
int narray; /* Index of next array element. */
const char *prefix; /* Prefix for variable and constant names. */
specifier *spec; /* Array of specifiers. */
-
- /* SBC_STRING and SBC_INT only. */
- char *restriction; /* Expression restricting string length. */
- char *message; /* Error message. */
- int translatable; /* Error message is translatable */
+ char *pv_options; /* PV_* options for SBC_VARLIST. */
};
/* Name of the command; i.e., DESCRIPTIVES. */
sbc->narray = 0;
sbc->type = SBC_PLAIN;
sbc->spec = NULL;
- sbc->translatable = 0;
if (match_token ('['))
{
if (match_token ('('))
{
force_string ();
- sbc->message = xstrdup (tokstr);
+ sbc->pv_options = xstrdup (tokstr);
lex_get();
skip_token (')');
}
- else sbc->message = NULL;
+ else
+ sbc->pv_options = NULL;
sbc->type = SBC_VARLIST;
}
else if (match_id ("INTEGER"))
- {
sbc->type = match_id ("LIST") ? SBC_INT_LIST : SBC_INT;
- if ( token == T_STRING)
- {
- sbc->restriction = xstrdup (tokstr);
- lex_get ();
- if ( match_id("N_") )
- {
- skip_token('(');
- force_string ();
- lex_get();
- skip_token(')');
- sbc->translatable = 1;
- }
- else {
- force_string ();
- lex_get ();
- }
- sbc->message = xstrdup (tokstr);
- }
- else
- sbc->restriction = NULL;
- }
else if (match_id ("PINT"))
sbc->type = SBC_PINT;
else if (match_id ("DOUBLE"))
sbc->type = SBC_DBL;
}
else if (match_id ("STRING"))
- {
- sbc->type = SBC_STRING;
- if (token == T_STRING)
- {
- sbc->restriction = xstrdup (tokstr);
- lex_get ();
- force_string ();
- sbc->message = xstrdup (tokstr);
- lex_get ();
- }
- else
- sbc->restriction = NULL;
- }
+ sbc->type = SBC_STRING;
else if (match_id ("CUSTOM"))
sbc->type = SBC_CUSTOM;
else
}
dump (1, "{");
- dump (0, "msg (SE, _(\"Bad argument for %s "
- "specifier of %s subcommand.\"));",
- s->specname, sbc->name);
+ dump (0, "lex_error (lexer, NULL);");
dump (0, "goto lossage;");
dump (-1, "}");
outdent ();
"PV_APPEND%s%s))",
st_lower (sbc->prefix), st_lower (sbc->name),
st_lower (sbc->prefix), st_lower (sbc->name),
- sbc->message ? " |" : "",
- sbc->message ? sbc->message : "");
+ sbc->pv_options ? " |" : "",
+ sbc->pv_options ? sbc->pv_options : "");
dump (0, "goto lossage;");
outdent ();
}
}
else if (sbc->type == SBC_STRING)
{
- if (sbc->restriction)
- {
- dump (1, "{");
- dump (0, "int x;");
- }
dump (1, "if (!lex_force_string (lexer))");
dump (0, "return false;");
outdent ();
- if (sbc->restriction)
- {
- dump (0, "x = ss_length (lex_tokss (lexer));");
- dump (1, "if (!(%s))", sbc->restriction);
- dump (1, "{");
- dump (0, "msg (SE, _(\"String for %s must be %s.\"));",
- sbc->name, sbc->message);
- dump (0, "goto lossage;");
- dump (-1, "}");
- outdent ();
- }
dump (0, "free(p->s_%s);", st_lower(sbc->name) );
dump (0, "p->s_%s = ss_xstrdup (lex_tokss (lexer));",
st_lower (sbc->name));
dump (0, "lex_get (lexer);");
- if (sbc->restriction)
- dump (-1, "}");
}
else if (sbc->type == SBC_DBL)
{
dump (0, "goto lossage;");
dump (-1, "x = lex_integer (lexer);");
dump (0, "lex_get(lexer);");
- if (sbc->restriction)
- {
- char buf[1024];
- dump (1, "if (!(%s))", sbc->restriction);
- dump (1, "{");
- sprintf(buf,sbc->message,sbc->name);
- if ( sbc->translatable )
- dump (0, "msg (SE, gettext(\"%s\"));",buf);
- else
- dump (0, "msg (SE, \"%s\");",buf);
- dump (0, "goto lossage;");
- dump (-1, "}");
- }
dump (0, "p->n_%s[p->sbc_%s - 1] = x;", st_lower (sbc->name), st_lower(sbc->name) );
dump (-1,"}");
}
dump (0, "#include \"language/lexer/subcommand-list.h\"");
dump (0, "#include \"language/lexer/variable-parser.h\"");
dump (0, "#include \"libpspp/assertion.h\"");
+ dump (0, "#include \"libpspp/cast.h\"");
dump (0, "#include \"libpspp/message.h\"");
dump (0, "#include \"libpspp/str.h\"");
dump_blank_line (0);
/* (specification)
"SET" (stc_):
blanks=custom;
- block=string "x==1" "one character long";
- boxstring=string "x==3 || x==11" "3 or 11 characters long";
+ block=string;
+ boxstring=string;
case=size:upper/uplow;
cca=string;
ccb=string;
ccd=string;
cce=string;
compression=compress:on/off;
- cpi=integer "x>0" "%s must be greater than 0";
+ cpi=integer;
decimal=dec:dot/comma;
epoch=custom;
errors=custom;
format=custom;
headers=headers:no/yes/blank;
highres=hires:on/off;
- histogram=string "x==1" "one character long";
+ histogram=string;
include=inc:on/off;
journal=custom;
log=custom;
length=custom;
locale=custom;
lowres=lores:auto/on/off;
- lpi=integer "x>0" "%s must be greater than 0";
+ lpi=integer;
menus=menus:standard/extended;
messages=custom;
mexpand=mexp:on/off;
- miterate=integer "x>0" "%s must be greater than 0";
- mnest=integer "x>0" "%s must be greater than 0";
+ miterate=integer;
+ mnest=integer;
mprint=mprint:on/off;
- mxerrs=integer "x >= 1" "%s must be at least 1";
- mxloops=integer "x >=1" "%s must be at least 1";
+ mxerrs=integer;
+ mxloops=integer;
mxmemory=integer;
mxwarns=integer;
printback=custom;
rrb=rrb:native/isl/isb/idl/idb/vf/vd/vg/zs/zl;
safer=safe:on;
scompression=scompress:on/off;
- scripttab=string "x==1" "one character long";
+ scripttab=string;
seed=custom;
tnumbers=custom;
- tb1=string "x==3 || x==11" "3 or 11 characters long";
+ tb1=string;
tbfonts=string;
undefined=undef:warn/nowarn;
wib=wib:msbfirst/lsbfirst/vax/native;
wrb=wrb:native/isl/isb/idl/idb/vf/vd/vg/zs/zl;
width=custom;
- workspace=integer "x>0" "%s must be positive";
+ workspace=integer;
xsort=xsort:yes/no.
*/
if (cmd.sbc_include)
settings_set_include (cmd.inc == STC_ON);
if (cmd.sbc_mxerrs)
- settings_set_max_messages (MSG_S_ERROR, cmd.n_mxerrs[0]);
+ {
+ if (cmd.n_mxerrs[0] >= 1)
+ settings_set_max_messages (MSG_S_ERROR, cmd.n_mxerrs[0]);
+ else
+ msg (SE, _("%s must be at least 1."), "MXERRS");
+ }
if (cmd.sbc_mxloops)
{
if (cmd.n_mxloops[0] >= 1)
msg (SE, _("%s must be at least 1."), "MXLOOPS");
}
if (cmd.sbc_mxwarns)
- settings_set_max_messages (MSG_S_WARNING, cmd.n_mxwarns[0]);
+ {
+ if (cmd.n_mxwarns[0] >= 0)
+ settings_set_max_messages (MSG_S_WARNING, cmd.n_mxwarns[0]);
+ else
+ msg (SE, _("%s must not be negative."), "MXWARNS");
+ }
if (cmd.sbc_rib)
settings_set_input_integer_format (stc_to_integer_format (cmd.rib));
if (cmd.sbc_rrb)
{
if ( cmd.n_workspace[0] < 1024 && ! settings_get_testing_mode ())
msg (SE, _("WORKSPACE must be at least 1MB"));
+ else if (cmd.n_workspace[0] <= 0)
+ msg (SE, _("WORKSPACE must be positive"));
else
settings_set_workspace (cmd.n_workspace[0] * 1024L);
}