WRITE
};
+static const struct trns_class print_binary_trns_class;
+static const struct trns_class print_text_trns_class;
+
static int internal_cmd_print (struct lexer *, struct dataset *ds,
enum which_formats, bool eject);
-static trns_proc_func print_text_trns_proc, print_binary_trns_proc;
-static trns_free_func print_trns_free;
static bool parse_specs (struct lexer *, struct pool *tmp_pool, struct print_trns *,
struct dictionary *dict, enum which_formats);
static void dump_table (struct print_trns *);
+
+static bool print_trns_free (void *trns_);
\f
/* Basic parsing. */
print_table = false;
else
{
- lex_error (lexer, _("expecting a valid subcommand"));
+ lex_error_expecting (lexer, "OUTFILE", "ENCODING", "RECORDS",
+ "TABLE", "NOTABLE");
goto error;
}
}
dump_table (trns);
/* Put the transformation in the queue. */
- add_transformation (ds,
- (binary
- ? print_binary_trns_proc
- : print_text_trns_proc),
- print_trns_free, trns);
+ add_transformation (ds, (binary
+ ? &print_binary_trns_class
+ : &print_text_trns_class), trns);
pool_destroy (tmp_pool);
fh_unref (fh);
enum which_formats which_formats)
{
const struct variable **vars;
- size_t n_vars, var_idx;
- struct fmt_spec *formats, *f;
- size_t n_formats;
- bool add_space;
-
+ size_t n_vars;
if (!parse_variables_const_pool (lexer, tmp_pool, dict,
- &vars, &n_vars, PV_DUPLICATE))
+ &vars, &n_vars, PV_DUPLICATE))
return false;
+ struct fmt_spec *formats, *f;
+ size_t n_formats;
+ bool add_space;
+ int formats_start = lex_ofs (lexer);
if (lex_is_number (lexer) || lex_token (lexer) == T_LPAREN)
{
if (!parse_var_placements (lexer, tmp_pool, n_vars, FMT_FOR_OUTPUT,
}
else
{
- size_t i;
-
lex_match (lexer, T_ASTERISK);
formats = pool_nmalloc (tmp_pool, n_vars, sizeof *formats);
n_formats = n_vars;
- for (i = 0; i < n_vars; i++)
+ for (size_t i = 0; i < n_vars; i++)
{
const struct variable *v = vars[i];
formats[i] = (which_formats == PRINT
}
add_space = which_formats == PRINT;
}
+ int formats_end = lex_ofs (lexer) - 1;
- var_idx = 0;
+ size_t var_idx = 0;
for (f = formats; f < &formats[n_formats]; f++)
if (!execute_placement_format (f, record, column))
{
- const struct variable *var;
- struct prt_out_spec *spec;
-
- var = vars[var_idx++];
- if (!fmt_check_width_compat (f, var_get_width (var)))
- return false;
-
- spec = pool_alloc (trns->pool, sizeof *spec);
- spec->type = PRT_VAR;
- spec->record = *record;
- spec->first_column = *column;
- spec->var = var;
- spec->format = *f;
- spec->add_space = add_space;
-
- /* This is a completely bizarre twist for compatibility:
- WRITE outputs the system-missing value as a field
- filled with spaces, instead of using the normal format
- that usually contains a period. */
- spec->sysmis_as_spaces = (which_formats == WRITE
- && var_is_numeric (var)
- && (fmt_get_category (spec->format.type)
- != FMT_CAT_BINARY));
-
+ const struct variable *var = vars[var_idx++];
+ char *error = fmt_check_width_compat__ (f, var_get_name (var),
+ var_get_width (var));
+ if (error)
+ {
+ lex_ofs_error (lexer, formats_start, formats_end, "%s", error);
+ free (error);
+ return false;
+ }
+
+ struct prt_out_spec *spec = pool_alloc (trns->pool, sizeof *spec);
+ *spec = (struct prt_out_spec) {
+ .type = PRT_VAR,
+ .record = *record,
+ .first_column = *column,
+ .var = var,
+ .format = *f,
+ .add_space = add_space,
+
+ /* This is a completely bizarre twist for compatibility: WRITE
+ outputs the system-missing value as a field filled with spaces,
+ instead of using the normal format that usually contains a
+ period. */
+ .sysmis_as_spaces = (which_formats == WRITE
+ && var_is_numeric (var)
+ && (fmt_get_category (f->type)
+ != FMT_CAT_BINARY)),
+ };
ll_push_tail (&trns->specs, &spec->ll);
*column += f->w + add_space;
bool *eject, int *record);
/* Performs the transformation inside print_trns T on case C. */
-static int
+static enum trns_result
print_text_trns_proc (void *trns_, struct ccase **c,
casenumber case_num UNUSED)
{
bool *eject, int *record);
/* Performs the transformation inside print_trns T on case C. */
-static int
+static enum trns_result
print_binary_trns_proc (void *trns_, struct ccase **c,
casenumber case_num UNUSED)
{
return ok;
}
+static const struct trns_class print_binary_trns_class = {
+ .name = "PRINT",
+ .execute = print_binary_trns_proc,
+ .destroy = print_trns_free,
+};
+
+static const struct trns_class print_text_trns_class = {
+ .name = "PRINT",
+ .execute = print_text_trns_proc,
+ .destroy = print_trns_free,
+};
+