Hello community, here is the log from the commit of package perl-Text-CSV_XS for openSUSE:Factory checked in at 2014-03-18 14:17:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Text-CSV_XS (Old) and /work/SRC/openSUSE:Factory/.perl-Text-CSV_XS.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Text-CSV_XS" Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Text-CSV_XS/perl-Text-CSV_XS.changes 2014-02-24 14:13:03.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.perl-Text-CSV_XS.new/perl-Text-CSV_XS.changes 2014-03-18 14:17:02.000000000 +0100 @@ -1,0 +2,11 @@ +Mon Mar 17 08:29:52 UTC 2014 - [email protected] + +- updated to 1.05 + * Allow case insensitive attributes and attribute aliases + (quote_always = always_quote) + * Enhanced the csv () function (diagnostics) + * Start callbacks support + * Minor doc fixes + * Make subclassing safer + +------------------------------------------------------------------- Old: ---- Text-CSV_XS-1.04.tgz New: ---- Text-CSV_XS-1.05.tgz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Text-CSV_XS.spec ++++++ --- /var/tmp/diff_new_pack.Pudn1P/_old 2014-03-18 14:17:02.000000000 +0100 +++ /var/tmp/diff_new_pack.Pudn1P/_new 2014-03-18 14:17:02.000000000 +0100 @@ -17,7 +17,7 @@ Name: perl-Text-CSV_XS -Version: 1.04 +Version: 1.05 Release: 0 %define cpan_name Text-CSV_XS Summary: comma-separated values manipulation routines ++++++ Text-CSV_XS-1.04.tgz -> Text-CSV_XS-1.05.tgz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/CSV_XS.pm new/Text-CSV_XS-1.05/CSV_XS.pm --- old/Text-CSV_XS-1.04/CSV_XS.pm 2014-02-06 07:37:44.000000000 +0100 +++ new/Text-CSV_XS-1.05/CSV_XS.pm 2014-03-06 12:46:25.000000000 +0100 @@ -28,7 +28,7 @@ use Carp; use vars qw( $VERSION @ISA @EXPORT_OK ); -$VERSION = "1.04"; +$VERSION = "1.05"; @ISA = qw( DynaLoader Exporter ); @EXPORT_OK = qw( csv ); bootstrap Text::CSV_XS $VERSION; @@ -74,6 +74,7 @@ auto_diag => 0, diag_verbose => 0, types => undef, + callbacks => undef, _EOF => 0, _RECNO => 0, @@ -86,6 +87,10 @@ _BOUND_COLUMNS => undef, _AHEAD => undef, ); +my %attr_alias = ( + quote_always => "always_quote", + verbose_diag => "diag_verbose", + ); my $last_new_err = Text::CSV_XS->SetDiag (0); sub _check_sanity @@ -104,35 +109,44 @@ sub new { - $last_new_err = SetDiag (undef, 1000, + $last_new_err = Text::CSV_XS->SetDiag (1000, "usage: my \$csv = Text::CSV_XS->new ([{ option => value, ... }]);"); my $proto = shift; my $class = ref ($proto) || $proto or return; @_ > 0 && ref $_[0] ne "HASH" and return; my $attr = shift || {}; + my %attr = map { + my $k = m/^[a-zA-Z]\w+$/ ? lc $_ : $_; + exists $attr_alias{$k} and $k = $attr_alias{$k}; + $k => $attr->{$_}; + } keys %$attr; - for (keys %{$attr}) { + for (keys %attr) { if (m/^[a-z]/ && exists $def_attr{$_}) { - defined $attr->{$_} && $] >= 5.008002 && m/_char$/ and - utf8::decode ($attr->{$_}); + defined $attr{$_} && $] >= 5.008002 && m/_char$/ and + utf8::decode ($attr{$_}); next; } # croak? - $last_new_err = SetDiag (undef, 1000, "INI - Unknown attribute '$_'"); - $attr->{auto_diag} and error_diag (); + $last_new_err = Text::CSV_XS->SetDiag (1000, "INI - Unknown attribute '$_'"); + $attr{auto_diag} and error_diag (); return; } - my $self = { %def_attr, %{$attr} }; + my $self = { %def_attr, %attr }; if (my $ec = _check_sanity ($self)) { - $last_new_err = SetDiag (undef, $ec); - $attr->{auto_diag} and error_diag (); + $last_new_err = Text::CSV_XS->SetDiag ($ec); + $attr{auto_diag} and error_diag (); return; } + if ($self->{callbacks} && ref $self->{callbacks} ne "HASH") { + carp "The 'callbacks' attribute is set but is not a hash: ignored\n"; + $self->{callbacks} = undef; + } - $last_new_err = SetDiag (undef, 0); - defined $\ && !exists $attr->{eol} and $self->{eol} = $\; + $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}); $self; @@ -160,6 +174,7 @@ quote_null => 31, quote_binary => 32, decode_utf8 => 35, + _has_hooks => 36, _is_bound => 26, # 26 .. 29 ); @@ -398,6 +413,33 @@ } } # types +sub callbacks +{ + my $self = shift; + if (@_) { + my $cb; + my $hf = 0x00; + if (!defined $_[0]) { + } + else { + $cb = @_ == 1 && ref $_[0] eq "HASH" ? shift + : @_ % 2 == 0 ? { @_ } + : croak ($self->SetDiag (1004)); + foreach my $cbk (keys %$cb) { + (defined $cbk && !ref $cbk && $cbk =~ m/^[\w.]+$/) && + (defined $cb->{$cbk} && ref $cb->{$cbk} eq "CODE") or + croak ($self->SetDiag (1004)); + } + exists $cb->{error} and $hf |= 0x01; + exists $cb->{after_parse} and $hf |= 0x02; + exists $cb->{before_print} and $hf |= 0x04; + } + $self->_set_attr_X ("_has_hooks", $hf); + $self->{callbacks} = $cb; + } + $self->{callbacks}; + } # callbacks + # erro_diag # # If (and only if) an error occurred, this function returns a code that @@ -414,6 +456,9 @@ $diag[1] = $self->{_ERROR_DIAG}; $diag[2] = 1 + $self->{_ERROR_POS} if exists $self->{_ERROR_POS}; $diag[3] = $self->{_RECNO}; + + $diag[0] && $self && $self->{callbacks} && $self->{callbacks}{error} and + return $self->{callbacks}{error}->(@diag); } my $context = wantarray; @@ -810,13 +855,16 @@ } my $frag = $c->{frag}; - # aoa - ref $hdrs or - return $frag ? $csv->fragment ($fh, $frag) : $csv->getline_all ($fh); - - # aoh - $csv->column_names ($hdrs); - return $frag ? $csv->fragment ($fh, $frag) : $csv->getline_hr_all ($fh); + my $ref = ref $hdrs + ? # aoh + do { + $csv->column_names ($hdrs); + $frag ? $csv->fragment ($fh, $frag) : $csv->getline_hr_all ($fh); + } + : # aoa + $frag ? $csv->fragment ($fh, $frag) : $csv->getline_all ($fh); + $ref or Text::CSV_XS->auto_diag; + return $ref; } # csv 1; @@ -1036,12 +1084,17 @@ =item eol X<eol> -An end-of-line string to add to rows. +The end-of-line string to add to rows for L</print> or the record separator +for L</getline>. When not passed in a B<parser> instance, the default behavior is to accept C<\n>, C<\r>, and C<\r\n>, so it is probably safer to not specify C<eol> at all. Passing C<undef> or the empty string behave the same. +When not passed in a B<generating> instance, lines are not terminated at +all, so it is probably wise to pass something you expect. A safe choice +for C<eol> on output is either C<$/> or C<\r\n>. + Common values for C<eol> are C<"\012"> (C<\n> or Line Feed), C<"\015\012"> (C<\r\n> or Carriage Return, Line Feed), and C<"\015"> (C<\r> or Carriage Return). The C<eol> attribute cannot exceed 7 (ASCII) characters. @@ -1338,6 +1391,11 @@ current input line (if known) to the diagnostic output with an indication of the position of the error. +=item callbacks +X<callbacks> + +See the L</Callbacks> section below. + =back To sum it up, @@ -1367,6 +1425,7 @@ verbatim => 0, auto_diag => 0, diag_verbose => 0, + callbacks => undef, }); For all of the above mentioned flags, an accessor method is available where @@ -1574,6 +1633,9 @@ $csv->column_names ("Name", "Age"); my $AoH = $csv->fragment ($io, "col=3;8"); +If the L</after_parse> callback is active, it is also called on every line +parsed and skipped before the fragment. + =over 2 =item row @@ -1896,8 +1958,8 @@ Used to specify the source. C<in> can be a file name (e.g. C<"file.csv">), which will be opened for reading and closed when finished, a file handle (e.g. -C<$fh> or C<FH>), a reference to a glob (e.g. C<\*ARGV>), or - when your -version of perl is not archaic - the glob itself (e.g. C<*STDIN>). +C<$fh> or C<FH>), a reference to a glob (e.g. C<\*ARGV>), or the glob itself +(e.g. C<*STDIN>). When used with L</out>, it should be a reference to a CSV structure (AoA or AoH). @@ -1920,8 +1982,7 @@ C<out> can be a file name (e.g. C<"file.csv">), which will be opened for writing and closed when finished, a file handle (e.g. C<$fh> or C<FH>), a -reference to a glob (e.g. C<\*STDOUT>), or - when your version of perl is -not archaic - the glob itself (e.g. C<*STDOUT>). +reference to a glob (e.g. C<\*STDOUT>), or the glob itself (e.g. C<*STDOUT>). =head3 encoding X<encoding> @@ -1970,6 +2031,90 @@ ); say $aoh->[15]{Foo}; +=head2 Callbacks + +Callbacks enable actions inside L</Text::CSV_XS>. While most of what this +offers can easily be done in an unrolled loop as described in the l</SYNOPSIS> +callbacks can be used to meet special demands or enhance the L</csv> function. + +=over 2 + +=item error + + $csv->callbacks (error => sub { $csv->SetDiag (0) }); + +the C<error> callback is invoked when an error occurs, but I<only> when +L</auto_diag> is set to a true value. The callback is passed the values +returned by L</error_diag>: + + my ($c, $s); + + sub ignore3006 + { + my ($err, $msg, $pos, $recno) = @_; + if ($err == 3006) { + # ignore this error + ($c, $s) = (undef, undef); + SetDiag (0); + } + # Any other error + return; + } # ignore3006 + + $csv->callbacks (error => \&ignore3006); + $csv->bind_columns (\$c, \$s); + while ($csv->getline ($fh)) { + # Error 3006 will not stop the loop + } + +=item after_parse + + $csv->callbacks (after_parse => sub { push @{$_[1]}, "NEW" }); + while (my $row = $csv->getline ($fh)) { + $row->[-1] eq "NEW"; + } + +This callback is invoked after parsing with L</getline> only if no error +occurred. The callback is invoked with two arguments: the current CSV +parser object and an array reference to the fields parsed. + +The return code of the callback is ignored. + + sub add_from_db + { + my ($csv, $row) = @_; + $sth->execute ($row->[4]); + push @$row, $sth->fetchrow_array; + } # add_from_db + + my $aoa = csv (in => "file.csv", callbacks => { + after_parse => \&add_from_db }); + +=item before_print + + my $idx = 1; + $csv->callbacks (before_print => sub { $_[1][0] = $idx++ }); + $csv->print (*STDOUT, [ 0, $_ ]) for @members; + +This callback is invoked before printing with L</print> only if no error +occurred. The callback is invoked with two arguments: the current CSV +parser object and an array reference to the fields passed. + +The return code of the callback is ignored. + + sub max_4_fields + { + my ($csv, $row) = @_; + @$row > 4 and splice @$row, 4; + } # max_4_fields + + csv (in => csv (in => "file.csv"), out => *STDOUT, + callbacks => { before print => \&max_4_fields }); + +This callback is not active for L</combine>. + +=back + =head1 INTERNALS =over 4 @@ -2177,8 +2322,10 @@ }, ] -Note that L</getline_all> already returns all rows for an open stream, but -this will not return flags. +Note that the L</csv> function already supports most of this, but does not +return flags. L</getline_all> returns all rows for an open stream, but this +will not return flags either. L</fragment> can reduce the required rows I<or> +columns, but cannot combine them. =back @@ -2305,6 +2452,12 @@ C<escape_char> is not allowed. =item * +1004 "INI - callbacks should be undef or a hashref" +X<1004> + +The C<callbacks> attribute only allows to be C<undef> or a hash reference. + +=item * 2010 "ECR - QUO char inside quotes followed by CR not part of EOL" X<2010> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/CSV_XS.xs new/Text-CSV_XS-1.05/CSV_XS.xs --- old/Text-CSV_XS-1.04/CSV_XS.xs 2014-02-01 11:00:14.000000000 +0100 +++ new/Text-CSV_XS-1.05/CSV_XS.xs 2014-03-06 12:42:11.000000000 +0100 @@ -57,11 +57,16 @@ #define CACHE_ID_diag_verbose 33 #define CACHE_ID_has_error_input 34 #define CACHE_ID_decode_utf8 35 +#define CACHE_ID__has_hooks 36 -#define CSV_FLAGS_QUO 0x0001 -#define CSV_FLAGS_BIN 0x0002 -#define CSV_FLAGS_EIF 0x0004 -#define CSV_FLAGS_MIS 0x0010 +#define CSV_FLAGS_QUO 0x0001 +#define CSV_FLAGS_BIN 0x0002 +#define CSV_FLAGS_EIF 0x0004 +#define CSV_FLAGS_MIS 0x0010 + +#define HOOK_ERROR 0x0001 +#define HOOK_AFTER_PARSE 0x0002 +#define HOOK_BEFORE_PRINT 0x0004 #define CH_TAB '\011' #define CH_NL '\012' @@ -77,6 +82,12 @@ #define _is_arrayref(f) ( f && \ (SvROK (f) || (SvRMAGICAL (f) && (mg_get (f), 1) && SvROK (f))) && \ SvOK (f) && SvTYPE (SvRV (f)) == SVt_PVAV ) +#define _is_hashref(f) ( f && \ + (SvROK (f) || (SvRMAGICAL (f) && (mg_get (f), 1) && SvROK (f))) && \ + SvOK (f) && SvTYPE (SvRV (f)) == SVt_PVHV ) +#define _is_coderef(f) ( f && \ + (SvROK (f) || (SvRMAGICAL (f) && (mg_get (f), 1) && SvROK (f))) && \ + SvOK (f) && SvTYPE (SvRV (f)) == SVt_PVCV ) #define CSV_XS_SELF \ if (!self || !SvOK (self) || !SvROK (self) || \ @@ -114,6 +125,7 @@ byte diag_verbose; byte has_error_input; byte decode_utf8; + byte has_hooks; long is_bound; @@ -157,6 +169,7 @@ { 1001, "INI - sep_char is equal to quote_char or escape_char" }, { 1002, "INI - allow_whitespace with escape_char or quote_char SP or TAB" }, { 1003, "INI - \r or \n in main attr not allowed" }, + { 1004, "INI - callbacks should be undef or a hashref" }, /* Parse errors */ { 2010, "ECR - QUO char inside quotes followed by CR not part of EOL" }, @@ -205,6 +218,7 @@ static char init_cache[CACHE_SIZE]; static int io_handle_loaded = 0; static SV *m_getline, *m_print, *m_read; +static int last_error = 0; #define require_IO_Handle \ unless (io_handle_loaded) {\ @@ -245,6 +259,7 @@ dSP; SV *err = SvDiag (xse); + last_error = xse; if (err) (void)hv_store (csv->self, "_ERROR_DIAG", 11, err, 0); if (xse == 0) { @@ -301,6 +316,7 @@ idx == CACHE_ID_verbatim || idx == CACHE_ID_auto_diag || idx == CACHE_ID_diag_verbose || + idx == CACHE_ID__has_hooks || idx == CACHE_ID_has_error_input) { cp[idx] = (byte)SvIV (val); return; @@ -382,6 +398,7 @@ _cache_show_byte ("keep_meta_info", CACHE_ID_keep_meta_info); _cache_show_byte ("verbatim", CACHE_ID_verbatim); + _cache_show_byte ("has_hooks", CACHE_ID__has_hooks); _cache_show_byte ("eol_is_cr", CACHE_ID_eol_is_cr); _cache_show_byte ("eol_len", CACHE_ID_eol_len); if (c < 8) @@ -420,6 +437,7 @@ STRLEN len; char *ptr; + last_error = 0; csv->self = self; csv->pself = pself; @@ -449,6 +467,7 @@ csv->empty_is_undef = csv->cache[CACHE_ID_empty_is_undef ]; csv->verbatim = csv->cache[CACHE_ID_verbatim ]; csv->has_ahead = csv->cache[CACHE_ID__has_ahead ]; + csv->has_hooks = csv->cache[CACHE_ID__has_hooks ]; csv->eol_is_cr = csv->cache[CACHE_ID_eol_is_cr ]; csv->eol_len = csv->cache[CACHE_ID_eol_len ]; if (csv->eol_len < 8) @@ -523,8 +542,16 @@ } csv->is_bound = 0; - if ((svp = hv_fetchs (self, "_is_bound", FALSE)) && *svp && SvOK(*svp)) + if ((svp = hv_fetchs (self, "_is_bound", FALSE)) && *svp && SvOK (*svp)) csv->is_bound = SvIV(*svp); + csv->has_hooks = 0; + if ((svp = hv_fetchs (self, "callbacks", FALSE)) && _is_hashref (*svp)) { + HV *cb = (HV *)SvRV (*svp); + if ((svp = hv_fetchs (cb, "after_parse", FALSE)) && _is_coderef (*svp)) + csv->has_hooks |= HOOK_AFTER_PARSE; + if ((svp = hv_fetchs (cb, "before_print", FALSE)) && _is_coderef (*svp)) + csv->has_hooks |= HOOK_BEFORE_PRINT; + } csv->binary = bool_opt ("binary"); csv->decode_utf8 = bool_opt ("decode_utf8"); @@ -576,6 +603,7 @@ memcpy ((char *)&csv->cache[CACHE_ID_eol], csv->eol, csv->eol_len); csv->cache[CACHE_ID_has_types] = csv->types ? 1 : 0; csv->cache[CACHE_ID__has_ahead] = csv->has_ahead = 0; + csv->cache[CACHE_ID__has_hooks] = csv->has_hooks; csv->cache[CACHE_ID__is_bound ] = (csv->is_bound & 0xFF000000) >> 24; csv->cache[CACHE_ID__is_bound + 1] = (csv->is_bound & 0x00FF0000) >> 16; csv->cache[CACHE_ID__is_bound + 2] = (csv->is_bound & 0x0000FF00) >> 8; @@ -1527,12 +1555,40 @@ return result; } /* c_xsParse */ +static void hook (pTHX_ HV *hv, char *cb_name, AV *av) +{ + SV **svp; + HV *cb; + + unless ((svp = hv_fetchs (hv, "callbacks", FALSE)) && _is_hashref (*svp)) + return; + + cb = (HV *)SvRV (*svp); + unless ((svp = hv_fetch (cb, cb_name, strlen (cb_name), FALSE)) && _is_coderef (*svp)) + return; + + { dSP; + ENTER; + SAVETMPS; + PUSHMARK (SP); + XPUSHs (newRV_noinc ((SV *)hv)); + XPUSHs (newRV_noinc ((SV *)av)); + PUTBACK; + call_sv (*svp, G_VOID | G_DISCARD); + FREETMPS; + LEAVE; + } + } /* hook */ + #define xsParse(self,hv,av,avf,src,useIO) cx_xsParse (aTHX_ self, hv, av, avf, src, useIO) static int cx_xsParse (pTHX_ SV *self, HV *hv, AV *av, AV *avf, SV *src, bool useIO) { csv_t csv; SetupCsv (&csv, hv, self); - return (c_xsParse (csv, hv, av, avf, src, useIO)); + int state = c_xsParse (csv, hv, av, avf, src, useIO); + if (state && csv.has_hooks & HOOK_AFTER_PARSE) + hook (aTHX_ hv, "after_parse", av); + return (state || !last_error); } /* xsParse */ #define av_empty(av) cx_av_empty (aTHX_ av) @@ -1585,6 +1641,8 @@ n--; } + if (csv.has_hooks & HOOK_AFTER_PARSE) + hook (aTHX_ hv, "after_parse", row); av_push (avr, newRV_noinc ((SV *)row)); if (n >= length && skip >= 0) @@ -1615,6 +1673,8 @@ if (csv.eol && *csv.eol) PL_ors_sv = NULL; #endif + if (useIO && csv.has_hooks & HOOK_BEFORE_PRINT) + hook (aTHX_ hv, "before_print", av); result = Combine (&csv, io, av); #if (PERL_BCDVERSION >= 0x5008000) PL_ors_sv = ors; @@ -1754,7 +1814,7 @@ av = newAV (); avf = newAV (); ST (0) = xsParse (self, hv, av, avf, io, 1) - ? sv_2mortal (newRV_noinc ((SV *)av)) + ? sv_2mortal (newRV_noinc ((SV *)av)) : &PL_sv_undef; XSRETURN (1); /* XS getline */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/ChangeLog new/Text-CSV_XS-1.05/ChangeLog --- old/Text-CSV_XS-1.04/ChangeLog 2014-02-01 11:02:39.000000000 +0100 +++ new/Text-CSV_XS-1.05/ChangeLog 2014-03-02 12:41:14.000000000 +0100 @@ -1,5 +1,13 @@ -1.04 - 2014-02-01, H.Merijn Brand - * get_columnd () with no argument now returns the empty list +1.05 - 2014-03-02, H.Merijn Brand + * Allow case insensitive attributes and attribute aliases + (quote_always = always_quote) + * Enhanced the csv () function (diagnostics) + * Start callbacks support + * Minor doc fixes + * Make subclassing safer + +1.04 - 2014-02-06, H.Merijn Brand + * get_columns () with no argument now returns the empty list instead of undef when no columns defined * fragments (rcf7111) now also support AoH (was AoA only) * Error code conflict for fragments resolved to 2013 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/MANIFEST new/Text-CSV_XS-1.05/MANIFEST --- old/Text-CSV_XS-1.04/MANIFEST 2014-02-06 08:47:02.000000000 +0100 +++ new/Text-CSV_XS-1.05/MANIFEST 2014-03-12 22:39:05.000000000 +0100 @@ -28,6 +28,7 @@ t/76_magic.t array_ref from magic t/77_getall.t Get all rows at once t/78_fragment.t Get fragments according to RFC7111 specs +t/79_callbacks.t Test callback features t/80_diag.t Error diagnostics t/81_subclass.t Subclassed t/90_csv.t Function csv () checks diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/META.json new/Text-CSV_XS-1.05/META.json --- old/Text-CSV_XS-1.04/META.json 2014-02-06 08:47:02.000000000 +0100 +++ new/Text-CSV_XS-1.05/META.json 2014-03-12 22:39:06.000000000 +0100 @@ -1,17 +1,47 @@ { + "provides" : { + "Text::CSV_XS" : { + "version" : "1.05", + "file" : "CSV_XS.pm" + } + }, + "meta-spec" : { + "version" : "2", + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + }, + "name" : "Text-CSV_XS", "generated_by" : "Author", + "author" : [ + "H.Merijn Brand <[email protected]>" + ], + "version" : "1.05", + "resources" : { + "repository" : { + "url" : "http://repo.or.cz/r/Text-CSV_XS.git", + "type" : "git", + "web" : "http://repo.or.cz/w/Text-CSV_XS.git" + }, + "license" : [ + "http://dev.perl.org/licenses/" + ] + }, "release_status" : "stable", - "dynamic_config" : 1, "prereqs" : { - "configure" : { + "runtime" : { "requires" : { - "ExtUtils::MakeMaker" : "0" + "DynaLoader" : "0", + "IO::Handle" : "0", + "perl" : "5.006001" + }, + "recommends" : { + "Encode" : "2.57", + "perl" : "5.018001" } }, "test" : { "requires" : { - "Tie::Scalar" : "0", - "Test::More" : "0" + "Test::More" : "0", + "Tie::Scalar" : "0" } }, "build" : { @@ -19,45 +49,15 @@ "Config" : "0" } }, - "runtime" : { - "recommends" : { - "perl" : "5.018001", - "Encode" : "2.57" - }, + "configure" : { "requires" : { - "IO::Handle" : "0", - "DynaLoader" : "0", - "perl" : "5.006001" + "ExtUtils::MakeMaker" : "0" } } }, - "author" : [ - "H.Merijn Brand <[email protected]>" - ], - "version" : "1.04", "license" : [ "perl_5" ], - "provides" : { - "Text::CSV_XS" : { - "file" : "CSV_XS.pm", - "version" : "1.04" - } - }, - "meta-spec" : { - "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" - }, - "resources" : { - "repository" : { - "web" : "http://repo.or.cz/w/Text-CSV_XS.git", - "url" : "http://repo.or.cz/r/Text-CSV_XS.git", - "type" : "git" - }, - "license" : [ - "http://dev.perl.org/licenses/" - ] - }, "abstract" : "Comma-Separated Values manipulation routines", - "name" : "Text-CSV_XS" + "dynamic_config" : 1 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/META.yml new/Text-CSV_XS-1.05/META.yml --- old/Text-CSV_XS-1.04/META.yml 2014-02-06 08:47:02.000000000 +0100 +++ new/Text-CSV_XS-1.05/META.yml 2014-03-12 22:39:06.000000000 +0100 @@ -7,7 +7,7 @@ configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 -generated_by: Author, CPAN::Meta::Converter version 2.133380 +generated_by: Author, CPAN::Meta::Converter version 2.140640 license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -16,7 +16,7 @@ provides: Text::CSV_XS: file: CSV_XS.pm - version: '1.04' + version: '1.05' recommends: Encode: '2.57' perl: '5.018001' @@ -29,4 +29,4 @@ resources: license: http://dev.perl.org/licenses/ repository: http://repo.or.cz/r/Text-CSV_XS.git -version: '1.04' +version: '1.05' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/Makefile.PL new/Text-CSV_XS-1.05/Makefile.PL --- old/Text-CSV_XS-1.04/Makefile.PL 2014-01-01 14:21:51.000000000 +0100 +++ new/Text-CSV_XS-1.05/Makefile.PL 2014-03-11 08:32:43.000000000 +0100 @@ -112,5 +112,8 @@ 'test_speed: pure_all', ' PERL_DL_NONLAZY=1 $(FULLPERLRUN) -I"$(INST_LIB)" -I"$(INST_ARCHLIB)" examples/speed.pl', '', + 'test_used: test', + ' prove -vwb sandbox/used-by.pl', + '', $min_vsn; } # postamble diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/t/12_acc.t new/Text-CSV_XS-1.05/t/12_acc.t --- old/Text-CSV_XS-1.04/t/12_acc.t 2013-03-30 15:58:16.000000000 +0100 +++ new/Text-CSV_XS-1.05/t/12_acc.t 2014-02-25 12:00:45.000000000 +0100 @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 133; +use Test::More tests => 136; BEGIN { use_ok "Text::CSV_XS"; @@ -99,6 +99,11 @@ $csv->binary (1); ok ( $csv->parse ("foo,foo\0bar"), "parse (foo)"); +# Attribute aliasses +ok ($csv = Text::CSV_XS-> new ({ quote_always => 1, verbose_diag => 1})); +is ($csv->always_quote, 1, "always_quote = quote_always"); +is ($csv->diag_verbose, 1, "diag_verbose = verbose_diag"); + # Some forbidden combinations foreach my $ws (" ", "\t") { ok ($csv = Text::CSV_XS->new ({ escape_char => $ws }), "New blank escape"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/t/79_callbacks.t new/Text-CSV_XS-1.05/t/79_callbacks.t --- old/Text-CSV_XS-1.04/t/79_callbacks.t 1970-01-01 01:00:00.000000000 +0100 +++ new/Text-CSV_XS-1.05/t/79_callbacks.t 2014-03-06 12:43:12.000000000 +0100 @@ -0,0 +1,120 @@ +#!/usr/bin/perl + +use strict; +use warnings; + + use Test::More tests => 57; +#use Test::More "no_plan"; + +BEGIN { + require_ok "Text::CSV_XS"; + plan skip_all => "Cannot load Text::CSV_XS" if $@; + require "t/util.pl"; + } + +$| = 1; + +ok (my $csv = Text::CSV_XS->new (), "new"); +is ($csv->callbacks, undef, "no callbacks"); + +ok ($csv->bind_columns (\my ($c, $s)), "bind"); +ok ($csv->getline (*DATA), "parse ok"); +is ($c, 1, "key"); +is ($s, "foo", "value"); +$s = "untouched"; +ok ($csv->getline (*DATA), "parse bad"); +is ($c, 1, "key"); +is ($s, "untouched", "untouched"); +ok ($csv->getline (*DATA), "parse bad"); +is ($c, "foo", "key"); +is ($s, "untouched", "untouched"); +ok ($csv->getline (*DATA), "parse good"); +is ($c, 2, "key"); +is ($s, "bar", "value"); +eval { is ($csv->getline (*DATA), undef,"parse bad"); }; +my @diag = $csv->error_diag; +is ($diag[0], 3006, "too many values"); + +foreach my $args ([""], [1], [[]], [sub{}], [1,2], [1,2,3], ["error",undef]) { + eval { $csv->callbacks (@$args); }; + my @diag = $csv->error_diag; + is ($diag[0], 1004, "invalid callbacks"); + is ($csv->callbacks, undef, "not set"); + } + +my $error = 3006; +sub ignore +{ + is ($_[0], $error, "Caught error $error"); + $csv->SetDiag (0); # Ignore this error + } # ignore + +my $idx = 1; +ok ($csv->auto_diag (1), "set auto_diag"); +my $callbacks = { + error => \&ignore, + after_parse => sub { + my ($c, $av) = @_; + # Just add a field + push @$av, "NEW"; + }, + before_print => sub { + my ($c, $av) = @_; + # First field set to line number + $av->[0] = $idx++; + # Maximum 2 fields + @{$av} > 2 and splice @{$av}, 2; + # Minimum 2 fields + @{$av} < 2 and push @{$av}, ""; + }, + }; +is (ref $csv->callbacks ($callbacks), "HASH", "callbacks set"); +ok ($csv->getline (*DATA), "parse ok"); +is ($c, 1, "key"); +is ($s, "foo", "value"); +ok ($csv->getline (*DATA), "parse bad, skip 3006"); +ok ($csv->getline (*DATA), "parse good"); +is ($c, 2, "key"); +is ($s, "bar", "value"); + +$csv->bind_columns (undef); +ok (my $row = $csv->getline (*DATA), "get row"); +is_deeply ($row, [ 1, 2, 3, "NEW" ], "fetch + value from hook"); + +$error = 2012; # EOF +ok ($csv->getline (*DATA), "parse past eof"); + +my $fn = "_79test.csv"; +END { unlink $fn; } + +ok ($csv->eol ("\n"), "eol for output"); +open my $fh, ">", $fn or die "$fn: $!"; +ok ($csv->print ($fh, [ 0, "foo" ]), "print OK"); +ok ($csv->print ($fh, [ 0, "bar", 3 ]), "print too many"); +ok ($csv->print ($fh, [ 0 ]), "print too few"); +close $fh; + +open $fh, "<", $fn or die "$fn: $!"; +is (do { local $/; <$fh> }, "1,foo\n2,bar\n3,\n", "Modified output"); +close $fh; + +is_deeply (Text::CSV_XS::csv (in => $fn, callbacks => $callbacks), + [[1,"foo","NEW"],[2,"bar","NEW"],[3,"","NEW"]], "using getline_all"); + +# Test the non-IO interface +ok ($csv->parse ("10,blah,33\n"), "parse"); +is_deeply ([ $csv->fields ], [ 10, "blah", 33, "NEW" ], "fields"); + +ok ($csv->combine (11, "fri", 22, 18), "combine - no hook"); +is ($csv->string, qq{11,fri,22,18\n}, "string"); + +__END__ +1,foo +1 +foo +2,bar +3,baz,2 +1,foo +3,baz,2 +2,bar +1,2,3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/t/80_diag.t new/Text-CSV_XS-1.05/t/80_diag.t --- old/Text-CSV_XS-1.04/t/80_diag.t 2014-02-01 11:00:07.000000000 +0100 +++ new/Text-CSV_XS-1.05/t/80_diag.t 2014-02-25 16:49:56.000000000 +0100 @@ -3,7 +3,7 @@ use strict; use warnings; - use Test::More tests => 179; + use Test::More tests => 180; #use Test::More "no_plan"; my %err; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.04/t/81_subclass.t new/Text-CSV_XS-1.05/t/81_subclass.t --- old/Text-CSV_XS-1.04/t/81_subclass.t 2013-07-25 15:29:03.000000000 +0200 +++ new/Text-CSV_XS-1.05/t/81_subclass.t 2014-02-28 21:12:21.000000000 +0100 @@ -7,7 +7,7 @@ use base "Text::CSV_XS"; -use Test::More tests => 5; +use Test::More tests => 6; ok (1, "Subclassed"); @@ -22,4 +22,6 @@ is (Text::CSV_XS::Subclass->error_diag (), "INI - Unknown attribute 'ecs_char'", "Last failure for new () - FAIL"); +is (Text::CSV_XS::Subclass->new ({ fail_me => "now" }), undef, "bad new ()"); + 1; -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
