summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/basic_functions.c8
-rw-r--r--ext/standard/file.c8
-rw-r--r--ext/standard/php_string.h1
-rw-r--r--ext/standard/string.c24
-rw-r--r--ext/standard/tests/strings/str_getcsv_001.phpt115
5 files changed, 154 insertions, 2 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 5a97ed1190..04715c9f77 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -2344,6 +2344,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_parse_str, 0, 0, 1)
ZEND_ARG_INFO(1, result)
ZEND_END_ARG_INFO()
+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()
+
ZEND_BEGIN_ARG_INFO(arginfo_str_repeat, 0)
ZEND_ARG_INFO(0, input)
ZEND_ARG_INFO(0, mult)
@@ -2745,6 +2752,7 @@ const 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 cbbda23634..62c614f736 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -2180,7 +2180,9 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char
memcpy(tptr, line_end, line_end_len);
tptr += line_end_len;
- if ((new_buf = php_stream_get_line(stream, NULL, 0, &new_len)) == NULL) {
+ if (stream == NULL) {
+ goto quit_loop_2;
+ } else if ((new_buf = php_stream_get_line(stream, NULL, 0, &new_len)) == NULL) {
/* we've got an unterminated enclosure,
* assign all the data from the start of
* the enclosure to end of data to the
@@ -2341,7 +2343,9 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char
out:
efree(temp);
- efree(buf);
+ if (stream) {
+ efree(buf);
+ }
}
/* }}} */
diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h
index e74609d79b..718f96ec9a 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 81392f11d9..c2d7ddf21c 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -50,6 +50,9 @@
#include "TSRM.h"
#endif
+/* For str_getcsv() support */
+#include "ext/standard/file.h"
+
#define STR_PAD_LEFT 0
#define STR_PAD_RIGHT 1
#define STR_PAD_BOTH 2
@@ -4456,6 +4459,27 @@ reg_char:
}
/* }}} */
+/* {{{ proto array str_getcsv(string input[, string delimiter[, string enclosure[, string escape]]])
+Parse a CSV string into an array */
+PHP_FUNCTION(str_getcsv)
+{
+ char *str, delim = ',', enc = '"', esc = '\\';
+ char *delim_str = NULL, *enc_str = NULL, *esc_str = NULL;
+ int str_len = 0, delim_len = 0, enc_len = 0, esc_len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sss", &str, &str_len, &delim_str, &delim_len,
+ &enc_str, &enc_len, &esc_str, &esc_len) == FAILURE) {
+ return;
+ }
+
+ delim = delim_len ? delim_str[0] : delim;
+ enc = enc_len ? enc_str[0] : enc;
+ esc = esc_len ? esc_str[0] : esc;
+
+ php_fgetcsv(NULL, delim, enc, esc, str_len, str, return_value TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ proto string str_repeat(string input, int mult)
Returns the input string repeat mult times */
PHP_FUNCTION(str_repeat)
diff --git a/ext/standard/tests/strings/str_getcsv_001.phpt b/ext/standard/tests/strings/str_getcsv_001.phpt
new file mode 100644
index 0000000000..5a562f44ef
--- /dev/null
+++ b/ext/standard/tests/strings/str_getcsv_001.phpt
@@ -0,0 +1,115 @@
+--TEST--
+str_getcsv(): Testing using various arguments
+--FILE--
+<?php
+
+// string input[, string delimiter[, string enclosure[, string escape]]]
+var_dump(str_getcsv('"f", "o", ""'));
+print "-----\n";
+var_dump(str_getcsv('foo||bar', '|'));
+print "-----\n";
+var_dump(str_getcsv('foo|bar', '|'));
+print "-----\n";
+var_dump(str_getcsv('|foo|-|bar|', '-', '|'));
+print "-----\n";
+var_dump(str_getcsv('|f.|.|bar|.|-|-.|', '.', '|', '-'));
+print "-----\n";
+var_dump(str_getcsv('.foo..bar.', '.', '.', '.'));
+print "-----\n";
+var_dump(str_getcsv('.foo. .bar.', ' ', '.', '.'));
+print "-----\n";
+var_dump(str_getcsv((binary)'1foo1 1bar111', (binary)' ', (binary)'1 ', (binary) '\ '));
+print "-----\n";
+var_dump(str_getcsv('.foo . . bar .', ' ', '.', ''));
+print "-----\n";
+var_dump(str_getcsv('" "" "', ' '));
+print "-----\n";
+var_dump(str_getcsv(NULL));
+print "-----\n";
+var_dump(str_getcsv(''));
+print "-----\n";
+
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ string(1) "f"
+ [1]=>
+ string(1) "o"
+ [2]=>
+ string(0) ""
+}
+-----
+array(3) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ string(0) ""
+ [2]=>
+ string(3) "bar"
+}
+-----
+array(2) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ string(3) "bar"
+}
+-----
+array(2) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ string(3) "bar"
+}
+-----
+array(3) {
+ [0]=>
+ string(2) "f."
+ [1]=>
+ string(3) "bar"
+ [2]=>
+ string(4) "-|-."
+}
+-----
+array(1) {
+ [0]=>
+ string(7) "foo.bar"
+}
+-----
+array(2) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ string(3) "bar"
+}
+-----
+array(2) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ string(4) "bar1"
+}
+-----
+array(2) {
+ [0]=>
+ string(5) "foo "
+ [1]=>
+ string(7) " bar "
+}
+-----
+array(1) {
+ [0]=>
+ string(3) " " "
+}
+-----
+array(1) {
+ [0]=>
+ string(0) ""
+}
+-----
+array(1) {
+ [0]=>
+ string(0) ""
+}
+-----