X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Fdata%2Fsys-file-reader.c;h=898b6739475b3fedc2e5ae29855747997a3d34f0;hb=207dcaa849d7c1d5090f198e9c86f9bfc484a89e;hp=f284f56e3f36a5de36d9acbe610626b55920f513;hpb=c5ad65b0351ab1d897eb072eeaec06fb37802b01;p=pspp diff --git a/src/data/sys-file-reader.c b/src/data/sys-file-reader.c index f284f56e3f..898b673947 100644 --- a/src/data/sys-file-reader.c +++ b/src/data/sys-file-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -42,7 +42,6 @@ #include "libpspp/array.h" #include "libpspp/assertion.h" #include "libpspp/compiler.h" -#include "libpspp/hash.h" #include "libpspp/i18n.h" #include "libpspp/message.h" #include "libpspp/misc.h" @@ -133,6 +132,10 @@ static void text_warn (struct sfm_reader *r, struct text_record *text, static char *text_get_token (struct text_record *, struct substring delimiters, char *delimiter); static bool text_match (struct text_record *, char c); +static bool text_read_variable_name (struct sfm_reader *, struct dictionary *, + struct text_record *, + struct substring delimiters, + struct variable **); static bool text_read_short_name (struct sfm_reader *, struct dictionary *, struct text_record *, struct substring delimiters, @@ -290,7 +293,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict, r->file = fn_open (fh_get_file_name (fh), "rb"); if (r->file == NULL) { - msg (ME, _("Error opening \"%s\" for reading as a system file: %s."), + msg (ME, _("Error opening `%s' for reading as a system file: %s."), fh_get_file_name (r->fh), strerror (errno)); goto error; } @@ -421,7 +424,7 @@ close_reader (struct sfm_reader *r) { if (fn_close (fh_get_file_name (r->fh), r->file) == EOF) { - msg (ME, _("Error closing system file \"%s\": %s."), + msg (ME, _("Error closing system file `%s': %s."), fh_get_file_name (r->fh), strerror (errno)); r->error = true; } @@ -592,7 +595,7 @@ read_variable_record (struct sfm_reader *r, struct dictionary *dict, /* Check variable name. */ if (name[0] == '$' || name[0] == '#') - sys_error (r, "Variable name begins with invalid character `%c'.", + sys_error (r, _("Variable name begins with invalid character `%c'."), name[0]); if (!var_is_plausible_name (name, false)) sys_error (r, _("Invalid variable name `%s'."), name); @@ -614,16 +617,20 @@ read_variable_record (struct sfm_reader *r, struct dictionary *dict, sys_error (r, _("Variable label indicator field is not 0 or 1.")); if (has_variable_label == 1) { - size_t len; + size_t len, read_len; char label[255 + 1]; len = read_int (r); - if (len >= sizeof label) - sys_error (r, _("Variable %s has label of invalid length %zu."), - name, len); - read_string (r, label, len + 1); + + /* Read up to 255 bytes of label. */ + read_len = MIN (sizeof label - 1, len); + read_string (r, label, read_len + 1); var_set_label (var, label); + /* Skip unread label bytes. */ + skip_bytes (r, len - read_len); + + /* Skip label padding up to multiple of 4 bytes. */ skip_bytes (r, ROUND_UP (len, 4) - len); } @@ -1040,13 +1047,20 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count, break; mrset->name = xstrdup (name); + if (mrset->name[0] != '$') + { + sys_warn (r, _("`%s' does not begin with `$' at offset %zu " + "in MRSETS record."), mrset->name, text_pos (text)); + break; + } + if (text_match (text, 'C')) { mrset->type = MRSET_MC; if (!text_match (text, ' ')) { - sys_warn (r, _("Missing space following 'C' at offset %zu " - "in MRSETS record"), text_pos (text)); + sys_warn (r, _("Missing space following `%c' at offset %zu " + "in MRSETS record"), 'C', text_pos (text)); break; } } @@ -1063,8 +1077,8 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count, mrset->cat_source = MRSET_COUNTEDVALUES; if (!text_match (text, ' ')) { - sys_warn (r, _("Missing space following 'E' at offset %zu " - "in MRSETS record"), text_pos (text)); + sys_warn (r, _("Missing space following `%c' at offset %zu " + "in MRSETS record"), 'E', text_pos (text)); break; } @@ -1072,13 +1086,13 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count, if (!strcmp (number, "11")) mrset->label_from_var_label = true; else if (strcmp (number, "1")) - sys_warn (r, _("Unexpected label source value \"%s\" " - "following 'E' at offset %zu in MRSETS record"), + sys_warn (r, _("Unexpected label source value `%s' " + "following `E' at offset %zu in MRSETS record"), number, text_pos (text)); } else { - sys_warn (r, _("Missing 'C', 'D', or 'E' at offset %zu " + sys_warn (r, _("Missing `C', `D', or `E' at offset %zu " "in MRSETS record."), text_pos (text)); break; @@ -1165,6 +1179,7 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count, dict_add_mrset (dict, mrset); mrset = NULL; + stringi_set_destroy (&var_names); } mrset_destroy (mrset); close_text_record (r, text); @@ -1494,7 +1509,7 @@ read_value_labels (struct sfm_reader *r, sys_warn (r, _("Duplicate value label for %g on %s."), label->value.f, var_get_name (v)); else - sys_warn (r, _("Duplicate value label for \"%.*s\" on %s."), + sys_warn (r, _("Duplicate value label for `%.*s' on %s."), max_width, value_str (&label->value, max_width), var_get_name (v)); } @@ -1671,11 +1686,11 @@ read_long_string_value_labels (struct sfm_reader *r, first 255 bytes. The maximum documented length of a label is 120 bytes so this is more than generous. */ - skip_bytes (r, sizeof label - (label_length + 1)); + skip_bytes (r, (label_length + 1) - sizeof label); } if (!skip && !var_add_value_label (v, &value, label)) - sys_warn (r, _("Duplicate value label for \"%.*s\" on %s."), + sys_warn (r, _("Duplicate value label for `%.*s' on %s."), width, value_str (&value, width), var_get_name (v)); } } @@ -1693,7 +1708,7 @@ read_variable_attributes (struct sfm_reader *r, for (;;) { struct variable *var; - if (!text_read_short_name (r, dict, text, ss_cstr (":"), &var)) + if (!text_read_variable_name (r, dict, text, ss_cstr (":"), &var)) break; read_attributes (r, text, var != NULL ? var_get_attributes (var) : NULL); } @@ -1758,11 +1773,11 @@ sys_file_casereader_read (struct casereader *reader, void *r_) return c; eof: - case_unref (c); if (i != 0) partial_record (r); if (r->case_cnt != -1) read_error (reader, r); + case_unref (c); return NULL; } @@ -2127,6 +2142,27 @@ read_variable_to_value_pair (struct sfm_reader *r, struct dictionary *dict, } } +static bool +text_read_variable_name (struct sfm_reader *r, struct dictionary *dict, + struct text_record *text, struct substring delimiters, + struct variable **var) +{ + char *name; + + name = text_get_token (text, delimiters, NULL); + if (name == NULL) + return false; + + *var = dict_lookup_var (dict, name); + if (*var != NULL) + return true; + + text_warn (r, text, _("Dictionary record refers to unknown variable %s."), + name); + return false; +} + + static bool text_read_short_name (struct sfm_reader *r, struct dictionary *dict, struct text_record *text, struct substring delimiters, @@ -2261,14 +2297,16 @@ sys_msg (struct sfm_reader *r, int class, const char *format, va_list args) struct string text; ds_init_empty (&text); - ds_put_format (&text, "\"%s\" near offset 0x%lx: ", - fh_get_file_name (r->fh), (unsigned long) ftell (r->file)); + ds_put_format (&text, "`%s' near offset 0x%llx: ", + fh_get_file_name (r->fh), (long long int) ftello (r->file)); ds_put_vformat (&text, format, args); m.category = msg_class_to_category (class); m.severity = msg_class_to_severity (class); m.where.file_name = NULL; m.where.line_number = 0; + m.where.first_column = 0; + m.where.last_column = 0; m.text = ds_cstr (&text); msg_emit (&m);