X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fpc%2B-file-reader.c;h=73b9ea804b715d83332d4af132d0225884dc0e48;hb=refs%2Fheads%2Frust;hp=c7c9e3b7f8b062b75d3e57c0ed5be2a262e34fe5;hpb=a49b940e58f148bf111c647d9b4822025636ff80;p=pspp diff --git a/src/data/pc+-file-reader.c b/src/data/pc+-file-reader.c index c7c9e3b7f8..73b9ea804b 100644 --- a/src/data/pc+-file-reader.c +++ b/src/data/pc+-file-reader.c @@ -80,6 +80,9 @@ struct pcp_var_record { unsigned int pos; + bool drop; + union value tmp; + char name[9]; int width; struct fmt_spec format; @@ -90,8 +93,6 @@ struct pcp_var_record struct pcp_value_label *val_labs; size_t n_val_labs; - - struct variable *var; }; struct pcp_value_label @@ -190,11 +191,10 @@ static bool parse_variable_records (struct pcp_reader *, struct dictionary *, static struct any_reader * pcp_open (struct file_handle *fh) { - struct pcp_reader *r; struct stat s; /* Create and initialize reader. */ - r = xzalloc (sizeof *r); + struct pcp_reader *r = XZALLOC (struct pcp_reader); r->any_reader.klass = &pcp_file_reader_class; r->pool = pool_create (); pool_register (r->pool, free, r); @@ -396,15 +396,7 @@ pcp_get_strings (const struct any_reader *r_, struct pool *pool, return aux.n; } -static void -find_and_delete_var (struct dictionary *dict, const char *name) -{ - struct variable *var = dict_lookup_var (dict, name); - if (var) - dict_delete_var (dict, var); -} - -/* Decodes the dictionary read from R, saving it into into *DICT. Character +/* Decodes the dictionary read from R, saving it into *DICT. Character strings in R are decoded using ENCODING, or an encoding obtained from R if ENCODING is null, or the locale encoding if R specifies no encoding. @@ -445,10 +437,6 @@ pcp_decode (struct any_reader *r_, const char *encoding, dictionary and may destroy or modify its variables. */ r->proto = caseproto_ref_pool (dict_get_proto (dict), r->pool); - find_and_delete_var (dict, "CASENUM_"); - find_and_delete_var (dict, "DATE_"); - find_and_delete_var (dict, "WEIGHT_"); - *dictp = dict; if (infop) { @@ -756,7 +744,7 @@ read_variables_record (struct pcp_reader *r) var->format.w = (format >> 8) & 0xff; var->format.d = format & 0xff; fmt_fix_output (&var->format); - var->width = fmt_var_width (&var->format); + var->width = fmt_var_width (var->format); if (var_label_ofs) { @@ -811,7 +799,7 @@ parse_header (struct pcp_reader *r, const struct pcp_main_header *header, info->integer_format = INTEGER_LSB_FIRST; info->float_format = FLOAT_IEEE_DOUBLE_LE; info->compression = r->compressed ? ANY_COMP_SIMPLE : ANY_COMP_NONE; - info->case_cnt = r->n_cases; + info->n_cases = r->n_cases; /* Convert file label to UTF-8 and put it into DICT. */ label = recode_and_trim_string (r->pool, dict_encoding, header->file_label); @@ -840,7 +828,6 @@ parse_variable_records (struct pcp_reader *r, struct dictionary *dict, for (rec = var_recs; rec < &var_recs[n_var_recs]; rec++) { - struct variable *var; char *name; size_t i; @@ -848,24 +835,28 @@ parse_variable_records (struct pcp_reader *r, struct dictionary *dict, rec->name, -1, r->pool); name[strcspn (name, " ")] = '\0'; - /* Transform $DATE => DATE_, $WEIGHT => WEIGHT_, $CASENUM => CASENUM_. */ - if (name[0] == '$') - name = pool_asprintf (r->pool, "%s_", name + 1); + /* Drop system variables. */ + rec->drop = name[0] == '$'; + if (rec->drop) + { + value_init_pool (r->pool, &rec->tmp, rec->width); + continue; + } - if (!dict_id_is_valid (dict, name, false) || name[0] == '#') + if (!dict_id_is_valid (dict, name) || name[0] == '#') { pcp_error (r, rec->pos, _("Invalid variable name `%s'."), name); return false; } - var = rec->var = dict_create_var (dict, name, rec->width); + struct variable *var = dict_create_var (dict, name, rec->width); if (var == NULL) { char *new_name = dict_make_unique_var_name (dict, NULL, NULL); pcp_warn (r, rec->pos, _("Renaming variable with duplicate name " "`%s' to `%s'."), name, new_name); - var = rec->var = dict_create_var_assert (dict, new_name, rec->width); + var = dict_create_var_assert (dict, new_name, rec->width); free (new_name); } if (rec->weight) @@ -925,7 +916,7 @@ parse_variable_records (struct pcp_reader *r, struct dictionary *dict, } /* Set formats. */ - var_set_both_formats (var, &rec->format); + var_set_both_formats (var, rec->format); } return true; @@ -958,10 +949,11 @@ pcp_file_casereader_read (struct casereader *reader, void *r_) r->n_cases--; c = case_create (r->proto); + size_t case_idx = 0; for (i = 0; i < r->n_vars; i++) { struct pcp_var_record *var = &r->vars[i]; - union value *v = case_data_rw_idx (c, i); + union value *v = var->drop ? &var->tmp : case_data_rw_idx (c, case_idx++); if (var->width == 0) retval = read_case_number (r, &v->f); @@ -1159,12 +1151,13 @@ pcp_msg (struct pcp_reader *r, off_t offset, ds_put_format (&text, _("`%s': "), fh_get_file_name (r->fh)); ds_put_vformat (&text, format, args); - struct msg m = { + struct msg *m = xmalloc (sizeof *m); + *m = (struct msg) { .category = msg_class_to_category (class), .severity = msg_class_to_severity (class), - .text = ds_cstr (&text), + .text = ds_steal_cstr (&text), }; - msg_emit (&m); + msg_emit (m); } /* Displays a warning for offset OFFSET in the file. */ @@ -1200,11 +1193,11 @@ pcp_error (struct pcp_reader *r, off_t offset, const char *format, ...) an error. */ static inline int read_bytes_internal (struct pcp_reader *r, bool eof_is_ok, - void *buf, size_t byte_cnt) + void *buf, size_t n_bytes) { - size_t bytes_read = fread (buf, 1, byte_cnt, r->file); + size_t bytes_read = fread (buf, 1, n_bytes, r->file); r->pos += bytes_read; - if (bytes_read == byte_cnt) + if (bytes_read == n_bytes) return 1; else if (ferror (r->file)) { @@ -1224,9 +1217,9 @@ read_bytes_internal (struct pcp_reader *r, bool eof_is_ok, Returns true if successful. Returns false upon I/O error or if end-of-file is encountered. */ static bool -read_bytes (struct pcp_reader *r, void *buf, size_t byte_cnt) +read_bytes (struct pcp_reader *r, void *buf, size_t n_bytes) { - return read_bytes_internal (r, false, buf, byte_cnt) == 1; + return read_bytes_internal (r, false, buf, n_bytes) == 1; } /* Reads BYTE_CNT bytes into BUF. @@ -1234,9 +1227,9 @@ read_bytes (struct pcp_reader *r, void *buf, size_t byte_cnt) Returns 0 if an immediate end-of-file is encountered. Returns -1 if an I/O error or a partial read occurs. */ static int -try_read_bytes (struct pcp_reader *r, void *buf, size_t byte_cnt) +try_read_bytes (struct pcp_reader *r, void *buf, size_t n_bytes) { - return read_bytes_internal (r, true, buf, byte_cnt); + return read_bytes_internal (r, true, buf, n_bytes); } /* Reads a 16-bit signed integer from R and stores its value in host format in