From: Sara Golemon Date: Tue, 5 Dec 2006 04:52:44 +0000 (+0000) Subject: Add str_getcsv() and fix a couple cases in recent fgetcsv() reimplementation X-Git-Tag: RELEASE_1_0_0RC1~815 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fac71c77c1710dd17017af0390a97d02cdc5eb02;p=php Add str_getcsv() and fix a couple cases in recent fgetcsv() reimplementation --- diff --git a/NEWS b/NEWS index d31dab6774..d8fbce1721 100644 --- a/NEWS +++ b/NEWS @@ -64,6 +64,7 @@ PHP NEWS . "context" and "binary_pipes" params in "other_options" arg. (Sara) . stream_resolve_include_path(). (Sara) - Added shm_has_var() function. (Mike) +- Added str_getcsv() function. (Sara) - Fixed bug #39504 (xmlwriter_write_dtd_entity() creates Attlist tag, not enity). (Hannes Magnusson) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 2891d0e457..4924f42d7c 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2751,6 +2751,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_parse_str, 0, 0, 1) ZEND_ARG_INFO(1, result) ZEND_END_ARG_INFO() +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_str_getcsv, 0, 0, 1) + ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, delimiter) + ZEND_ARG_INFO(0, enclosure) + ZEND_ARG_INFO(0, escape) +ZEND_END_ARG_INFO() + static ZEND_BEGIN_ARG_INFO(arginfo_str_repeat, 0) ZEND_ARG_INFO(0, input) @@ -3230,6 +3238,7 @@ zend_function_entry basic_functions[] = { PHP_FE(chr, arginfo_chr) PHP_FE(ord, arginfo_ord) PHP_FE(parse_str, arginfo_parse_str) + PHP_FE(str_getcsv, arginfo_str_getcsv) PHP_FE(str_pad, arginfo_str_pad) PHP_FALIAS(chop, rtrim, arginfo_rtrim) PHP_FALIAS(strchr, strstr, arginfo_strstr) diff --git a/ext/standard/file.c b/ext/standard/file.c index eff25d0e75..c035722609 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -2423,11 +2423,21 @@ post_enc: /* Simple character */ p++; + + if (p == e) { + add_next_index_stringl(return_value, field_start, p - field_start, 1); + /* Reset scanner even though we're dying */ + state = PHP_FGETCSV_READY; + field_start = field_end = NULL; + p += delimiter_len; + } break; } } - efree(buffer); + if (stream) { + efree(buffer); + } } /* }}} */ @@ -2617,11 +2627,21 @@ post_enc: /* Simple character */ p++; + + if (p == e) { + add_next_index_unicodel(return_value, field_start, p - field_start, 1); + /* Reset scanner even though we're dying */ + state = PHP_FGETCSV_READY; + field_start = field_end = NULL; + p += delimiter_len; + } break; } } - efree(buffer); + if (stream) { + efree(buffer); + } } /* }}} */ diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index c33fd679c4..909c3d29d1 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -76,6 +76,7 @@ PHP_FUNCTION(nl_langinfo); PHP_FUNCTION(stristr); PHP_FUNCTION(chunk_split); PHP_FUNCTION(parse_str); +PHP_FUNCTION(str_getcsv); PHP_FUNCTION(bin2hex); PHP_FUNCTION(similar_text); PHP_FUNCTION(strip_tags); diff --git a/ext/standard/string.c b/ext/standard/string.c index ab610e0a79..4adfb4cff8 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -56,6 +56,9 @@ #include "unicode/uchar.h" #include "unicode/ubrk.h" +/* For str_getcsv() support */ +#include "ext/standard/file.h" + #define STR_PAD_LEFT 0 #define STR_PAD_RIGHT 1 #define STR_PAD_BOTH 2 @@ -6734,6 +6737,46 @@ reg_char: } /* }}} */ +/* {{{ proto array str_getcsv(string input[, string delimiter[, string enclosure[, string escape]]]) U +Parse a CSV string into an array */ +PHP_FUNCTION(str_getcsv) +{ + zend_uchar str_type, delim_type = IS_STRING, enc_type = IS_STRING, esc_type = IS_STRING; + char *str, *delim = ",", *enc = "\"", *esc = "\\"; + int str_len, delim_len = 1, enc_len = 1, esc_len = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "T|TTT", + &str, &str_len, &str_type, + &delim, &delim_len, &delim_type, + &enc, &enc_len, &enc_type, + &esc, &esc_len, &esc_type) == FAILURE) { + return; + } + + if (str_type == IS_UNICODE) { + UChar udelim = ',', uenc = '"', uesc = '\\'; + + /* Non-passed params would need to be upconverted, but we can cheat with some local declarations */ + if (delim_type == IS_STRING) { + delim = (char*)&udelim; + delim_len = 1; + } + if (enc_type == IS_STRING) { + enc = (char*)&uenc; + enc_len = 1; + } + if (esc_type == IS_STRING) { + esc = (char*)&uesc; + esc_len = 1; + } + + php_u_fgetcsv(NULL, (UChar*)delim, delim_len, (UChar*)enc, enc_len, (UChar*)esc, esc_len, (UChar*)str, str_len, return_value TSRMLS_CC); + } else { + php_fgetcsv_ex(NULL, delim, delim_len, enc, enc_len, esc, esc_len, str, str_len, return_value TSRMLS_CC); + } +} +/* }}} */ + /* {{{ proto string str_repeat(string input, int mult) U Returns the input string repeat mult times */ PHP_FUNCTION(str_repeat)