Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:9042 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 46063 invoked by uid 1010); 11 Apr 2004 17:07:33 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 45915 invoked from network); 11 Apr 2004 17:07:30 -0000 Received: from unknown (HELO mail.zend.com) (192.117.235.230) by pb1.pair.com with SMTP; 11 Apr 2004 17:07:30 -0000 Received: (qmail 23260 invoked from network); 11 Apr 2004 17:07:21 -0000 Received: from localhost (HELO AndiNotebook.zend.com) (127.0.0.1) by localhost with SMTP; 11 Apr 2004 17:07:21 -0000 Message-ID: <5.1.0.14.2.20040411200658.022bae60@127.0.0.1> X-Sender: andi@127.0.0.1 X-Mailer: QUALCOMM Windows Eudora Version 5.1 Date: Sun, 11 Apr 2004 20:07:12 +0300 To: David Sklar ,internals@lists.php.net In-Reply-To: <40797364.1010209@sklar.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; format=flowed Subject: Re: [PHP-DEV] fputcsv() From: andi@zend.com (Andi Gutmans) References: <40797364.1010209@sklar.com> How about using PHP_EOL? At 12:33 PM 4/11/2004 -0400, David Sklar wrote: >Attached is a patch that implements fputcsv() as a complement to fgetcsv(). > >There are two things that still need improvement: > >- It adds "\n" as a newline onto the end of each line. I think it would be >better to add a platform-specific line ending. > >- It is not mbstring-aware. > >Any suggestions for fixing these things (or other issues) would be >appreciated. > >Thanks, >David > > >Index: ext/standard/basic_functions.c >=================================================================== >RCS file: /repository/php-src/ext/standard/basic_functions.c,v >retrieving revision 1.662 >diff -u -B -b -r1.662 basic_functions.c >--- ext/standard/basic_functions.c 3 Apr 2004 09:51:57 -0000 1.662 >+++ ext/standard/basic_functions.c 11 Apr 2004 16:31:33 -0000 >@@ -596,6 +596,7 @@ > 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.h >=================================================================== >RCS file: /repository/php-src/ext/standard/file.h,v >retrieving revision 1.88 >diff -u -B -b -r1.88 file.h >--- ext/standard/file.h 8 Jan 2004 17:32:51 -0000 1.88 >+++ ext/standard/file.h 11 Apr 2004 16:31:33 -0000 >@@ -39,6 +39,7 @@ > 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/file.c >=================================================================== >RCS file: /repository/php-src/ext/standard/file.c,v >retrieving revision 1.380 >diff -u -B -b -r1.380 file.c >--- ext/standard/file.c 25 Feb 2004 20:16:26 -0000 1.380 >+++ ext/standard/file.c 11 Apr 2004 16:31:35 -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 > #include >@@ -1704,6 +1705,112 @@ > return ptr; > } > >+/* {{{ 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; >+ int delimiter_str_len = 0; >+ char *enclosure_str = NULL; >+ int enclosure_str_len = 0; >+ char *buffer = NULL; >+ int csvline_len = 0; >+ HashPosition pos; >+ int count = 0, 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; >+ } >+ >+ /* use first character from string */ >+ delimiter[0] = delimiter_str[0]; >+ } >+ >+ if (enclosure_str != NULL) { >+ if (enclosure_str_len < 1) { >+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must >be a character"); >+ RETURN_FALSE; >+ } >+ /* use first character from string */ >+ enclosure[0] = enclosure_str[0]; >+ } >+ >+ PHP_STREAM_TO_ZVAL(stream, &fp); >+ >+ enc_double[0] = enc_double[1] = enclosure[0]; >+ 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 ((*field)->type != IS_STRING) { >+ SEPARATE_ZVAL(field); >+ convert_to_string(*field); >+ } >+ /* enclose a field that contains a delimiter, an enclosure >+ character, or a newline */ >+ if (php_memnstr(Z_STRVAL_PP(field), delimiter, 1, >Z_STRVAL_PP(field) + Z_STRLEN_PP(field)) || >+ php_memnstr(Z_STRVAL_PP(field), enclosure, 1, >Z_STRVAL_PP(field) + Z_STRLEN_PP(field)) || >+ php_memnstr(Z_STRVAL_PP(field), "\n", 1, Z_STRVAL_PP(field) + >Z_STRLEN_PP(field)) || >+ php_memnstr(Z_STRVAL_PP(field), "\r", 1, Z_STRVAL_PP(field) + >Z_STRLEN_PP(field))) { >+ >+ smart_str_appendl(&csvline, enclosure, 1); >+ >+ { >+ zval enclosed_field; >+ php_char_to_str_ex(Z_STRVAL_PP(field), >Z_STRLEN_PP(field), enclosure[0], >+ 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); >+ } >+ >+ /* XXX: this should be platform-specific */ >+ smart_str_appendc(&csvline, '\n'); >+ >+ smart_str_0(&csvline); >+ >+ if (PG(magic_quotes_runtime)) { >+ buffer = estrndup(csvline.c, csvline.len); >+ php_stripslashes(buffer, &csvline_len TSRMLS_CC); >+ } else { >+ csvline_len = csvline.len; >+ } >+ >+ ret = php_stream_write(stream, buffer ? buffer : csvline.c, >csvline_len); >+ >+ if (buffer) { >+ 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) > >-- >PHP Internals - PHP Runtime Development Mailing List >To unsubscribe, visit: http://www.php.net/unsub.php