dsp             Wed Oct  3 10:44:32 2007 UTC

  Added files:                 (Branch: PHP_5_3)
    /php-src/ext/standard/tests/file    bug40501.csv bug40501.phpt 

  Modified files:              
    /php-src    NEWS 
    /php-src/ext/spl    spl_directory.c spl_directory.h 
    /php-src/ext/standard       file.c file.h 
    /php-src/ext/standard/tests/file    fgetcsv_error.phpt 
  Log:
  MFH: Add an escape parameter to fgetcsv to satisfy rfc4180 and bug #40501.
  [DOC] 5th parameter available since PHP 5.3+
  
  
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.20&r2=1.2027.2.547.2.965.2.21&diff_format=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.2027.2.547.2.965.2.20 
php-src/NEWS:1.2027.2.547.2.965.2.21
--- php-src/NEWS:1.2027.2.547.2.965.2.20        Wed Oct  3 10:33:01 2007
+++ php-src/NEWS        Wed Oct  3 10:44:32 2007
@@ -1,6 +1,7 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 20??, PHP 5.3.0
+- Added optional escape character parameter to fgetcsv. (David Soria Parra)
 - Added xsl->setProfiling() for profiling stylesheets. (Christian)
 - Added long-option feature to getopt() and made getopt() available also on 
   win32 systems by adding a common getopt implementation into core.
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_directory.c?r1=1.45.2.27.2.23.2.1&r2=1.45.2.27.2.23.2.2&diff_format=u
Index: php-src/ext/spl/spl_directory.c
diff -u php-src/ext/spl/spl_directory.c:1.45.2.27.2.23.2.1 
php-src/ext/spl/spl_directory.c:1.45.2.27.2.23.2.2
--- php-src/ext/spl/spl_directory.c:1.45.2.27.2.23.2.1  Thu Sep 27 18:00:44 2007
+++ php-src/ext/spl/spl_directory.c     Wed Oct  3 10:44:32 2007
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: spl_directory.c,v 1.45.2.27.2.23.2.1 2007/09/27 18:00:44 dmitry Exp $ 
*/
+/* $Id: spl_directory.c,v 1.45.2.27.2.23.2.2 2007/10/03 10:44:32 dsp Exp $ */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -1589,7 +1589,7 @@
        spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, 
arg2 TSRMLS_CC); \
 }
 
-static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char 
delimiter, char enclosure, zval *return_value TSRMLS_DC) /* {{{ */
+static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char 
delimiter, char enclosure, char escape, zval *return_value TSRMLS_DC) /* {{{ */
 {
        int ret = SUCCESS;
        
@@ -1606,7 +1606,7 @@
                }
                ALLOC_INIT_ZVAL(intern->u.file.current_zval);
 
-               php_fgetcsv(intern->u.file.stream, delimiter, enclosure, 
buf_len, buf, intern->u.file.current_zval TSRMLS_CC);
+               php_fgetcsv(intern->u.file.stream, delimiter, enclosure, 
escape, buf_len, buf, intern->u.file.current_zval TSRMLS_CC);
                if (return_value) {
                        if (Z_TYPE_P(return_value) != IS_NULL) {
                                zval_dtor(return_value);
@@ -1632,7 +1632,7 @@
                        return FAILURE;
                }
                if (intern->flags & SPL_FILE_OBJECT_READ_CSV) {
-                       return spl_filesystem_file_read_csv(intern, 
intern->u.file.delimiter, intern->u.file.enclosure, NULL TSRMLS_CC);
+                       return spl_filesystem_file_read_csv(intern, 
intern->u.file.delimiter, intern->u.file.enclosure, intern->u.file.escape, NULL 
TSRMLS_CC);
                } else {
                        zend_call_method_with_0_params(&this_ptr, 
Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval);
                }
@@ -1943,18 +1943,25 @@
 }
 /* }}} */
 
