Hello David,

  as promised i looked at the patch. Besides a small misstake it looks
good. But it seems to work different then fgetcsv(). In other words if
you write using fputcsv() you are not sure to get the same back with
fgetcsv(). Though my current opinion is that fputcsv() is doing it right.
The attached patch includes a testfile that demonstrates the problem.

  anyone having thoughts?

Wednesday, August 11, 2004, 8:40:07 PM, me wrote:

> Hello David,

> Wednesday, August 11, 2004, 3:53:11 PM, you wrote:

>> Attached is my fputcsv() patch (and a test case) from April. Could 
>> someone commit this to 5.1 or 5.0.1?

> That's a new function so it can only go to 5.1. Anyway it's a nice feature.
> So if nobody has anything against i'd look into it more detailed later this
> week and commit it. Thanks David.

> regards
> marcus




-- 
Best regards,
 Marcus                            mailto:[EMAIL PROTECTED]
Index: ext/standard/basic_functions.c
===================================================================
RCS file: /repository/php-src/ext/standard/basic_functions.c,v
retrieving revision 1.685
diff -u -p -d -r1.685 basic_functions.c
--- ext/standard/basic_functions.c      19 Aug 2004 15:14:04 -0000      1.685
+++ ext/standard/basic_functions.c      1 Sep 2004 21:20:08 -0000
@@ -610,6 +610,7 @@ function_entry basic_functions[] = {
        PHP_FE(stream_copy_to_stream,                                                  
                                 NULL)
        PHP_FE(stream_get_contents,                                                    
                                         NULL)
        PHP_FE(fgetcsv,                                                                
                                                 NULL)
+       PHP_FE(fputcsv,                                                                
                                                 NULL)
        PHP_FE(flock,                                                                  
                  third_arg_force_ref)
        PHP_FE(get_meta_tags,                                                          
                                         NULL)
        PHP_FE(stream_set_write_buffer,                                                
                                 NULL)
Index: ext/standard/file.c
===================================================================
RCS file: /repository/php-src/ext/standard/file.c,v
retrieving revision 1.384
diff -u -p -d -r1.384 file.c
--- ext/standard/file.c 22 Jul 2004 12:12:28 -0000      1.384
+++ ext/standard/file.c 1 Sep 2004 21:20:09 -0000
@@ -35,6 +35,7 @@
 #include "php_open_temporary_file.h"
 #include "ext/standard/basic_functions.h"
 #include "php_ini.h"
+#include "php_smart_str.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -1715,6 +1716,108 @@ quit_loop:
        return ptr;
 }
 
