X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fpor-file-reader.c;h=58d4d03985688b5a39e03872811b0f2038907c6b;hb=refs%2Fbuilds%2F20110525030502%2Fpspp;hp=00ca4196fd502314b558693e54fea300b8663275;hpb=5c3291dc396b795696e94f47780308fd7ace6fc4;p=pspp
diff --git a/src/data/por-file-reader.c b/src/data/por-file-reader.c
index 00ca4196fd..58d4d03985 100644
--- a/src/data/por-file-reader.c
+++ b/src/data/por-file-reader.c
@@ -1,5 +1,5 @@
/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 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
@@ -15,7 +15,8 @@
along with this program. If not, see . */
#include
-#include "por-file-reader.h"
+
+#include "data/por-file-reader.h"
#include
#include
@@ -26,24 +27,26 @@
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "xalloc.h"
+#include "data/casereader-provider.h"
+#include "data/casereader.h"
+#include "data/dictionary.h"
+#include "data/file-handle-def.h"
+#include "data/file-name.h"
+#include "data/format.h"
+#include "data/missing-values.h"
+#include "data/short-names.h"
+#include "data/value-labels.h"
+#include "data/variable.h"
+#include "libpspp/compiler.h"
+#include "libpspp/i18n.h"
+#include "libpspp/message.h"
+#include "libpspp/misc.h"
+#include "libpspp/pool.h"
+#include "libpspp/str.h"
+
+#include "gl/intprops.h"
+#include "gl/minmax.h"
+#include "gl/xalloc.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
@@ -95,16 +98,19 @@ error (struct pfm_reader *r, const char *msg, ...)
va_list args;
ds_init_empty (&text);
- ds_put_format (&text, _("portable file %s corrupt at offset 0x%lx: "),
- fh_get_file_name (r->fh), ftell (r->file));
+ ds_put_format (&text, _("portable file %s corrupt at offset 0x%llx: "),
+ fh_get_file_name (r->fh), (long long int) ftello (r->file));
va_start (args, msg);
ds_put_vformat (&text, msg, args);
va_end (args);
- m.category = MSG_GENERAL;
- m.severity = MSG_ERROR;
- m.where.file_name = NULL;
- m.where.line_number = 0;
+ m.category = MSG_C_GENERAL;
+ m.severity = MSG_S_ERROR;
+ m.file_name = NULL;
+ m.first_line = 0;
+ m.last_line = 0;
+ m.first_column = 0;
+ m.last_column = 0;
m.text = ds_cstr (&text);
msg_emit (&m);
@@ -124,16 +130,19 @@ warning (struct pfm_reader *r, const char *msg, ...)
va_list args;
ds_init_empty (&text);
- ds_put_format (&text, _("reading portable file %s at offset 0x%lx: "),
- fh_get_file_name (r->fh), ftell (r->file));
+ ds_put_format (&text, _("reading portable file %s at offset 0x%llx: "),
+ fh_get_file_name (r->fh), (long long int) ftello (r->file));
va_start (args, msg);
ds_put_vformat (&text, msg, args);
va_end (args);
- m.category = MSG_GENERAL;
- m.severity = MSG_WARNING;
- m.where.file_name = NULL;
- m.where.line_number = 0;
+ m.category = MSG_C_GENERAL;
+ m.severity = MSG_S_WARNING;
+ m.file_name = NULL;
+ m.first_line = 0;
+ m.last_line = 0;
+ m.first_column = 0;
+ m.last_column = 0;
m.text = ds_cstr (&text);
msg_emit (&m);
@@ -152,7 +161,7 @@ close_reader (struct pfm_reader *r)
{
if (fn_close (fh_get_file_name (r->fh), r->file) == EOF)
{
- msg (ME, _("Error closing portable file \"%s\": %s."),
+ msg (ME, _("Error closing portable file `%s': %s."),
fh_get_file_name (r->fh), strerror (errno));
r->ok = false;
}
@@ -242,7 +251,7 @@ pfm_open_reader (struct file_handle *fh, struct dictionary **dict,
struct pool *volatile pool = NULL;
struct pfm_reader *volatile r = NULL;
- *dict = dict_create ();
+ *dict = dict_create (get_default_encoding ());
/* Create and initialize reader. */
pool = pool_create ();
@@ -271,7 +280,7 @@ pfm_open_reader (struct file_handle *fh, struct dictionary **dict,
r->file = fn_open (fh_get_file_name (r->fh), "rb");
if (r->file == NULL)
{
- msg (ME, _("An error occurred while opening \"%s\" for reading "
+ msg (ME, _("An error occurred while opening `%s' for reading "
"as a portable file: %s."),
fh_get_file_name (r->fh), strerror (errno));
goto error;
@@ -446,6 +455,28 @@ read_string (struct pfm_reader *r, char *buf)
*buf = '\0';
}
+
+/* Reads a string into BUF, which must have room for 256
+ characters.
+ Returns the number of bytes read.
+*/
+static size_t
+read_bytes (struct pfm_reader *r, uint8_t *buf)
+{
+ int n = read_int (r);
+ if (n < 0 || n > 255)
+ error (r, _("Bad string length %d."), n);
+
+ while (n-- > 0)
+ {
+ *buf++ = r->cc;
+ advance (r);
+ }
+ return n;
+}
+
+
+
/* Reads a string and returns a copy of it allocated from R's
pool. */
static char *
@@ -606,8 +637,7 @@ assign_default:
return fmt_default_for_width (var_get_width (v));
}
-static void parse_value (struct pfm_reader *, struct variable *,
- union value *);
+static void parse_value (struct pfm_reader *, int width, union value *);
/* Read information on all the variables. */
static void
@@ -655,7 +685,8 @@ read_variables (struct pfm_reader *r, struct dictionary *dict)
for (j = 0; j < 6; j++)
fmt[j] = read_int (r);
- if (!var_is_valid_name (name, false) || *name == '#' || *name == '$')
+ if (!dict_id_is_valid (dict, name, false)
+ || *name == '#' || *name == '$')
error (r, _("Invalid variable name `%s' in position %d."), name, i);
str_uppercase (name);
@@ -665,17 +696,15 @@ read_variables (struct pfm_reader *r, struct dictionary *dict)
v = dict_create_var (dict, name, width);
if (v == NULL)
{
- int i;
- for (i = 1; i < 100000; i++)
+ unsigned long int i;
+ for (i = 1; ; i++)
{
- char try_name[VAR_NAME_LEN + 1];
- sprintf (try_name, "%.*s_%d", VAR_NAME_LEN - 6, name, i);
+ char try_name[8 + 1 + INT_STRLEN_BOUND (i) + 1];
+ sprintf (try_name, "%s_%lu", name, i);
v = dict_create_var (dict, try_name, width);
if (v != NULL)
break;
}
- if (v == NULL)
- error (r, _("Duplicate variable name %s in position %d."), name, i);
warning (r, _("Duplicate variable name %s in position %d renamed "
"to %s."), name, i, var_get_name (v));
}
@@ -686,7 +715,7 @@ read_variables (struct pfm_reader *r, struct dictionary *dict)
var_set_write_format (v, &write);
/* Range missing values. */
- mv_init (&miss, var_get_width (v));
+ mv_init (&miss, width);
if (match (r, 'B'))
{
double x = read_float (r);
@@ -701,19 +730,23 @@ read_variables (struct pfm_reader *r, struct dictionary *dict)
/* Single missing values. */
while (match (r, '8'))
{
+ int mv_width = MIN (width, 8);
union value value;
- parse_value (r, v, &value);
+
+ parse_value (r, mv_width, &value);
+ value_resize (&value, mv_width, width);
mv_add_value (&miss, &value);
- value_destroy (&value, var_get_width (v));
+ value_destroy (&value, width);
}
var_set_missing_values (v, &miss);
+ mv_destroy (&miss);
if (match (r, 'C'))
{
char label[256];
read_string (r, label);
- var_set_label (v, label);
+ var_set_label (v, label, false); /* XXX */
}
}
@@ -728,16 +761,16 @@ read_variables (struct pfm_reader *r, struct dictionary *dict)
}
}
-/* Parse a value for variable VV into value V. */
+/* Parse a value of with WIDTH into value V. */
static void
-parse_value (struct pfm_reader *r, struct variable *vv, union value *v)
+parse_value (struct pfm_reader *r, int width, union value *v)
{
- value_init (v, var_get_width (vv));
- if (var_is_alpha (vv))
+ value_init (v, width);
+ if (width > 0)
{
- char string[256];
- read_string (r, string);
- buf_copy_str_rpad (value_str_rw (v, 8), 8, string, ' ');
+ uint8_t buf[256];
+ size_t n_bytes = read_bytes (r, buf);
+ value_copy_buf_rpad (v, width, buf, n_bytes, ' ');
}
else
v->f = read_float (r);
@@ -780,17 +813,12 @@ read_value_label (struct pfm_reader *r, struct dictionary *dict)
char label[256];
int j;
- parse_value (r, v[0], &val);
+ parse_value (r, var_get_width (v[0]), &val);
read_string (r, label);
/* Assign the value label to each variable. */
for (j = 0; j < nv; j++)
- {
- struct variable *var = v[j];
-
- if (!var_is_long_string (var))
- var_replace_value_label (var, &val, label);
- }
+ var_replace_value_label (v[j], &val, label);
value_destroy (&val, var_get_width (v[0]));
}
@@ -808,7 +836,7 @@ read_documents (struct pfm_reader *r, struct dictionary *dict)
{
char line[256];
read_string (r, line);
- dict_add_document_line (dict, line);
+ dict_add_document_line (dict, line, false);
}
}
@@ -820,7 +848,6 @@ por_file_casereader_read (struct casereader *reader, void *r_)
struct pfm_reader *r = r_;
struct ccase *volatile c;
size_t i;
- size_t idx;
c = case_create (r->proto);
setjmp (r->bail_out);
@@ -838,22 +865,17 @@ por_file_casereader_read (struct casereader *reader, void *r_)
return NULL;
}
- idx = 0;
for (i = 0; i < r->var_cnt; i++)
{
int width = caseproto_get_width (r->proto, i);
if (width == 0)
- {
- case_data_rw_idx (c, idx)->f = read_float (r);
- idx++;
- }
+ case_data_rw_idx (c, i)->f = read_float (r);
else
{
- char string[256];
- read_string (r, string);
- buf_copy_str_rpad (case_str_rw_idx (c, idx), width, string, ' ');
- idx += DIV_RND_UP (width, MAX_SHORT_STRING);
+ uint8_t buf[256];
+ size_t n_bytes = read_bytes (r, buf);
+ u8_buf_copy_rpad (case_str_rw_idx (c, i), width, buf, n_bytes, ' ');
}
}
@@ -867,17 +889,30 @@ pfm_detect (FILE *file)
{
unsigned char header[464];
char trans[256];
- int cooked_cnt, raw_cnt;
+ int cooked_cnt, raw_cnt, line_len;
int i;
cooked_cnt = raw_cnt = 0;
+ line_len = 0;
while (cooked_cnt < sizeof header)
{
int c = getc (file);
if (c == EOF || raw_cnt++ > 512)
return false;
- else if (c != '\n' && c != '\r')
- header[cooked_cnt++] = c;
+ else if (c == '\n')
+ {
+ while (line_len < 80 && cooked_cnt < sizeof header)
+ {
+ header[cooked_cnt++] = ' ';
+ line_len++;
+ }
+ line_len = 0;
+ }
+ else if (c != '\r')
+ {
+ header[cooked_cnt++] = c;
+ line_len++;
+ }
}
memset (trans, 0, 256);