X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fpfm-read.c;h=f398747584ae9b7e48c5ffeee25bebfb66581fc1;hb=4f31116689eeda21658601c6ecf75a915b80103b;hp=24f9283379dd1b44d98b2e00f2e73e9488321b48;hpb=3417680e253b1bfc4519347ef06536378026be2a;p=pspp diff --git a/src/pfm-read.c b/src/pfm-read.c index 24f9283379..f398747584 100644 --- a/src/pfm-read.c +++ b/src/pfm-read.c @@ -1,5 +1,5 @@ /* PSPP - computes sample statistics. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. Written by Ben Pfaff . Code for parsing floating-point numbers adapted from GNU C library. @@ -49,6 +49,16 @@ #include "debug-print.h" +/* portable_to_local[PORTABLE] translates the given portable + character into the local character set. */ +static const char portable_to_local[256] = + { + " " + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ." + "<(+|&[]!$*);^-/|,%_>?`:$@'=\" ~- 0123456789 -() {}\\ " + " " + }; + /* Portable file reader. */ struct pfm_reader { @@ -82,7 +92,7 @@ error (struct pfm_reader *r, const char *msg, ...) e.class = ME; getl_location (&e.where.filename, &e.where.line_number); - filename = handle_get_filename (r->fh); + filename = fh_get_filename (r->fh); e.title = title = pool_alloc (r->pool, strlen (filename) + 80); sprintf (title, _("portable file %s corrupt at offset %ld: "), filename, ftell (r->file)); @@ -149,7 +159,7 @@ pfm_open_reader (struct file_handle *fh, struct dictionary **dict, struct pfm_reader *volatile r = NULL; *dict = dict_create (); - if (!fh_open (fh, "portable file", "rs")) + if (!fh_open (fh, FH_REF_FILE, "portable file", "rs")) goto error; /* Create and initialize reader. */ @@ -159,7 +169,7 @@ pfm_open_reader (struct file_handle *fh, struct dictionary **dict, if (setjmp (r->bail_out)) goto error; r->fh = fh; - r->file = pool_fopen (r->pool, handle_get_filename (r->fh), "rb"); + r->file = pool_fopen (r->pool, fh_get_filename (r->fh), "rb"); r->weight_index = -1; r->trans = NULL; r->var_cnt = 0; @@ -171,7 +181,7 @@ pfm_open_reader (struct file_handle *fh, struct dictionary **dict, { msg (ME, _("An error occurred while opening \"%s\" for reading " "as a portable file: %s."), - handle_get_filename (r->fh), strerror (errno)); + fh_get_filename (r->fh), strerror (errno)); err_cond_fail (); goto error; } @@ -353,16 +363,6 @@ read_pool_string (struct pfm_reader *r) static void read_header (struct pfm_reader *r) { - /* portable_to_local[PORTABLE] translates the given portable - character into the local character set. */ - static const char portable_to_local[256] = - { - " " - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ." - "<(+|&[]!$*);^-/|,%_>?`:$@'=\" ~- 0123456789 -() {}\\ " - " " - }; - char *trans; int i; @@ -400,7 +400,7 @@ read_header (struct pfm_reader *r) for (i = 0; i < 8; i++) if (!match (r, "SPSSPORT"[i])) { - msg (SE, _("%s: Not a portable file."), handle_get_filename (r->fh)); + msg (SE, _("%s: Not a portable file."), fh_get_filename (r->fh)); longjmp (r->bail_out, 1); } } @@ -492,7 +492,7 @@ read_variables (struct pfm_reader *r, struct dictionary *dict) r->var_cnt = read_int (r); if (r->var_cnt <= 0 || r->var_cnt == NOT_INT) error (r, _("Invalid number of variables %d."), r->var_cnt); - r->widths = pool_alloc (r->pool, sizeof *r->widths * r->var_cnt); + r->widths = pool_nalloc (r->pool, r->var_cnt, sizeof *r->widths); /* Purpose of this value is unknown. It is typically 161. */ read_int (r); @@ -608,7 +608,7 @@ read_value_label (struct pfm_reader *r, struct dictionary *dict) int i; nv = read_int (r); - v = pool_alloc (r->pool, sizeof *v * nv); + v = pool_nalloc (r->pool, nv, sizeof *v); for (i = 0; i < nv; i++) { char name[256]; @@ -687,3 +687,38 @@ pfm_read_case (struct pfm_reader *r, struct ccase *c) return true; } + +/* Returns true if FILE is an SPSS portable file, + false otherwise. */ +bool +pfm_detect (FILE *file) +{ + unsigned char header[464]; + char trans[256]; + int cooked_cnt, raw_cnt; + int i; + + cooked_cnt = raw_cnt = 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; + } + + memset (trans, 0, 256); + for (i = 64; i < 256; i++) + { + unsigned char c = header[i + 200]; + if (trans[c] == 0) + trans[c] = portable_to_local[i]; + } + + for (i = 0; i < 8; i++) + if (trans[header[i + 456]] != "SPSSPORT"[i]) + return false; + + return true; +}