You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#include <config.h>
#include "pfm-read.h"
#include <math.h>
#include <setjmp.h>
#include "alloc.h"
-#include "bool.h"
+#include <stdbool.h>
#include "case.h"
#include "dictionary.h"
#include "file-handle.h"
#include "format.h"
-#include "getline.h"
+#include "getl.h"
#include "hash.h"
#include "magic.h"
#include "misc.h"
#include "value-labels.h"
#include "var.h"
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
#include "debug-print.h"
/* Portable file reader. */
struct file_handle *fh; /* File handle. */
FILE *file; /* File stream. */
char cc; /* Current character. */
- unsigned char *trans; /* 256-byte character set translation table. */
-
+ char *trans; /* 256-byte character set translation table. */
int var_cnt; /* Number of variables. */
int weight_index; /* 0-based index of weight variable, or -1. */
int *widths; /* Variable widths, 0 for numeric. */
getl_location (&e.where.filename, &e.where.line_number);
filename = handle_get_filename (r->fh);
e.title = title = pool_alloc (r->pool, strlen (filename) + 80);
- sprintf (e.title, _("portable file %s corrupt at offset %ld: "),
+ sprintf (title, _("portable file %s corrupt at offset %ld: "),
filename, ftell (r->file));
va_start (args, msg);
/* Reads a string and returns a copy of it allocated from R's
pool. */
-static unsigned char *
+static char *
read_pool_string (struct pfm_reader *r)
{
char string[256];
{
/* portable_to_local[PORTABLE] translates the given portable
character into the local character set. */
- static const unsigned char portable_to_local[256] =
+ static const char portable_to_local[256] =
{
" "
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ."
" "
};
- unsigned char *trans;
+ char *trans;
int i;
/* Read and ignore vanity splash strings. */
/* Skip and verify signature. */
for (i = 0; i < 8; i++)
- if (!match (r, "SPSSPORT"[i]))
- error (r, _("Missing SPSSPORT signature."));
+ if (!match (r, "SPSSPORT"[i]))
+ {
+ msg (SE, _("%s: Not a portable file."), handle_get_filename (r->fh));
+ longjmp (r->bail_out, 1);
+ }
}
/* Reads the version and date info record, as well as product and
static void
read_version_data (struct pfm_reader *r, struct pfm_read_info *info)
{
- char *date, *time, *product, *subproduct;
+ static char empty_string[] = "";
+ char *date, *time, *product, *author, *subproduct;
int i;
/* Read file. */
error (r, "Unrecognized version code `%c'.", r->cc);
date = read_pool_string (r);
time = read_pool_string (r);
- product = match (r, '1') ? read_pool_string (r) : (unsigned char *) "";
- subproduct
- = match (r, '3') ? read_pool_string (r) : (unsigned char *) "";
+ product = match (r, '1') ? read_pool_string (r) : empty_string;
+ author = match (r, '2') ? read_pool_string (r) : empty_string;
+ subproduct = match (r, '3') ? read_pool_string (r) : empty_string;
/* Validate file. */
if (strlen (date) != 8)
info->creation_time[8] = 0;
/* Product. */
- st_trim_copy (info->product, product, sizeof info->product);
- st_trim_copy (info->subproduct, subproduct, sizeof info->subproduct);
+ str_copy_trunc (info->product, sizeof info->product, product);
+ str_copy_trunc (info->subproduct, sizeof info->subproduct, subproduct);
}
}
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);
if (match (r, '6'))
{
weight_name = read_pool_string (r);
- if (strlen (weight_name) > 8)
+ if (strlen (weight_name) > SHORT_NAME_LEN)
error (r, _("Weight variable name (%s) truncated."), weight_name);
}
for (j = 0; j < 6; j++)
fmt[j] = read_int (r);
- if (!var_is_valid_name (name, false) || *name == '#')
- error (r, _("position %d: Invalid variable name `%s'."), name);
- st_uppercase (name);
+ if (!var_is_valid_name (name, false) || *name == '#' || *name == '$')
+ error (r, _("position %d: Invalid variable name `%s'."), i, name);
+ str_uppercase (name);
if (width < 0 || width > 255)
error (r, "Bad width %d for variable %s.", width, name);
convert_format (r, &fmt[3], &v->write, v);
/* Range missing values. */
- if (match (r, 'B'))
- {
- v->miss_type = MISSING_RANGE;
- v->missing[0] = parse_value (r, v);
- v->missing[1] = parse_value (r, v);
- }
+ if (match (r, 'B'))
+ {
+ double x = read_float (r);
+ double y = read_float (r);
+ mv_add_num_range (&v->miss, x, y);
+ }
else if (match (r, 'A'))
- {
- v->miss_type = MISSING_HIGH;
- v->missing[0] = parse_value (r, v);
- }
+ mv_add_num_range (&v->miss, read_float (r), HIGHEST);
else if (match (r, '9'))
- {
- v->miss_type = MISSING_LOW;
- v->missing[0] = parse_value (r, v);
- }
+ mv_add_num_range (&v->miss, LOWEST, read_float (r));
/* Single missing values. */
- while (match (r, '8'))
- {
- static const int map_next[MISSING_COUNT] =
- {
- MISSING_1, MISSING_2, MISSING_3, -1,
- MISSING_RANGE_1, MISSING_LOW_1, MISSING_HIGH_1,
- -1, -1, -1,
- };
-
- static const int map_ofs[MISSING_COUNT] =
- {
- -1, 0, 1, 2, -1, -1, -1, 2, 1, 1,
- };
-
- v->miss_type = map_next[v->miss_type];
- if (v->miss_type == -1)
- error (r, _("Bad missing values for %s."), v->name);
-
- assert (map_ofs[v->miss_type] != -1);
- v->missing[map_ofs[v->miss_type]] = parse_value (r, v);
- }
+ while (match (r, '8'))
+ {
+ union value value = parse_value (r, v);
+ mv_add_value (&v->miss, &value);
+ }
if (match (r, 'C'))
{
{
char string[256];
read_string (r, string);
- st_bare_pad_copy (v.s, string, 8);
+ buf_copy_str_rpad (v.s, 8, string);
}
else
v.f = read_float (r);
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];
{
char string[256];
read_string (r, string);
- st_bare_pad_copy (case_data_rw (c, idx)->s, string, width);
+ buf_copy_str_rpad (case_data_rw (c, idx)->s, width, string);
idx += DIV_RND_UP (width, MAX_SHORT_STRING);
}
}