+#define FPUTCSV_FLD_CHK(c) php_memnstr(Z_STRVAL_PP(field), c, 1, Z_STRVAL_PP(field) + 
Z_STRLEN_PP(field))
+
+/* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string 
enclosure]])
+   Format line as CSV and write to file pointer */
+PHP_FUNCTION(fputcsv)
+{
+       char delimiter = ',';   /* allow this to be set as parameter */
+       char enclosure = '"';   /* allow this to be set as parameter */
+       php_stream *stream;
+       int ret;
+       zval *fp = NULL, *fields = NULL, **field = NULL;
+       char *delimiter_str = NULL, *enclosure_str = NULL;
+       int delimiter_str_len, enclosure_str_len;
+       HashPosition pos;
+       int count, i = 0;
+       char enc_double[3];
+       smart_str csvline = {0};
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ass",
+                       &fp, &fields, &delimiter_str, &delimiter_str_len,
+                       &enclosure_str, &enclosure_str_len) == FAILURE) {
+               return;
+       }       
+
+       if (delimiter_str != NULL) {
+               /* Make sure that there is at least one character in string */
+               if (delimiter_str_len < 1) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be 
a character");
+                       RETURN_FALSE;
+               } else if (delimiter_str_len > 1) {
+                       php_error_docref(NULL TSRMLS_CC, E_NOTICE, "delimiter must be 
a single character");
+               }
+
+               /* use first character from string */
+               delimiter = *delimiter_str;
+       }
+
+       if (enclosure_str != NULL) {
+               if (enclosure_str_len < 1) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be 
a character");
+                       RETURN_FALSE;
+               } else if (enclosure_str_len > 1) {
+                       php_error_docref(NULL TSRMLS_CC, E_NOTICE, "enclosure must be 
a single character");
+               }
+               /* use first character from string */
+               enclosure = *enclosure_str;
+       }
+    
+       PHP_STREAM_TO_ZVAL(stream, &fp);
+
+       enc_double[0] = enclosure;
+       enc_double[1] = enclosure;
+       enc_double[2] = '\0';
+       count = zend_hash_num_elements(Z_ARRVAL_P(fields));
+       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos);
+       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field, 
&pos) == SUCCESS) {
+               if (Z_TYPE_PP(field) != IS_STRING) {
+                       SEPARATE_ZVAL(field);
+                       convert_to_string(*field);
+               } 
+               /* enclose a field that contains a delimiter, an enclosure character, 
or a newline */
+               if (FPUTCSV_FLD_CHK(&delimiter) || FPUTCSV_FLD_CHK(&enclosure) || 
FPUTCSV_FLD_CHK("\n") ||
+                       FPUTCSV_FLD_CHK("\r") || FPUTCSV_FLD_CHK(" ") || 
FPUTCSV_FLD_CHK("\t")
+               ) {
+                       zval enclosed_field;
+                       smart_str_appendl(&csvline, &enclosure, 1);
+
+                       php_char_to_str_ex(Z_STRVAL_PP(field), Z_STRLEN_PP(field),
+                                               enclosure, enc_double, 2, 
&enclosed_field, 0, NULL);
+                       smart_str_appendl(&csvline, Z_STRVAL(enclosed_field), 
Z_STRLEN(enclosed_field));
+                       zval_dtor(&enclosed_field);
+
+                       smart_str_appendl(&csvline, &enclosure, 1);
+               } else {
+                       smart_str_appendl(&csvline, Z_STRVAL_PP(field), 
Z_STRLEN_PP(field));
+               }
+
+               if (++i != count) {
+                       smart_str_appendl(&csvline, &delimiter, 1);
+               }
+               zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos);
+       }
+
+       smart_str_appendc(&csvline, '\n');
+       smart_str_0(&csvline);
+
+       if (!PG(magic_quotes_runtime)) {
+               ret = php_stream_write(stream, csvline.c, csvline.len);
+       } else {
+               char *buffer = estrndup(csvline.c, csvline.len);
+               int len = csvline.len;
+               php_stripslashes(buffer, &len TSRMLS_CC);
+               ret = php_stream_write(stream, buffer, len);
+               efree(buffer);
+       }
+
+       smart_str_free(&csvline);
+
+       RETURN_LONG(ret);
+}
+/* }}} */
+
 /* {{{ proto array fgetcsv(resource fp [,int length [, string delimiter [, string 
enclosure]]])
    Get line from file pointer and parse for CSV fields */
 PHP_FUNCTION(fgetcsv)
Index: ext/standard/file.h
===================================================================
RCS file: /repository/php-src/ext/standard/file.h,v
retrieving revision 1.91
diff -u -p -d -r1.91 file.h
--- ext/standard/file.h 30 Jul 2004 22:49:02 -0000      1.91
+++ ext/standard/file.h 1 Sep 2004 21:20:09 -0000
@@ -39,6 +39,7 @@ PHPAPI PHP_FUNCTION(fgets);
 PHP_FUNCTION(fscanf);
 PHPAPI PHP_FUNCTION(fgetss);
 PHP_FUNCTION(fgetcsv);
+PHP_FUNCTION(fputcsv);
 PHPAPI PHP_FUNCTION(fwrite);
 PHPAPI PHP_FUNCTION(fflush);
 PHPAPI PHP_FUNCTION(rewind);
