Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package perl-Text-CSV_XS for
openSUSE:Factory checked in at 2023-08-09 17:24:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Text-CSV_XS (Old)
and /work/SRC/openSUSE:Factory/.perl-Text-CSV_XS.new.11712 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Text-CSV_XS"
Wed Aug 9 17:24:28 2023 rev:50 rq:1102958 version:1.510.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Text-CSV_XS/perl-Text-CSV_XS.changes
2023-03-11 18:24:22.306984348 +0100
+++
/work/SRC/openSUSE:Factory/.perl-Text-CSV_XS.new.11712/perl-Text-CSV_XS.changes
2023-08-09 17:24:32.549114756 +0200
@@ -1,0 +2,15 @@
+Tue Aug 8 03:10:51 UTC 2023 - Tina Müller <[email protected]>
+
+- updated to 1.51
+ see /usr/share/doc/packages/perl-Text-CSV_XS/ChangeLog
+
+ 1.51 - 2023-08-07, H.Merijn Brand
+ * Contact e-mail update
+ * Attribute skip_empty_rows extended
+ * Fix comments (PR#45)
+ * Fix help (x12340, PR#46)
+ * Update to Devel::PPPort-3.71
+ * Fix HTML on Windows
+ * Fix double header-interpretation on bom + headers => "auto" (issue 47)
+
+-------------------------------------------------------------------
Old:
----
Text-CSV_XS-1.50.tgz
New:
----
Text-CSV_XS-1.51.tgz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-Text-CSV_XS.spec ++++++
--- /var/tmp/diff_new_pack.9BRxaQ/_old 2023-08-09 17:24:33.117118292 +0200
+++ /var/tmp/diff_new_pack.9BRxaQ/_new 2023-08-09 17:24:33.121118317 +0200
@@ -18,15 +18,18 @@
%define cpan_name Text-CSV_XS
Name: perl-Text-CSV_XS
-Version: 1.50
+Version: 1.510.0
Release: 0
+%define cpan_version 1.51
License: Artistic-1.0 OR GPL-1.0-or-later
Summary: Comma-Separated Values manipulation routines
URL: https://metacpan.org/release/%{cpan_name}
-Source0:
https://cpan.metacpan.org/authors/id/H/HM/HMBRAND/%{cpan_name}-%{version}.tgz
+Source0:
https://cpan.metacpan.org/authors/id/H/HM/HMBRAND/%{cpan_name}-%{cpan_version}.tgz
Source1: cpanspec.yml
BuildRequires: perl
BuildRequires: perl-macros
+Provides: perl(Text::CSV_XS) = 1.510.0
+%define __perllib_provides /bin/true
Recommends: perl(Encode) >= 3.19
%{perl_requires}
@@ -39,9 +42,9 @@
user-specified characters for delimiters, separators, and escapes.
%prep
-%autosetup -n %{cpan_name}-%{version}
+%autosetup -n %{cpan_name}-%{cpan_version}
-find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path
"*/script/*" ! -name "configure" -print0 | xargs -0 chmod 644
+find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path
"*/script/*" ! -path "*/scripts/*" ! -name "configure" -print0 | xargs -0 chmod
644
# MANUAL BEGIN
sed -i -e 's,/pro/bin/perl,/usr/bin/perl,' examples/*
# MANUAL END
++++++ Text-CSV_XS-1.50.tgz -> Text-CSV_XS-1.51.tgz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/CSV_XS.pm
new/Text-CSV_XS-1.51/CSV_XS.pm
--- old/Text-CSV_XS-1.50/CSV_XS.pm 2023-03-01 09:35:05.000000000 +0100
+++ new/Text-CSV_XS-1.51/CSV_XS.pm 2023-08-07 13:57:49.000000000 +0200
@@ -9,12 +9,9 @@
# HISTORY
#
-# 0.24 -
-# H.Merijn Brand ([email protected])
-# 0.10 - 0.23
-# Jochen Wiedmann <[email protected]>
-# Based on (the original) Text::CSV by:
-# Alan Citterman <[email protected]>
+# 0.24 - H.Merijn Brand <[email protected]>
+# 0.10 - 0.23 Jochen Wiedmann <[email protected]>
+# Based on (the original) Text::CSV by Alan Citterman <[email protected]>
require 5.006001;
@@ -26,7 +23,7 @@
use Carp;
use vars qw( $VERSION @ISA @EXPORT_OK %EXPORT_TAGS );
-$VERSION = "1.50";
+$VERSION = "1.51";
@ISA = qw( Exporter );
XSLoader::load ("Text::CSV_XS", $VERSION);
@@ -51,7 +48,7 @@
CSV_TYPE_NV
)],
);
-@EXPORT_OK = (qw( csv PV IV NV ), @{$EXPORT_TAGS{CONSTANTS}});
+@EXPORT_OK = (qw( csv PV IV NV ), @{$EXPORT_TAGS{'CONSTANTS'}});
if ($] < 5.008002) {
no warnings "redefine";
@@ -113,6 +110,7 @@
'_BOUND_COLUMNS' => undef,
'_AHEAD' => undef,
'_FORMULA_CB' => undef,
+ '_EMPTROW_CB' => undef,
'ENCODING' => undef,
);
@@ -255,8 +253,9 @@
$last_new_err = Text::CSV_XS->SetDiag (0);
defined $\ && !exists $attr{'eol'} and $self->{'eol'} = $\;
bless $self, $class;
- defined $self->{'types'} and $self->types ($self->{'types'});
- defined $attr_formula and $self->{'formula'} = _supported_formula ($self,
$attr_formula);
+ defined $self->{'types'} and $self->types ($self->{'types'});
+ defined $self->{'skip_empty_rows'} and $self->{'skip_empty_rows'} =
_supported_skip_empty_rows ($self, $self->{'skip_empty_rows'});
+ defined $attr_formula and $self->{'formula'} =
_supported_formula ($self, $attr_formula);
$self;
} # new
@@ -455,13 +454,36 @@
my $self = shift;
@_ and $self->_set_attr_X ("strict", shift);
$self->{'strict'};
- } # always_quote
+ } # strict
+
+sub _supported_skip_empty_rows {
+ my ($self, $f) = @_;
+ defined $f or return 0;
+ if ($self && $f && ref $f && ref $f eq "CODE") {
+ $self->{'_EMPTROW_CB'} = $f;
+ return 6;
+ }
+ $f =~ m/^(?: 0 | undef )$/xi ? 0 :
+ $f =~ m/^(?: 1 | skip )$/xi ? 1 :
+ $f =~ m/^(?: 2 | eof | stop )$/xi ? 2 :
+ $f =~ m/^(?: 3 | die )$/xi ? 3 :
+ $f =~ m/^(?: 4 | croak )$/xi ? 4 :
+ $f =~ m/^(?: 5 | error )$/xi ? 5 :
+ $f =~ m/^(?: 6 | cb )$/xi ? 6 : do {
+ $self ||= "Text::CSV_XS";
+ croak ($self->_SetDiagInfo (1500, "skip_empty_rows '$f' is not
supported"));
+ };
+ } # _supported_skip_empty_rows
sub skip_empty_rows {
my $self = shift;
- @_ and $self->_set_attr_X ("skip_empty_rows", shift);
- $self->{'skip_empty_rows'};
- } # always_quote
+ @_ and $self->_set_attr_N ("skip_empty_rows", _supported_skip_empty_rows
($self, shift));
+ my $ser = $self->{'skip_empty_rows'};
+ $ser == 6 or $self->{'_EMPTROW_CB'} = undef;
+ $ser <= 1 ? $ser : $ser == 2 ? "eof" : $ser == 3 ? "die" :
+ $ser == 4 ? "croak" : $ser == 5 ? "error" :
+ $self->{'_EMPTROW_CB'};
+ } # skip_empty_rows
sub _SetDiagInfo {
my ($self, $err, $msg) = @_;
@@ -496,7 +518,8 @@
@_ and $self->_set_attr_N ("formula", _supported_formula ($self, shift));
$self->{'formula'} == 6 or $self->{'_FORMULA_CB'} = undef;
[qw( none die croak diag empty undef cb )]->[_supported_formula ($self,
$self->{'formula'})];
- } # always_quote
+ } # formula
+
sub formula_handling {
my $self = shift;
$self->formula (@_);
@@ -621,7 +644,7 @@
sub eof {
my $self = shift;
return $self->{'_EOF'};
- } # status
+ } # eof
sub types {
my $self = shift;
@@ -996,7 +1019,7 @@
ref $args{'munge_column_names'} eq "HASH" and
@hdr = map { $args{'munge_column_names'}->{$_} || $_ } @hdr;
my %hdr; $hdr{$_}++ for @hdr;
- exists $hdr{""} and croak ($self->SetDiag (1012));
+ exists $hdr{''} and croak ($self->SetDiag (1012));
unless (keys %hdr == @hdr) {
croak ($self->_SetDiagInfo (1013, join ", " =>
map { "$_ ($hdr{$_})" } grep { $hdr{$_} > 1 } keys %hdr));
@@ -1390,7 +1413,7 @@
!defined $c->{'hd_s'} && $c->{'attr'}{'sep'} and
$c->{'hd_s'} = [ $c->{'attr'}{'sep'} ];
defined $c->{'hd_s'} and $harg{'sep_set'} = $c->{'hd_s'};
- defined $c->{'hd_d'} and $harg{'detect_bom'} = $c->{'hd_b'};
+ defined $c->{'hd_b'} and $harg{'detect_bom'} = $c->{'hd_b'};
defined $c->{'hd_m'} and $harg{'munge_column_names'} = $hdrs ? "none"
: $c->{'hd_m'};
defined $c->{'hd_c'} and $harg{'set_column_names'} = $hdrs ? 0
: $c->{'hd_c'};
@row1 = $csv->header ($fh, \%harg);
@@ -1417,28 +1440,33 @@
$c->{'fltr'} && grep m/\D/ => keys %{$c->{'fltr'}} and $hdrs ||= "auto";
if (defined $hdrs) {
- if (!ref $hdrs) {
- if ($hdrs eq "skip") {
- $csv->getline ($fh); # discard;
+ if (!ref $hdrs or ref $hdrs eq "CODE") {
+ my $h = $c->{'hd_b'}
+ ? [ $csv->column_names () ]
+ : $csv->getline ($fh);
+ my $has_h = $h && @$h;
+
+ if (ref $hdrs) {
+ $has_h or return;
+ my $cr = $hdrs;
+ $hdrs = [ map { $cr->($hdr{$_} || $_) } @{$h} ];
+ }
+ elsif ($hdrs eq "skip") {
+ # discard;
}
elsif ($hdrs eq "auto") {
- my $h = $csv->getline ($fh) or return;
+ $has_h or return;
$hdrs = [ map { $hdr{$_} || $_ } @{$h} ];
}
elsif ($hdrs eq "lc") {
- my $h = $csv->getline ($fh) or return;
+ $has_h or return;
$hdrs = [ map { lc ($hdr{$_} || $_) } @{$h} ];
}
elsif ($hdrs eq "uc") {
- my $h = $csv->getline ($fh) or return;
+ $has_h or return;
$hdrs = [ map { uc ($hdr{$_} || $_) } @{$h} ];
}
}
- elsif (ref $hdrs eq "CODE") {
- my $h = $csv->getline ($fh) or return;
- my $cr = $hdrs;
- $hdrs = [ map { $cr->($hdr{$_} || $_) } @{$h} ];
- }
$c->{'kh'} and $hdrs and @{$c->{'kh'}} = @{$hdrs};
}
@@ -1470,7 +1498,7 @@
do {
my @h = $csv->column_names ($hdrs);
my %h; $h{$_}++ for @h;
- exists $h{""} and croak ($csv->SetDiag (1012));
+ exists $h{''} and croak ($csv->SetDiag (1012));
unless (keys %h == @h) {
croak ($csv->_SetDiagInfo (1013, join ", " =>
map { "$_ ($h{$_})" } grep { $h{$_} > 1 } keys %h));
@@ -1570,7 +1598,7 @@
headers => "auto"); # as array of hash
# Write array of arrays as csv file
- csv (in => $aoa, out => "file.csv", sep_char=> ";");
+ csv (in => $aoa, out => "file.csv", sep_char => ";");
# Only show lines where "code" is odd
csv (in => "data.csv", filter => { code => sub { $_ % 2 }});
@@ -1956,14 +1984,82 @@
X<skip_empty_rows>
my $csv = Text::CSV_XS->new ({ skip_empty_rows => 1 });
- $csv->skip_empty_rows (0);
+ $csv->skip_empty_rows ("eof");
my $f = $csv->skip_empty_rows;
-If this attribute is set to C<1>, any row that has an L</eol> immediately
-following the start of line will be skipped. Default behavior is to return
-one single empty field.
+This attribute defines the behavior for empty rows: an L</eol> immediately
+following the start of line. Default behavior is to return one single empty
+field.
+
+This attribute is only used in parsing. This attribute is ineffective when
+using L</parse> and L</fields>.
+
+Possible values for this attribute are
+
+=over 2
+
+=item 0 | undef
+
+ my $csv = Text::CSV_XS->new ({ skip_empty_rows => 0 });
+ $csv->skip_empty_rows (undef);
+
+No special action is taken. The result will be one single empty field.
+
+=item 1 | "skip"
+
+ my $csv = Text::CSV_XS->new ({ skip_empty_rows => 1 });
+ $csv->skip_empty_rows ("skip");
+
+The row will be skipped.
-This attribute is only used in parsing.
+=item 2 | "eof" | "stop"
+
+ my $csv = Text::CSV_XS->new ({ skip_empty_rows => 2 });
+ $csv->skip_empty_rows ("eof");
+
+The parsing will stop as if an L</eof> was detected.
+
+=item 3 | "die"
+
+ my $csv = Text::CSV_XS->new ({ skip_empty_rows => 3 });
+ $csv->skip_empty_rows ("die");
+
+The parsing will stop. The internal error code will be set to 2015 and the
+parser will C<die>.
+
+=item 4 | "croak"
+
+ my $csv = Text::CSV_XS->new ({ skip_empty_rows => 4 });
+ $csv->skip_empty_rows ("croak");
+
+The parsing will stop. The internal error code will be set to 2015 and the
+parser will C<croak>.
+
+=item 5 | "error"
+
+ my $csv = Text::CSV_XS->new ({ skip_empty_rows => 5 });
+ $csv->skip_empty_rows ("error");
+
+The parsing will fail. The internal error code will be set to 2015.
+
+=item callback
+
+ my $csv = Text::CSV_XS->new ({ skip_empty_rows => sub { [] } });
+ $csv->skip_empty_rows (sub { [ 42, $., undef, "empty" ] });
+
+The callback is invoked and its result used instead. If you want the parse
+to stop after the callback, make sure to return a false value.
+
+The returned value from the callback should be an array-ref. Any other type
+will cause the parse to stop, so these are equivalent in behavior:
+
+ csv (in => $fh, skip_empty_rows => "stop");
+ csv (in => $fh. skip_empty_rows => sub { 0; });
+
+=back
+
+Without arguments, the current value is returned: C<0>, C<1>, C<eof>, C<die>,
+C<croak> or the callback.
=head3 formula_handling
X<formula_handling>
@@ -3563,6 +3659,8 @@
my $aoa = csv (in => $fh, headers => "skip");
+C<skip> is invalid/ignored in combinations with L<C<detect_bom>|/detect_bom>.
+
=item auto
X<auto>
@@ -4606,6 +4704,18 @@
will not return flags either. L</fragment> can reduce the required rows
I<or> columns, but cannot combine them.
+=item provider
+
+ csv (in => $fh) vs csv (provider => sub { get_line });
+
+Whatever the attribute name might end up to be, this should make it easier
+to add input providers for parsing. Currently most special variations for
+the C<in> attribute are aimed at CSV generation: e.g. a callback is defined
+to return a reference to a record. This new attribute should enable passing
+data to parse, like getline.
+
+Suggested by Johan Vromans.
+
=item Cookbook
Write a document that has recipes for most known non-standard (and maybe
@@ -4881,6 +4991,12 @@
Inconsistent number of fields under strict parsing.
=item *
+2015 "ERW - Empty row"
+X<2015>
+
+An empty row was not allowed.
+
+=item *
2021 "EIQ - NL char inside quotes, binary off"
X<2021>
@@ -5033,7 +5149,7 @@
escape and separator characters, the binary mode and the print and getline
methods. See F<ChangeLog> releases 0.10 through 0.23.
-H.Merijn Brand F<E<lt>[email protected]<gt>> cleaned up the code, added
+H.Merijn Brand F<E<lt>[email protected]<gt>> cleaned up the code, added
the field flags methods, wrote the major part of the test suite, completed
the documentation, fixed most RT bugs, added all the allow flags and the
L</csv> function. See ChangeLog releases 0.25 and on.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/CSV_XS.xs
new/Text-CSV_XS-1.51/CSV_XS.xs
--- old/Text-CSV_XS-1.50/CSV_XS.xs 2023-03-01 09:17:51.000000000 +0100
+++ new/Text-CSV_XS-1.51/CSV_XS.xs 2023-08-07 09:06:27.000000000 +0200
@@ -276,6 +276,7 @@
{ 2012, "EOF - End of data in parsing input stream"
},
{ 2013, "ESP - Specification error for fragments RFC7111"
},
{ 2014, "ENF - Inconsistent number of fields"
},
+ { 2015, "ERW - Empty row"
},
/* EIQ - Error Inside Quotes */
{ 2021, "EIQ - NL char inside quotes, binary off"
},
@@ -735,7 +736,6 @@
csv->decode_utf8 = bool_opt ("decode_utf8");
csv->always_quote = bool_opt ("always_quote");
csv->strict = bool_opt ("strict");
- csv->skip_empty_rows = bool_opt ("skip_empty_rows");
csv->quote_empty = bool_opt ("quote_empty");
csv->quote_space = bool_opt_def ("quote_space", 1);
csv->escape_null = bool_opt_def ("escape_null", 1);
@@ -751,6 +751,7 @@
csv->auto_diag = num_opt ("auto_diag");
csv->diag_verbose = num_opt ("diag_verbose");
csv->keep_meta_info = num_opt ("keep_meta_info");
+ csv->skip_empty_rows = num_opt ("skip_empty_rows");
csv->formula = num_opt ("formula");
unless (csv->escape_char) csv->escape_null = 0;
@@ -951,6 +952,79 @@
return NULL;
} /* _formula */
+#define SkipEmptyRow {\
+ int ser = csv->skip_empty_rows; \
+ \
+ if (ser == 3) { (void)SetDiag (csv, 2015); die ("Empty row"); } \
+ if (ser == 4) { (void)SetDiag (csv, 2015); croak ("Empty row"); } \
+ if (ser == 5) { (void)SetDiag (csv, 2015); return FALSE; } \
+ \
+ if (ser <= 2) { /* skip & eof */ \
+ csv->fld_idx = 0; \
+ c = CSV_GET; \
+ if (c == EOF || ser == 2) { \
+ sv_free (sv); \
+ sv = NULL; \
+ waitingForField = 0; \
+ if (ser == 2) return FALSE; \
+ break; \
+ } \
+ } \
+ \
+ if (ser == 6) { \
+ int result, n, i; \
+ SV *rv, **svp = hv_fetchs (csv->self, "_EMPTROW_CB", FALSE); \
+ AV *avp; \
+ unless (svp && _is_coderef (*svp)) \
+ return FALSE; /* A callback is wanted, but none found */ \
+ \
+ dSP; \
+ ENTER; \
+ SAVE_DEFSV; /* local $_ */ \
+ DEFSV = sv; \
+ PUSHMARK (SP); \
+ PUTBACK; \
+ result = call_sv (*svp, G_SCALAR); \
+ SPAGAIN; \
+ unless (result) { \
+ /* A false return will stop the parsing */ \
+ sv_free (sv); \
+ sv = NULL; \
+ waitingForField = 0; \
+ return FALSE; \
+ } \
+ \
+ PUTBACK; \
+ LEAVE; \
+ \
+ rv = POPs; \
+ /* Result should be a ref to a list. */ \
+ unless (_is_arrayref (rv)) \
+ return FALSE; \
+ \
+ avp = (AV *)SvRV (rv); \
+ \
+ unless (avp) return FALSE; \
+ n = av_len (avp); \
+ if (n <= 0) return TRUE; \
+ \
+ if (csv->is_bound && csv->is_bound < n) \
+ n = csv->is_bound - 1; \
+ \
+ for (i = 0; i <= n; i++) { \
+ SV **svp = av_fetch (avp, i, FALSE); \
+ sv = svp && *svp ? *svp : NULL; \
+ if (sv) { \
+ SvREFCNT_inc (sv); \
+ /* upgrade IV to IVPV if needed */ \
+ (void)SvPV_nolen (sv); \
+ } \
+ AV_PUSH; \
+ } \
+ return TRUE; \
+ } \
+ }
+
#define Combine(csv,dst,fields) cx_Combine (aTHX_ csv, dst, fields)
static int cx_Combine (pTHX_ csv_t *csv, SV *dst, AV *fields) {
SSize_t i, n;
@@ -958,7 +1032,7 @@
int aq = (int)csv->always_quote;
int qe = (int)csv->quote_empty;
int kmi = (int)csv->keep_meta_info;
- AV *qm = NULL;
+ AV *qm = NULL;
n = (IV)av_len (fields);
if (n < 0 && csv->is_bound) {
@@ -1288,11 +1362,13 @@
#endif
#define AV_PUSH { \
+ int svc; \
*SvEND (sv) = (char)0; \
+ svc = SvCUR (sv); \
SvUTF8_off (sv); \
- if (csv->formula && SvCUR (sv) && *(SvPV_nolen (sv)) == '=') \
+ if (svc && csv->formula && *(SvPV_nolen (sv)) == '=') \
(void)_formula (csv, sv, NULL, fnum); \
- if (SvCUR (sv) == 0 && ( \
+ if (svc == 0 && ( \
csv->empty_is_undef || \
(!(f & CSV_FLAGS_QUO) && csv->blank_is_undef))) \
SvSetUndef (sv); \
@@ -1679,14 +1755,7 @@
_pretty_strl (csv->bptr + csv->used));
#endif
if (fnum == 1 && f == 0 && SvCUR (sv) == 0 && csv->skip_empty_rows)
{
- csv->fld_idx = 0;
- c = CSV_GET;
- if (c == EOF) {
- sv_free (sv);
- sv = NULL;
- waitingForField = 0;
- break;
- }
+ SkipEmptyRow;
goto restart;
}
@@ -1814,14 +1883,7 @@
csv->used--;
csv->has_ahead++;
if (fnum == 1 && f == 0 && SvCUR (sv) == 0 &&
csv->skip_empty_rows) {
- csv->fld_idx = 0;
- c = CSV_GET;
- if (c == EOF) {
- sv_free (sv);
- sv = NULL;
- waitingForField = 0;
- break;
- }
+ SkipEmptyRow;
goto restart;
}
AV_PUSH;
@@ -1879,14 +1941,7 @@
csv->used--;
csv->has_ahead++;
if (fnum == 1 && f == 0 && SvCUR (sv) == 0 &&
csv->skip_empty_rows) {
- csv->fld_idx = 0;
- c = CSV_GET;
- if (c == EOF) {
- sv_free (sv);
- sv = NULL;
- waitingForField = 0;
- break;
- }
+ SkipEmptyRow;
goto restart;
}
AV_PUSH;
@@ -2008,8 +2063,11 @@
if (f & CSV_FLAGS_QUO)
ERROR_INSIDE_QUOTES (2027);
- if (sv)
+ if (sv) {
AV_PUSH;
+ }
+ else if (f == 0 && fnum == 1 && csv->skip_empty_rows == 1)
+ return FALSE;
return TRUE;
} /* Parse */
@@ -2276,9 +2334,7 @@
Perl_load_module (aTHX_ PERL_LOADMOD_NOIMPORT, newSVpvs ("IO::Handle"),
NULL, NULL, NULL);
void
-SetDiag (self, xse, ...)
- SV *self
- int xse
+SetDiag (SV *self, int xse, ...)
PPCODE:
HV *hv;
@@ -2303,8 +2359,7 @@
/* XS SetDiag */
void
-error_input (self)
- SV *self
+error_input (SV *self)
PPCODE:
if (self && SvOK (self) && SvROK (self) && SvTYPE (SvRV (self)) ==
SVt_PVHV) {
@@ -2322,11 +2377,7 @@
/* XS error_input */
void
-Combine (self, dst, fields, useIO)
- SV *self
- SV *dst
- SV *fields
- bool useIO
+Combine (SV *self, SV *dst, SV *fields, bool useIO)
PPCODE:
HV *hv;
@@ -2339,11 +2390,7 @@
/* XS Combine */
void
-Parse (self, src, fields, fflags)
- SV *self
- SV *src
- SV *fields
- SV *fflags
+Parse (SV *self, SV *src, SV *fields, SV *fflags)
PPCODE:
HV *hv;
@@ -2359,10 +2406,7 @@
/* XS Parse */
void
-print (self, io, fields)
- SV *self
- SV *io
- SV *fields
+print (SV *self, SV *io, SV *fields)
PPCODE:
HV *hv;
@@ -2383,9 +2427,7 @@
/* XS print */
void
-getline (self, io)
- SV *self
- SV *io
+getline (SV *self, SV *io)
PPCODE:
HV *hv;
@@ -2402,9 +2444,7 @@
/* XS getline */
void
-getline_all (self, io, ...)
- SV *self
- SV *io
+getline_all (SV *self, SV *io, ...)
PPCODE:
HV *hv;
@@ -2420,10 +2460,7 @@
/* XS getline_all */
void
-_cache_set (self, idx, val)
- SV *self
- int idx
- SV *val
+_cache_set (SV *self, int idx, SV *val)
PPCODE:
HV *hv;
@@ -2434,8 +2471,7 @@
/* XS _cache_set */
void
-_cache_diag (self)
- SV *self
+_cache_diag (SV *self)
PPCODE:
HV *hv;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/ChangeLog
new/Text-CSV_XS-1.51/ChangeLog
--- old/Text-CSV_XS-1.50/ChangeLog 2023-03-01 09:55:17.000000000 +0100
+++ new/Text-CSV_XS-1.51/ChangeLog 2023-08-07 13:58:29.000000000 +0200
@@ -1,3 +1,12 @@
+1.51 - 2023-08-07, H.Merijn Brand
+ * Contact e-mail update
+ * Attribute skip_empty_rows extended
+ * Fix comments (PR#45)
+ * Fix help (x12340, PR#46)
+ * Update to Devel::PPPort-3.71
+ * Fix HTML on Windows
+ * Fix double header-interpretation on bom + headers => "auto" (issue 47)
+
1.50 - 2023-03-01, H.Merijn Brand
* Promote sep to sep_set in csv () with auto-headers
* Fix bug in set_diag surfaced by PERL_RC_STACK
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/MANIFEST
new/Text-CSV_XS-1.51/MANIFEST
--- old/Text-CSV_XS-1.50/MANIFEST 2023-03-01 11:54:03.000000000 +0100
+++ new/Text-CSV_XS-1.51/MANIFEST 2023-08-07 18:20:02.000000000 +0200
@@ -26,6 +26,8 @@
t/60_samples.t Miscellaneous problems from the modules history.
t/65_allow.t Allow bad formats
t/66_formula.t Formula behavior
+t/67_emptrow.t Empty row behavior
+t/68_header.t Test header option combinations
t/70_rt.t Tests based on RT reports
t/75_hashref.t getline_hr related tests
t/76_magic.t array_ref from magic
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/META.json
new/Text-CSV_XS-1.51/META.json
--- old/Text-CSV_XS-1.50/META.json 2023-03-01 11:54:04.000000000 +0100
+++ new/Text-CSV_XS-1.51/META.json 2023-08-07 18:20:03.000000000 +0200
@@ -1,67 +1,70 @@
{
- "meta-spec" : {
- "version" : 2,
- "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec"
+ "release_status" : "stable",
+ "abstract" : "Comma-Separated Values manipulation routines",
+ "resources" : {
+ "bugtracker" : {
+ "web" : "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Text-CSV_XS"
},
- "author" : [
- "H.Merijn Brand <[email protected]>"
+ "license" : [
+ "http://dev.perl.org/licenses/"
],
+ "x_IRC" : "irc://irc.perl.org/#csv",
+ "homepage" : "https://metacpan.org/pod/Text::CSV_XS",
+ "repository" : {
+ "web" : "https://github.com/Tux/Text-CSV_XS",
+ "url" : "https://github.com/Tux/Text-CSV_XS",
+ "type" : "git"
+ }
+ },
"generated_by" : "Author",
- "license" : [
- "perl_5"
- ],
+ "provides" : {
+ "Text::CSV_XS" : {
+ "file" : "CSV_XS.pm",
+ "version" : "1.51"
+ }
+ },
"prereqs" : {
+ "test" : {
+ "requires" : {
+ "Test::More" : "0",
+ "Tie::Scalar" : "0"
+ }
+ },
"build" : {
"requires" : {
"Config" : "0"
- }
- },
- "test" : {
- "requires" : {
- "Tie::Scalar" : "0",
- "Test::More" : "0"
- }
- },
+ }
+ },
"runtime" : {
"recommends" : {
"Encode" : "3.19"
- },
+ },
"requires" : {
"perl" : "5.006001",
"XSLoader" : "0",
"IO::Handle" : "0"
- }
- },
+ }
+ },
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
- }
- }
- },
- "version" : "1.50",
- "provides" : {
- "Text::CSV_XS" : {
- "file" : "CSV_XS.pm",
- "version" : "1.50"
- }
- },
- "name" : "Text-CSV_XS",
- "release_status" : "stable",
- "resources" : {
- "license" : [
- "http://dev.perl.org/licenses/"
- ],
- "homepage" : "https://metacpan.org/pod/Text::CSV_XS",
- "repository" : {
- "url" : "https://github.com/Tux/Text-CSV_XS",
- "web" : "https://github.com/Tux/Text-CSV_XS",
- "type" : "git"
},
- "x_IRC" : "irc://irc.perl.org/#csv",
- "bugtracker" : {
- "web" : "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Text-CSV_XS"
+ "recommends" : {
+ "ExtUtils::MakeMaker" : "7.70"
}
- },
- "dynamic_config" : 1,
- "abstract" : "Comma-Separated Values manipulation routines"
- }
+ }
+ },
+ "license" : [
+ "perl_5"
+ ],
+ "version" : "1.51",
+ "author" : [
+ "H.Merijn Brand <hmbrand.org>"
+ ],
+ "name" : "Text-CSV_XS",
+ "meta-spec" : {
+ "version" : 2,
+ "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec"
+ },
+ "dynamic_config" : 1
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/META.yml
new/Text-CSV_XS-1.51/META.yml
--- old/Text-CSV_XS-1.50/META.yml 2023-03-01 11:54:04.000000000 +0100
+++ new/Text-CSV_XS-1.51/META.yml 2023-08-07 18:20:03.000000000 +0200
@@ -1,7 +1,7 @@
---
abstract: Comma-Separated Values manipulation routines
author:
- - H.Merijn Brand <[email protected]>
+ - H.Merijn Brand <hmbrand.org>
build_requires:
Config: 0
configure_requires:
@@ -16,7 +16,7 @@
provides:
Text::CSV_XS:
file: CSV_XS.pm
- version: '1.50'
+ version: '1.51'
recommends:
Encode: '3.19'
requires:
@@ -31,4 +31,4 @@
homepage: https://metacpan.org/pod/Text::CSV_XS
license: http://dev.perl.org/licenses/
repository: https://github.com/Tux/Text-CSV_XS
-version: '1.50'
+version: '1.51'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/README new/Text-CSV_XS-1.51/README
--- old/Text-CSV_XS-1.50/README 2023-01-03 13:19:01.000000000 +0100
+++ new/Text-CSV_XS-1.51/README 2023-05-30 17:31:32.000000000 +0200
@@ -11,7 +11,7 @@
This distribution provides several examples of scripts that convert CSV
files or data streams into XLS or XLSX or simply check if the CSV data
is valid. It is easy to amend those scripts to do whatever the end-user
- actually requires. The full documentation also provaides various small
+ actually requires. The full documentation also provides various small
snippets of example code.
Convert a CSV file into JSON:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/cpanfile
new/Text-CSV_XS-1.51/cpanfile
--- old/Text-CSV_XS-1.50/cpanfile 2023-03-01 11:54:04.000000000 +0100
+++ new/Text-CSV_XS-1.51/cpanfile 2023-08-07 18:20:02.000000000 +0200
@@ -5,6 +5,8 @@
on "configure" => sub {
requires "ExtUtils::MakeMaker";
+
+ recommends "ExtUtils::MakeMaker" => "7.70";
};
on "build" => sub {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/examples/csvdiff
new/Text-CSV_XS-1.51/examples/csvdiff
--- old/Text-CSV_XS-1.50/examples/csvdiff 2023-01-03 13:17:23.000000000
+0100
+++ new/Text-CSV_XS-1.51/examples/csvdiff 2023-08-07 13:57:49.000000000
+0200
@@ -1,12 +1,12 @@
#!/pro/bin/perl
-use strict;
+use 5.012000;
use warnings;
# csvdiff: Show differences between CSV files
-# (m)'19 [05 Mar 2019] Copyright H.M.Brand 2009-2023
+# (m)'23 [05 Aug 2023] Copyright H.M.Brand 2009-2023
-our $VERSION = "1.02 - 20190305";
+our $VERSION = "1.03 - 20230805";
sub usage {
my $err = shift and select STDERR;
@@ -15,9 +15,9 @@
" assuming first line is header and first field is the key\n",
" --no-color do not use colors\n",
" -h --html produce HTML output\n",
- " -w --ignore-all-space ignore all whistespace is all
fields\n",
- " -b --ignore-space-change ignore whitespace length changes\n",
- " -Z --ignore-trailing-space ignore trailing whitespace per
field\n",
+ " -w --ignore-all-space ignore all white space\n",
+ " -b --ignore-space-change ignore changes in the amount of
white space\n",
+ " -Z --ignore-trailing-space ignore white space at line end\n",
" -o F --output=F send output to file F\n";
exit $err;
} # usage
@@ -51,14 +51,15 @@
if ($opt_h) {
binmode STDOUT, ":encoding(utf-8)";
- print <<EOH;
+ my $name = $^O eq "MSWin32" ? Win32::LoginName () : scalar getpwuid $<;
+ print <<"EOH";
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>CFI School updates</title>
<meta name="Generator" content="perl $]" />
- <meta name="Author" content="@{[scalar getpwuid $<]}" />
+ <meta name="Author" content="$name" />
<meta name="Description" content="CSV diff @ARGV" />
<style type="text/css">
.rd { background: #ffe0e0; }
@@ -99,7 +100,7 @@
my @i = (1, 1);
my $hdr = "# csvdiff < $ARGV[0] > $ARGV[1]\n";
-$f[$_][1+$n[$_]][0] = $opt_n ? 2147483647 : "\xff\xff\xff\xff" for 0, 1;
+$f[$_][1+$n[$_]][0] = $opt_n ? 0x7FFFFFFF : "\xff\xff\xff\xff" for 0, 1;
my %cls;
%cls = (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/ppport.h
new/Text-CSV_XS-1.51/ppport.h
--- old/Text-CSV_XS-1.50/ppport.h 2022-05-24 10:08:04.000000000 +0200
+++ new/Text-CSV_XS-1.51/ppport.h 2023-08-07 09:06:27.000000000 +0200
@@ -4,9 +4,9 @@
/*
----------------------------------------------------------------------
- ppport.h -- Perl/Pollution/Portability Version 3.68
+ ppport.h -- Perl/Pollution/Portability Version 3.71
- Automatically created by Devel::PPPort running under perl 5.036000.
+ Automatically created by Devel::PPPort running under perl 5.038000.
Do NOT edit this file directly! -- Edit PPPort_pm.PL and the
includes in parts/inc/ instead.
@@ -21,7 +21,7 @@
=head1 NAME
-ppport.h - Perl/Pollution/Portability version 3.68
+ppport.h - Perl/Pollution/Portability version 3.71
=head1 SYNOPSIS
@@ -588,7 +588,7 @@
# Disable broken TRIE-optimization
BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if "$]" >= "5.009004" && "$]" <=
"5.009005"}
-my $VERSION = 3.68;
+my $VERSION = 3.71;
my %opt = (
quiet => 0,
@@ -5680,7 +5680,6 @@
nextchar|5.005000||Viu
NEXT_LINE_CHAR|5.007003||Viu
NEXT_OFF|5.005000||Viu
-NEXTOPER|5.003007||Viu
next_symbol|5.007003||Viu
ninstr|5.003007|5.003007|n
NL_LANGINFO_LOCK|5.033005||Viu
@@ -7733,7 +7732,6 @@
prepare_SV_for_RV|5.010001||Viu
prescan_version|5.011004|5.011004|
PRESCAN_VERSION|5.019008||Viu
-PREVOPER|5.003007||Viu
PREV_RANGE_MATCHES_INVLIST|5.023002||Viu
printbuf|5.009004||Viu
print_bytes_for_locale|5.027002||Viu
@@ -8126,6 +8124,8 @@
reg_named_buff_scalar|5.009005||cVu
regnext|5.003007||cVu
reg_node|5.005000||Viu
+REGNODE_AFTER|5.003007||Viu
+REGNODE_BEFORE|5.003007||Viu
regnode_guts|5.021005||Viu
regnode_guts_debug|||Viu
REGNODE_MAX|5.009004||Viu
@@ -12822,17 +12822,12 @@
#undef STMT_START
#undef STMT_END
-#if defined(VOIDFLAGS) && defined(PERL_USE_GCC_BRACE_GROUPS)
-# define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */
-# define STMT_END )
-#else
-# if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__))
&& !defined(__GNUC__)
+#if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__)) &&
!defined(__GNUC__)
# define STMT_START if (1)
# define STMT_END else (void)0
-# else
+#else
# define STMT_START do
# define STMT_END while (0)
-# endif
#endif
#ifndef boolSV
# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
@@ -15123,17 +15118,18 @@
# else
# define D_PPP_FIX_UTF8_ERRSV_FOR_SV(sv) STMT_START {} STMT_END
# endif
-# define croak_sv(sv) \
- STMT_START { \
- SV *_sv = (sv); \
- if (SvROK(_sv)) { \
- sv_setsv(ERRSV, _sv); \
- croak(NULL); \
- } else { \
- D_PPP_FIX_UTF8_ERRSV_FOR_SV(_sv); \
- croak("%" SVf, SVfARG(_sv)); \
- } \
- } STMT_END
+PERL_STATIC_INLINE void D_PPP_croak_sv(SV *sv) {
+ dTHX;
+ SV *_sv = (sv);
+ if (SvROK(_sv)) {
+ sv_setsv(ERRSV, _sv);
+ croak(NULL);
+ } else {
+ D_PPP_FIX_UTF8_ERRSV_FOR_SV(_sv);
+ croak("%" SVf, SVfARG(_sv));
+ }
+}
+# define croak_sv(sv) D_PPP_croak_sv(sv)
#elif (PERL_BCDVERSION >= 0x5004000)
# define croak_sv(sv) croak("%" SVf, SVfARG(sv))
#else
@@ -16444,10 +16440,10 @@
#if !defined(sv_unmagicext)
#if defined(NEED_sv_unmagicext)
-static int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, MGVTBL
* vtbl);
+static int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, const
MGVTBL * vtbl);
static
#else
-extern int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, MGVTBL
* vtbl);
+extern int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, const
MGVTBL * vtbl);
#endif
#if defined(NEED_sv_unmagicext) || defined(NEED_sv_unmagicext_GLOBAL)
@@ -16460,7 +16456,7 @@
int
-DPPP_(my_sv_unmagicext)(pTHX_ SV *const sv, const int type, MGVTBL *vtbl)
+DPPP_(my_sv_unmagicext)(pTHX_ SV *const sv, const int type, const MGVTBL *vtbl)
{
MAGIC* mg;
MAGIC** mgp;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/t/67_emptrow.t
new/Text-CSV_XS-1.51/t/67_emptrow.t
--- old/Text-CSV_XS-1.50/t/67_emptrow.t 1970-01-01 01:00:00.000000000 +0100
+++ new/Text-CSV_XS-1.51/t/67_emptrow.t 2023-08-07 15:01:22.000000000 +0200
@@ -0,0 +1,124 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More;
+
+BEGIN {
+ if ($] < 5.008001) {
+ plan skip_all => "This test unit requires perl-5.8.1 or higher";
+ }
+ else {
+ plan tests => 47;
+ }
+
+ use_ok "Text::CSV_XS", ("csv");
+ plan skip_all => "Cannot load Text::CSV_XS" if $@;
+ }
+my $tfn = "_67test.csv"; END { -f $tfn and unlink $tfn; }
+
+ok (my $csv = Text::CSV_XS->new, "new");
+
+is ($csv->skip_empty_rows, 0, "default");
+is ($csv->skip_empty_rows (1), 1, "+1");
+is ($csv->skip_empty_rows ("skip"), 1, "skip");
+is ($csv->skip_empty_rows ("SKIP"), 1, "SKIP");
+is ($csv->skip_empty_rows (2), "eof", "+2");
+is ($csv->skip_empty_rows ("eof"), "eof", "eof");
+is ($csv->skip_empty_rows ("EOF"), "eof", "EOF");
+is ($csv->skip_empty_rows ("stop"), "eof", "stop");
+is ($csv->skip_empty_rows ("STOP"), "eof", "STOP");
+is ($csv->skip_empty_rows (3), "die", "+3");
+is ($csv->skip_empty_rows ("die"), "die", "die");
+is ($csv->skip_empty_rows ("DIE"), "die", "DIE");
+is ($csv->skip_empty_rows (4), "croak", "+4");
+is ($csv->skip_empty_rows ("croak"), "croak", "croak");
+is ($csv->skip_empty_rows ("CROAK"), "croak", "CROAK");
+is ($csv->skip_empty_rows (5), "error", "+5");
+is ($csv->skip_empty_rows ("error"), "error", "error");
+is ($csv->skip_empty_rows ("ERROR"), "error", "ERROR");
+
+sub cba { [ 3, 42, undef, 3 ] }
+sub cbh { { a => 3, b => 42, c => undef, d => 3 } }
+
+is ($csv->skip_empty_rows (\&cba), \&cba, "callback");
+
+is ($csv->skip_empty_rows (0), 0, "+0");
+is ($csv->skip_empty_rows (undef), 0, "undef");
+
+open my $fh, ">", $tfn;
+print $fh "a,b,c,d\n";
+print $fh "1,2,0,4\n";
+print $fh "4,0,9,1\n";
+print $fh "\n";
+print $fh "8,2,7,1\n";
+print $fh "\n";
+print $fh "\n";
+print $fh "5,7,9,3\n";
+print $fh "\n";
+close $fh;
+
+my @parg = (auto_diag => 0, in => $tfn);
+my @head = ([qw( a b c d )], [1,2,0,4], [4,0,9,1]);
+my @repl = (1..4);
+my $ea = \@repl;
+
+# Array behavior
+is_deeply (csv (@parg, skip_empty_rows => 0), [ @head,
+ [""],[8,2,7,1],[""],[""],[5,7,9,3],[""]], "A Default");
+
+is_deeply (csv (@parg, skip_empty_rows => 1), [ @head,
+ [8,2,7,1],[5,7,9,3]], "A Skip");
+
+is_deeply (csv (@parg, skip_empty_rows => 2), \@head, "A EOF");
+
+is (eval { csv (@parg, skip_empty_rows => 3); }, undef, "A
die");
+like ($@, qr{^Empty row}, "A msg");
+
+is (eval { csv (@parg, skip_empty_rows => 4); }, undef, "A
croak");
+like ($@, qr{^Empty row}, "A msg");
+
+$@ = "";
+$csv = Text::CSV_XS->new ({ skip_empty_rows => 5 });
+is_deeply ($csv->csv (@parg), \@head, "A error");
+is ($@, "", "A msg");
+is (0 + $csv->error_diag, 2015, "A
code");
+
+is_deeply (csv (@parg, skip_empty_rows => sub {\@repl}), [ @head,
+ $ea,[8,2,7,1],$ea,$ea,[5,7,9,3],$ea], "A Callback");
+is_deeply (csv (@parg, skip_empty_rows => sub {0}), \@head, "A Callback 0");
+
+# Hash behavior
+push @parg => bom => 1;
+my $eh = { a => "", b => undef, c => undef, d => undef },
+@head = ({ a => 1, b => 2, c => 0, d => 4 },
+ { a => 4, b => 0, c => 9, d => 1 });
+is_deeply (csv (@parg, skip_empty_rows => 0), [ @head, $eh,
+ { a => 8, b => 2, c => 7, d => 1 },$eh,$eh,
+ { a => 5, b => 7, c => 9, d => 3 },$eh], "H Default");
+
+is_deeply (csv (@parg, skip_empty_rows => 1), [ @head,
+ { a => 8, b => 2, c => 7, d => 1 },
+ { a => 5, b => 7, c => 9, d => 3 }], "H Skip");
+
+is_deeply (csv (@parg, skip_empty_rows => 2), \@head, "H EOF");
+
+is (eval { csv (@parg, skip_empty_rows => 3); }, undef, "H
die");
+like ($@, qr{^Empty row}, "H msg");
+
+is (eval { csv (@parg, skip_empty_rows => 4); }, undef, "H
croak");
+like ($@, qr{^Empty row}, "H msg");
+
+$@ = "";
+$csv = Text::CSV_XS->new ({ skip_empty_rows => 5 });
+is_deeply ($csv->csv (@parg), \@head, "H error");
+is ($@, "", "H msg");
+is (0 + $csv->error_diag, 2015, "H
code");
+
+$eh = { a => 1, b => 2, c => 3, d => 4 };
+is_deeply (csv (@parg, skip_empty_rows => sub {\@repl}), [ @head, $eh,
+ { a => 8, b => 2, c => 7, d => 1 },$eh,$eh,
+ { a => 5, b => 7, c => 9, d => 3 },$eh], "H Callback");
+
+is_deeply (csv (@parg, skip_empty_rows => sub {0}), \@head, "H Callback 0");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/t/68_header.t
new/Text-CSV_XS-1.51/t/68_header.t
--- old/Text-CSV_XS-1.50/t/68_header.t 1970-01-01 01:00:00.000000000 +0100
+++ new/Text-CSV_XS-1.51/t/68_header.t 2023-08-07 15:01:18.000000000 +0200
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More;
+
+BEGIN {
+ if ($] < 5.008001) {
+ plan skip_all => "This test unit requires perl-5.8.1 or higher";
+ }
+ else {
+ plan tests => 32;
+ }
+
+ use_ok "Text::CSV_XS", "csv";
+ require "./t/util.pl";
+ }
+
+my $tfn = "_68test.csv"; END { unlink $tfn, "_$tfn"; }
+
+my @dta = (
+ [qw( foo bar zap )],
+ [qw( mars venus pluto )],
+ [qw( 1 2 3 )],
+ );
+my @dth = (
+ { foo => "mars", bar => "venus", zap => "pluto" },
+ { foo => 1, bar => 2, zap => 3 },
+ );
+
+{ open my $fh, ">", $tfn or die "$tfn: $!\n";
+ local $" = ",";
+ print $fh "@$_\n" for @dta;
+ close $fh;
+ }
+
+is_deeply (csv (in => $tfn), \@dta, "csv ()");
+is_deeply (csv (in => $tfn, bom => 1), \@dth, "csv (bom)");
+is_deeply (csv (in => $tfn, headers => "auto"), \@dth, "csv
(headers)");
+is_deeply (csv (in => $tfn, bom => 1, headers => "auto"), \@dth, "csv (bom,
headers)");
+
+foreach my $arg ("", "bom", "auto", "bom, auto") {
+ open my $fh, "<", $tfn or die "$tfn: $!\n";
+ my %attr;
+ $arg =~ m/bom/ and $attr{bom} = 1;
+ $arg =~ m/auto/ and $attr{headers} = "auto";
+ ok (my $csv = Text::CSV_XS->new (), "New ($arg)");
+ is ($csv->record_number, 0, "start");
+ if ($arg) {
+ is_deeply ([ $csv->header ($fh, \%attr) ], $dta[0], "Header") if $arg;
+ is ($csv->record_number, 1, "first data-record");
+ is_deeply ($csv->getline_hr ($fh), $dth[$_], "getline $_") for 0..$#dth;
+ }
+ else {
+ is_deeply ($csv->getline ($fh), $dta[$_], "getline $_") for 0..$#dta;
+ }
+ is ($csv->record_number, 3, "done");
+ close $fh;
+ }
+
+done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Text-CSV_XS-1.50/t/80_diag.t
new/Text-CSV_XS-1.51/t/80_diag.t
--- old/Text-CSV_XS-1.50/t/80_diag.t 2021-03-22 13:20:10.000000000 +0100
+++ new/Text-CSV_XS-1.51/t/80_diag.t 2023-04-04 15:25:58.000000000 +0200
@@ -3,7 +3,7 @@
use strict;
use warnings;
- use Test::More tests => 335;
+ use Test::More tests => 345;
#use Test::More "no_plan";
my %err;
@@ -61,7 +61,7 @@
parse_err 2037, 1, 11, 1, qq{\0 };
{ my @warn;
- local $SIG{__WARN__} = sub { push @warn, @_ };
+ local $SIG{__WARN__} = sub { push @warn => @_ };
$csv->error_diag ();
ok (@warn == 1, "Got error message");
like ($warn[0], qr{^# CSV_XS ERROR: 2037 - EIF}, "error content");
@@ -74,26 +74,26 @@
is (Text::CSV_XS->new ({ ecs_char => ":" }), undef, "Unsupported option");
{ my @warn;
- local $SIG{__WARN__} = sub { push @warn, @_ };
+ local $SIG{__WARN__} = sub { push @warn => @_ };
Text::CSV_XS::error_diag ();
ok (@warn == 1, "Error_diag in void context ::");
like ($warn[0], qr{^# CSV_XS ERROR: 1000 - INI}, "error content");
}
{ my @warn;
- local $SIG{__WARN__} = sub { push @warn, @_ };
+ local $SIG{__WARN__} = sub { push @warn => @_ };
Text::CSV_XS->error_diag ();
ok (@warn == 1, "Error_diag in void context ->");
like ($warn[0], qr{^# CSV_XS ERROR: 1000 - INI}, "error content");
}
{ my @warn;
- local $SIG{__WARN__} = sub { push @warn, @_ };
+ local $SIG{__WARN__} = sub { push @warn => @_ };
is (Text::CSV_XS->new ({ auto_diag => 0, ecs_char => ":" }), undef,
"Unsupported option");
ok (@warn == 0, "Error_diag in from new ({ auto_diag => 0})");
}
{ my @warn;
- local $SIG{__WARN__} = sub { push @warn, @_ };
+ local $SIG{__WARN__} = sub { push @warn => @_ };
is (Text::CSV_XS->new ({ auto_diag => 1, ecs_char => ":" }), undef,
"Unsupported option");
ok (@warn == 1, "Error_diag in from new ({ auto_diag => 1})");
@@ -116,7 +116,7 @@
ok (1, "Test auto_diag");
$csv = Text::CSV_XS->new ({ auto_diag => 1 });
{ my @warn;
- local $SIG{__WARN__} = sub { push @warn, @_ };
+ local $SIG{__WARN__} = sub { push @warn => @_ };
is ($csv->{_RECNO}, 0, "No records read yet");
is ($csv->parse ('"","'), 0, "1 - bad parse");
ok (@warn == 1, "1 - One error");
@@ -124,7 +124,7 @@
is ($csv->{_RECNO}, 1, "One record read");
}
{ my @warn;
- local $SIG{__WARN__} = sub { push @warn, @_ };
+ local $SIG{__WARN__} = sub { push @warn => @_ };
is ($csv->diag_verbose (3), 3, "Set diag_verbose");
is ($csv->parse ('"","'), 0, "1 - bad parse");
ok (@warn == 1, "1 - One error");
@@ -141,7 +141,7 @@
}
{ my @warn;
- local $SIG{__WARN__} = sub { push @warn, @_ };
+ local $SIG{__WARN__} = sub { push @warn => @_ };
# Invalid error_input calls
is (Text::CSV_XS::error_input (undef), undef, "Bad error_input call");
@@ -299,7 +299,7 @@
is_deeply ($aoh, [{ 1 => 1, 2 => 2, 3 => 3 }], "Column dropped");
my @e;
eval {
- local $SIG{__WARN__} = sub { push @e, @_ };
+ local $SIG{__WARN__} = sub { push @e => @_ };
$aoh = Text::CSV_XS::csv (in => $tfn, headers => "auto", strict => 1);
};
is_deeply ($aoh, [], "Fail under strict");
@@ -314,7 +314,7 @@
is_deeply ($aoh, [{ 1 => 1, 2 => 2, 3 => 3, 4 => undef }], "Column added");
@e = ();
eval {
- local $SIG{__WARN__} = sub { push @e, @_ };
+ local $SIG{__WARN__} = sub { push @e => @_ };
$aoh = Text::CSV_XS::csv (in => $tfn, headers => "auto", strict => 1);
};
is_deeply ($aoh, [], "Fail under strict");
@@ -339,7 +339,7 @@
}
SKIP: {
- $] < 5.008 and skip qq{$] does not support ScalarIO}, 14;
+ $] < 5.008 and skip qq{$] does not support ScalarIO}, 24;
foreach my $key ({}, sub {}, []) {
my $csv = Text::CSV_XS->new;
my $x = eval { $csv->csv (in => \"a,b", key => $key) };
@@ -362,6 +362,17 @@
my @diag = $csv->error_diag;
is ($diag[0], 1503, "Invalid value type");
}
+
+ foreach my $ser ("die", 4) {
+ ok (my $csv = Text::CSV_XS->new ({ skip_empty_rows => $ser }),
+ "New CSV for SER $ser");
+ is (eval { $csv->csv (in => \"\n") }, undef,
+ "Parse empty line for SER
$ser");
+ like ($@, qr{^Empty row}, "Message");
+ my @diag = $csv->error_diag;
+ is ($diag[0], 2015, "Empty row");
+ like ($diag[1], qr{^ERW - Empty row}, "Error description");
+ }
}
# Issue 19: auto_diag > 1 does not die if ->header () is used
@@ -378,8 +389,8 @@
my $ok = eval {
open $fh, "<", $tfn or die "$tfn: $!\n";
my $csv = Text::CSV_XS->new ({ auto_diag => 2 });
- $h and push @row, [ $csv->header ($fh) ];
- while (my $row = $csv->getline ($fh)) { push @row, $row }
+ $h and push @row => [ $csv->header ($fh) ];
+ while (my $row = $csv->getline ($fh)) { push @row => $row }
close $fh;
1;
};