/* PSPP - a program for statistical analysis.
- Copyright (C) 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2009, 2010, 2011, 2012, 2013 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
int *first_column, int *last_column, struct string *tmp,
struct substring *field)
{
+ size_t length_before_separators;
struct substring line, p;
+ bool quoted;
if (dfm_eof (reader))
return false;
}
*first_column = dfm_column_start (reader);
- if (ss_find_byte (parser->quotes, ss_first (p)) != SIZE_MAX)
+ quoted = ss_find_byte (parser->quotes, ss_first (p)) != SIZE_MAX;
+ if (quoted)
{
/* Quoted field. */
int quote = ss_get_byte (&p);
*field = ds_ss (tmp);
}
*last_column = *first_column + (ss_length (line) - ss_length (p));
-
- /* Skip trailing soft separator and a single hard separator
- if present. */
- if (!ss_is_empty (p))
- {
- size_t n_seps = ss_ltrim (&p, parser->soft_seps);
- if (!ss_is_empty (p)
- && ss_find_byte (parser->hard_seps, ss_first (p)) != SIZE_MAX)
- {
- ss_advance (&p, 1);
- n_seps++;
- }
- if (!n_seps)
- msg (DW, _("Missing delimiter following quoted string."));
- }
}
else
{
/* Regular field. */
ss_get_bytes (&p, ss_cspan (p, ds_ss (&parser->any_sep)), field);
*last_column = *first_column + ss_length (*field);
+ }
- if (!ss_ltrim (&p, parser->soft_seps) || ss_is_empty (p)
- || ss_find_byte (parser->hard_seps, p.string[0]) != SIZE_MAX)
- {
- /* Advance past a trailing hard separator,
- regardless of whether one actually existed. If
- we "skip" a delimiter that was not actually
- there, then we will return end-of-line on our
- next call, which is what we want. */
- dfm_forward_columns (reader, 1);
- }
+ /* Skip trailing soft separator and a single hard separator if present. */
+ length_before_separators = ss_length (p);
+ ss_ltrim (&p, parser->soft_seps);
+ if (!ss_is_empty (p)
+ && ss_find_byte (parser->hard_seps, ss_first (p)) != SIZE_MAX)
+ {
+ ss_advance (&p, 1);
+ ss_ltrim (&p, parser->soft_seps);
}
+ if (ss_is_empty (p))
+ dfm_forward_columns (reader, 1);
+ else if (quoted && length_before_separators == ss_length (p))
+ msg (DW, _("Missing delimiter following quoted string."));
dfm_forward_columns (reader, ss_length (line) - ss_length (p));
return true;
AT_SETUP([DATA LIST LIST with SKIP and tab delimiter])
AT_DATA([data-list.pspp], [dnl
-data list free (tab) skip=2/A B C D.
+data list list (tab) notable skip=2/A B C D.
begin data.
# These records
# are skipped.
])
AT_CLEANUP
+dnl Results of this test were confirmed with SPSS 21:
+dnl http://lists.gnu.org/archive/html/pspp-dev/2013-09/msg00003.html
+AT_SETUP([DATA LIST FREE with explicit delimiter at end of line])
+AT_DATA([data-list.pspp], [dnl
+DATA LIST FREE(',')/x y z.
+BEGIN DATA.
+1,2,3
+4,5,6
+7,8,9
+END DATA.
+LIST.
+
+DATA LIST FREE(',')/x y z.
+BEGIN DATA.
+11,12,13,
+14,15,16,
+17,18,19,
+END DATA.
+LIST.
+
+DATA LIST FREE(TAB)/x y z.
+BEGIN DATA.
+21 22 23
+24 25 26
+27 28 29
+END DATA.
+LIST.
+
+DATA LIST FREE(TAB)/x y z.
+BEGIN DATA.
+31 32 33 @&t@
+34 35 36 @&t@
+37 38 39 @&t@
+END DATA.
+LIST.
+])
+AT_CHECK([pspp -O format=csv data-list.pspp], [0], [dnl
+Table: Data List
+x,y,z
+1.00,2.00,3.00
+4.00,5.00,6.00
+7.00,8.00,9.00
+
+Table: Data List
+x,y,z
+11.00,12.00,13.00
+14.00,15.00,16.00
+17.00,18.00,19.00
+
+Table: Data List
+x,y,z
+21.00,22.00,23.00
+24.00,25.00,26.00
+27.00,28.00,29.00
+
+Table: Data List
+x,y,z
+31.00,32.00,33.00
+34.00,35.00,36.00
+37.00,38.00,39.00
+])
+AT_CLEANUP
+
AT_SETUP([DATA LIST FIXED with multiple records per case])
AT_DATA([data-list.pspp], [dnl
data list fixed notable