Index: ext/standard/tests/file/fputcsv.phpt
===================================================================
RCS file: ext/standard/tests/file/fputcsv.phpt
diff -N ext/standard/tests/file/fputcsv.phpt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ ext/standard/tests/file/fputcsv.phpt        1 Sep 2004 21:20:09 -0000
@@ -0,0 +1,107 @@
+--TEST--
+various fputcsv() functionality tests
+--INI--
+magic_quotes_runtime=0
+--FILE--
+<?php
+
+$list = array (
+  0 => 'aaa,bbb',
+  1 => 'aaa,"bbb"',
+  2 => '"aaa","bbb"',
+  3 => 'aaa,bbb',
+  4 => '"aaa",bbb',
+  5 => '"aaa",   "bbb"',
+  6 => ',',
+  7 => 'aaa,',
+  8 => ',"aaa"',
+  9 => '"",""',
+  10 => '"""""",',
+  11 => '""""",aaa',
+  12 => 'aaa,bbb   ',
+  13 => 'aaa,"bbb   "',
+  14 => 'aaa"aaa","bbb"bbb',
+  15 => 'aaa"aaa""",bbb',
+  16 => 'aaa,"\\"bbb,ccc',
+  17 => 'aaa"\\"a","bbb"',
+  18 => '"\\"","aaa"',
+  19 => '"\\""",aaa',
+);
+
+$file = dirname(__FILE__) . 'fgetcsv.csv';
[EMAIL PROTECTED]($file);
+
+$fp = fopen($file, "w");
+foreach ($list as $v) {
+       fputcsv($fp, split(',', $v));
+}
+fclose($fp);
+
+$res = file($file);
+foreach($res as &$val)
+{
+       $val = substr($val, 0, -1);
+}
+echo '$list = ';var_export($res);echo ";\n";
+
+$fp = fopen($file, "r");
+$res = array();
+while($l=fgetcsv($fp))
+{
+       $res[] = join(',',$l);
+}
+fclose($fp);
+
+echo '$list = ';var_export($res);echo ";\n";
+
[EMAIL PROTECTED]($file);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+$list = array (
+  0 => 'aaa,bbb',
+  1 => 'aaa,"""bbb"""',
+  2 => '"""aaa""","""bbb"""',
+  3 => 'aaa,bbb',
+  4 => '"""aaa""",bbb',
+  5 => '"""aaa""","   ""bbb"""',
+  6 => ',',
+  7 => 'aaa,',
+  8 => ',"""aaa"""',
+  9 => '"""""",""""""',
+  10 => '"""""""""""""",',
+  11 => '"""""""""""",aaa',
+  12 => 'aaa,"bbb   "',
+  13 => 'aaa,"""bbb   """',
+  14 => '"aaa""aaa""","""bbb""bbb"',
+  15 => '"aaa""aaa""""""",bbb',
+  16 => 'aaa,"""\\""bbb",ccc',
+  17 => '"aaa""\\""a""","""bbb"""',
+  18 => '"""\\""""","""aaa"""',
+  19 => '"""\\""""""",aaa',
+);
+$list = array (
+  0 => 'aaa,bbb',
+  1 => 'aaa,"bbb"',
+  2 => '"aaa","bbb"',
+  3 => 'aaa,bbb',
+  4 => '"aaa",bbb',
+  5 => '"aaa",   "bbb"',
+  6 => ',',
+  7 => 'aaa,',
+  8 => ',"aaa"',
+  9 => '"",""',
+  10 => '"""""",',
+  11 => '""""",aaa',
+  12 => 'aaa,bbb   ',
+  13 => 'aaa,"bbb   "',
+  14 => 'aaa"aaa","bbb"bbb',
+  15 => 'aaa"aaa""",bbb',
+  16 => 'aaa,"\\"bbb,ccc',
+  17 => 'aaa"\\"a","bbb"',
+  18 => '"\\"","aaa"',
+  19 => '"\\""",aaa',
+);
+===DONE===
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to