andrey          Sun Jul 18 07:34:28 2004 EDT

  Modified files:              
    /php-src/ext/standard       string.c 
    /php-src/ext/standard/tests/strings explode.phpt 
  Log:
  Add support for negative values of limit of explode(). If limit is negative
  then all components are returned except the last abs(limit) ones.
  
  
http://cvs.php.net/diff.php/php-src/ext/standard/string.c?r1=1.420&r2=1.421&ty=u
Index: php-src/ext/standard/string.c
diff -u php-src/ext/standard/string.c:1.420 php-src/ext/standard/string.c:1.421
--- php-src/ext/standard/string.c:1.420 Sun Jul 11 17:15:04 2004
+++ php-src/ext/standard/string.c       Sun Jul 18 07:34:28 2004
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: string.c,v 1.420 2004/07/11 21:15:04 andrey Exp $ */
+/* $Id: string.c,v 1.421 2004/07/18 11:34:28 andrey Exp $ */
 
 /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
 
@@ -784,8 +784,52 @@
 }
 /* }}} */
 
+/* {{{ php_explode_negative_limit
+ */
+PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_value, 
int limit) 
+{
+#define EXPLODE_ALLOC_STEP 50
+       char *p1, *p2, *endp;
+       int allocated = EXPLODE_ALLOC_STEP, found = 0, i = 0, to_return = 0;
+       char **positions = safe_emalloc(allocated, sizeof(char *), 0);
+       
+       endp = Z_STRVAL_P(str) + Z_STRLEN_P(str);
+
+       p1 = Z_STRVAL_P(str);
+       p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp);
+
+       if (p2 == NULL) {
+               /*
+               do nothing since limit <= -1, thus if only one chunk - 1 + (limit) <= 0
+               by doing nothing we return empty array
+               */
+       } else {
+               positions[found++] = p1;
+               do {
+                       if (found >= allocated) {
+                               allocated = found + EXPLODE_ALLOC_STEP;/* make sure we 
have enough memory */
+                               positions = erealloc(positions, allocated*sizeof(char 
*));
+                       }
+                       positions[found++] = p1 = p2 + Z_STRLEN_P(delim);
+               } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), 
endp)) != NULL);
+               
+               to_return = limit + found;
+               /* limit is at least -1 therefore no need of bounds checking : i will 
be always less than found */
+               for (i = 0;i < to_return;i++) { /* this checks also for to_return > 0 
*/
+                       add_next_index_stringl(return_value, positions[i], 
+                                       (positions[i+1] - Z_STRLEN_P(delim)) - 
positions[i],
+                                       1
+                               );
+               }
+       }
+       efree(positions);
+#undef EXPLODE_ALLOC_STEP
+}
+/* }}} */
+
+
 /* {{{ proto array explode(string separator, string str [, int limit])
-   Splits a string on string separator and return array of components */
+   Splits a string on string separator and return array of components. If limit is 
positive only limit number of components is returned. If limit is negative all 
components except the last abs(limit) are returned. */
 PHP_FUNCTION(explode)
 {
        zval **str, **delim, **zlimit = NULL;
@@ -810,8 +854,16 @@
 
        array_init(return_value);
 
+       if (! Z_STRLEN_PP(str)) {
+               add_next_index_stringl(return_value, "", sizeof("") - 1, 1);
+               return;
+       }
+
+
        if (limit == 0 || limit == 1) {
                add_index_stringl(return_value, 0, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 
1);
+       } else if (limit < 0 && argc == 3) {
+               php_explode_negative_limit(*delim, *str, return_value, limit);
        } else {
                php_explode(*delim, *str, return_value, limit);
        }
http://cvs.php.net/diff.php/php-src/ext/standard/tests/strings/explode.phpt?r1=1.3&r2=1.4&ty=u
Index: php-src/ext/standard/tests/strings/explode.phpt
diff -u php-src/ext/standard/tests/strings/explode.phpt:1.3 
php-src/ext/standard/tests/strings/explode.phpt:1.4
--- php-src/ext/standard/tests/strings/explode.phpt:1.3 Wed May 19 04:45:23 2004
+++ php-src/ext/standard/tests/strings/explode.phpt     Sun Jul 18 07:34:28 2004
@@ -19,6 +19,14 @@
 var_dump(@explode("a", "aaaaaa"));
 var_dump(@explode("==", str_repeat("-=".ord(0)."=-", 10)));
 var_dump(@explode("=", str_repeat("-=".ord(0)."=-", 10)));
+//////////////////////////////////////
+var_dump(explode(":","a lazy dog:jumps:over:",-1));
+var_dump(explode(":","a lazy dog:jumps:over", -1));
+var_dump(explode(":","a lazy dog:jumps:over", -2));
+var_dump(explode(":","a lazy dog:jumps:over:",-4));
+var_dump(explode(":","a lazy dog:jumps:over:",-40000000000000));
+var_dump(explode(":^:","a lazy dog:^:jumps::over:^:",-1));
+var_dump(explode(":^:","a lazy dog:^:jumps::over:^:",-2));
 ?>
 --EXPECTF--
 26d4e18734cb2582df5055e2175223df
@@ -111,4 +119,36 @@
   string(2) "48"
   [20]=>
   string(1) "-"
+}
+array(3) {
+  [0]=>
+  string(10) "a lazy dog"
+  [1]=>
+  string(5) "jumps"
+  [2]=>
+  string(4) "over"
+}
+array(2) {
+  [0]=>
+  string(10) "a lazy dog"
+  [1]=>
+  string(5) "jumps"
+}
+array(1) {
+  [0]=>
+  string(10) "a lazy dog"
+}
+array(0) {
+}
+array(0) {
+}
+array(2) {
+  [0]=>
+  string(10) "a lazy dog"
+  [1]=>
+  string(11) "jumps::over"
+}
+array(1) {
+  [0]=>
+  string(10) "a lazy dog"
 }

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to