/SAFER=ON
/LOCALE='@var{string}'
+(macros)
+ /MEXPAND=@{ON,OFF@}
+ /MPRINT=@{ON,OFF@}
+ /MITERATE=@var{number}
+ /MNEST=@var{number}
+
(settings not yet implemented, but accepted and ignored)
/BASETEXTDIRECTION=@{AUTOMATIC,RIGHTTOLEFT,LEFTTORIGHT@}
/BLOCK='@var{c}'
/COMPRESSION=@{ON,OFF@}
/CMPTRANS=@{ON,OFF@}
/HEADER=@{NO,YES,BLANK@}
- /MEXPAND=@{ON,OFF@}
- /MITERATE=@var{number}
- /MNEST=@var{number}
- /MPRINT=@{ON,OFF@}
@end display
@cmd{SET} allows the user to adjust several parameters relating to
of the system's locale.
@end table
+The following subcommands affect the interpretation of macros.
+
+@table @asis
+@item MEXPAND
+Controls whether macros are expanded. The default is ON.
+
+@item MPRINT
+Controls whether the expansion of macros is included in output. This
+is separate from whether command syntax in general is included in
+output. The default is OFF.
+
+@item MITERATE
+Limits the number of iterations executed in @code{!DO} loops within
+macros. This does not affect other language constructs such as
+@cmd{LOOP}. This must be set to a positive integer. The default is
+1000.
+
+@item MNEST
+Limits the number of levels of nested macro expansion. This must be
+set to a positive integer. The default is 50.
+@end table
+
The following subcommands are not yet implemented, but PSPP accepts
them and ignores the settings.
@itemx COMPRESSION
@itemx CMPTRANS
@itemx HEADER
-@itemx MEXPAND
-@itemx MITERATE
-@itemx MNEST
-@itemx MPRINT
@end table
@node SHOW
[FORMAT]
[FUZZBITS]
[LENGTH]
+ [MEXPAND]
+ [MPRINT]
+ [MITERATE]
+ [MNEST]
[MXERRS]
[MXLOOPS]
[MXWARNS]
double blanks;
int max_messages[MSG_N_SEVERITIES];
bool printback;
- bool mprint;
+
+ /* Macro settings. */
+ bool mexpand; /* Expand macros? */
+ bool mprint; /* Print macro expansions? */
+ int miterate; /* Maximum iterations of !FOR. */
+ int mnest; /* Maximum nested macro expansion levels. */
+
int mxloops;
size_t workspace;
struct fmt_spec default_format;
},
.printback = true,
- .mprint = true,
+
+ .mexpand = true,
+ .mprint = false,
+ .miterate = 1000,
+ .mnest = 50,
+
.mxloops = 40,
.workspace = 64L * 1024 * 1024,
.default_format = { .type = FMT_F, .w = 8, .d = 2 },
the_settings.max_messages[severity] = max;
}
+/* Returns whether to expand macro invocations. */
+bool
+settings_get_mexpand (void)
+{
+ return the_settings.mexpand;
+}
+
+/* Sets whether to expand macro invocations. */
+void
+settings_set_mexpand (bool mexpand)
+{
+ the_settings.mexpand = mexpand;
+}
+
/* Independent of get_printback, controls whether the commands
generated by macro invocations are displayed. */
bool
the_settings.mprint = mprint;
}
+/* Returns the limit for loop iterations within a macro. */
+int
+settings_get_miterate (void)
+{
+ return the_settings.miterate;
+}
+
+/* Sets the limit for loop iterations within a macro. */
+void
+settings_set_miterate (int miterate)
+{
+ the_settings.miterate = miterate;
+}
+
+/* Returns the limit for recursion macro expansions. */
+int settings_get_mnest (void)
+{
+ return the_settings.mnest;
+}
+
+/* Sets the limit for recursion macro expansions. */
+void
+settings_set_mnest (int mnest)
+{
+ the_settings.mnest = mnest;
+}
+
+int settings_get_mxloops (void);
+void settings_set_mxloops (int);
/* Implied limit of unbounded loop. */
int
settings_get_mxloops (void)
int settings_get_max_messages (enum msg_severity);
void settings_set_max_messages (enum msg_severity, int max);
+/* Macro settings. */
+bool settings_get_mexpand (void);
+void settings_set_mexpand (bool);
+
bool settings_get_mprint (void);
void settings_set_mprint (bool);
+int settings_get_miterate (void);
+void settings_set_miterate (int);
+
+int settings_get_mnest (void);
+void settings_set_mnest (int);
+
int settings_get_mxloops (void);
void settings_set_mxloops (int);
static bool
parse_MEXPAND (struct lexer *lexer)
{
- return parse_unimplemented (lexer, "MEXPAND");
+ int mexpand = force_parse_bool (lexer);
+ if (mexpand != -1)
+ settings_set_mexpand (mexpand);
+ return mexpand != -1;
}
static bool
parse_MITERATE (struct lexer *lexer)
{
- return parse_unimplemented (lexer, "MITERATE");
+ if (!lex_force_int_range (lexer, "MITERATE", 1, INT_MAX))
+ return false;
+ settings_set_miterate (lex_integer (lexer));
+ lex_get (lexer);
+ return true;
}
static bool
parse_MNEST (struct lexer *lexer)
{
- return parse_unimplemented (lexer, "MNEST");
+ if (!lex_force_int_range (lexer, "MNEST", 1, INT_MAX))
+ return false;
+ settings_set_mnest (lex_integer (lexer));
+ lex_get (lexer);
+ return true;
}
static bool
parse_MPRINT (struct lexer *lexer)
{
- return parse_unimplemented (lexer, "MPRINT");
+ int mprint = force_parse_bool (lexer);
+ if (mprint != -1)
+ settings_set_mprint (mprint);
+ return mprint != -1;
}
static bool
return xstrdup (get_default_encoding ());
}
+static char *
+show_mexpand (const struct dataset *ds UNUSED)
+{
+ return xstrdup (settings_get_mexpand () ? "ON" : "OFF");
+}
+
+static char *
+show_mprint (const struct dataset *ds UNUSED)
+{
+ return xstrdup (settings_get_mprint () ? "ON" : "OFF");
+}
+
+static char *
+show_miterate (const struct dataset *ds UNUSED)
+{
+ return xasprintf ("%d", settings_get_miterate ());
+}
+
+static char *
+show_mnest (const struct dataset *ds UNUSED)
+{
+ return xasprintf ("%d", settings_get_mnest ());
+}
+
static char *
show_messages (const struct dataset *ds UNUSED)
{
{"JOURNAL", show_journal},
{"LENGTH", show_length},
{"LOCALE", show_locale},
+ {"MEXPAND", show_mexpand},
+ {"MPRINT", show_mprint},
+ {"MITERATE", show_miterate},
+ {"MNEST", show_mnest},
{"MESSAGES", show_messages},
{"MXERRS", show_mxerrs},
{"MXLOOPS", show_mxloops},
AT_CLEANUP
-\f
+AT_SETUP([SET macro - MEXPAND MPRINT MITERATE MNEST])
+AT_DATA([set-macro.sps], [dnl
+show mexpand mprint miterate mnest.
+preserve.
+set mexpand=off mprint=on miterate=10 mnest=11.
+show mexpand mprint miterate mnest.
+restore.
+show mexpand mprint miterate mnest.
+])
+AT_CHECK([pspp -O format=csv set-macro.sps], [0], [dnl
+set-macro.sps:1: note: SHOW: MEXPAND is ON.
+
+set-macro.sps:1: note: SHOW: MPRINT is OFF.
+
+set-macro.sps:1: note: SHOW: MITERATE is 1000.
+
+set-macro.sps:1: note: SHOW: MNEST is 50.
+
+set-macro.sps:4: note: SHOW: MEXPAND is OFF.
+
+set-macro.sps:4: note: SHOW: MPRINT is ON.
+
+set-macro.sps:4: note: SHOW: MITERATE is 10.
+set-macro.sps:4: note: SHOW: MNEST is 11.
+
+set-macro.sps:6: note: SHOW: MEXPAND is ON.
+
+set-macro.sps:6: note: SHOW: MPRINT is OFF.
+
+set-macro.sps:6: note: SHOW: MITERATE is 1000.
+
+set-macro.sps:6: note: SHOW: MNEST is 50.
+])
+AT_CLEANUP
+\f
AT_BANNER([PRESERVE and RESTORE])
AT_SETUP([PRESERVE of SET FORMAT])