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]

Reply via email to