From 399bf939cf7597e9dbe1810a07ffcb5c2ed57d32 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 17 Jun 2009 21:11:10 -0700 Subject: [PATCH] por-file-reader: Tolerate short lines when detecting portable files. When the portable file reader reads a file, it assumes that a line shorter than 80 bytes should actually be padded out on the right with spaces, because this is a fairly common problem in practice, perhaps due to text editors or other software that drops spaces at the end of a line. However, pfm_detect, the function that is supposed to detect whether a given file is an SPSS portable file, did not apply this heuristic to the data that it read at the beginning of the file, and thus files in which the first few lines were truncated this way were not detected properly as portable files. This commit fixes the problem by making pfm_detect a little bit smarter. It would probably be better to actually unify the file-reading logic, instead of implementing it in two separate places, but this appears to work adequately too. Thanks to Tony Reardon for reporting the problem and supplying a file that demonstrated it. --- src/data/por-file-reader.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/data/por-file-reader.c b/src/data/por-file-reader.c index 52c0cc8e..823361b0 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 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2009 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 @@ -867,17 +867,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); -- 2.30.2