/* 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 <blp@gnu.org>.
Code for parsing floating-point numbers adapted from GNU C
library.
#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
{
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));
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. */
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;
{
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;
}
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;
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);
}
}
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;
+}