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. */
#include <config.h>
-#include <assert.h>
#include <stdlib.h>
#include "alloc.h"
+#include "case.h"
#include "command.h"
#include "data-in.h"
-#include "dfm.h"
+#include "dfm-read.h"
+#include "dictionary.h"
+#include "error.h"
#include "file-handle.h"
#include "format.h"
#include "lexer.h"
/* Limited variable column specifications. */
struct col_spec
{
- char name[9]; /* Variable name. */
+ char name[LONG_NAME_LEN + 1]; /* Variable name. */
int fc, nc; /* First column (1-based), # of columns. */
int fmt; /* Format type. */
struct variable *v; /* Variable. */
struct file_type_pgm
{
int type; /* One of the FTY_* constants. */
- struct file_handle *handle; /* File handle of input file. */
+ struct dfm_reader *reader; /* Data file to read. */
struct col_spec record; /* RECORD subcommand. */
struct col_spec case_sbc; /* CASE subcommand. */
int wild; /* 0=NOWARN, 1=WARN. */
DATA LIST. */
struct record_type *recs_head; /* List of record types. */
struct record_type *recs_tail; /* Last in list of record types. */
+ size_t case_size; /* Case size in bytes. */
};
static int parse_col_spec (struct col_spec *, const char *);
static void create_col_var (struct col_spec *c);
+int cmd_file_type (void);
+
/* Parses FILE TYPE command. */
int
cmd_file_type (void)
{
- static struct file_type_pgm *fty;
+ static struct file_type_pgm *fty; /* FIXME: static? WTF? */
+ struct file_handle *fh = NULL;
/* Initialize. */
discard_variables ();
fty = xmalloc (sizeof *fty);
- fty->handle = inline_file;
+ fty->reader = NULL;
fty->record.name[0] = 0;
fty->case_sbc.name[0] = 0;
fty->wild = fty->duplicate = fty->missing = fty->ordered = 0;
fty->had_rec_type = 0;
fty->recs_head = fty->recs_tail = NULL;
- lex_match_id ("TYPE");
if (lex_match_id ("MIXED"))
fty->type = FTY_MIXED;
else if (lex_match_id ("GROUPED"))
if (lex_match_id ("FILE"))
{
lex_match ('=');
- fty->handle = fh_parse_file_handle ();
- if (!fty->handle)
+ fh = fh_parse ();
+ if (fh == NULL)
goto error;
}
else if (lex_match_id ("RECORD"))
goto error;
}
- if (!strcmp (fty->case_sbc.name, fty->record.name))
+ if (!strcasecmp (fty->case_sbc.name, fty->record.name))
{
msg (SE, _("CASE and RECORD must specify different variable "
"names."));
}
}
- default_handle = fty->handle;
+ fty->reader = dfm_open_reader (fh);
+ if (fty->reader == NULL)
+ goto error;
+ default_handle = fh;
- vfm_source = create_case_source (&file_type_source_class, fty);
create_col_var (&fty->record);
if (fty->case_sbc.name[0])
create_col_var (&fty->case_sbc);
+ vfm_source = create_case_source (&file_type_source_class, fty);
return CMD_SUCCESS;
spec.type = c->fmt;
spec.w = c->nc;
spec.d = 0;
- return check_input_specifier (&spec);
+ return check_input_specifier (&spec, 1);
}
\f
/* RECORD TYPE. */
}
}
- lex_match_id ("RECORD");
- lex_match_id ("TYPE");
-
/* Parse record type values. */
if (lex_match_id ("OTHER"))
rct->flags |= RCT_OTHER;
{
int mv = 0;
- while (token == T_NUM || token == T_STRING)
+ while (lex_is_number () || token == T_STRING)
{
if (rct->nv >= mv)
{
if (!lex_force_string ())
goto error;
rct->v[rct->nv].c = xmalloc (fty->record.nc + 1);
- st_bare_pad_copy (rct->v[rct->nv].c, ds_value (&tokstr),
- fty->record.nc + 1);
+ buf_copy_str_rpad (rct->v[rct->nv].c, fty->record.nc + 1,
+ ds_c_str (&tokstr));
}
else
{
\f
/* END FILE TYPE. */
+int cmd_end_file_type (void);
int
cmd_end_file_type (void)
{
return CMD_FAILURE;
}
fty = vfm_source->aux;
-
- lex_match_id ("TYPE");
+ fty->case_size = dict_get_case_size (default_dict);
if (fty->recs_tail)
{
static void read_from_file_type_grouped(void);
static void read_from_file_type_nested(void); */
-/* Reads any number of cases into temp_case and calls write_case() for
- each one. Compare data-list.c:read_from_data_list. */
+/* Reads any number of cases into case C and calls write_case()
+ for each one. Compare data-list.c:read_from_data_list. */
static void
file_type_source_read (struct case_source *source,
+ struct ccase *c,
write_case_func *write_case UNUSED,
write_case_data wc_data UNUSED)
{
struct file_type_pgm *fty = source->aux;
- char *line;
- int len;
-
struct fmt_spec format;
- dfm_push (fty->handle);
+ dfm_push (fty->reader);
format.type = fty->record.fmt;
format.w = fty->record.nc;
format.d = 0;
- while (NULL != (line = dfm_get_record (fty->handle, &len)))
+ while (!dfm_eof (fty->reader))
{
+ struct fixed_string line;
struct record_type *iter;
union value v;
int i;
+ dfm_expand_tabs (fty->reader);
+ dfm_get_record (fty->reader, &line);
if (formats[fty->record.fmt].cat & FCAT_STRING)
{
struct data_in di;
- v.c = temp_case->data[fty->record.v->fv].s;
+ v.c = case_data_rw (c, fty->record.v->fv)->s;
- data_in_finite_line (&di, line, len,
+ data_in_finite_line (&di, ls_c_str (&line), ls_length (&line),
fty->record.fc, fty->record.fc + fty->record.nc);
di.v = (union value *) v.c;
di.flags = 0;
{
struct data_in di;
- data_in_finite_line (&di, line, len,
+ data_in_finite_line (&di, ls_c_str (&line), ls_length (&line),
fty->record.fc, fty->record.fc + fty->record.nc);
di.v = &v;
di.flags = 0;
di.format = format;
data_in (&di);
- memcpy (&temp_case->data[fty->record.v->fv].f, &v.f, sizeof v.f);
+ case_data_rw (c, fty->record.v->fv)->f = v.f;
for (iter = fty->recs_head; iter; iter = iter->next)
{
if (iter->flags & RCT_OTHER)
if (fty->wild)
msg (SW, _("Unknown record type %g."), v.f);
}
- dfm_fwd_record (fty->handle);
+ dfm_forward_record (fty->reader);
continue;
found:
/* Arrive here if there is a matching record_type, which is in
iter. */
- dfm_fwd_record (fty->handle);
+ dfm_forward_record (fty->reader);
}
/* switch(fty->type)
default: assert(0);
} */
- dfm_pop (fty->handle);
+ dfm_pop (fty->reader);
}
static void
struct record_type *iter, *next;
cancel_transformations ();
+ dfm_close_reader (fty->reader);
for (iter = fty->recs_head; iter; iter = next)
{
next = iter->next;
const struct case_source_class file_type_source_class =
{
"FILE TYPE",
+ NULL,
file_type_source_read,
file_type_source_destroy,
};