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. */
/* FIXME: seems like a lot of code duplication with data-list.c. */
#include "tab.h"
#include "var.h"
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
/* Describes what to do when an output field is encountered. */
enum
{
/* PRINT, PRINT EJECT, WRITE private data structure. */
struct print_trns
{
- struct trns_header h;
struct dfm_writer *writer; /* Output file, NULL=listing file. */
int options; /* PRT_* bitmapped field. */
struct prt_out_spec *spec; /* Output specifications. */
struct file_handle *fh = NULL;
/* Fill in prt to facilitate error-handling. */
- prt.h.proc = print_trns_proc;
- prt.h.free = print_trns_free;
prt.writer = NULL;
prt.options = f;
prt.spec = NULL;
{
lex_match ('=');
- fh = fh_parse ();
+ fh = fh_parse (FH_REF_FILE);
if (fh == NULL)
goto error;
}
if (prt.writer == NULL)
goto error;
- if (handle_get_mode (fh) == MODE_BINARY)
+ if (fh_get_mode (fh) == FH_MODE_BINARY)
prt.options |= PRT_BINARY;
}
/* Put the transformation in the queue. */
trns = xmalloc (sizeof *trns);
memcpy (trns, &prt, sizeof *trns);
- add_transformation ((struct trns_header *) trns);
+ add_transformation (print_trns_proc, print_trns_free, trns);
return CMD_SUCCESS;
error:
- print_trns_free ((struct trns_header *) & prt);
+ print_trns_free (&prt);
return CMD_FAILURE;
}
static struct
{
struct variable **v; /* variable list */
- int nv; /* number of variables in list */
- int cv; /* number of variables from list used up so far
+ size_t nv; /* number of variables in list */
+ size_t cv; /* number of variables from list used up so far
by the FORTRAN-like format specifiers */
int recno; /* current 1-based record number */
else
{
/* User wants dictionary format specifiers. */
- int i;
+ size_t i;
lex_match ('*');
for (i = 0; i < fx.nv; i++)
return 0;
}
+/* Verifies that FORMAT doesn't need a variable wider than WIDTH.
+ Returns true iff that is the case. */
+static bool
+check_string_width (const struct fmt_spec *format, const struct variable *v)
+{
+ if (get_format_var_width (format) > v->width)
+ {
+ msg (SE, _("Variable %s has width %d so it cannot be output "
+ "as format %s."),
+ v->name, v->width, fmt_to_string (format));
+ return false;
+ }
+ return true;
+}
+
/* Parses a column specification for parse_specs(). */
static int
fixed_parse_compatible (void)
{
- int dividend;
+ int individual_var_width;
int type;
- int i;
+ size_t i;
type = fx.v[0]->type;
for (i = 1; i < fx.nv; i++)
if ((fx.lc - fx.fc + 1) % fx.nv)
{
- msg (SE, _("The %d columns %d-%d can't be evenly divided into %d "
- "fields."), fx.lc - fx.fc + 1, fx.fc + 1, fx.lc + 1, fx.nv);
+ msg (SE, _("The %d columns %d-%d can't be evenly divided into %u "
+ "fields."),
+ fx.lc - fx.fc + 1, fx.fc + 1, fx.lc + 1, (unsigned) fx.nv);
return 0;
}
- dividend = (fx.lc - fx.fc + 1) / fx.nv;
- fx.spec.u.v.f.w = dividend;
- if (!check_output_specifier (&fx.spec.u.v.f, 1))
+ individual_var_width = (fx.lc - fx.fc + 1) / fx.nv;
+ fx.spec.u.v.f.w = individual_var_width;
+ if (!check_output_specifier (&fx.spec.u.v.f, true)
+ || !check_specifier_type (&fx.spec.u.v.f, type, true))
return 0;
- if ((type == ALPHA) ^ (formats[fx.spec.u.v.f.type].cat & FCAT_STRING))
- {
- msg (SE, _("%s variables cannot be displayed with format %s."),
- type == ALPHA ? _("String") : _("Numeric"),
- fmt_to_string (&fx.spec.u.v.f));
- return 0;
- }
-
- /* Check that, for string variables, the user didn't specify a width
- longer than an actual string width. */
if (type == ALPHA)
{
- /* Minimum width of all the string variables specified. */
- int min_len = fx.v[0]->width;
-
- for (i = 1; i < fx.nv; i++)
- min_len = min (min_len, fx.v[i]->width);
- if (!check_string_specifier (&fx.spec.u.v.f, min_len))
- return 0;
+ for (i = 0; i < fx.nv; i++)
+ if (!check_string_width (&fx.spec.u.v.f, fx.v[i]))
+ return false;
}
fx.spec.type = PRT_VAR;
for (i = 0; i < fx.nv; i++)
{
- fx.spec.fc = fx.fc + dividend * i;
+ fx.spec.fc = fx.fc + individual_var_width * i;
fx.spec.u.v.v = fx.v[i];
append_var_spec (&fx.spec);
}
/* Destroy a format list and, optionally, all its sublists. */
static void
-destroy_fmt_list (struct fmt_list * f, int recurse)
+destroy_fmt_list (struct fmt_list *f, int recurse)
{
struct fmt_list *next;
FORTRAN-like format specifications, like 4(F10,2X)) into the
structure prt. */
static int
-dump_fmt_list (struct fmt_list * f)
+dump_fmt_list (struct fmt_list *f)
{
int i;
}
v = fx.v[fx.cv++];
- if ((v->type == ALPHA) ^ (formats[f->f.type].cat & FCAT_STRING))
- {
- msg (SE, _("Display format %s may not be used with a "
- "%s variable."), fmt_to_string (&f->f),
- v->type == ALPHA ? _("string") : _("numeric"));
- return 0;
- }
- if (!check_string_specifier (&f->f, v->width))
- return 0;
+ if (!check_output_specifier (&f->f, true)
+ || !check_specifier_type (&f->f, v->type, true)
+ || !check_string_width (&f->f, v))
+ return false;
fx.spec.type = PRT_VAR;
fx.spec.u.v.v = v;
}
if (fh != NULL)
- tab_title (t, 1, _("Writing %d record(s) to file %s."),
- recno, handle_get_filename (fh));
+ tab_title (t, 1, ngettext ("Writing %d record to %s.",
+ "Writing %d records to %s.", recno),
+ recno, fh_get_name (fh));
else
- tab_title (t, 1, _("Writing %d record(s) to the listing file."), recno);
+ tab_title (t, 1, ngettext ("Writing %d record.",
+ "Writing %d records.", recno), recno);
tab_submit (t);
}
/* Performs the transformation inside print_trns T on case C. */
static int
-print_trns_proc (struct trns_header * trns, struct ccase * c,
- int case_num UNUSED)
+print_trns_proc (void *trns_, struct ccase *c, int case_num UNUSED)
{
/* Transformation. */
- struct print_trns *t = (struct print_trns *) trns;
+ struct print_trns *t = trns_;
/* Iterator. */
struct prt_out_spec *i;
/* Frees all the data inside print_trns T. Does not free T. */
static void
-print_trns_free (struct trns_header * t)
+print_trns_free (void *prt_)
{
- struct print_trns *prt = (struct print_trns *) t;
+ struct print_trns *prt = prt_;
struct prt_out_spec *i, *n;
for (i = prt->spec; i; i = n)
if (prt->writer != NULL)
dfm_close_writer (prt->writer);
free (prt->line);
+ free (prt);
}
\f
/* PRINT SPACE. */
/* PRINT SPACE transformation. */
struct print_space_trns
{
- struct trns_header h;
-
struct dfm_writer *writer; /* Output data file. */
struct expression *e; /* Number of lines; NULL=1. */
}
{
lex_match ('=');
- fh = fh_parse ();
+ fh = fh_parse (FH_REF_FILE);
if (fh == NULL)
return CMD_FAILURE;
lex_get ();
writer = NULL;
t = xmalloc (sizeof *t);
- t->h.proc = print_space_trns_proc;
- if (e)
- t->h.free = print_space_trns_free;
- else
- t->h.free = NULL;
t->writer = writer;
t->e = e;
- add_transformation ((struct trns_header *) t);
+ add_transformation (print_space_trns_proc, print_space_trns_free, t);
return CMD_SUCCESS;
}
static int
-print_space_trns_proc (struct trns_header * trns, struct ccase * c,
+print_space_trns_proc (void *t_, struct ccase *c,
int case_num UNUSED)
{
- struct print_space_trns *t = (struct print_space_trns *) trns;
+ struct print_space_trns *t = t_;
double n = 1.;
if (t->e)
}
static void
-print_space_trns_free (struct trns_header * trns)
+print_space_trns_free (void *trns_)
{
- expr_free (((struct print_space_trns *) trns)->e);
+ struct print_space_trns *trns = trns_;
+ expr_free (trns->e);
+ free (trns);
}