X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffile-type.c;h=4c7c4a03075931aaa0bcf25f7b2e0b4e88f8cf15;hb=bcf41af107e8dffb506a506f576c6535d1b3bde7;hp=fee98518557bb80ae0ad6021f51081b8be623054;hpb=f9d47b5bba8416419cf3bcd3aa23c2d40a05fcac;p=pspp-builds.git diff --git a/src/file-type.c b/src/file-type.c index fee98518..4c7c4a03 100644 --- a/src/file-type.c +++ b/src/file-type.c @@ -14,16 +14,18 @@ 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 -#include #include #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" @@ -31,6 +33,9 @@ #include "var.h" #include "vfm.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) + /* Defines the three types of complex files read by FILE TYPE. */ enum { @@ -42,7 +47,7 @@ enum /* 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. */ @@ -69,12 +74,11 @@ struct record_type int ft, lt; /* First, last transformation index. */ }; /* record_type */ -/* Represents a FILE TYPE input program. Does not contain a - trns_header because it's never submitted as a transformation. */ +/* Represents a FILE TYPE input program. */ 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. */ @@ -86,29 +90,32 @@ struct file_type_pgm 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 = fh_inline_file (); /* 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")) @@ -132,8 +139,8 @@ cmd_file_type (void) if (lex_match_id ("FILE")) { lex_match ('='); - fty->handle = fh_parse_file_handle (); - if (!fty->handle) + fh = fh_parse (FH_REF_FILE | FH_REF_INLINE); + if (fh == NULL) goto error; } else if (lex_match_id ("RECORD")) @@ -261,7 +268,7 @@ cmd_file_type (void) 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.")); @@ -269,12 +276,15 @@ cmd_file_type (void) } } - default_handle = fty->handle; + fty->reader = dfm_open_reader (fh); + if (fty->reader == NULL) + goto error; + fh_set_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; @@ -367,7 +377,7 @@ parse_col_spec (struct col_spec *c, const char *def_name) spec.type = c->fmt; spec.w = c->nc; spec.d = 0; - return check_input_specifier (&spec); + return check_input_specifier (&spec, 1); } /* RECORD TYPE. */ @@ -422,9 +432,6 @@ cmd_record_type (void) } } - lex_match_id ("RECORD"); - lex_match_id ("TYPE"); - /* Parse record type values. */ if (lex_match_id ("OTHER")) rct->flags |= RCT_OTHER; @@ -432,12 +439,12 @@ cmd_record_type (void) { int mv = 0; - while (token == T_NUM || token == T_STRING) + while (lex_is_number () || token == T_STRING) { if (rct->nv >= mv) { mv += 16; - rct->v = xrealloc (rct->v, mv * sizeof *rct->v); + rct->v = xnrealloc (rct->v, mv, sizeof *rct->v); } if (formats[fty->record.fmt].cat & FCAT_STRING) @@ -445,8 +452,8 @@ cmd_record_type (void) 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 { @@ -566,6 +573,7 @@ cmd_record_type (void) /* END FILE TYPE. */ +int cmd_end_file_type (void); int cmd_end_file_type (void) { @@ -579,8 +587,7 @@ 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) { @@ -616,37 +623,38 @@ cmd_end_file_type (void) 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; @@ -669,7 +677,7 @@ file_type_source_read (struct case_source *source, { 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; @@ -677,7 +685,7 @@ file_type_source_read (struct case_source *source, 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) @@ -689,13 +697,13 @@ file_type_source_read (struct case_source *source, 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) @@ -706,7 +714,7 @@ file_type_source_read (struct case_source *source, default: assert(0); } */ - dfm_pop (fty->handle); + dfm_pop (fty->reader); } static void @@ -716,6 +724,7 @@ file_type_source_destroy (struct case_source *source) struct record_type *iter, *next; cancel_transformations (); + dfm_close_reader (fty->reader); for (iter = fty->recs_head; iter; iter = next) { next = iter->next; @@ -726,6 +735,7 @@ file_type_source_destroy (struct case_source *source) const struct case_source_class file_type_source_class = { "FILE TYPE", + NULL, file_type_source_read, file_type_source_destroy, };