-/* {{{ proto array SplFileObject::fgetcsv([string delimiter [, string 
enclosure]])
+/* {{{ proto array SplFileObject::fgetcsv([string delimiter [, string 
enclosure [, escape = '\\']]])
    Return current line as csv */
 SPL_METHOD(SplFileObject, fgetcsv)
 {
        spl_filesystem_object *intern = 
(spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       char delimiter = intern->u.file.delimiter, enclosure = 
intern->u.file.enclosure;
-       char *delim, *enclo;
-       int d_len, e_len;
+       char delimiter = intern->u.file.delimiter, enclosure = 
intern->u.file.enclosure, escape = intern->u.file.escape;
+       char *delim, *enclo, *esc;
+       int d_len, e_len, esc_len;
        
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &delim, 
&d_len, &enclo, &e_len) == SUCCESS) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, 
&d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) {
                switch(ZEND_NUM_ARGS())
                {
+                   case 3:
+                               if (esc_len != 1) {
+                                       php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "escape must be a character");
+                                       RETURN_FALSE;
+                               }
+                               escape = esc[0];
+                /* no break */
                        case 2:
                                if (e_len != 1) {
                                        php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "enclosure must be a character");
@@ -1972,23 +1979,30 @@
                        case 0:
                                break;
                }
-               spl_filesystem_file_read_csv(intern, delimiter, enclosure, 
return_value TSRMLS_CC);
+               spl_filesystem_file_read_csv(intern, delimiter, enclosure, 
escape, return_value TSRMLS_CC);
        }
 }
 /* }}} */
 
-/* {{{ proto void SplFileObject::setCsvControl([string delimiter = ',' [, 
string enclosure = '"']])
+/* {{{ proto void SplFileObject::setCsvControl([string delimiter = ',' [, 
string enclosure = '"' [, string escape = '\\']]])
    Set the delimiter and enclosure character used in fgetcsv */
 SPL_METHOD(SplFileObject, setCsvControl)
 {
        spl_filesystem_object *intern = 
(spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       char delimiter = ',', enclosure = '"';
-       char *delim, *enclo;
-       int d_len, e_len;
+       char delimiter = ',', enclosure = '"', escape='\\';
+       char *delim, *enclo, *esc;
+       int d_len, e_len, esc_len;
        
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &delim, 
&d_len, &enclo, &e_len) == SUCCESS) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, 
&d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) {
                switch(ZEND_NUM_ARGS())
                {
+                    case 3:
+                               if (esc_len != 1) {
+                                       php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "escape must be a character");
+                                       RETURN_FALSE;
+                               }
+                               escape = esc[0];
+                /* no break */
                        case 2:
                                if (e_len != 1) {
                                        php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "enclosure must be a character");
@@ -2008,6 +2022,7 @@
                }
                intern->u.file.delimiter = delimiter;
                intern->u.file.enclosure = enclosure;
+               intern->u.file.escape    = escape;
        }
 }
 /* }}} */
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_directory.h?r1=1.12.2.5.2.4&r2=1.12.2.5.2.4.2.1&diff_format=u
Index: php-src/ext/spl/spl_directory.h
diff -u php-src/ext/spl/spl_directory.h:1.12.2.5.2.4 
php-src/ext/spl/spl_directory.h:1.12.2.5.2.4.2.1
--- php-src/ext/spl/spl_directory.h:1.12.2.5.2.4        Mon Jan  1 09:36:07 2007
+++ php-src/ext/spl/spl_directory.h     Wed Oct  3 10:44:32 2007
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: spl_directory.h,v 1.12.2.5.2.4 2007/01/01 09:36:07 sebastian Exp $ */
+/* $Id: spl_directory.h,v 1.12.2.5.2.4.2.1 2007/10/03 10:44:32 dsp Exp $ */
 
 #ifndef SPL_DIRECTORY_H
 #define SPL_DIRECTORY_H
@@ -84,6 +84,7 @@
                        zend_function      *func_getCurr;
                        char               delimiter;
                        char               enclosure;
+                       char               escape;
                } file;
        } u;
 };
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/file.c?r1=1.409.2.6.2.28&r2=1.409.2.6.2.28.2.1&diff_format=u
Index: php-src/ext/standard/file.c
diff -u php-src/ext/standard/file.c:1.409.2.6.2.28 
php-src/ext/standard/file.c:1.409.2.6.2.28.2.1
--- php-src/ext/standard/file.c:1.409.2.6.2.28  Tue Sep  4 12:51:49 2007
+++ php-src/ext/standard/file.c Wed Oct  3 10:44:32 2007
@@ -21,7 +21,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: file.c,v 1.409.2.6.2.28 2007/09/04 12:51:49 iliaa Exp $ */
+/* $Id: file.c,v 1.409.2.6.2.28.2.1 2007/10/03 10:44:32 dsp Exp $ */
 
 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
 
