cvs: php4 /ext/standard php_string.h string.c
| From: | Jeroen van Wolffelaar | Date: | Fri, 03 Aug 2001 23:09:06 +0000 |
| Subject: | cvs: php4 /ext/standard php_string.h string.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-6528@lists.php.net to get a copy of this message | ||
jeroen Fri Aug 3 19:09:06 2001 EDT
Modified files:
/php4/ext/standard string.c php_string.h
Log:
Un-revert patch
Index: php4/ext/standard/string.c diff -u php4/ext/standard/string.c:1.215 php4/ext/standard/string.c:1.216 --- php4/ext/standard/string.c:1.215 Fri Aug 3 18:42:01 2001 +++ php4/ext/standard/string.c Fri Aug 3 19:09:05 2001 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: string.c,v 1.215 2001/08/03 22:42:01 jeroen Exp $ */ +/* $Id: string.c,v 1.216 2001/08/03 23:09:05 jeroen Exp $ */ /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ @@ -403,23 +403,62 @@ /* }}} */ #endif +/* {{{ php_charmask + * Fills a 256-byte bytemask with input. You can specify a range like 'a..z', + * it needs to be incrementing. + */ +void php_charmask(unsigned char *input, int len, char *mask) +{ + unsigned char *end; + unsigned char c; + + memset(mask, 0, 256); + for (end=input+len; input<end; input++) { + c=*input; + if (input+3<end && *(input+1) == '.' && *(input+2) == '.' + && *(input+3) >= c) { + memset(mask+c, 1, *(input+3) - c + 1); + input+=3; + } else + mask[c]=1; + } +} +/* }}} */ + /* {{{ php_trim + Compatibility function, ports old-API to new one. (DEPRECATED) +*/ +void php_trim(zval *str, zval *return_value, int mode) +{ + php_trim2(str, NULL, return_value, mode); +} +/* }}} */ + +/* {{{ php_trim2 */ -PHPAPI void php_trim(zval *str, zval * return_value, int mode) +PHPAPI void php_trim2(zval *str, zval *what, zval *return_value, int mode) /* mode 1 : trim left mode 2 : trim right mode 3 : trim left and right + + what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0') */ { register int i; int len = str->value.str.len; int trimmed = 0; char *c = str->value.str.val; + char mask[256]; + + if (what) { + php_charmask(what->value.str.val, what->value.str.len, mask); + } else { + php_charmask(" \n\r\t\v\0", 6, mask); + } if (mode & 1) { for (i = 0; i < len; i++) { - if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || - c[i] == '\t' || c[i] == '\v' || c[i] == '\0') { + if (mask[(unsigned char)c[i]]) { trimmed++; } else { break; @@ -430,8 +469,7 @@ } if (mode & 2) { for (i = len - 1; i >= 0; i--) { - if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || - c[i] == '\t' || c[i] == '\v' || c[i] == '\0') { + if (mask[(unsigned char)c[i]]) { len--; } else { break; @@ -450,18 +488,19 @@ Remove trailing whitespace */ PHP_FUNCTION(chop) { - zval **str; + zval **str, **what; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) WRONG_PARAM_COUNT; - } + zend_get_parameters_ex(2, &str, &what); convert_to_string_ex(str); + if (ZEND_NUM_ARGS() == 2) + convert_to_string_ex(str); - if ((*str)->type == IS_STRING) { - php_trim(*str, return_value, 2); - return; - } - RETURN_FALSE; + /* convert_to_string_ex never fails (last line: op->type = IS_STRING), + so, not checking for that. */ + + php_trim2(*str, ZEND_NUM_ARGS()==2?*what:NULL, return_value, 2); } /* }}} */ @@ -469,18 +508,16 @@ Strip whitespace from the beginning and end of a string */ PHP_FUNCTION(trim) { - zval **str; + zval **str, **what; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) WRONG_PARAM_COUNT; - } + zend_get_parameters_ex(2, &str, &what); convert_to_string_ex(str); + if (ZEND_NUM_ARGS() == 2) + convert_to_string_ex(str); - if ((*str)->type == IS_STRING) { - php_trim(*str, return_value, 3); - return; - } - RETURN_FALSE; + php_trim2(*str, ZEND_NUM_ARGS()==2?*what:NULL, return_value, 3); } /* }}} */ @@ -488,17 +525,16 @@ Strip whitespace from the beginning of a string */ PHP_FUNCTION(ltrim) { - zval **str; + zval **str, **what; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) WRONG_PARAM_COUNT; - } + zend_get_parameters_ex(2, &str, &what); convert_to_string_ex(str); - if ((*str)->type == IS_STRING) { - php_trim(*str, return_value, 1); - return; - } - RETURN_FALSE; + if (ZEND_NUM_ARGS() == 2) + convert_to_string_ex(str); + + php_trim2(*str, ZEND_NUM_ARGS()==2?*what:NULL, return_value, 1); } /* }}} */ @@ -803,60 +839,86 @@ } /* }}} */ +#define STRTOK_TABLE(p) BG(strtok_table)[(unsigned char) *p] + /* {{{ proto string strtok([string str,] string token) Tokenize a string */ PHP_FUNCTION(strtok) { - zval **str, **tok; - char *token = NULL, *tokp=NULL; - char *first = NULL; - int argc; - - argc = ZEND_NUM_ARGS(); - - if ((argc == 1 && zend_get_parameters_ex(1, &tok) == FAILURE) || - (argc == 2 && zend_get_parameters_ex(2, &str, &tok) == FAILURE) || - argc < 1 || argc > 2) { + zval **args[2]; + zval **tok, **str; + char *token; + char *token_end; + char *p; + char *pe; + + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 || + zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) WRONG_PARAM_COUNT; + + switch (ZEND_NUM_ARGS()) { + case 1: + tok = args[0]; + break; + case 2: + str = args[0]; + tok = args[1]; + convert_to_string_ex(str); + + zval_add_ref(str); + if (BG(strtok_zval)) + zval_ptr_dtor(BG(strtok_zval)); + BG(strtok_zval) = str; + + BG(strtok_last) = BG(strtok_string) = Z_STRVAL_PP(str); + BG(strtok_len) = Z_STRLEN_PP(str); + break; } - convert_to_string_ex(tok); - tokp = token = (*tok)->value.str.val; + + p = BG(strtok_last); /* Where we start to search */ + pe = BG(strtok_string) + BG(strtok_len); - if (argc == 2) { - convert_to_string_ex(str); + if (!p || p >= pe) + RETURN_FALSE; - STR_FREE(BG(strtok_string)); - BG(strtok_string) = estrndup((*str)->value.str.val,(*str)->value.str.len); - BG(strtok_pos1) = BG(strtok_string); - BG(strtok_pos2) = NULL; - } - if (BG(strtok_pos1) && *BG(strtok_pos1)) { - for ( /* NOP */ ; token && *token; token++) { - BG(strtok_pos2) = strchr(BG(strtok_pos1), (int) *token); - if (!first || (BG(strtok_pos2) && BG(strtok_pos2) < first)) { - first = BG(strtok_pos2); - } - } /* NB: token is unusable now */ + convert_to_string_ex(tok); + + token = Z_STRVAL_PP(tok); + token_end = token + Z_STRLEN_PP(tok); - BG(strtok_pos2) = first; - if (BG(strtok_pos2)) { - *BG(strtok_pos2) = '\0'; - } - RETVAL_STRING(BG(strtok_pos1),1); -#if 0 - /* skip 'token' white space for next call to strtok */ - while (BG(strtok_pos2) && - strchr(tokp, *(BG(strtok_pos2)+1))) { - BG(strtok_pos2)++; + while (token < token_end) + STRTOK_TABLE(token++) = 1; + + /* Skip leading delimiters */ + while (STRTOK_TABLE(p)) + if (++p >= pe) { + /* no other chars left */ + BG(strtok_last) = NULL; + RETVAL_FALSE; + goto restore; } -#endif - if (BG(strtok_pos2)) - BG(strtok_pos1) = BG(strtok_pos2) + 1; - else - BG(strtok_pos1) = NULL; + + /* We know at this place that *p is no delimiter, so skip it */ + while (++p < pe) + if (STRTOK_TABLE(p)) + goto return_token; + + if (p - BG(strtok_last)) { +return_token: + RETVAL_STRINGL(BG(strtok_last), p - BG(strtok_last), 1); + BG(strtok_last) = p + 1; } else { RETVAL_FALSE; + BG(strtok_last) = NULL; } + + /* Restore table -- usually faster then memset'ing the table + on every invocation */ +restore: + token = Z_STRVAL_PP(tok); + + while (token < token_end) + STRTOK_TABLE(token++) = 0; } /* }}} */ Index: php4/ext/standard/php_string.h diff -u php4/ext/standard/php_string.h:1.42 php4/ext/standard/php_string.h:1.43 --- php4/ext/standard/php_string.h:1.42 Fri Aug 3 18:42:02 2001 +++ php4/ext/standard/php_string.h Fri Aug 3 19:09:05 2001 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_string.h,v 1.42 2001/08/03 22:42:02 jeroen Exp $ */ +/* $Id: php_string.h,v 1.43 2001/08/03 23:09:05 jeroen Exp $ */ /* Synced with php 3.0 revision 1.43 1999-06-16 [ssb] */ @@ -112,6 +112,7 @@ PHPAPI char *php_str_to_str(char *haystack, int length, char *needle, int needle_len, char *str, int str_len, int *_new_length); PHPAPI void php_trim(pval *str, pval *return_value, int mode); +void php_trim2(zval *str, zval *what, zval *return_value, int mode); PHPAPI void php_strip_tags(char *rbuf, int len, int state, char *allow, int allow_len); PHPAPI void php_char_to_str(char *str, uint len, char from, char *to, int to_len, pval *result);
Index: php4/ext/standard/string.c diff -u php4/ext/standard/string.c:1.215 php4/ext/standard/string.c:1.216 --- php4/ext/standard/string.c:1.215 Fri Aug 3 18:42:01 2001 +++ php4/ext/standard/string.c Fri Aug 3 19:09:05 2001 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: string.c,v 1.215 2001/08/03 22:42:01 jeroen Exp $ */ +/* $Id: string.c,v 1.216 2001/08/03 23:09:05 jeroen Exp $ */ /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ @@ -403,23 +403,62 @@ /* }}} */ #endif +/* {{{ php_charmask + * Fills a 256-byte bytemask with input. You can specify a range like 'a..z', + * it needs to be incrementing. + */ +void php_charmask(unsigned char *input, int len, char *mask) +{ + unsigned char *end; + unsigned char c; + + memset(mask, 0, 256); + for (end=input+len; input<end; input++) { + c=*input; + if (input+3<end && *(input+1) == '.' && *(input+2) == '.' + && *(input+3) >= c) { + memset(mask+c, 1, *(input+3) - c + 1); + input+=3; + } else + mask[c]=1; + } +} +/* }}} */ + /* {{{ php_trim + Compatibility function, ports old-API to new one. (DEPRECATED) +*/ +void php_trim(zval *str, zval *return_value, int mode) +{ + php_trim2(str, NULL, return_value, mode); +} +/* }}} */ + +/* {{{ php_trim2 */ -PHPAPI void php_trim(zval *str, zval * return_value, int mode) +PHPAPI void php_trim2(zval *str, zval *what, zval *return_value, int mode) /* mode 1 : trim left mode 2 : trim right mode 3 : trim left and right + + what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0') */ { register int i; int len = str->value.str.len; int trimmed = 0; char *c = str->value.str.val; + char mask[256]; + + if (what) { + php_charmask(what->value.str.val, what->value.str.len, mask); + } else { + php_charmask(" \n\r\t\v\0", 6, mask); + } if (mode & 1) { for (i = 0; i < len; i++) { - if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || - c[i] == '\t' || c[i] == '\v' || c[i] == '\0') { + if (mask[(unsigned char)c[i]]) { trimmed++; } else { break; @@ -430,8 +469,7 @@ } if (mode & 2) { for (i = len - 1; i >= 0; i--) { - if (c[i] == ' ' || c[i] == '\n' || c[i] == '\r' || - c[i] == '\t' || c[i] == '\v' || c[i] == '\0') { + if (mask[(unsigned char)c[i]]) { len--; } else { break; @@ -450,18 +488,19 @@ Remove trailing whitespace */ PHP_FUNCTION(chop) { - zval **str; + zval **str, **what; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) WRONG_PARAM_COUNT; - } + zend_get_parameters_ex(2, &str, &what); convert_to_string_ex(str); + if (ZEND_NUM_ARGS() == 2) + convert_to_string_ex(str); - if ((*str)->type == IS_STRING) { - php_trim(*str, return_value, 2); - return; - } - RETURN_FALSE; + /* convert_to_string_ex never fails (last line: op->type = IS_STRING), + so, not checking for that. */ + + php_trim2(*str, ZEND_NUM_ARGS()==2?*what:NULL, return_value, 2); } /* }}} */ @@ -469,18 +508,16 @@ Strip whitespace from the beginning and end of a string */ PHP_FUNCTION(trim) { - zval **str; + zval **str, **what; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) WRONG_PARAM_COUNT; - } + zend_get_parameters_ex(2, &str, &what); convert_to_string_ex(str); + if (ZEND_NUM_ARGS() == 2) + convert_to_string_ex(str); - if ((*str)->type == IS_STRING) { - php_trim(*str, return_value, 3); - return; - } - RETURN_FALSE; + php_trim2(*str, ZEND_NUM_ARGS()==2?*what:NULL, return_value, 3); } /* }}} */ @@ -488,17 +525,16 @@ Strip whitespace from the beginning of a string */ PHP_FUNCTION(ltrim) { - zval **str; + zval **str, **what; - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2) WRONG_PARAM_COUNT; - } + zend_get_parameters_ex(2, &str, &what); convert_to_string_ex(str); - if ((*str)->type == IS_STRING) { - php_trim(*str, return_value, 1); - return; - } - RETURN_FALSE; + if (ZEND_NUM_ARGS() == 2) + convert_to_string_ex(str); + + php_trim2(*str, ZEND_NUM_ARGS()==2?*what:NULL, return_value, 1); } /* }}} */ @@ -803,60 +839,86 @@ } /* }}} */ +#define STRTOK_TABLE(p) BG(strtok_table)[(unsigned char) *p] + /* {{{ proto string strtok([string str,] string token) Tokenize a string */ PHP_FUNCTION(strtok) { - zval **str, **tok; - char *token = NULL, *tokp=NULL; - char *first = NULL; - int argc; - - argc = ZEND_NUM_ARGS(); - - if ((argc == 1 && zend_get_parameters_ex(1, &tok) == FAILURE) || - (argc == 2 && zend_get_parameters_ex(2, &str, &tok) == FAILURE) || - argc < 1 || argc > 2) { + zval **args[2]; + zval **tok, **str; + char *token; + char *token_end; + char *p; + char *pe; + + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 || + zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) WRONG_PARAM_COUNT; + + switch (ZEND_NUM_ARGS()) { + case 1: + tok = args[0]; + break; + case 2: + str = args[0]; + tok = args[1]; + convert_to_string_ex(str); + + zval_add_ref(str); + if (BG(strtok_zval)) + zval_ptr_dtor(BG(strtok_zval)); + BG(strtok_zval) = str; + + BG(strtok_last) = BG(strtok_string) = Z_STRVAL_PP(str); + BG(strtok_len) = Z_STRLEN_PP(str); + break; } - convert_to_string_ex(tok); - tokp = token = (*tok)->value.str.val; + + p = BG(strtok_last); /* Where we start to search */ + pe = BG(strtok_string) + BG(strtok_len); - if (argc == 2) { - convert_to_string_ex(str); + if (!p || p >= pe) + RETURN_FALSE; - STR_FREE(BG(strtok_string)); - BG(strtok_string) = estrndup((*str)->value.str.val,(*str)->value.str.len); - BG(strtok_pos1) = BG(strtok_string); - BG(strtok_pos2) = NULL; - } - if (BG(strtok_pos1) && *BG(strtok_pos1)) { - for ( /* NOP */ ; token && *token; token++) { - BG(strtok_pos2) = strchr(BG(strtok_pos1), (int) *token); - if (!first || (BG(strtok_pos2) && BG(strtok_pos2) < first)) { - first = BG(strtok_pos2); - } - } /* NB: token is unusable now */ + convert_to_string_ex(tok); + + token = Z_STRVAL_PP(tok); + token_end = token + Z_STRLEN_PP(tok); - BG(strtok_pos2) = first; - if (BG(strtok_pos2)) { - *BG(strtok_pos2) = '\0'; - } - RETVAL_STRING(BG(strtok_pos1),1); -#if 0 - /* skip 'token' white space for next call to strtok */ - while (BG(strtok_pos2) && - strchr(tokp, *(BG(strtok_pos2)+1))) { - BG(strtok_pos2)++; + while (token < token_end) + STRTOK_TABLE(token++) = 1; + + /* Skip leading delimiters */ + while (STRTOK_TABLE(p)) + if (++p >= pe) { + /* no other chars left */ + BG(strtok_last) = NULL; + RETVAL_FALSE; + goto restore; } -#endif - if (BG(strtok_pos2)) - BG(strtok_pos1) = BG(strtok_pos2) + 1; - else - BG(strtok_pos1) = NULL; + + /* We know at this place that *p is no delimiter, so skip it */ + while (++p < pe) + if (STRTOK_TABLE(p)) + goto return_token; + + if (p - BG(strtok_last)) { +return_token: + RETVAL_STRINGL(BG(strtok_last), p - BG(strtok_last), 1); + BG(strtok_last) = p + 1; } else { RETVAL_FALSE; + BG(strtok_last) = NULL; } + + /* Restore table -- usually faster then memset'ing the table + on every invocation */ +restore: + token = Z_STRVAL_PP(tok); + + while (token < token_end) + STRTOK_TABLE(token++) = 0; } /* }}} */ Index: php4/ext/standard/php_string.h diff -u php4/ext/standard/php_string.h:1.42 php4/ext/standard/php_string.h:1.43 --- php4/ext/standard/php_string.h:1.42 Fri Aug 3 18:42:02 2001 +++ php4/ext/standard/php_string.h Fri Aug 3 19:09:05 2001 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_string.h,v 1.42 2001/08/03 22:42:02 jeroen Exp $ */ +/* $Id: php_string.h,v 1.43 2001/08/03 23:09:05 jeroen Exp $ */ /* Synced with php 3.0 revision 1.43 1999-06-16 [ssb] */ @@ -112,6 +112,7 @@ PHPAPI char *php_str_to_str(char *haystack, int length, char *needle, int needle_len, char *str, int str_len, int *_new_length); PHPAPI void php_trim(pval *str, pval *return_value, int mode); +void php_trim2(zval *str, zval *what, zval *return_value, int mode); PHPAPI void php_strip_tags(char *rbuf, int len, int state, char *allow, int allow_len); PHPAPI void php_char_to_str(char *str, uint len, char from, char *to, int to_len, pval *result);