Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:12090 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 26328 invoked by uid 1010); 11 Aug 2004 13:53:15 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 26304 invoked from network); 11 Aug 2004 13:53:15 -0000 Received: from unknown (HELO home.sklar.com) (24.199.89.111) by pb1.pair.com with SMTP; 11 Aug 2004 13:53:15 -0000 Received: from [127.0.0.1] ([127.0.0.1]) by home.sklar.com with Microsoft SMTPSVC(6.0.2600.1106); Wed, 11 Aug 2004 09:53:12 -0400 Message-ID: <411A24C7.9090507@sklar.com> Date: Wed, 11 Aug 2004 09:53:11 -0400 User-Agent: Mozilla Thunderbird 0.7.1 (Windows/20040626) X-Accept-Language: en-us, en MIME-Version: 1.0 To: internals@lists.php.net Content-Type: multipart/mixed; boundary="------------010208070103020306080900" X-OriginalArrivalTime: 11 Aug 2004 13:53:12.0471 (UTC) FILETIME=[8AE5F270:01C47FAA] Subject: fputcsv() From: sklar@sklar.com (David Sklar) --------------010208070103020306080900 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Attached is my fputcsv() patch (and a test case) from April. Could someone commit this to 5.1 or 5.0.1? Thanks, David --------------010208070103020306080900 Content-Type: text/plain; name="fputcsv.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="fputcsv.diff" Index: ext/standard/file.c =================================================================== RCS file: /repository/php-src/ext/standard/file.c,v retrieving revision 1.380 diff -u -r1.380 file.c --- ext/standard/file.c 25 Feb 2004 20:16:26 -0000 1.380 +++ ext/standard/file.c 12 Apr 2004 17:53:55 -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,108 @@ 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, *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] = 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); + } + +#define FPUTCSV_FLD_CHK(c) php_memnstr(Z_STRVAL_PP(field), c, 1, Z_STRVAL_PP(field) + Z_STRLEN_PP(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; + 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.88 diff -u -r1.88 file.h --- ext/standard/file.h 8 Jan 2004 17:32:51 -0000 1.88 +++ ext/standard/file.h 12 Apr 2004 17:53:55 -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/basic_functions.c =================================================================== RCS file: /repository/php-src/ext/standard/basic_functions.c,v retrieving revision 1.663 diff -u -r1.663 basic_functions.c --- ext/standard/basic_functions.c 12 Apr 2004 12:21:24 -0000 1.663 +++ ext/standard/basic_functions.c 12 Apr 2004 17:53:57 -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) --------------010208070103020306080900 Content-Type: text/plain; name="013.phpt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="013.phpt" --TEST-- Testing fputcsv() --FILE-- --EXPECT-- nothing,special,here this,"that""","the other" "a new line","another thing","some ,commas" "what about'a single",quote,"or a tab" --------------010208070103020306080900--