@@ -2013,12 +2013,14 @@
 }
 /* }}} */
 
-/* {{{ proto array fgetcsv(resource fp [,int length [, string delimiter [, 
string enclosure]]])
+/* {{{ proto array fgetcsv(resource fp [,int length [, string delimiter [, 
string enclosure [, string escape]]]])
    Get line from file pointer and parse for CSV fields */
 PHP_FUNCTION(fgetcsv)
 {
        char delimiter = ',';   /* allow this to be set as parameter */
        char enclosure = '"';   /* allow this to be set as parameter */
+       char escape = '\\';
+
        /* first section exactly as php_fgetss */
 
        long len = 0;
@@ -2032,10 +2034,13 @@
                int delimiter_str_len = 0;
                char *enclosure_str = NULL;
                int enclosure_str_len = 0;
+               char *escape_str = NULL;
+               int escape_str_len = 0;
 
-               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|Zss",
-                                       &fd, &len_zv, &delimiter_str, 
&delimiter_str_len,
-                                       &enclosure_str, &enclosure_str_len) == 
FAILURE) {
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|Zsss",
+                                                                 &fd, &len_zv, 
&delimiter_str, &delimiter_str_len,
+                                                                 
&enclosure_str, &enclosure_str_len, 
+                                                                 &escape_str, 
&escape_str_len) == FAILURE) {
                        return;
                }       
 
@@ -2064,6 +2069,17 @@
                        enclosure = enclosure_str[0];
                }
 
+               if (escape_str != NULL) {
+                       if (escape_str_len < 1) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"escape must be character");
+                               RETURN_FALSE;
+                       } else if (escape_str_len > 1) {
+                               php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
"escape must be a single character");
+                       }
+
+                       escape = escape_str[0];
+               }
+
                if (len_zv != NULL && Z_TYPE_PP(len_zv) != IS_NULL) {
                        convert_to_long_ex(len_zv);
                        len = Z_LVAL_PP(len_zv);
@@ -2092,14 +2108,13 @@
                }
        }
 
-       php_fgetcsv(stream, delimiter, enclosure, buf_len, buf, return_value 
TSRMLS_CC);
+       php_fgetcsv(stream, delimiter, enclosure, escape, buf_len, buf, 
return_value TSRMLS_CC);
 }
 /* }}} */
 
-PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, 
size_t buf_len, char *buf, zval *return_value TSRMLS_DC) /* {{{ */
+PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, 
char escape_char, size_t buf_len, char *buf, zval *return_value TSRMLS_DC) /* 
{{{ */
 {
        char *temp, *tptr, *bptr, *line_end, *limit;
-       const char escape_char = '\\';
 
        size_t temp_len, line_end_len;
        int inc_len;
@@ -2250,7 +2265,8 @@
                                                                state = 0;
                                                                break;
                                                        default:
-                                                               if (*bptr == 
escape_char) {
+                                                               if 
((escape_char == enclosure && *bptr == escape_char && *(bptr+1) == escape_char) 
+                                                                       || 
(escape_char != enclosure && *bptr == escape_char)) {
                                                                        state = 
1;
                                                                } else if 
(*bptr == enclosure) {
                                                                        state = 
2;
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/file.h?r1=1.94.2.2.2.5&r2=1.94.2.2.2.5.2.1&diff_format=u
Index: php-src/ext/standard/file.h
diff -u php-src/ext/standard/file.h:1.94.2.2.2.5 
php-src/ext/standard/file.h:1.94.2.2.2.5.2.1
--- php-src/ext/standard/file.h:1.94.2.2.2.5    Wed Jan 10 14:40:06 2007
+++ php-src/ext/standard/file.h Wed Oct  3 10:44:32 2007
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: file.h,v 1.94.2.2.2.5 2007/01/10 14:40:06 bjori Exp $ */
+/* $Id: file.h,v 1.94.2.2.2.5.2.1 2007/10/03 10:44:32 dsp Exp $ */
 
 /* Synced with php 3.0 revision 1.30 1999-06-16 [ssb] */
 
@@ -78,7 +78,7 @@
 PHPAPI int php_copy_file_ex(char *src, char *dest, int src_chk TSRMLS_DC);
 PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC);
 PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC);
-PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, 
size_t buf_len, char *buf, zval *return_value TSRMLS_DC);
+PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, 
char escape_char, size_t buf_len, char *buf, zval *return_value TSRMLS_DC);
 
 #define META_DEF_BUFSIZE 8192
 
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/fgetcsv_error.phpt?r1=1.1.2.1&r2=1.1.2.1.2.1&diff_format=u
Index: php-src/ext/standard/tests/file/fgetcsv_error.phpt
diff -u php-src/ext/standard/tests/file/fgetcsv_error.phpt:1.1.2.1 
php-src/ext/standard/tests/file/fgetcsv_error.phpt:1.1.2.1.2.1
--- php-src/ext/standard/tests/file/fgetcsv_error.phpt:1.1.2.1  Wed Aug  8 
13:13:18 2007
+++ php-src/ext/standard/tests/file/fgetcsv_error.phpt  Wed Oct  3 10:44:32 2007
@@ -3,7 +3,7 @@
 --FILE--
 <?php
 /*
- Prototype: array fgetcsv ( resource $handle [, int $length [, string 
$delimiter [, string $enclosure]]] );
+ Prototype: array fgetcsv ( resource $handle [, int $length [, string 
$delimiter [, string $enclosure [, string $escape]]]] );
  Description: Gets line from file pointer and parse for CSV fields
 */
 
@@ -18,7 +18,8 @@
 $len = 1024;
 $delim = ";";
 $enclosure ="\"";
-var_dump( fgetcsv($fp, $len, $delim, $enclosure, $fp) );
+$escape = '"';
+var_dump( fgetcsv($fp, $len, $delim, $enclosure, $escape, $fp) );
 fclose($fp);
 
 // test invalid arguments : non-resources
@@ -35,7 +36,7 @@
 for($loop_counter = 1; $loop_counter <= count($invalid_args); $loop_counter++) 
{
   echo "-- Iteration $loop_counter --\n";
   var_dump( fgetcsv($invalid_args[$loop_counter - 1]) ); // with default args
-  var_dump( fgetcsv($invalid_args[$loop_counter - 1], $len, $delim, 
$enclosure) ); // all args specified
+  var_dump( fgetcsv($invalid_args[$loop_counter - 1], $len, $delim, 
$enclosure, $escape) ); // all args specified
 }
 
 echo "Done\n";
@@ -47,7 +48,7 @@
 NULL
 -- Testing fgetcsv() with more than expected number of arguments --
 
-Warning: fgetcsv() expects at most 4 parameters, 5 given in %s on line %d
+Warning: fgetcsv() expects at most 5 parameters, 6 given in %s on line %d
 NULL
 -- Testing fgetcsv() with invalid arguments --
 -- Iteration 1 --

http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/bug40501.csv?view=markup&rev=1.1
Index: php-src/ext/standard/tests/file/bug40501.csv
+++ php-src/ext/standard/tests/file/bug40501.csv
"this element contains the delimiter, and ends with an odd number of
backslashes (ex: 1)\",and it isn't the last element$
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/bug40501.phpt?view=markup&rev=1.1
Index: php-src/ext/standard/tests/file/bug40501.phpt
+++ php-src/ext/standard/tests/file/bug40501.phpt
--TEST--
Bug #40501 (fgetcsv() can't handle trailing odd number of backslashes)
--FILE--
<?php
$file = dirname(__FILE__).'/bug40501.csv';

$h = fopen($file, 'r');
$data = fgetcsv($h, NULL, ',', '"', '"');
fclose($h);

var_dump($data);
?>
--EXPECT--
array(2) {
  [0]=>
  string(88) "this element contains the delimiter, and ends with an odd number 
of
backslashes (ex: 1)\"
  [1]=>
  string(30) "and it isn't the last element$"
}
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to