diff options
author | SVN Migration <svn@php.net> | 2003-02-27 17:43:39 +0000 |
---|---|---|
committer | SVN Migration <svn@php.net> | 2003-02-27 17:43:39 +0000 |
commit | 078bcec0997ad0e07b720c43cc9e6d0e046a75ab (patch) | |
tree | 36cb0f6be2ef078fe3374de8c087b93ecf82f812 /ext/standard/string.c | |
parent | fd61f69077f6156ca71dde60ecfd9ed9765a02db (diff) | |
download | php-git-PHP-5.tar.gz |
This commit was manufactured by cvs2svn to create branch 'PHP_5'.PHP-5
Diffstat (limited to 'ext/standard/string.c')
-rw-r--r-- | ext/standard/string.c | 4421 |
1 files changed, 0 insertions, 4421 deletions
diff --git a/ext/standard/string.c b/ext/standard/string.c deleted file mode 100644 index e21cf53f06..0000000000 --- a/ext/standard/string.c +++ /dev/null @@ -1,4421 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 4 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2003 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 2.02 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://www.php.net/license/2_02.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Rasmus Lerdorf <rasmus@php.net> | - | Stig Sæther Bakken <ssb@fast.no> | - | Zeev Suraski <zeev@zend.com> | - +----------------------------------------------------------------------+ - */ - -/* $Id$ */ - -/* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ - -#include <stdio.h> -#include "php.h" -#include "reg.h" -#include "php_rand.h" -#include "php_string.h" -#include "php_variables.h" -#ifdef HAVE_LOCALE_H -# include <locale.h> -#endif -#ifdef HAVE_LANGINFO_H -# include <langinfo.h> -#endif -#ifdef HAVE_MONETARY_H -# include <monetary.h> -#endif - -#include <math.h> - -#include "scanf.h" -#include "zend_API.h" -#include "zend_execute.h" -#include "php_globals.h" -#include "basic_functions.h" -#include "php_smart_str.h" -#ifdef ZTS -#include "TSRM.h" -#endif - -#define STR_PAD_LEFT 0 -#define STR_PAD_RIGHT 1 -#define STR_PAD_BOTH 2 -#define PHP_PATHINFO_DIRNAME 1 -#define PHP_PATHINFO_BASENAME 2 -#define PHP_PATHINFO_EXTENSION 4 -#define PHP_PATHINFO_ALL (PHP_PATHINFO_DIRNAME | PHP_PATHINFO_BASENAME | PHP_PATHINFO_EXTENSION) - -#define STR_STRSPN 0 -#define STR_STRCSPN 1 - -/* {{{ register_string_constants - */ -void register_string_constants(INIT_FUNC_ARGS) -{ - REGISTER_LONG_CONSTANT("STR_PAD_LEFT", STR_PAD_LEFT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STR_PAD_RIGHT", STR_PAD_RIGHT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STR_PAD_BOTH", STR_PAD_BOTH, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PATHINFO_DIRNAME", PHP_PATHINFO_DIRNAME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PATHINFO_BASENAME", PHP_PATHINFO_BASENAME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("PATHINFO_EXTENSION", PHP_PATHINFO_EXTENSION, CONST_CS | CONST_PERSISTENT); - -#ifdef HAVE_LOCALECONV - /* If last members of struct lconv equal CHAR_MAX, no grouping is done */ - -/* This is bad, but since we are going to be hardcoding in the POSIX stuff anyway... */ -# ifndef HAVE_LIMITS_H -# define CHAR_MAX 127 -# endif - - REGISTER_LONG_CONSTANT("CHAR_MAX", CHAR_MAX, CONST_CS | CONST_PERSISTENT); -#endif - -#ifdef HAVE_LOCALE_H - REGISTER_LONG_CONSTANT("LC_CTYPE", LC_CTYPE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LC_NUMERIC", LC_NUMERIC, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LC_TIME", LC_TIME, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LC_COLLATE", LC_COLLATE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LC_MONETARY", LC_MONETARY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("LC_ALL", LC_ALL, CONST_CS | CONST_PERSISTENT); -# ifdef LC_MESSAGES - REGISTER_LONG_CONSTANT("LC_MESSAGES", LC_MESSAGES, CONST_CS | CONST_PERSISTENT); -# endif -#endif - -} -/* }}} */ - -int php_tag_find(char *tag, int len, char *set); - -/* this is read-only, so it's ok */ -static char hexconvtab[] = "0123456789abcdef"; - -/* localeconv mutex */ -#ifdef ZTS -static MUTEX_T locale_mutex = NULL; -#endif - -/* {{{ php_bin2hex - */ -static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *newlen) -{ - register unsigned char *result = NULL; - size_t i, j; - - result = (char *) emalloc(oldlen * 2 * sizeof(char) + 1); - - for (i = j = 0; i < oldlen; i++) { - result[j++] = hexconvtab[old[i] >> 4]; - result[j++] = hexconvtab[old[i] & 15]; - } - result[j] = '\0'; - - if (newlen) - *newlen = oldlen * 2 * sizeof(char); - - return result; -} -/* }}} */ - -#ifdef HAVE_LOCALECONV -/* {{{ localeconv_r - * glibc's localeconv is not reentrant, so lets make it so ... sorta */ -struct lconv *localeconv_r(struct lconv *out) -{ - struct lconv *res; - -# ifdef ZTS - tsrm_mutex_lock( locale_mutex ); -# endif - - /* localeconv doesn't return an error condition */ - res = localeconv(); - - *out = *res; - -# ifdef ZTS - tsrm_mutex_unlock( locale_mutex ); -# endif - - return out; -} -/* }}} */ - -# ifdef ZTS -/* {{{ PHP_MINIT_FUNCTION - */ -PHP_MINIT_FUNCTION(localeconv) -{ - locale_mutex = tsrm_mutex_alloc(); - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_MSHUTDOWN_FUNCTION - */ -PHP_MSHUTDOWN_FUNCTION(localeconv) -{ - tsrm_mutex_free( locale_mutex ); - locale_mutex = NULL; - return SUCCESS; -} -/* }}} */ -# endif -#endif - -/* {{{ proto string bin2hex(string data) - Converts the binary representation of data to hex */ -PHP_FUNCTION(bin2hex) -{ - zval **data; - char *result; - size_t newlen; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &data) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(data); - - result = php_bin2hex(Z_STRVAL_PP(data), Z_STRLEN_PP(data), &newlen); - - if (!result) { - RETURN_FALSE; - } - - RETURN_STRINGL(result, newlen, 0); -} -/* }}} */ - -static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) -{ - char *s11, *s22; - int len1, len2, start, len; - - start = 0; - len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", &s11, &len1, - &s22, &len2, &start, &len) == FAILURE) { - return; - } - - if (ZEND_NUM_ARGS() < 4) { - len = len1; - } - - /* look at substr() function for more information */ - - if (start < 0) { - start += len1; - if (start < 0) { - start = 0; - } - } else if (start > len1) { - RETURN_FALSE; - } - - if (len < 0) { - len += (len1 - start); - if (len < 0) { - len = 0; - } - } - - if ((start + len) > len1) { - len = len1 - start; - } - - if (behavior == STR_STRSPN) { - RETURN_LONG(php_strspn(s11 + start /*str1_start*/, - s22 /*str2_start*/, - s11 + start + len /*str1_end*/, - s22 + len2 /*str2_end*/)); - } else if (behavior == STR_STRCSPN) { - RETURN_LONG(php_strcspn(s11 + start /*str1_start*/, - s22 /*str2_start*/, - s11 + start + len /*str1_end*/, - s22 + len2 /*str2_end*/)); - } - -} - -/* {{{ proto int strspn(string str, string mask [, start [, len]]) - Finds length of initial segment consisting entirely of characters found in mask. If start or/and length is provided works like strspn(substr($s,$start,$len),$good_chars) */ -PHP_FUNCTION(strspn) -{ - php_spn_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, STR_STRSPN); -} -/* }}} */ - -/* {{{ proto int strcspn(string str, string mask [, start [, len]]) - Finds length of initial segment consisting entirely of characters not found in mask. If start or/and length is provide works like strcspn(substr($s,$start,$len),$bad_chars) */ -PHP_FUNCTION(strcspn) -{ - php_spn_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, STR_STRCSPN); -} -/* }}} */ - -/* {{{ PHP_MINIT_FUNCTION(nl_langinfo) */ -#if HAVE_NL_LANGINFO -PHP_MINIT_FUNCTION(nl_langinfo) -{ -#define REGISTER_NL_LANGINFO_CONSTANT(x) REGISTER_LONG_CONSTANT(#x, x, CONST_CS | CONST_PERSISTENT) -#ifdef ABDAY_1 - REGISTER_NL_LANGINFO_CONSTANT(ABDAY_1); - REGISTER_NL_LANGINFO_CONSTANT(ABDAY_2); - REGISTER_NL_LANGINFO_CONSTANT(ABDAY_3); - REGISTER_NL_LANGINFO_CONSTANT(ABDAY_4); - REGISTER_NL_LANGINFO_CONSTANT(ABDAY_5); - REGISTER_NL_LANGINFO_CONSTANT(ABDAY_6); - REGISTER_NL_LANGINFO_CONSTANT(ABDAY_7); -#endif -#ifdef DAY_1 - REGISTER_NL_LANGINFO_CONSTANT(DAY_1); - REGISTER_NL_LANGINFO_CONSTANT(DAY_2); - REGISTER_NL_LANGINFO_CONSTANT(DAY_3); - REGISTER_NL_LANGINFO_CONSTANT(DAY_4); - REGISTER_NL_LANGINFO_CONSTANT(DAY_5); - REGISTER_NL_LANGINFO_CONSTANT(DAY_6); - REGISTER_NL_LANGINFO_CONSTANT(DAY_7); -#endif -#ifdef ABMON_1 - REGISTER_NL_LANGINFO_CONSTANT(ABMON_1); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_2); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_3); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_4); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_5); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_6); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_7); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_8); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_9); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_10); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_11); - REGISTER_NL_LANGINFO_CONSTANT(ABMON_12); -#endif -#ifdef MON_1 - REGISTER_NL_LANGINFO_CONSTANT(MON_1); - REGISTER_NL_LANGINFO_CONSTANT(MON_2); - REGISTER_NL_LANGINFO_CONSTANT(MON_3); - REGISTER_NL_LANGINFO_CONSTANT(MON_4); - REGISTER_NL_LANGINFO_CONSTANT(MON_5); - REGISTER_NL_LANGINFO_CONSTANT(MON_6); - REGISTER_NL_LANGINFO_CONSTANT(MON_7); - REGISTER_NL_LANGINFO_CONSTANT(MON_8); - REGISTER_NL_LANGINFO_CONSTANT(MON_9); - REGISTER_NL_LANGINFO_CONSTANT(MON_10); - REGISTER_NL_LANGINFO_CONSTANT(MON_11); - REGISTER_NL_LANGINFO_CONSTANT(MON_12); -#endif -#ifdef AM_STR - REGISTER_NL_LANGINFO_CONSTANT(AM_STR); -#endif -#ifdef PM_STR - REGISTER_NL_LANGINFO_CONSTANT(PM_STR); -#endif -#ifdef D_T_FMT - REGISTER_NL_LANGINFO_CONSTANT(D_T_FMT); -#endif -#ifdef D_FMT - REGISTER_NL_LANGINFO_CONSTANT(D_FMT); -#endif -#ifdef T_FMT - REGISTER_NL_LANGINFO_CONSTANT(T_FMT); -#endif -#ifdef T_FMT_AMPM - REGISTER_NL_LANGINFO_CONSTANT(T_FMT_AMPM); -#endif -#ifdef ERA - REGISTER_NL_LANGINFO_CONSTANT(ERA); -#endif -#ifdef ERA_YEAR - REGISTER_NL_LANGINFO_CONSTANT(ERA_YEAR); -#endif -#ifdef ERA_D_T_FMT - REGISTER_NL_LANGINFO_CONSTANT(ERA_D_T_FMT); -#endif -#ifdef ERA_D_FMT - REGISTER_NL_LANGINFO_CONSTANT(ERA_D_FMT); -#endif -#ifdef ERA_T_FMT - REGISTER_NL_LANGINFO_CONSTANT(ERA_T_FMT); -#endif -#ifdef ALT_DIGITS - REGISTER_NL_LANGINFO_CONSTANT(ALT_DIGITS); -#endif -#ifdef INT_CURR_SYMBOL - REGISTER_NL_LANGINFO_CONSTANT(INT_CURR_SYMBOL); -#endif -#ifdef CURRENCY_SYMBOL - REGISTER_NL_LANGINFO_CONSTANT(CURRENCY_SYMBOL); -#endif -#ifdef CRNCYSTR - REGISTER_NL_LANGINFO_CONSTANT(CRNCYSTR); -#endif -#ifdef MON_DECIMAL_POINT - REGISTER_NL_LANGINFO_CONSTANT(MON_DECIMAL_POINT); -#endif -#ifdef MON_THOUSANDS_SEP - REGISTER_NL_LANGINFO_CONSTANT(MON_THOUSANDS_SEP); -#endif -#ifdef MON_GROUPING - REGISTER_NL_LANGINFO_CONSTANT(MON_GROUPING); -#endif -#ifdef POSITIVE_SIGN - REGISTER_NL_LANGINFO_CONSTANT(POSITIVE_SIGN); -#endif -#ifdef NEGATIVE_SIGN - REGISTER_NL_LANGINFO_CONSTANT(NEGATIVE_SIGN); -#endif -#ifdef INT_FRAC_DIGITS - REGISTER_NL_LANGINFO_CONSTANT(INT_FRAC_DIGITS); -#endif -#ifdef FRAC_DIGITS - REGISTER_NL_LANGINFO_CONSTANT(FRAC_DIGITS); -#endif -#ifdef P_CS_PRECEDES - REGISTER_NL_LANGINFO_CONSTANT(P_CS_PRECEDES); -#endif -#ifdef P_SEP_BY_SPACE - REGISTER_NL_LANGINFO_CONSTANT(P_SEP_BY_SPACE); -#endif -#ifdef N_CS_PRECEDES - REGISTER_NL_LANGINFO_CONSTANT(N_CS_PRECEDES); -#endif -#ifdef N_SEP_BY_SPACE - REGISTER_NL_LANGINFO_CONSTANT(N_SEP_BY_SPACE); -#endif -#ifdef P_SIGN_POSN - REGISTER_NL_LANGINFO_CONSTANT(P_SIGN_POSN); -#endif -#ifdef N_SIGN_POSN - REGISTER_NL_LANGINFO_CONSTANT(N_SIGN_POSN); -#endif -#ifdef DECIMAL_POINT - REGISTER_NL_LANGINFO_CONSTANT(DECIMAL_POINT); -#endif -#ifdef RADIXCHAR - REGISTER_NL_LANGINFO_CONSTANT(RADIXCHAR); -#endif -#ifdef THOUSANDS_SEP - REGISTER_NL_LANGINFO_CONSTANT(THOUSANDS_SEP); -#endif -#ifdef THOUSEP - REGISTER_NL_LANGINFO_CONSTANT(THOUSEP); -#endif -#ifdef GROUPING - REGISTER_NL_LANGINFO_CONSTANT(GROUPING); -#endif -#ifdef YESEXPR - REGISTER_NL_LANGINFO_CONSTANT(YESEXPR); -#endif -#ifdef NOEXPR - REGISTER_NL_LANGINFO_CONSTANT(NOEXPR); -#endif -#ifdef YESSTR - REGISTER_NL_LANGINFO_CONSTANT(YESSTR); -#endif -#ifdef NOSTR - REGISTER_NL_LANGINFO_CONSTANT(NOSTR); -#endif -#ifdef CODESET - REGISTER_NL_LANGINFO_CONSTANT(CODESET); -#endif -#undef REGISTER_NL_LANGINFO_CONSTANT - return SUCCESS; -} -/* }}} */ - -/* {{{ proto string nl_langinfo(int item) - Query language and locale information */ -PHP_FUNCTION(nl_langinfo) -{ - zval **item; - char *value; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &item) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(item); - - value = nl_langinfo(Z_LVAL_PP(item)); - if (value == NULL) { - RETURN_FALSE; - } else { - RETURN_STRING(value, 1); - } -} -#endif -/* }}} */ - -#ifdef HAVE_STRCOLL -/* {{{ proto int strcoll(string str1, string str2) - Compares two strings using the current locale */ -PHP_FUNCTION(strcoll) -{ - zval **s1, **s2; - - if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(s1); - convert_to_string_ex(s2); - - RETURN_LONG(strcoll((const char *) Z_STRVAL_PP(s1), - (const char *) Z_STRVAL_PP(s2))); -} -/* }}} */ -#endif - -/* {{{ php_charmask - * Fills a 256-byte bytemask with input. You can specify a range like 'a..z', - * it needs to be incrementing. - * Returns: FAILURE/SUCCESS wether the input was correct (i.e. no range errors) - */ -static inline int php_charmask(unsigned char *input, int len, char *mask TSRMLS_DC) -{ - unsigned char *end; - unsigned char c; - int result = SUCCESS; - - 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 if ((input+1 < end) && input[0] == '.' && input[1] == '.') { - /* Error, try to be as helpful as possible: - (a range ending/starting with '.' won't be captured here) */ - if (end-len >= input) { /* there was no 'left' char */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range, no character to the left of '..'."); - result = FAILURE; - continue; - } - if (input+2 >= end) { /* there is no 'right' char */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range, no character to the right of '..'."); - result = FAILURE; - continue; - } - if (input[-1] > input[2]) { /* wrong order */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range, '..'-range needs to be incrementing."); - result = FAILURE; - continue; - } - /* FIXME: better error (a..b..c is the only left possibility?) */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range."); - result = FAILURE; - continue; - } else { - mask[c]=1; - } - } - return result; -} -/* }}} */ - -/* {{{ php_trim() - * 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') - */ -PHPAPI char *php_trim(char *c, int len, char *what, int what_len, zval *return_value, int mode TSRMLS_DC) -{ - register int i; - int trimmed = 0; - char mask[256]; - - if (what) { - php_charmask(what, what_len, mask TSRMLS_CC); - } else { - php_charmask(" \n\r\t\v\0", 6, mask TSRMLS_CC); - } - - if (mode & 1) { - for (i = 0; i < len; i++) { - if (mask[(unsigned char)c[i]]) { - trimmed++; - } else { - break; - } - } - len -= trimmed; - c += trimmed; - } - if (mode & 2) { - for (i = len - 1; i >= 0; i--) { - if (mask[(unsigned char)c[i]]) { - len--; - } else { - break; - } - } - } - - if (return_value) { - RETVAL_STRINGL(c, len, 1); - } else { - return estrndup(c, len); - } - return ""; -} -/* }}} */ - -/* {{{ php_do_trim - * Base for trim(), rtrim() and ltrim() functions. - */ -static void php_do_trim(INTERNAL_FUNCTION_PARAMETERS, int mode) -{ - zval **str; - zval **what = NULL; - int argc = ZEND_NUM_ARGS(); - - if (argc < 1 || argc > 2 || zend_get_parameters_ex(argc, &str, &what) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(str); - - if (argc > 1) { - convert_to_string_ex(what); - php_trim(Z_STRVAL_PP(str), Z_STRLEN_PP(str), Z_STRVAL_PP(what), Z_STRLEN_PP(what), return_value, mode TSRMLS_CC); - } else { - php_trim(Z_STRVAL_PP(str), Z_STRLEN_PP(str), NULL, 0, return_value, mode TSRMLS_CC); - } -} -/* }}} */ - -/* {{{ proto string trim(string str [, string character_mask]) - Strips whitespace from the beginning and end of a string */ -PHP_FUNCTION(trim) -{ - php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3); -} -/* }}} */ - -/* {{{ proto string rtrim(string str [, string character_mask]) - Removes trailing whitespace */ -PHP_FUNCTION(rtrim) -{ - php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2); -} -/* }}} */ - -/* {{{ proto string ltrim(string str [, string character_mask]) - Strips whitespace from the beginning of a string */ -PHP_FUNCTION(ltrim) -{ - php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ proto string wordwrap(string str [, int width [, string break [, int cut]]]) - Wraps buffer to selected number of characters using string break char */ -PHP_FUNCTION(wordwrap) -{ - const char *text, *breakchar = "\n"; - char *newtext; - int textlen, breakcharlen = 1, newtextlen, alloced, chk; - long current = 0, laststart = 0, lastspace = 0; - long linelength = 75; - zend_bool docut = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lsb", &text, &textlen, &linelength, &breakchar, &breakcharlen, &docut) == FAILURE) { - return; - } - - if (textlen == 0) - RETURN_FALSE; - - if (linelength == 0 && docut) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't force cut when width is zero."); - RETURN_FALSE; - } - - /* Special case for a single-character break as it needs no - additional storage space */ - if (breakcharlen == 1 && !docut) { - newtext = estrndup(text, textlen); - - laststart = lastspace = 0; - for (current = 0; current < textlen; current++) { - if (text[current] == breakchar[0]) { - laststart = lastspace = current; - } else if (text[current] == ' ') { - if (current - laststart >= linelength) { - newtext[current] = breakchar[0]; - laststart = current; - } - lastspace = current; - } else if (current - laststart >= linelength && laststart != lastspace) { - newtext[lastspace] = breakchar[0]; - laststart = lastspace; - } - } - - RETURN_STRINGL(newtext, textlen, 0); - } else { - /* Multiple character line break or forced cut */ - if (linelength > 0) { - chk = (int)(textlen/linelength + 1); - alloced = textlen + chk * breakcharlen + 1; - } else { - chk = textlen; - alloced = textlen * (breakcharlen + 1) + 1; - } - newtext = emalloc(alloced); - - /* now keep track of the actual new text length */ - newtextlen = 0; - - laststart = lastspace = 0; - for (current = 0; current < textlen; current++) { - if (chk <= 0) { - alloced += (int) (((textlen - current + 1)/linelength + 1) * breakcharlen) + 1; - newtext = erealloc(newtext, alloced); - chk = (int) ((textlen - current)/linelength) + 1; - } - /* when we hit an existing break, copy to new buffer, and - * fix up laststart and lastspace */ - if (text[current] == breakchar[0] - && current + breakcharlen < textlen - && !strncmp(text+current, breakchar, breakcharlen)) { - memcpy(newtext+newtextlen, text+laststart, current-laststart+breakcharlen); - newtextlen += current-laststart+breakcharlen; - current += breakcharlen - 1; - laststart = lastspace = current + 1; - chk--; - } - /* if it is a space, check if it is at the line boundary, - * copy and insert a break, or just keep track of it */ - else if (text[current] == ' ') { - if (current - laststart >= linelength) { - memcpy(newtext+newtextlen, text+laststart, current-laststart); - newtextlen += current - laststart; - memcpy(newtext+newtextlen, breakchar, breakcharlen); - newtextlen += breakcharlen; - laststart = current + 1; - chk--; - } - lastspace = current; - } - /* if we are cutting, and we've accumulated enough - * characters, and we haven't see a space for this line, - * copy and insert a break. */ - else if (current - laststart >= linelength - && docut && laststart >= lastspace) { - memcpy(newtext+newtextlen, text+laststart, current-laststart); - newtextlen += current - laststart; - memcpy(newtext+newtextlen, breakchar, breakcharlen); - newtextlen += breakcharlen; - laststart = lastspace = current; - chk--; - } - /* if the current word puts us over the linelength, copy - * back up until the last space, insert a break, and move - * up the laststart */ - else if (current - laststart >= linelength - && laststart < lastspace) { - memcpy(newtext+newtextlen, text+laststart, lastspace-laststart); - newtextlen += lastspace - laststart; - memcpy(newtext+newtextlen, breakchar, breakcharlen); - newtextlen += breakcharlen; - laststart = lastspace = lastspace + 1; - chk--; - } - } - - /* copy over any stragglers */ - if (laststart != current) { - memcpy(newtext+newtextlen, text+laststart, current-laststart); - newtextlen += current - laststart; - } - - newtext[newtextlen] = '\0'; - /* free unused memory */ - newtext = erealloc(newtext, newtextlen+1); - - RETURN_STRINGL(newtext, newtextlen, 0); - } -} -/* }}} */ - -/* {{{ php_explode - */ -PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit) -{ - char *p1, *p2, *endp; - - 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) { - add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), 1); - } else { - do { - add_next_index_stringl(return_value, p1, p2 - p1, 1); - p1 = p2 + Z_STRLEN_P(delim); - } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL && - (limit == -1 || --limit > 1)); - - if (p1 <= endp) - add_next_index_stringl(return_value, p1, endp-p1, 1); - } -} -/* }}} */ - -/* {{{ proto array explode(string separator, string str [, int limit]) - Splits a string on string separator and return array of components */ -PHP_FUNCTION(explode) -{ - zval **str, **delim, **zlimit = NULL; - int limit = -1; - int argc = ZEND_NUM_ARGS(); - - if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &delim, &str, &zlimit) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - convert_to_string_ex(delim); - - if (argc > 2) { - convert_to_long_ex(zlimit); - limit = Z_LVAL_PP(zlimit); - } - - if (! Z_STRLEN_PP(delim)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); - RETURN_FALSE; - } - - array_init(return_value); - - if (limit == 0 || limit == 1) { - add_index_stringl(return_value, 0, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); - } else { - php_explode(*delim, *str, return_value, limit); - } -} -/* }}} */ - -/* {{{ proto string join(array src, string glue) - An alias for implode */ -/* }}} */ - -/* {{{ php_implode - */ -PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value) -{ - zval **tmp; - HashPosition pos; - smart_str implstr = {0}; - int numelems, i = 0; - - numelems = zend_hash_num_elements(Z_ARRVAL_P(arr)); - - if (numelems == 0) { - RETURN_EMPTY_STRING(); - } - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); - - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **) &tmp, &pos) == SUCCESS) { - SEPARATE_ZVAL(tmp); - convert_to_string(*tmp); - - smart_str_appendl(&implstr, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); - if (++i != numelems) { - smart_str_appendl(&implstr, Z_STRVAL_P(delim), Z_STRLEN_P(delim)); - } - zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); - } - smart_str_0(&implstr); - - RETURN_STRINGL(implstr.c, implstr.len, 0); -} -/* }}} */ - -/* {{{ proto string implode([string glue,] array pieces) - Joins array elements placing glue string between items and return one string */ -PHP_FUNCTION(implode) -{ - zval **arg1 = NULL, **arg2 = NULL, *delim, *arr; - int argc = ZEND_NUM_ARGS(); - int arg1_separated = 0, arg2_separated = 0, delim_needs_dtor = 0; - - if (argc < 1 || argc > 2 || - zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) { - WRONG_PARAM_COUNT; - } - - if (argc == 1) { - if (Z_TYPE_PP(arg1) != IS_ARRAY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument to implode must be an array."); - return; - } - - MAKE_STD_ZVAL(delim); -#define _IMPL_EMPTY "" - ZVAL_STRINGL(delim, _IMPL_EMPTY, sizeof(_IMPL_EMPTY) - 1, 0); - - SEPARATE_ZVAL(arg1); - arg1_separated = 1; - delim_needs_dtor = 1; - arr = *arg1; - } else { - if (Z_TYPE_PP(arg1) == IS_ARRAY) { - SEPARATE_ZVAL(arg1); - arg1_separated = 1; - arr = *arg1; - convert_to_string_ex(arg2); - delim = *arg2; - } else if (Z_TYPE_PP(arg2) == IS_ARRAY) { - SEPARATE_ZVAL(arg2); - arg2_separated = 1; - arr = *arg2; - convert_to_string_ex(arg1); - delim = *arg1; - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad arguments."); - return; - } - } - - php_implode(delim, arr, return_value); - - if (arg1 != NULL && arg1_separated) { - zval_ptr_dtor(arg1); - } - if (arg2 != NULL && arg2_separated) { - zval_ptr_dtor(arg2); - } - if (delim_needs_dtor) { - FREE_ZVAL(delim); - } -} -/* }}} */ - -#define STRTOK_TABLE(p) BG(strtok_table)[(unsigned char) *p] - -/* {{{ proto string strtok([string str,] string token) - Tokenize a string */ -PHP_FUNCTION(strtok) -{ - zval **args[2]; - zval **tok, **str; - char *token; - char *token_end; - char *p; - char *pe; - int skipped = 0; - - 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; - - default: - 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; - } - - p = BG(strtok_last); /* Where we start to search */ - pe = BG(strtok_string) + BG(strtok_len); - - if (!p || p >= pe) { - RETURN_FALSE; - } - - convert_to_string_ex(tok); - - token = Z_STRVAL_PP(tok); - token_end = token + Z_STRLEN_PP(tok); - - 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; - } - skipped++; - } - - /* 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) + skipped, (p - BG(strtok_last)) - skipped, 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; - } -} -/* }}} */ - -/* {{{ php_strtoupper - */ -PHPAPI char *php_strtoupper(char *s, size_t len) -{ - unsigned char *c, *e; - - c = s; - e = c+len; - - while (c < e) { - *c = toupper(*c); - c++; - } - return s; -} -/* }}} */ - -/* {{{ proto string strtoupper(string str) - Makes a string uppercase */ -PHP_FUNCTION(strtoupper) -{ - zval **arg; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg)) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(arg); - - *return_value = **arg; - zval_copy_ctor(return_value); - php_strtoupper(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value)); -} -/* }}} */ - -/* {{{ php_strtolower - */ -PHPAPI char *php_strtolower(char *s, size_t len) -{ - unsigned char *c, *e; - - c = s; - e = c+len; - - while (c < e) { - *c = tolower(*c); - c++; - } - return s; -} -/* }}} */ - -/* {{{ proto string strtolower(string str) - Makes a string lowercase */ -PHP_FUNCTION(strtolower) -{ - zval **str; - char *ret; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str)) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - *return_value = **str; - zval_copy_ctor(return_value); - ret = php_strtolower(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value)); -} -/* }}} */ - -/* {{{ php_basename - */ -PHPAPI char *php_basename(char *s, size_t len, char *suffix, size_t sufflen) -{ - char *ret=NULL, *c, *p=NULL, buf='\0', *p2=NULL, buf2='\0'; - c = s + len - 1; - - /* do suffix removal as the unix command does */ - if (suffix && (len > sufflen)) { - if (!strncmp(suffix, c-sufflen+1, sufflen)) { - c -= sufflen; - buf2 = *(c + 1); /* Save overwritten char */ - *(c + 1) = '\0'; /* overwrite char */ - p2 = c + 1; /* Save pointer to overwritten char */ - } - } - - /* strip trailing slashes */ - while (*c == '/' -#ifdef PHP_WIN32 - || (*c == '\\' && !IsDBCSLeadByte(*(c-1))) -#endif - ) { - c--; - } - - if (c < s+len-1) { - buf = *(c + 1); /* Save overwritten char */ - *(c + 1) = '\0'; /* overwrite char */ - p = c + 1; /* Save pointer to overwritten char */ - } - - if ((c = strrchr(s, '/')) -#ifdef PHP_WIN32 - || ((c = strrchr(s, '\\')) && !IsDBCSLeadByte(*(c-1))) -#endif - ) { - ret = estrdup(c + 1); - } else { - ret = estrdup(s); - } - if (buf) { - *p = buf; - } - if (buf2) { - *p2 = buf2; - } - return (ret); -} -/* }}} */ - -/* {{{ proto string basename(string path [, string suffix]) - Returns the filename component of the path */ -PHP_FUNCTION(basename) -{ - char *ret; - char *string, *suffix = NULL; - int string_len, suffix_len = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &string, &string_len, &suffix, &suffix_len) == FAILURE) { - return; - } - - ret = php_basename(string, string_len, suffix, suffix_len); - RETURN_STRING(ret, 0); -} -/* }}} */ - -/* {{{ php_dirname - Returns directory name component of path */ -PHPAPI void php_dirname(char *path, int len) -{ - register char *end = path + len - 1; - -#ifdef PHP_WIN32 - /* Note that on Win32 CWD is per drive (heritage from CP/M). - * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive. - */ - if ((2 <= len) && isalpha(path[0]) && (':' == path[1])) { - /* Skip over the drive spec (if any) so as not to change */ - path += 2; - if (2 == len) { - /* Return "c:" on Win32 for dirname("c:"). - * It would be more consistent to return "c:." - * but that would require making the string *longer*. - */ - return; - } - } -#endif - - if (len <= 0) { - /* Illegal use of this function */ - return; - } - - /* Strip trailing slashes */ - while (end >= path && IS_SLASH_P(end)) { - end--; - } - if (end < path) { - /* The path only contained slashes */ - path[0] = DEFAULT_SLASH; - path[1] = '\0'; - return; - } - - /* Strip filename */ - while (end >= path && !IS_SLASH_P(end)) { - end--; - } - if (end < path) { - /* No slash found, therefore return '.' */ - path[0] = '.'; - path[1] = '\0'; - return; - } - - /* Strip slashes which came before the file name */ - while (end >= path && IS_SLASH_P(end)) { - end--; - } - if (end < path) { - path[0] = DEFAULT_SLASH; - path[1] = '\0'; - return; - } - *(end+1) = '\0'; -} -/* }}} */ - -/* {{{ proto string dirname(string path) - Returns the directory name component of the path */ -PHP_FUNCTION(dirname) -{ - zval **str; - char *ret; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - ret = estrndup(Z_STRVAL_PP(str), Z_STRLEN_PP(str)); - php_dirname(ret, Z_STRLEN_PP(str)); - - RETURN_STRING(ret, 0); -} -/* }}} */ - -/* {{{ proto array pathinfo(string path) - Returns information about a certain string */ -PHP_FUNCTION(pathinfo) -{ - zval *tmp; - char *path, *ret = NULL; - int path_len; - int opt = PHP_PATHINFO_ALL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &path, &path_len, &opt) == FAILURE) { - return; - } - - MAKE_STD_ZVAL(tmp); - array_init(tmp); - - if ((opt & PHP_PATHINFO_DIRNAME) == PHP_PATHINFO_DIRNAME) { - ret = estrndup(path, path_len); - php_dirname(ret, path_len); - if (*ret) { - add_assoc_string(tmp, "dirname", ret, 1); - } - efree(ret); - } - - if ((opt & PHP_PATHINFO_BASENAME) == PHP_PATHINFO_BASENAME) { - ret = php_basename(path, path_len, NULL, 0); - add_assoc_string(tmp, "basename", ret, 0); - } - - if ((opt & PHP_PATHINFO_EXTENSION) == PHP_PATHINFO_EXTENSION) { - char *p; - int idx; - int ret_len; - int have_basename = ((opt & PHP_PATHINFO_BASENAME) == PHP_PATHINFO_BASENAME); - - /* Have we alrady looked up the basename? */ - if (!have_basename) { - ret = php_basename(path, path_len, NULL, 0); - } - - ret_len = strlen(ret); - - p = strrchr(ret, '.'); - - if (p) { - idx = p - ret; - add_assoc_stringl(tmp, "extension", ret + idx + 1, ret_len - idx - 1, 1); - } - - if (!have_basename) { - efree(ret); - } - } - - if (opt == PHP_PATHINFO_ALL) { - *return_value = *tmp; - } else { - zval **element; - if (zend_hash_get_current_data(Z_ARRVAL_P(tmp), (void **) &element) == SUCCESS) { - *return_value = **element; - } else { - ZVAL_EMPTY_STRING(return_value); - } - } - - zval_copy_ctor(return_value); - zval_dtor(tmp); - efree(tmp); -} -/* }}} */ - -/* {{{ php_stristr - case insensitve strstr */ -PHPAPI char *php_stristr(unsigned char *s, unsigned char *t, size_t s_len, size_t t_len) -{ - php_strtolower(s, s_len); - php_strtolower(t, t_len); - return php_memnstr(s, t, t_len, s + s_len); -} -/* }}} */ - -/* {{{ php_strspn - */ -PHPAPI size_t php_strspn(char *s1, char *s2, char *s1_end, char *s2_end) -{ - register const char *p = s1, *spanp; - register char c = *p; - -cont: - for (spanp = s2; p != s1_end && spanp != s2_end;) { - if (*spanp++ == c) { - c = *(++p); - goto cont; - } - } - return (p - s1); -} -/* }}} */ - -/* {{{ php_strcspn - */ -PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end) -{ - register const char *p, *spanp; - register char c = *s1; - - for (p = s1;;) { - spanp = s2; - do { - if (*spanp == c || p == s1_end) { - return p - s1; - } - } while (spanp++ < s2_end); - c = *++p; - } - /* NOTREACHED */ -} -/* }}} */ - -/* {{{ proto string stristr(string haystack, string needle) - Finds first occurrence of a string within another, case insensitive */ -PHP_FUNCTION(stristr) -{ - zval **haystack, **needle; - char *found = NULL; - int found_offset; - char *haystack_orig; - char needle_char[2]; - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { - WRONG_PARAM_COUNT; - } - - SEPARATE_ZVAL(haystack); - SEPARATE_ZVAL(needle); - - convert_to_string_ex(haystack); - - haystack_orig = estrndup(Z_STRVAL_PP(haystack), Z_STRLEN_PP(haystack)); - - if (Z_TYPE_PP(needle) == IS_STRING) { - if (!Z_STRLEN_PP(needle)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); - efree(haystack_orig); - zval_ptr_dtor(haystack); - zval_ptr_dtor(needle); - RETURN_FALSE; - } - - found = php_stristr(Z_STRVAL_PP(haystack), - Z_STRVAL_PP(needle), - Z_STRLEN_PP(haystack), - Z_STRLEN_PP(needle)); - } else { - convert_to_long_ex(needle); - needle_char[0] = (char) Z_LVAL_PP(needle); - needle_char[1] = 0; - - found = php_stristr(Z_STRVAL_PP(haystack), - needle_char, - Z_STRLEN_PP(haystack), - 1); - } - - if (found) { - found_offset = found - Z_STRVAL_PP(haystack); - RETVAL_STRINGL(haystack_orig + found_offset, Z_STRLEN_PP(haystack) - found_offset, 1); - } else { - RETVAL_FALSE; - } - - zval_ptr_dtor(haystack); - zval_ptr_dtor(needle); - efree(haystack_orig); -} -/* }}} */ - -/* {{{ proto string strstr(string haystack, string needle) - Finds first occurrence of a string within another */ -PHP_FUNCTION(strstr) -{ - zval **haystack, **needle; - char *found = NULL; - char needle_char[2]; - long found_offset; - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(haystack); - - if (Z_TYPE_PP(needle) == IS_STRING) { - if (!Z_STRLEN_PP(needle)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); - RETURN_FALSE; - } - - found = php_memnstr(Z_STRVAL_PP(haystack), - Z_STRVAL_PP(needle), - Z_STRLEN_PP(needle), - Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); - } else { - convert_to_long_ex(needle); - needle_char[0] = (char) Z_LVAL_PP(needle); - needle_char[1] = 0; - - found = php_memnstr(Z_STRVAL_PP(haystack), - needle_char, - 1, - Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); - } - - if (found) { - found_offset = found - Z_STRVAL_PP(haystack); - RETURN_STRINGL(found, Z_STRLEN_PP(haystack) - found_offset, 1); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ proto string strchr(string haystack, string needle) - An alias for strstr */ -/* }}} */ - -/* {{{ proto int strpos(string haystack, string needle [, int offset]) - Finds position of first occurrence of a string within another */ -PHP_FUNCTION(strpos) -{ - zval **haystack, **needle, **z_offset; - char *found = NULL; - char needle_char[2]; - int offset = 0; - int argc = ZEND_NUM_ARGS(); - - if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &haystack, &needle, &z_offset) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(haystack); - - if (argc > 2) { - convert_to_long_ex(z_offset); - offset = Z_LVAL_PP(z_offset); - } - - if (offset < 0 || offset > Z_STRLEN_PP(haystack)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); - RETURN_FALSE; - } - - if (Z_TYPE_PP(needle) == IS_STRING) { - if (!Z_STRLEN_PP(needle)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); - RETURN_FALSE; - } - - found = php_memnstr(Z_STRVAL_PP(haystack) + offset, - Z_STRVAL_PP(needle), - Z_STRLEN_PP(needle), - Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); - } else { - convert_to_long_ex(needle); - needle_char[0] = (char) Z_LVAL_PP(needle); - needle_char[1] = 0; - - found = php_memnstr(Z_STRVAL_PP(haystack) + offset, - needle_char, - 1, - Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); - } - - if (found) { - RETURN_LONG(found - Z_STRVAL_PP(haystack)); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ proto int stripos(string haystack, string needle [, int offset]) - Finds position of first occurrence of a string within another, case insensitive */ -PHP_FUNCTION(stripos) -{ - char *found = NULL; - char *haystack; - int haystack_len; - long offset = 0; - char *needle_dup = NULL, *haystack_dup; - char needle_char[2]; - zval *needle; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &needle, &offset) == FAILURE) { - return; - } - - if (offset < 0 || offset > haystack_len) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); - RETURN_FALSE; - } - - haystack_dup = estrndup(haystack, haystack_len); - php_strtolower(haystack_dup, haystack_len); - - if (Z_TYPE_P(needle) == IS_STRING) { - needle_dup = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle)); - php_strtolower(needle_dup, Z_STRLEN_P(needle)); - found = php_memnstr(haystack_dup + offset, needle_dup, Z_STRLEN_P(needle), haystack_dup + haystack_len); - } else { - switch (Z_TYPE_P(needle)) { - case IS_LONG: - case IS_BOOL: - needle_char[0] = tolower((char) Z_LVAL_P(needle)); - break; - case IS_DOUBLE: - needle_char[0] = tolower((char) Z_DVAL_P(needle)); - break; - default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "needle is not a string or an integer."); - efree(haystack_dup); - RETURN_FALSE; - break; - - } - needle_char[1] = '\0'; - found = php_memnstr(haystack_dup + offset, - needle_char, - sizeof(needle_char) - 1, - haystack_dup + haystack_len); - } - - efree(haystack_dup); - if (needle_dup) { - efree(needle_dup); - } - - if (found) { - RETURN_LONG(found - haystack_dup); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ proto int strrpos(string haystack, string needle [, int offset]) - Finds position of last occurrence of a character in a string within another */ -PHP_FUNCTION(strrpos) -{ - zval **haystack, **needle, **offset; - char *found = NULL; - int argc = ZEND_NUM_ARGS(); - int off = 0; - - if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &haystack, &needle, &offset) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(haystack); - - if (argc == 3) { - convert_to_long_ex(offset); - if (Z_LVAL_PP(offset) < 0 || Z_LVAL_PP(offset) > Z_STRLEN_PP(haystack)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); - RETURN_FALSE; - } - off = Z_LVAL_PP(offset); - } - - if (Z_TYPE_PP(needle) == IS_STRING) { - found = strrchr(Z_STRVAL_PP(haystack) + off, *Z_STRVAL_PP(needle)); - } else { - convert_to_long_ex(needle); - found = strrchr(Z_STRVAL_PP(haystack) + off, (char) Z_LVAL_PP(needle)); - } - - if (found) { - RETURN_LONG(Z_STRLEN_PP(haystack) - strlen(found)); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ proto int strripos(string haystack, string needle [, int offset]) - Finds position of last occurrence of a character in a string within another, case insensitive */ -PHP_FUNCTION(strripos) -{ - zval **haystack, **needle, **offset; - char *found = NULL; - int argc = ZEND_NUM_ARGS(); - int off = 0; - char *haystack_dup; - char needle_dup; - - if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &haystack, &needle, &offset) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(haystack); - - if (argc == 3) { - convert_to_long_ex(offset); - if (Z_LVAL_PP(offset) < 0 || Z_LVAL_PP(offset) > Z_STRLEN_PP(haystack)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); - RETURN_FALSE; - } - off = Z_LVAL_PP(offset); - } - - haystack_dup = estrndup(Z_STRVAL_PP(haystack), Z_STRLEN_PP(haystack)); - php_strtolower(haystack_dup, Z_STRLEN_PP(haystack)); - - if (Z_TYPE_PP(needle) == IS_STRING) { - needle_dup = *Z_STRVAL_PP(needle); - } else { - convert_to_long_ex(needle); - needle_dup = (char) Z_LVAL_PP(needle); - } - - found = strrchr(haystack_dup + off, tolower(needle_dup)); - - efree(haystack_dup); - - if (found) { - RETURN_LONG(Z_STRLEN_PP(haystack) - strlen(found)); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ proto string strrchr(string haystack, string needle) - Finds the last occurrence of a character in a string within another */ -PHP_FUNCTION(strrchr) -{ - zval **haystack, **needle; - char *found = NULL; - long found_offset; - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == - FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(haystack); - - if (Z_TYPE_PP(needle) == IS_STRING) { - found = strrchr(Z_STRVAL_PP(haystack), *Z_STRVAL_PP(needle)); - } else { - convert_to_long_ex(needle); - found = strrchr(Z_STRVAL_PP(haystack), (char) Z_LVAL_PP(needle)); - } - - if (found) { - found_offset = found - Z_STRVAL_PP(haystack); - RETURN_STRINGL(found, Z_STRLEN_PP(haystack) - found_offset, 1); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ php_chunk_split - */ -static char *php_chunk_split(char *src, int srclen, char *end, int endlen, int chunklen, int *destlen) -{ - char *dest; - char *p, *q; - int chunks; /* complete chunks! */ - int restlen; - - chunks = srclen / chunklen; - restlen = srclen - chunks * chunklen; /* srclen % chunklen */ - - dest = emalloc((srclen + (chunks + 1) * endlen + 1) * sizeof(char)); - - for (p = src, q = dest; p < (src + srclen - chunklen + 1); ) { - memcpy(q, p, chunklen); - q += chunklen; - memcpy(q, end, endlen); - q += endlen; - p += chunklen; - } - - if (restlen) { - memcpy(q, p, restlen); - q += restlen; - memcpy(q, end, endlen); - q += endlen; - } - - *q = '\0'; - if (destlen) { - *destlen = q - dest; - } - - return(dest); -} -/* }}} */ - -/* {{{ proto string chunk_split(string str [, int chunklen [, string ending]]) - Returns split line */ -PHP_FUNCTION(chunk_split) -{ - zval **p_str, **p_chunklen, **p_ending; - char *result; - char *end = "\r\n"; - int endlen = 2; - int chunklen = 76; - int result_len; - int argc = ZEND_NUM_ARGS(); - - if (argc < 1 || argc > 3 || zend_get_parameters_ex(argc, &p_str, &p_chunklen, &p_ending) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(p_str); - - if (argc > 1) { - convert_to_long_ex(p_chunklen); - chunklen = Z_LVAL_PP(p_chunklen); - } - - if (argc > 2) { - convert_to_string_ex(p_ending); - end = Z_STRVAL_PP(p_ending); - endlen = Z_STRLEN_PP(p_ending); - } - - if (chunklen <= 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Chunk length should be greater than zero."); - RETURN_FALSE; - } - - if (!Z_STRLEN_PP(p_str)) { - RETURN_EMPTY_STRING(); - } - - result = php_chunk_split(Z_STRVAL_PP(p_str), Z_STRLEN_PP(p_str), end, endlen, chunklen, &result_len); - - if (result) { - RETURN_STRINGL(result, result_len, 0); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ proto string substr(string str, int start [, int length]) - Returns part of a string */ -PHP_FUNCTION(substr) -{ - zval **str, **from, **len; - int l; - int f; - int argc = ZEND_NUM_ARGS(); - - if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &str, &from, &len) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(str); - convert_to_long_ex(from); - - if (argc > 2) { - convert_to_long_ex(len); - l = Z_LVAL_PP(len); - } else { - l = Z_STRLEN_PP(str); - } - - f = Z_LVAL_PP(from); - - /* if "from" position is negative, count start position from the end - * of the string - */ - if (f < 0) { - f = Z_STRLEN_PP(str) + f; - if (f < 0) { - f = 0; - } - } - - /* if "length" position is negative, set it to the length - * needed to stop that many chars from the end of the string - */ - if (l < 0) { - l = (Z_STRLEN_PP(str) - f) + l; - if (l < 0) { - l = 0; - } - } - - if (f >= Z_STRLEN_PP(str)) { - RETURN_FALSE; - } - - if ((f + l) > Z_STRLEN_PP(str)) { - l = Z_STRLEN_PP(str) - f; - } - - RETURN_STRINGL(Z_STRVAL_PP(str) + f, l, 1); -} -/* }}} */ - -/* {{{ proto string substr_replace(string str, string repl, int start [, int length]) - Replaces part of a string with another string */ -PHP_FUNCTION(substr_replace) -{ - zval **str; - zval **from; - zval **len; - zval **repl; - char *result; - int result_len; - int l; - int f; - int argc = ZEND_NUM_ARGS(); - - if (argc < 3 || argc > 4 || zend_get_parameters_ex(argc, &str, &repl, &from, &len) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(str); - convert_to_string_ex(repl); - convert_to_long_ex(from); - - if (argc > 3) { - convert_to_long_ex(len); - l = Z_LVAL_PP(len); - } else { - l = Z_STRLEN_PP(str); - } - - f = Z_LVAL_PP(from); - - /* if "from" position is negative, count start position from the end - * of the string - */ - if (f < 0) { - f = Z_STRLEN_PP(str) + f; - if (f < 0) { - f = 0; - } - } else if (f > Z_STRLEN_PP(str)) { - f = Z_STRLEN_PP(str); - } - - - /* if "length" position is negative, set it to the length - * needed to stop that many chars from the end of the string - */ - if (l < 0) { - l = (Z_STRLEN_PP(str) - f) + l; - if (l < 0) { - l = 0; - } - } - - if ((f + l) > Z_STRLEN_PP(str)) { - l = Z_STRLEN_PP(str) - f; - } - - result_len = Z_STRLEN_PP(str) - l + Z_STRLEN_PP(repl); - result = ecalloc(result_len + 1, sizeof(char *)); - - memcpy(result, Z_STRVAL_PP(str), f); - memcpy(&result[f], Z_STRVAL_PP(repl), Z_STRLEN_PP(repl)); - memcpy(&result[f + Z_STRLEN_PP(repl)], Z_STRVAL_PP(str) + f + l, Z_STRLEN_PP(str) - f - l); - - RETURN_STRINGL(result, result_len, 0); -} -/* }}} */ - -/* {{{ proto string quotemeta(string str) - Quotes meta characters */ -PHP_FUNCTION(quotemeta) -{ - zval **arg; - char *str, *old; - char *old_end; - char *p, *q; - char c; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(arg); - - old = Z_STRVAL_PP(arg); - old_end = Z_STRVAL_PP(arg) + Z_STRLEN_PP(arg); - - if (old == old_end) { - RETURN_FALSE; - } - - str = emalloc(2 * Z_STRLEN_PP(arg) + 1); - - for (p = old, q = str; p != old_end; p++) { - c = *p; - switch (c) { - case '.': - case '\\': - case '+': - case '*': - case '?': - case '[': - case '^': - case ']': - case '$': - case '(': - case ')': - *q++ = '\\'; - /* break is missing _intentionally_ */ - default: - *q++ = c; - } - } - *q = 0; - - RETURN_STRINGL(erealloc(str, q - str + 1), q - str, 0); -} -/* }}} */ - -/* {{{ proto int ord(string character) - Returns ASCII value of character */ -PHP_FUNCTION(ord) -{ - zval **str; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - RETURN_LONG((unsigned char) Z_STRVAL_PP(str)[0]); -} -/* }}} */ - -/* {{{ proto string chr(int ascii) - Converts ASCII code to a character */ -PHP_FUNCTION(chr) -{ - zval **num; - char temp[2]; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &num) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(num); - - temp[0] = (char) Z_LVAL_PP(num); - temp[1] = 0; - - RETVAL_STRINGL(temp, 1, 1); -} -/* }}} */ - -/* {{{ proto string ucfirst(string str) - Makes a string's first character uppercase */ -PHP_FUNCTION(ucfirst) -{ - zval **str; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - if (!Z_STRLEN_PP(str)) { - RETURN_EMPTY_STRING(); - } - - ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); - *Z_STRVAL_P(return_value) = toupper((unsigned char) *Z_STRVAL_P(return_value)); -} -/* }}} */ - -/* {{{ proto string ucwords(string str) - Uppercase the first character of every word in a string */ -PHP_FUNCTION(ucwords) -{ - zval **str; - register char *r, *r_end; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - if (!Z_STRLEN_PP(str)) { - RETURN_EMPTY_STRING(); - } - - ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); - r = Z_STRVAL_P(return_value); - - *r = toupper((unsigned char) *r); - for (r_end = r + Z_STRLEN_P(return_value) - 1; r < r_end; ) { - if (isspace((int) *(unsigned char *)r++)) { - *r = toupper((unsigned char) *r); - } - } -} -/* }}} */ - -/* {{{ php_strtr - */ -PHPAPI char *php_strtr(char *str, int len, char *str_from, char *str_to, int trlen) -{ - int i; - unsigned char xlat[256]; - - if ((trlen < 1) || (len < 1)) { - return str; - } - - for (i = 0; i < 256; xlat[i] = i, i++); - - for (i = 0; i < trlen; i++) { - xlat[(unsigned char) str_from[i]] = str_to[i]; - } - - for (i = 0; i < len; i++) { - str[i] = xlat[(unsigned char) str[i]]; - } - - return str; -} -/* }}} */ - -/* {{{ php_strtr_array - */ -static void php_strtr_array(zval *return_value, char *str, int slen, HashTable *hash) -{ - zval **entry; - char *string_key; - uint string_key_len; - zval **trans; - zval ctmp; - ulong num_key; - int minlen = 128*1024; - int maxlen = 0, pos, len, found; - char *key; - HashPosition hpos; - smart_str result = {0}; - - zend_hash_internal_pointer_reset_ex(hash, &hpos); - while (zend_hash_get_current_data_ex(hash, (void **)&entry, &hpos) == SUCCESS) { - switch (zend_hash_get_current_key_ex(hash, &string_key, &string_key_len, &num_key, 0, &hpos)) { - case HASH_KEY_IS_STRING: - len = string_key_len-1; - if (len > maxlen) { - maxlen = len; - } - if (len < minlen) { - minlen = len; - } - break; - - case HASH_KEY_IS_LONG: - Z_TYPE(ctmp) = IS_LONG; - Z_LVAL(ctmp) = num_key; - - convert_to_string(&ctmp); - len = Z_STRLEN(ctmp); - zval_dtor(&ctmp); - - if (len > maxlen) { - maxlen = len; - } - if (len < minlen) { - minlen = len; - } - break; - } - zend_hash_move_forward_ex(hash, &hpos); - } - - key = emalloc(maxlen+1); - pos = 0; - - while (pos < slen) { - if ((pos + maxlen) > slen) { - maxlen = slen - pos; - } - - found = 0; - memcpy(key, str+pos, maxlen); - - for (len = maxlen; len >= minlen; len--) { - key[len] = 0; - - if (zend_hash_find(hash, key, len+1, (void**)&trans) == SUCCESS) { - char *tval; - int tlen; - zval tmp; - - if (Z_TYPE_PP(trans) != IS_STRING) { - tmp = **trans; - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - tval = Z_STRVAL(tmp); - tlen = Z_STRLEN(tmp); - } else { - tval = Z_STRVAL_PP(trans); - tlen = Z_STRLEN_PP(trans); - } - - smart_str_appendl(&result, tval, tlen); - pos += len; - found = 1; - - if (Z_TYPE_PP(trans) != IS_STRING) { - zval_dtor(&tmp); - } - break; - } - } - - if (! found) { - smart_str_appendc(&result, str[pos++]); - } - } - - efree(key); - smart_str_0(&result); - RETVAL_STRINGL(result.c, result.len, 0); -} -/* }}} */ - -/* {{{ proto string strtr(string str, string from, string to) - Translates characters in str using given translation tables */ -PHP_FUNCTION(strtr) -{ - zval **str, **from, **to; - int ac = ZEND_NUM_ARGS(); - - if (ac < 2 || ac > 3 || zend_get_parameters_ex(ac, &str, &from, &to) == FAILURE) { - WRONG_PARAM_COUNT; - } - - if (ac == 2 && Z_TYPE_PP(from) != IS_ARRAY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument is not an array."); - RETURN_FALSE; - } - - convert_to_string_ex(str); - - /* shortcut for empty string */ - if (Z_STRLEN_PP(str) == 0) { - RETURN_EMPTY_STRING(); - } - - if (ac == 2) { - php_strtr_array(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), HASH_OF(*from)); - } else { - convert_to_string_ex(from); - convert_to_string_ex(to); - - ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); - - php_strtr(Z_STRVAL_P(return_value), - Z_STRLEN_P(return_value), - Z_STRVAL_PP(from), - Z_STRVAL_PP(to), - MIN(Z_STRLEN_PP(from), - Z_STRLEN_PP(to))); - } -} -/* }}} */ - -/* {{{ proto string strrev(string str) - Reverse a string */ -PHP_FUNCTION(strrev) -{ - zval **str; - char *s, *e, *n, *p; - - if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &str) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - n = emalloc(Z_STRLEN_PP(str)+1); - p = n; - - s = Z_STRVAL_PP(str); - e = s + Z_STRLEN_PP(str); - - while (--e>=s) { - *p++ = *e; - } - - *p = '\0'; - - RETVAL_STRINGL(n, Z_STRLEN_PP(str), 0); -} -/* }}} */ - -/* {{{ php_similar_str - */ -static void php_similar_str(const char *txt1, int len1, const char *txt2, int len2, int *pos1, int *pos2, int *max) -{ - char *p, *q; - char *end1 = (char *) txt1 + len1; - char *end2 = (char *) txt2 + len2; - int l; - - *max = 0; - for (p = (char *) txt1; p < end1; p++) { - for (q = (char *) txt2; q < end2; q++) { - for (l = 0; (p + l < end1) && (q + l < end2) && (p[l] == q[l]); l++); - if (l > *max) { - *max = l; - *pos1 = p - txt1; - *pos2 = q - txt2; - } - } - } -} -/* }}} */ - -/* {{{ php_similar_char - */ -static int php_similar_char(const char *txt1, int len1, const char *txt2, int len2) -{ - int sum; - int pos1, pos2, max; - - php_similar_str(txt1, len1, txt2, len2, &pos1, &pos2, &max); - if ((sum = max)) { - if (pos1 && pos2) { - sum += php_similar_char(txt1, pos1, - txt2, pos2); - } - if ((pos1 + max < len1) && (pos2 + max < len2)) { - sum += php_similar_char(txt1 + pos1 + max, len1 - pos1 - max, - txt2 + pos2 + max, len2 - pos2 - max); - } - } - - return sum; -} -/* }}} */ - -/* {{{ proto int similar_text(string str1, string str2 [, float percent]) - Calculates the similarity between two strings */ -PHP_FUNCTION(similar_text) -{ - zval **t1, **t2, **percent; - int ac = ZEND_NUM_ARGS(); - int sim; - - if (ac < 2 || ac > 3 || zend_get_parameters_ex(ac, &t1, &t2, &percent) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(t1); - convert_to_string_ex(t2); - - if (ac > 2) { - convert_to_double_ex(percent); - } - - if (Z_STRLEN_PP(t1) + Z_STRLEN_PP(t2) == 0) { - if (ac > 2) { - Z_DVAL_PP(percent) = 0; - } - - RETURN_LONG(0); - } - - sim = php_similar_char(Z_STRVAL_PP(t1), Z_STRLEN_PP(t1), Z_STRVAL_PP(t2), Z_STRLEN_PP(t2)); - - if (ac > 2) { - Z_DVAL_PP(percent) = sim * 200.0 / (Z_STRLEN_PP(t1) + Z_STRLEN_PP(t2)); - } - - RETURN_LONG(sim); -} -/* }}} */ - -/* {{{ php_stripslashes - * - * be careful, this edits the string in-place */ -PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC) -{ - char *s, *t; - int l; - - if (len != NULL) { - l = *len; - } else { - l = strlen(str); - } - s = str; - t = str; - - if (PG(magic_quotes_sybase)) { - while (l > 0) { - if (*t == '\'') { - if ((l > 0) && (t[1] == '\'')) { - t++; - if (len != NULL) { - (*len)--; - } - l--; - } - *s++ = *t++; - } else if (*t == '\\' && l > 0 && t[1] == '0') { - *s++='\0'; - t += 2; - if (len != NULL) { - (*len)--; - } - l--; - } else { - *s++ = *t++; - } - l--; - } - *s = '\0'; - - return; - } - - while (l > 0) { - if (*t == '\\') { - t++; /* skip the slash */ - if (len != NULL) { - (*len)--; - } - l--; - if (l > 0) { - if (*t == '0') { - *s++='\0'; - t++; - } else { - *s++ = *t++; /* preserve the next character */ - } - l--; - } - } else { - if (s != t) { - *s++ = *t++; - } else { - s++; - t++; - } - l--; - } - } - if (s != t) { - *s = '\0'; - } -} -/* }}} */ - -/* {{{ proto string addcslashes(string str, string charlist) - Escapes all chars mentioned in charlist with backslash. It creates octal representations if asked to backslash characters with 8th bit set or with ASCII<32 (except '\n', '\r', '\t' etc...) */ -PHP_FUNCTION(addcslashes) -{ - zval **str, **what; - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &str, &what) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - convert_to_string_ex(what); - - if (Z_STRLEN_PP(str) == 0) { - RETURN_EMPTY_STRING(); - } - - if (Z_STRLEN_PP(what) == 0) { - RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); - } - - RETURN_STRING(php_addcslashes(Z_STRVAL_PP(str), - Z_STRLEN_PP(str), - &Z_STRLEN_P(return_value), 0, - Z_STRVAL_PP(what), - Z_STRLEN_PP(what) TSRMLS_CC), 0); -} -/* }}} */ - -/* {{{ proto string addslashes(string str) - Escapes single quote, double quotes and backslash characters in a string with backslashes */ -PHP_FUNCTION(addslashes) -{ - zval **str; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - if (Z_STRLEN_PP(str) == 0) { - RETURN_EMPTY_STRING(); - } - - RETURN_STRING(php_addslashes(Z_STRVAL_PP(str), - Z_STRLEN_PP(str), - &Z_STRLEN_P(return_value), 0 - TSRMLS_CC), 0); -} -/* }}} */ - -/* {{{ proto string stripcslashes(string str) - Strips backslashes from a string. Uses C-style conventions */ -PHP_FUNCTION(stripcslashes) -{ - zval **str; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); - php_stripcslashes(Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value)); -} -/* }}} */ - -/* {{{ proto string stripslashes(string str) - Strips backslashes from a string */ -PHP_FUNCTION(stripslashes) -{ - zval **str; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(str); - - ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); - php_stripslashes(Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value) TSRMLS_CC); -} -/* }}} */ - -#ifndef HAVE_STRERROR -/* {{{ php_strerror - */ -char *php_strerror(int errnum) -{ - extern int sys_nerr; - extern char *sys_errlist[]; - TSRMLS_FETCH(); - - if ((unsigned int) errnum < sys_nerr) { - return(sys_errlist[errnum]); - } - - (void) sprintf(BG(str_ebuf), "Unknown error: %d", errnum); - return(BG(str_ebuf)); -} -/* }}} */ -#endif - -/* {{{ php_stripcslashes - */ -PHPAPI void php_stripcslashes(char *str, int *len) -{ - char *source, *target, *end; - int nlen = *len, i; - char numtmp[4]; - - for (source=str, end=str+nlen, target=str; source < end; source++) { - if (*source == '\\' && source+1 < end) { - source++; - switch (*source) { - case 'n': *target++='\n'; nlen--; break; - case 'r': *target++='\r'; nlen--; break; - case 'a': *target++='\a'; nlen--; break; - case 't': *target++='\t'; nlen--; break; - case 'v': *target++='\v'; nlen--; break; - case 'b': *target++='\b'; nlen--; break; - case 'f': *target++='\f'; nlen--; break; - case '\\': *target++='\\'; nlen--; break; - case 'x': - if (source+1 < end && isxdigit((int)(*(source+1)))) { - numtmp[0] = *++source; - if (source+1 < end && isxdigit((int)(*(source+1)))) { - numtmp[1] = *++source; - numtmp[2] = '\0'; - nlen-=3; - } else { - numtmp[1] = '\0'; - nlen-=2; - } - *target++=(char)strtol(numtmp, NULL, 16); - break; - } - /* break is left intentionally */ - default: - i=0; - while (source < end && *source >= '0' && *source <= '7' && i<3) { - numtmp[i++] = *source++; - } - if (i) { - numtmp[i]='\0'; - *target++=(char)strtol(numtmp, NULL, 8); - nlen-=i; - source--; - } else { - *target++=*source; - nlen--; - } - } - } else { - *target++=*source; - } - } - - if (nlen != 0) { - *target='\0'; - } - - *len = nlen; -} -/* }}} */ - -/* {{{ php_addcslashes - */ -PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int should_free, char *what, int wlength TSRMLS_DC) -{ - char flags[256]; - char *new_str = emalloc((length?length:(length=strlen(str)))*4+1); - char *source, *target; - char *end; - char c; - int newlen; - - if (!wlength) { - wlength = strlen(what); - } - - if (!length) { - length = strlen(str); - } - - php_charmask(what, wlength, flags TSRMLS_CC); - - for (source = str, end = source + length, target = new_str; (c = *source) || (source < end); source++) { - if (flags[(unsigned char)c]) { - if ((unsigned char) c < 32 || (unsigned char) c > 126) { - *target++ = '\\'; - switch (c) { - case '\n': *target++ = 'n'; break; - case '\t': *target++ = 't'; break; - case '\r': *target++ = 'r'; break; - case '\a': *target++ = 'a'; break; - case '\v': *target++ = 'v'; break; - case '\b': *target++ = 'b'; break; - case '\f': *target++ = 'f'; break; - default: target += sprintf(target, "%03o", (unsigned char) c); - } - continue; - } - *target++ = '\\'; - } - *target++ = c; - } - *target = 0; - newlen = target - new_str; - if (target - new_str < length * 4) { - new_str = erealloc(new_str, newlen + 1); - } - if (new_length) { - *new_length = newlen; - } - if (should_free) { - STR_FREE(str); - } - return new_str; -} -/* }}} */ - -/* {{{ php_addslashes - */ -PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_free TSRMLS_DC) -{ - /* maximum string length, worst case situation */ - char *new_str; - char *source, *target; - char *end; - int local_new_length; - - if (!new_length) { - new_length = &local_new_length; - } - if (!str) { - *new_length = 0; - return str; - } - new_str = (char *) emalloc((length ? length : (length = strlen(str))) * 2 + 1); - source = str; - end = source + length; - target = new_str; - - if (PG(magic_quotes_sybase)) { - while (source < end) { - switch (*source) { - case '\0': - *target++ = '\\'; - *target++ = '0'; - break; - case '\'': - *target++ = '\''; - *target++ = '\''; - break; - default: - *target++ = *source; - break; - } - source++; - } - } else { - while (source < end) { - switch (*source) { - case '\0': - *target++ = '\\'; - *target++ = '0'; - break; - case '\'': - case '\"': - case '\\': - *target++ = '\\'; - /* break is missing *intentionally* */ - default: - *target++ = *source; - break; - } - - source++; - } - } - - *target = 0; - *new_length = target - new_str; - if (should_free) { - STR_FREE(str); - } - new_str = (char *) erealloc(new_str, *new_length + 1); - return new_str; -} -/* }}} */ - -#define _HEB_BLOCK_TYPE_ENG 1 -#define _HEB_BLOCK_TYPE_HEB 2 -#define isheb(c) (((((unsigned char) c) >= 224) && (((unsigned char) c) <= 250)) ? 1 : 0) -#define _isblank(c) (((((unsigned char) c) == ' ' || ((unsigned char) c) == '\t')) ? 1 : 0) -#define _isnewline(c) (((((unsigned char) c) == '\n' || ((unsigned char) c) == '\r')) ? 1 : 0) - -/* {{{ php_char_to_str - */ -PHPAPI int php_char_to_str(char *str, uint len, char from, char *to, int to_len, zval *result) -{ - int char_count = 0; - int replaced = 0; - char *source, *target, *tmp, *source_end=str+len, *tmp_end = NULL; - - for (source = str; source < source_end; source++) { - if (*source == from) { - char_count++; - } - } - - if (char_count == 0) { - ZVAL_STRINGL(result, str, len, 1); - return 0; - } - - Z_STRLEN_P(result) = len + (char_count * (to_len - 1)); - Z_STRVAL_P(result) = target = emalloc(Z_STRLEN_P(result) + 1); - Z_TYPE_P(result) = IS_STRING; - - for (source = str; source < source_end; source++) { - if (*source == from) { - replaced = 1; - for (tmp = to, tmp_end = tmp+to_len; tmp < tmp_end; tmp++) { - *target = *tmp; - target++; - } - } else { - *target = *source; - target++; - } - } - *target = 0; - return replaced; -} -/* }}} */ - -/* {{{ php_str_to_str_ex - */ -PHPAPI char *php_str_to_str_ex(char *haystack, int length, - char *needle, int needle_len, char *str, int str_len, int *_new_length, int case_sensitivity) -{ - char *new_str; - - if (needle_len < length) { - char *end, *haystack_dup, *needle_dup; - char *e, *s, *p, *r; - - if (needle_len == str_len) { - new_str = estrndup(haystack, length); - *_new_length = length; - - if (case_sensitivity) { - end = new_str + length; - for (p = new_str; (r = php_memnstr(p, needle, needle_len, end)); p = r + needle_len) { - memcpy(r, str, str_len); - } - } else { - haystack_dup = estrndup(haystack, length); - needle_dup = estrndup(needle, needle_len); - php_strtolower(haystack_dup, length); - php_strtolower(needle_dup, needle_len); - end = haystack_dup + length; - for (p = haystack_dup; (r = php_memnstr(p, needle_dup, needle_len, end)); p = r + needle_len) { - memcpy(new_str + (r - haystack_dup), str, str_len); - } - efree(haystack_dup); - efree(needle_dup); - } - return new_str; - } else { - if (str_len < needle_len) { - new_str = emalloc(length + 1); - } else { - new_str = emalloc((length / needle_len + 1) * str_len); - } - - e = s = new_str; - - if (case_sensitivity) { - end = haystack + length; - for (p = haystack; (r = php_memnstr(p, needle, needle_len, end)); p = r + needle_len) { - memcpy(e, p, r - p); - e += r - p; - memcpy(e, str, str_len); - e += str_len; - } - - if (p < end) { - memcpy(e, p, end - p); - e += end - p; - } - } else { - haystack_dup = estrndup(haystack, length); - needle_dup = estrndup(needle, needle_len); - php_strtolower(haystack_dup, length); - php_strtolower(needle_dup, needle_len); - - end = haystack_dup + length; - - for (p = haystack_dup; (r = php_memnstr(p, needle_dup, needle_len, end)); p = r + needle_len) { - memcpy(e, haystack + (p - haystack_dup), r - p); - e += r - p; - memcpy(e, str, str_len); - e += str_len; - } - - if (p < end) { - memcpy(e, haystack + (p - haystack_dup), end - p); - e += end - p; - } - efree(haystack_dup); - efree(needle_dup); - } - - *e = '\0'; - *_new_length = e - s; - - new_str = erealloc(new_str, *_new_length + 1); - return new_str; - } - } else if (needle_len > length) { -nothing_todo: - *_new_length = length; - new_str = estrndup(haystack, length); - return new_str; - } else { - if (case_sensitivity ? strncmp(haystack, needle, length) : strncasecmp(haystack, needle, length)) { - goto nothing_todo; - } else { - *_new_length = str_len; - new_str = estrndup(str, str_len); - return new_str; - } - } - -} -/* }}} */ - -/* {{{ php_str_to_str - */ -PHPAPI char *php_str_to_str(char *haystack, int length, - char *needle, int needle_len, char *str, int str_len, int *_new_length) -{ - return php_str_to_str_ex(haystack, length, needle, needle_len, str, str_len, _new_length, 1); -} -/* }}} - */ - -/* {{{ php_str_replace_in_subject - */ -static void php_str_replace_in_subject(zval *search, zval *replace, zval **subject, zval *result, int case_sensitivity) -{ - zval **search_entry, - **replace_entry = NULL, - temp_result; - char *replace_value = NULL; - int replace_len = 0; - - /* Make sure we're dealing with strings. */ - convert_to_string_ex(subject); - Z_TYPE_P(result) = IS_STRING; - if (Z_STRLEN_PP(subject) == 0) { - ZVAL_STRINGL(result, empty_string, 0, 1); - return; - } - - /* If search is an array */ - if (Z_TYPE_P(search) == IS_ARRAY) { - /* Duplicate subject string for repeated replacement */ - *result = **subject; - zval_copy_ctor(result); - INIT_PZVAL(result); - - zend_hash_internal_pointer_reset(Z_ARRVAL_P(search)); - - if (Z_TYPE_P(replace) == IS_ARRAY) { - zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace)); - } else { - /* Set replacement value to the passed one */ - replace_value = Z_STRVAL_P(replace); - replace_len = Z_STRLEN_P(replace); - } - - /* For each entry in the search array, get the entry */ - while (zend_hash_get_current_data(Z_ARRVAL_P(search), (void **) &search_entry) == SUCCESS) { - /* Make sure we're dealing with strings. */ - SEPARATE_ZVAL(search_entry); - convert_to_string(*search_entry); - if (Z_STRLEN_PP(search_entry) == 0) { - zend_hash_move_forward(Z_ARRVAL_P(search)); - continue; - } - - /* If replace is an array. */ - if (Z_TYPE_P(replace) == IS_ARRAY) { - /* Get current entry */ - if (zend_hash_get_current_data(Z_ARRVAL_P(replace), (void **)&replace_entry) == SUCCESS) { - /* Make sure we're dealing with strings. */ - convert_to_string_ex(replace_entry); - - /* Set replacement value to the one we got from array */ - replace_value = Z_STRVAL_PP(replace_entry); - replace_len = Z_STRLEN_PP(replace_entry); - - zend_hash_move_forward(Z_ARRVAL_P(replace)); - } else { - /* We've run out of replacement strings, so use an empty one. */ - replace_value = empty_string; - replace_len = 0; - } - } - - if (Z_STRLEN_PP(search_entry) == 1) { - php_char_to_str(Z_STRVAL_P(result), - Z_STRLEN_P(result), - Z_STRVAL_PP(search_entry)[0], - replace_value, - replace_len, - &temp_result); - } else if (Z_STRLEN_PP(search_entry) > 1) { - Z_STRVAL(temp_result) = php_str_to_str_ex(Z_STRVAL_P(result), Z_STRLEN_P(result), - Z_STRVAL_PP(search_entry), Z_STRLEN_PP(search_entry), - replace_value, replace_len, &Z_STRLEN(temp_result), case_sensitivity); - } - - efree(Z_STRVAL_P(result)); - Z_STRVAL_P(result) = Z_STRVAL(temp_result); - Z_STRLEN_P(result) = Z_STRLEN(temp_result); - - if (Z_STRLEN_P(result) == 0) { - return; - } - - zend_hash_move_forward(Z_ARRVAL_P(search)); - } - } else { - if (Z_STRLEN_P(search) == 1) { - php_char_to_str(Z_STRVAL_PP(subject), - Z_STRLEN_PP(subject), - Z_STRVAL_P(search)[0], - Z_STRVAL_P(replace), - Z_STRLEN_P(replace), - result); - } else if (Z_STRLEN_P(search) > 1) { - Z_STRVAL_P(result) = php_str_to_str_ex(Z_STRVAL_PP(subject), Z_STRLEN_PP(subject), - Z_STRVAL_P(search), Z_STRLEN_P(search), - Z_STRVAL_P(replace), Z_STRLEN_P(replace), &Z_STRLEN_P(result), case_sensitivity); - } else { - *result = **subject; - zval_copy_ctor(result); - INIT_PZVAL(result); - } - } -} -/* }}} */ - -/* {{{ php_str_replace_common - */ -static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensitivity) -{ - zval **subject, **search, **replace, **subject_entry; - zval *result; - char *string_key; - uint string_key_len; - ulong num_key; - - if (ZEND_NUM_ARGS() != 3 || - zend_get_parameters_ex(3, &search, &replace, &subject) == FAILURE) { - WRONG_PARAM_COUNT; - } - - SEPARATE_ZVAL(search); - SEPARATE_ZVAL(replace); - SEPARATE_ZVAL(subject); - - /* Make sure we're dealing with strings and do the replacement. */ - if (Z_TYPE_PP(search) != IS_ARRAY) { - convert_to_string_ex(search); - convert_to_string_ex(replace); - } else if (Z_TYPE_PP(replace) != IS_ARRAY) { - convert_to_string_ex(replace); - } - - /* if subject is an array */ - if (Z_TYPE_PP(subject) == IS_ARRAY) { - array_init(return_value); - zend_hash_internal_pointer_reset(Z_ARRVAL_PP(subject)); - - /* For each subject entry, convert it to string, then perform replacement - and add the result to the return_value array. */ - while (zend_hash_get_current_data(Z_ARRVAL_PP(subject), (void **)&subject_entry) == SUCCESS) { - MAKE_STD_ZVAL(result); - php_str_replace_in_subject(*search, *replace, subject_entry, result, case_sensitivity); - /* Add to return array */ - switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key, - &string_key_len, &num_key, 0, NULL)) { - case HASH_KEY_IS_STRING: - add_assoc_zval_ex(return_value, string_key, string_key_len, result); - break; - - case HASH_KEY_IS_LONG: - add_index_zval(return_value, num_key, result); - break; - } - - zend_hash_move_forward(Z_ARRVAL_PP(subject)); - } - } else { /* if subject is not an array */ - php_str_replace_in_subject(*search, *replace, subject, return_value, case_sensitivity); - } -} -/* }}} */ - -/* {{{ proto mixed str_replace(mixed search, mixed replace, mixed subject) - Replaces all occurrences of search in haystack with replace */ -PHP_FUNCTION(str_replace) -{ - php_str_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ proto mixed str_ireplace(mixed search, mixed replace, mixed subject) - Replaces all occurrences of search in haystack with replace / case-insensitive */ -PHP_FUNCTION(str_ireplace) -{ - php_str_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ php_hebrev - * - * Converts Logical Hebrew text (Hebrew Windows style) to Visual text - * Cheers/complaints/flames - Zeev Suraski <zeev@php.net> - */ -static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, int convert_newlines) -{ - zval **str, **max_chars_per_line; - char *heb_str, *tmp, *target, *broken_str; - int block_start, block_end, block_type, block_length, i; - long max_chars=0; - int begin, end, char_count, orig_begin; - - - switch (ZEND_NUM_ARGS()) { - case 1: - if (zend_get_parameters_ex(1, &str) == FAILURE) { - RETURN_FALSE; - } - break; - case 2: - if (zend_get_parameters_ex(2, &str, &max_chars_per_line) == FAILURE) { - RETURN_FALSE; - } - convert_to_long_ex(max_chars_per_line); - max_chars = Z_LVAL_PP(max_chars_per_line); - break; - default: - WRONG_PARAM_COUNT; - break; - } - - convert_to_string_ex(str); - - if (Z_STRLEN_PP(str) == 0) { - RETURN_FALSE; - } - - tmp = Z_STRVAL_PP(str); - block_start=block_end=0; - - heb_str = (char *) emalloc(Z_STRLEN_PP(str)+1); - target = heb_str+Z_STRLEN_PP(str); - *target = 0; - target--; - - block_length=0; - - if (isheb(*tmp)) { - block_type = _HEB_BLOCK_TYPE_HEB; - } else { - block_type = _HEB_BLOCK_TYPE_ENG; - } - - do { - if (block_type == _HEB_BLOCK_TYPE_HEB) { - while ((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end<Z_STRLEN_PP(str)-1) { - tmp++; - block_end++; - block_length++; - } - for (i = block_start; i<= block_end; i++) { - *target = Z_STRVAL_PP(str)[i]; - switch (*target) { - case '(': - *target = ')'; - break; - case ')': - *target = '('; - break; - case '[': - *target = ']'; - break; - case ']': - *target = '['; - break; - case '{': - *target = '}'; - break; - case '}': - *target = '{'; - break; - case '<': - *target = '>'; - break; - case '>': - *target = '<'; - break; - case '\\': - *target = '/'; - break; - case '/': - *target = '\\'; - break; - default: - break; - } - target--; - } - block_type = _HEB_BLOCK_TYPE_ENG; - } else { - while (!isheb(*(tmp+1)) && (int)*(tmp+1)!='\n' && block_end < Z_STRLEN_PP(str)-1) { - tmp++; - block_end++; - block_length++; - } - while ((_isblank((int)*tmp) || ispunct((int)*tmp)) && *tmp!='/' && *tmp!='-' && block_end > block_start) { - tmp--; - block_end--; - } - for (i = block_end; i >= block_start; i--) { - *target = Z_STRVAL_PP(str)[i]; - target--; - } - block_type = _HEB_BLOCK_TYPE_HEB; - } - block_start=block_end+1; - } while (block_end < Z_STRLEN_PP(str)-1); - - - broken_str = (char *) emalloc(Z_STRLEN_PP(str)+1); - begin=end=Z_STRLEN_PP(str)-1; - target = broken_str; - - while (1) { - char_count=0; - while ((!max_chars || char_count < max_chars) && begin > 0) { - char_count++; - begin--; - if (begin <= 0 || _isnewline(heb_str[begin])) { - while (begin > 0 && _isnewline(heb_str[begin-1])) { - begin--; - char_count++; - } - break; - } - } - if (char_count == max_chars) { /* try to avoid breaking words */ - int new_char_count=char_count, new_begin=begin; - - while (new_char_count > 0) { - if (_isblank(heb_str[new_begin]) || _isnewline(heb_str[new_begin])) { - break; - } - new_begin++; - new_char_count--; - } - if (new_char_count > 0) { - char_count=new_char_count; - begin=new_begin; - } - } - orig_begin=begin; - - if (_isblank(heb_str[begin])) { - heb_str[begin]='\n'; - } - while (begin <= end && _isnewline(heb_str[begin])) { /* skip leading newlines */ - begin++; - } - for (i = begin; i <= end; i++) { /* copy content */ - *target = heb_str[i]; - target++; - } - for (i = orig_begin; i <= end && _isnewline(heb_str[i]); i++) { - *target = heb_str[i]; - target++; - } - begin=orig_begin; - - if (begin <= 0) { - *target = 0; - break; - } - begin--; - end=begin; - } - efree(heb_str); - - if (convert_newlines) { - php_char_to_str(broken_str, Z_STRLEN_PP(str),'\n', "<br />\n", 7, return_value); - efree(broken_str); - } else { - Z_STRVAL_P(return_value) = broken_str; - Z_STRLEN_P(return_value) = Z_STRLEN_PP(str); - Z_TYPE_P(return_value) = IS_STRING; - } -} -/* }}} */ - -/* {{{ proto string hebrev(string str [, int max_chars_per_line]) - Converts logical Hebrew text to visual text */ -PHP_FUNCTION(hebrev) -{ - php_hebrev(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ proto string hebrevc(string str [, int max_chars_per_line]) - Converts logical Hebrew text to visual text with newline conversion */ -PHP_FUNCTION(hebrevc) -{ - php_hebrev(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - - -/* {{{ proto string nl2br(string str) - Converts newlines to HTML line breaks */ -PHP_FUNCTION(nl2br) -{ - /* in brief this inserts <br /> before matched regexp \n\r?|\r\n? */ - zval **zstr; - char *tmp, *str; - int new_length; - char *end, *target; - int repl_cnt = 0; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &zstr) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(zstr); - - str = Z_STRVAL_PP(zstr); - end = str + Z_STRLEN_PP(zstr); - - /* it is really faster to scan twice and allocate mem once insted scanning once - and constantly reallocing */ - while (str < end) { - if (*str == '\r') { - if (*(str+1) == '\n') { - str++; - } - repl_cnt++; - } else if (*str == '\n') { - if (*(str+1) == '\r') { - str++; - } - repl_cnt++; - } - - str++; - } - - if (repl_cnt == 0) { - RETURN_STRINGL(Z_STRVAL_PP(zstr), Z_STRLEN_PP(zstr), 1); - } - - new_length = Z_STRLEN_PP(zstr) + repl_cnt * (sizeof("<br />") - 1); - tmp = target = emalloc(new_length + 1); - - str = Z_STRVAL_PP(zstr); - - while (str < end) { - switch (*str) { - case '\r': - case '\n': - *target++ = '<'; - *target++ = 'b'; - *target++ = 'r'; - *target++ = ' '; - *target++ = '/'; - *target++ = '>'; - - if ((*str == '\r' && *(str+1) == '\n') || (*str == '\n' && *(str+1) == '\r')) { - *target++ = *str++; - } - /* lack of a break; is intentional */ - default: - *target++ = *str; - } - - str++; - } - - *target = '\0'; - - RETURN_STRINGL(tmp, new_length, 0); -} -/* }}} */ - - -/* {{{ proto string strip_tags(string str [, string allowable_tags]) - Strips HTML and PHP tags from a string */ -PHP_FUNCTION(strip_tags) -{ - char *buf; - zval **str, **allow=NULL; - char *allowed_tags=NULL; - int allowed_tags_len=0; - size_t retval_len; - - switch (ZEND_NUM_ARGS()) { - case 1: - if (zend_get_parameters_ex(1, &str) == FAILURE) { - RETURN_FALSE; - } - break; - case 2: - if (zend_get_parameters_ex(2, &str, &allow) == FAILURE) { - RETURN_FALSE; - } - convert_to_string_ex(allow); - allowed_tags = Z_STRVAL_PP(allow); - allowed_tags_len = Z_STRLEN_PP(allow); - break; - default: - WRONG_PARAM_COUNT; - break; - } - convert_to_string_ex(str); - buf = estrndup(Z_STRVAL_PP(str), Z_STRLEN_PP(str)); - retval_len = php_strip_tags(buf, Z_STRLEN_PP(str), NULL, allowed_tags, allowed_tags_len); - RETURN_STRINGL(buf, retval_len, 0); -} -/* }}} */ - -/* {{{ proto string setlocale(mixed category, string locale [, string ...]) - Set locale information */ -PHP_FUNCTION(setlocale) -{ - pval ***args = (pval ***) emalloc(sizeof(pval **)*ZEND_NUM_ARGS()); - zval **pcategory, **plocale; - int i, cat, n_args=ZEND_NUM_ARGS(); - char *loc, *retval; - - if (zend_get_parameters_array_ex(n_args, args) == FAILURE || n_args < 2) { - efree(args); - WRONG_PARAM_COUNT; - } -#ifdef HAVE_SETLOCALE - pcategory = args[0]; - if (Z_TYPE_PP(pcategory) == IS_LONG) { - convert_to_long_ex(pcategory); - cat = Z_LVAL_PP(pcategory); - } else { /* FIXME: The following behaviour should be removed. */ - char *category; - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passing locale category name as string is deprecated. Use the LC_* -constants instead."); - convert_to_string_ex(pcategory); - category = Z_STRVAL_P(*pcategory); - - if (!strcasecmp ("LC_ALL", category)) - cat = LC_ALL; - else if (!strcasecmp ("LC_COLLATE", category)) - cat = LC_COLLATE; - else if (!strcasecmp ("LC_CTYPE", category)) - cat = LC_CTYPE; -#ifdef LC_MESSAGES - else if (!strcasecmp ("LC_MESSAGES", category)) - cat = LC_MESSAGES; -#endif - else if (!strcasecmp ("LC_MONETARY", category)) - cat = LC_MONETARY; - else if (!strcasecmp ("LC_NUMERIC", category)) - cat = LC_NUMERIC; - else if (!strcasecmp ("LC_TIME", category)) - cat = LC_TIME; - else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid locale category name %s, must be one of LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, or LC_TIME.", category); - efree(args); - RETURN_FALSE; - } - } - - if (Z_TYPE_PP(args[1]) == IS_ARRAY) { - zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args[1])); - i=0; /* not needed in this case: only kill a compiler warning */ - } else { - i=1; - } - while (1) { - if (Z_TYPE_PP(args[1]) == IS_ARRAY) { - zend_hash_get_current_data(Z_ARRVAL_PP(args[1]),(void **)&plocale); - } else { - plocale = args[i]; - } - - convert_to_string_ex(plocale); - - if (!strcmp ("0", Z_STRVAL_PP(plocale))) { - loc = NULL; - } else { - loc = Z_STRVAL_PP(plocale); - } - - retval = setlocale (cat, loc); - if (retval) { - /* Remember if locale was changed */ - if (loc) { - STR_FREE(BG(locale_string)); - BG(locale_string) = estrdup(retval); - } - - efree(args); - RETVAL_STRING(retval, 1); - - if (cat == LC_NUMERIC || cat == LC_ALL) { - struct lconv lc; - localeconv_r(&lc); - - EG(float_separator)[0] = (lc.decimal_point)[0]; - - if ((lc.decimal_point)[0] != '.') { - /* set locale back to C */ - setlocale(LC_NUMERIC, "C"); - } - } - - return; - } - - if (Z_TYPE_PP(args[1]) == IS_ARRAY) { - if (zend_hash_move_forward(Z_ARRVAL_PP(args[1])) == FAILURE) break; - } else { - if (++i >= n_args) break; - } - } - -#endif - efree(args); - - RETURN_FALSE; -} -/* }}} */ - -/* {{{ proto void parse_str(string encoded_string [, array result]) - Parses GET/POST/COOKIE data and sets global variables */ -PHP_FUNCTION(parse_str) -{ - zval **arg; - zval **arrayArg; - zval *sarg; - char *res = NULL; - int argCount; - int old_rg; - - argCount = ZEND_NUM_ARGS(); - if (argCount < 1 || argCount > 2 || zend_get_parameters_ex(argCount, &arg, &arrayArg) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(arg); - sarg = *arg; - if (Z_STRVAL_P(sarg) && *Z_STRVAL_P(sarg)) { - res = estrndup(Z_STRVAL_P(sarg), Z_STRLEN_P(sarg)); - } - - old_rg = PG(register_globals); - if (argCount == 1) { - PG(register_globals) = 1; - sapi_module.treat_data(PARSE_STRING, res, NULL TSRMLS_CC); - } else { - PG(register_globals) = 0; - /* Clear out the array that was passed in. */ - zval_dtor(*arrayArg); - array_init(*arrayArg); - - sapi_module.treat_data(PARSE_STRING, res, *arrayArg TSRMLS_CC); - } - PG(register_globals) = old_rg; -} -/* }}} */ - -#define PHP_TAG_BUF_SIZE 1023 - -/* {{{ php_tag_find - * - * Check if tag is in a set of tags - * - * states: - * - * 0 start tag - * 1 first non-whitespace char seen - */ -int php_tag_find(char *tag, int len, char *set) { - char c, *n, *t; - int state=0, done=0; - char *norm = emalloc(len+1); - - n = norm; - t = tag; - c = tolower(*t); - /* - normalize the tag removing leading and trailing whitespace - and turn any <a whatever...> into just <a> and any </tag> - into <tag> - */ - if (!len) { - return 0; - } - while (!done) { - switch (c) { - case '<': - *(n++) = c; - break; - case '>': - done =1; - break; - default: - if (!isspace((int)c)) { - if (state == 0) { - state=1; - if (c != '/') - *(n++) = c; - } else { - *(n++) = c; - } - } else { - if (state == 1) - done=1; - } - break; - } - c = tolower(*(++t)); - } - *(n++) = '>'; - *n = '\0'; - if (strstr(set, norm)) { - done=1; - } else { - done=0; - } - efree(norm); - return done; -} -/* }}} */ - -/* {{{ php_strip_tags - - A simple little state-machine to strip out html and php tags - - State 0 is the output state, State 1 means we are inside a - normal html tag and state 2 means we are inside a php tag. - - The state variable is passed in to allow a function like fgetss - to maintain state across calls to the function. - - lc holds the last significant character read and br is a bracket - counter. - - When an allow string is passed in we keep track of the string - in state 1 and when the tag is closed check it against the - allow string to see if we should allow it. - - swm: Added ability to strip <?xml tags without assuming it PHP - code. -*/ -PHPAPI size_t php_strip_tags(char *rbuf, int len, int *stateptr, char *allow, int allow_len) -{ - char *tbuf, *buf, *p, *tp, *rp, c, lc; - int br, i=0, depth=0; - int state = 0; - - if (stateptr) - state = *stateptr; - - buf = estrndup(rbuf, len); - c = *buf; - lc = '\0'; - p = buf; - rp = rbuf; - br = 0; - if (allow) { - php_strtolower(allow, allow_len); - tbuf = emalloc(PHP_TAG_BUF_SIZE+1); - tp = tbuf; - } else { - tbuf = tp = NULL; - } - - while (i < len) { - switch (c) { - case '<': - if (isspace(*(p + 1))) { - goto reg_char; - } - if (state == 0) { - lc = '<'; - state = 1; - if (allow) { - *(tp++) = '<'; - } - } else if (state == 1) { - depth++; - } - break; - - case '(': - if (state == 2) { - if (lc != '"' && lc != '\'') { - lc = '('; - br++; - } - } else if (allow && state == 1) { - *(tp++) = c; - } else if (state == 0) { - *(rp++) = c; - } - break; - - case ')': - if (state == 2) { - if (lc != '"' && lc != '\'') { - lc = ')'; - br--; - } - } else if (allow && state == 1) { - *(tp++) = c; - } else if (state == 0) { - *(rp++) = c; - } - break; - - case '>': - if (depth) { - depth--; - break; - } - - switch (state) { - case 1: /* HTML/XML */ - lc = '>'; - state = 0; - if (allow) { - *(tp++) = '>'; - *tp='\0'; - if (php_tag_find(tbuf, tp-tbuf, allow)) { - memcpy(rp, tbuf, tp-tbuf); - rp += tp-tbuf; - } - tp = tbuf; - } - break; - - case 2: /* PHP */ - if (!br && lc != '\"' && *(p-1) == '?') { - state = 0; - tp = tbuf; - } - break; - - case 3: /* JavaScript/CSS/etc... */ - if (*(p-1) == '-' && *(p-2) == '-') { - state = 0; - tp = tbuf; - } - break; - - default: - *(rp++) = c; - break; - } - break; - - case '"': - case '\'': - if (state == 2 && *(p-1) != '\\') { - if (lc == c) { - lc = '\0'; - } else if (lc != '\\') { - lc = c; - } - } else if (state == 0) { - *(rp++) = c; - } else if (allow && state == 1) { - *(tp++) = c; - } - break; - - case '!': - /* JavaScript & Other HTML scripting languages */ - if (state == 1 && *(p-1) == '<') { - state = 3; - lc = c; - } else { - if (state == 0) { - *(rp++) = c; - } else if (allow && state == 1) { - *(tp++) = c; - if ( (tp-tbuf) >= PHP_TAG_BUF_SIZE ) { - /* prevent buffer overflows */ - tp = tbuf; - } - } - } - break; - - case '?': - - if (state == 1 && *(p-1)=='<') { - br=0; - state=2; - break; - } - - case 'E': - case 'e': - /* !DOCTYPE exception */ - if (state==3 && p > buf+6 - && tolower(*(p-1)) == 'p' - && tolower(*(p-2)) == 'y' - && tolower(*(p-3)) == 't' - && tolower(*(p-4)) == 'c' - && tolower(*(p-5)) == 'o' - && tolower(*(p-6)) == 'd') { - state = 1; - break; - } - /* fall-through */ - - case 'l': - - /* swm: If we encounter '<?xml' then we shouldn't be in - * state == 2 (PHP). Switch back to HTML. - */ - - if (state == 2 && p > buf+2 && *(p-1) == 'm' && *(p-2) == 'x') { - state = 1; - break; - } - - /* fall-through */ - default: -reg_char: - if (state == 0) { - *(rp++) = c; - } else if (allow && state == 1) { - *(tp++) = c; - if ( (tp-tbuf) >= PHP_TAG_BUF_SIZE ) { /* no buffer overflows */ - tp = tbuf; - } - } - break; - } - c = *(++p); - i++; - } - if (rp < rbuf + len) { - *rp = '\0'; - } - efree(buf); - if (allow) - efree(tbuf); - if (stateptr) - *stateptr = state; - - return (size_t)(rp - rbuf); -} -/* }}} */ - -/* {{{ proto string str_repeat(string input, int mult) - Returns the input string repeat mult times */ -PHP_FUNCTION(str_repeat) -{ - zval **input_str; /* Input string */ - zval **mult; /* Multiplier */ - char *result; /* Resulting string */ - int result_len; /* Length of the resulting string */ - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) { - WRONG_PARAM_COUNT; - } - - /* Make sure we're dealing with proper types */ - convert_to_string_ex(input_str); - convert_to_long_ex(mult); - - if (Z_LVAL_PP(mult) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument has to be greater than or equal to 0."); - return; - } - - /* Don't waste our time if it's empty */ - if (Z_STRLEN_PP(input_str) == 0) - RETURN_STRINGL(empty_string, 0, 1); - - /* ... or if the multiplier is zero */ - if (Z_LVAL_PP(mult) == 0) - RETURN_STRINGL(empty_string, 0, 1); - - /* Initialize the result string */ - result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult); - result = (char *)emalloc(result_len + 1); - - /* Heavy optimization for situations where input string is 1 byte long */ - if (Z_STRLEN_PP(input_str) == 1) { - memset(result, *(Z_STRVAL_PP(input_str)), Z_LVAL_PP(mult)); - } else { - char *s, *e, *ee; - int l=0; - memcpy(result, Z_STRVAL_PP(input_str), Z_STRLEN_PP(input_str)); - s = result; - e = result + Z_STRLEN_PP(input_str); - ee = result + result_len; - - while (e<ee) { - l = (e-s) < (ee-e) ? (e-s) : (ee-e); - memmove(e, s, l); - e += l; - } - } - - result[result_len] = '\0'; - - RETURN_STRINGL(result, result_len, 0); -} -/* }}} */ - -/* {{{ proto mixed count_chars(string input [, int mode]) - Returns info about what characters are used in input */ -PHP_FUNCTION(count_chars) -{ - zval **input, **mode; - int chars[256]; - int ac=ZEND_NUM_ARGS(); - int mymode=0; - unsigned char *buf; - int len, inx; - char retstr[256]; - int retlen=0; - - if (ac < 1 || ac > 2 || zend_get_parameters_ex(ac, &input, &mode) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(input); - - if (ac == 2) { - convert_to_long_ex(mode); - mymode = Z_LVAL_PP(mode); - - if (mymode < 0 || mymode > 4) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown mode."); - RETURN_FALSE; - } - } - - len = Z_STRLEN_PP(input); - buf = (unsigned char *) Z_STRVAL_PP(input); - memset((void*) chars, 0, sizeof(chars)); - - while (len > 0) { - chars[*buf]++; - buf++; - len--; - } - - if (mymode < 3) { - array_init(return_value); - } - - for (inx = 0; inx < 256; inx++) { - switch (mymode) { - case 0: - add_index_long(return_value, inx, chars[inx]); - break; - case 1: - if (chars[inx] != 0) { - add_index_long(return_value, inx, chars[inx]); - } - break; - case 2: - if (chars[inx] == 0) { - add_index_long(return_value, inx, chars[inx]); - } - break; - case 3: - if (chars[inx] != 0) { - retstr[retlen++] = inx; - } - break; - case 4: - if (chars[inx] == 0) { - retstr[retlen++] = inx; - } - break; - } - } - - if (mymode >= 3 && mymode <= 4) { - RETURN_STRINGL(retstr, retlen, 1); - } -} -/* }}} */ - -/* {{{ php_strnatcmp - */ -static void php_strnatcmp(INTERNAL_FUNCTION_PARAMETERS, int fold_case) -{ - zval **s1, **s2; - - if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(s1); - convert_to_string_ex(s2); - - RETURN_LONG(strnatcmp_ex(Z_STRVAL_PP(s1), Z_STRLEN_PP(s1), - Z_STRVAL_PP(s2), Z_STRLEN_PP(s2), - fold_case)); -} -/* }}} */ - -/* {{{ proto int strnatcmp(string s1, string s2) - Returns the result of string comparison using 'natural' algorithm */ -PHP_FUNCTION(strnatcmp) -{ - php_strnatcmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); -} -/* }}} */ - -/* {{{ proto array localeconv(void) - Returns numeric formatting information based on the current locale */ -PHP_FUNCTION(localeconv) -{ - zval *grouping, *mon_grouping; - int len, i; - - /* We don't need no stinkin' parameters... */ - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; - } - - MAKE_STD_ZVAL(grouping); - MAKE_STD_ZVAL(mon_grouping); - - array_init(return_value); - array_init(grouping); - array_init(mon_grouping); - -#ifdef HAVE_LOCALECONV - { - struct lconv currlocdata; - - localeconv_r( &currlocdata ); - - /* Grab the grouping data out of the array */ - len = strlen(currlocdata.grouping); - - for (i = 0; i < len; i++) { - add_index_long(grouping, i, currlocdata.grouping[i]); - } - - /* Grab the monetary grouping data out of the array */ - len = strlen(currlocdata.mon_grouping); - - for (i = 0; i < len; i++) { - add_index_long(mon_grouping, i, currlocdata.mon_grouping[i]); - } - - add_assoc_string(return_value, "decimal_point", currlocdata.decimal_point, 1); - add_assoc_string(return_value, "thousands_sep", currlocdata.thousands_sep, 1); - add_assoc_string(return_value, "int_curr_symbol", currlocdata.int_curr_symbol, 1); - add_assoc_string(return_value, "currency_symbol", currlocdata.currency_symbol, 1); - add_assoc_string(return_value, "mon_decimal_point", currlocdata.mon_decimal_point, 1); - add_assoc_string(return_value, "mon_thousands_sep", currlocdata.mon_thousands_sep, 1); - add_assoc_string(return_value, "positive_sign", currlocdata.positive_sign, 1); - add_assoc_string(return_value, "negative_sign", currlocdata.negative_sign, 1); - add_assoc_long( return_value, "int_frac_digits", currlocdata.int_frac_digits ); - add_assoc_long( return_value, "frac_digits", currlocdata.frac_digits ); - add_assoc_long( return_value, "p_cs_precedes", currlocdata.p_cs_precedes ); - add_assoc_long( return_value, "p_sep_by_space", currlocdata.p_sep_by_space ); - add_assoc_long( return_value, "n_cs_precedes", currlocdata.n_cs_precedes ); - add_assoc_long( return_value, "n_sep_by_space", currlocdata.n_sep_by_space ); - add_assoc_long( return_value, "p_sign_posn", currlocdata.p_sign_posn ); - add_assoc_long( return_value, "n_sign_posn", currlocdata.n_sign_posn ); - } -#else - /* Ok, it doesn't look like we have locale info floating around, so I guess it - wouldn't hurt to just go ahead and return the POSIX locale information? */ - - add_index_long(grouping, 0, -1); - add_index_long(mon_grouping, 0, -1); - - add_assoc_string(return_value, "decimal_point", "\x2E", 1); - add_assoc_string(return_value, "thousands_sep", "", 1); - add_assoc_string(return_value, "int_curr_symbol", "", 1); - add_assoc_string(return_value, "currency_symbol", "", 1); - add_assoc_string(return_value, "mon_decimal_point", "\x2E", 1); - add_assoc_string(return_value, "mon_thousands_sep", "", 1); - add_assoc_string(return_value, "positive_sign", "", 1); - add_assoc_string(return_value, "negative_sign", "", 1); - add_assoc_long( return_value, "int_frac_digits", CHAR_MAX ); - add_assoc_long( return_value, "frac_digits", CHAR_MAX ); - add_assoc_long( return_value, "p_cs_precedes", CHAR_MAX ); - add_assoc_long( return_value, "p_sep_by_space", CHAR_MAX ); - add_assoc_long( return_value, "n_cs_precedes", CHAR_MAX ); - add_assoc_long( return_value, "n_sep_by_space", CHAR_MAX ); - add_assoc_long( return_value, "p_sign_posn", CHAR_MAX ); - add_assoc_long( return_value, "n_sign_posn", CHAR_MAX ); -#endif - - zend_hash_update(Z_ARRVAL_P(return_value), "grouping", 9, &grouping, sizeof(zval *), NULL); - zend_hash_update(Z_ARRVAL_P(return_value), "mon_grouping", 13, &mon_grouping, sizeof(zval *), NULL); -} -/* }}} */ - -/* {{{ proto int strnatcasecmp(string s1, string s2) - Returns the result of case-insensitive string comparison using 'natural' algorithm */ -PHP_FUNCTION(strnatcasecmp) -{ - php_strnatcmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); -} -/* }}} */ - -/* {{{ proto int substr_count(string haystack, string needle) - Returns the number of times a substring occurs in the string */ -PHP_FUNCTION(substr_count) -{ - zval **haystack, **needle; - int count = 0; - char *p, *endp, cmp; - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(haystack); - convert_to_string_ex(needle); - - if (Z_STRLEN_PP(needle) == 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty substring."); - RETURN_FALSE; - } - - p = Z_STRVAL_PP(haystack); - endp = p + Z_STRLEN_PP(haystack); - - if (Z_STRLEN_PP(needle) == 1) { - cmp = Z_STRVAL_PP(needle)[0]; - - while (p < endp) { - if (*(p++) == cmp) { - count++; - } - } - } else { - while ((p = php_memnstr(p, Z_STRVAL_PP(needle), Z_STRLEN_PP(needle), endp))) { - p += Z_STRLEN_PP(needle); - count++; - } - } - - RETURN_LONG(count); -} -/* }}} */ - -/* {{{ proto string str_pad(string input, int pad_length [, string pad_string [, int pad_type]]) - Returns input string padded on the left or right to specified length with pad_string */ -PHP_FUNCTION(str_pad) -{ - /* Input arguments */ - zval **input, /* Input string */ - **pad_length, /* Length to pad to */ - **pad_string, /* Padding string */ - **pad_type; /* Padding type (left/right/both) */ - - /* Helper variables */ - int num_pad_chars; /* Number of padding characters (total - input size) */ - char *result = NULL; /* Resulting string */ - int result_len = 0; /* Length of the resulting string */ - char *pad_str_val = " "; /* Pointer to padding string */ - int pad_str_len = 1; /* Length of the padding string */ - int pad_type_val = STR_PAD_RIGHT; /* The padding type value */ - int i, left_pad=0, right_pad=0; - - - if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 4 || - zend_get_parameters_ex(ZEND_NUM_ARGS(), &input, &pad_length, &pad_string, &pad_type) == FAILURE) { - WRONG_PARAM_COUNT; - } - - /* Perform initial conversion to expected data types. */ - convert_to_string_ex(input); - convert_to_long_ex(pad_length); - - num_pad_chars = Z_LVAL_PP(pad_length) - Z_STRLEN_PP(input); - - /* If resulting string turns out to be shorter than input string, - we simply copy the input and return. */ - if (num_pad_chars < 0) { - *return_value = **input; - zval_copy_ctor(return_value); - return; - } - - /* Setup the padding string values if specified. */ - if (ZEND_NUM_ARGS() > 2) { - convert_to_string_ex(pad_string); - if (Z_STRLEN_PP(pad_string) == 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding string cannot be empty."); - return; - } - pad_str_val = Z_STRVAL_PP(pad_string); - pad_str_len = Z_STRLEN_PP(pad_string); - - if (ZEND_NUM_ARGS() > 3) { - convert_to_long_ex(pad_type); - pad_type_val = Z_LVAL_PP(pad_type); - if (pad_type_val < STR_PAD_LEFT || pad_type_val > STR_PAD_BOTH) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH."); - return; - } - } - } - - result = (char *)emalloc(Z_STRLEN_PP(input) + num_pad_chars + 1); - - /* We need to figure out the left/right padding lengths. */ - switch (pad_type_val) { - case STR_PAD_RIGHT: - left_pad = 0; - right_pad = num_pad_chars; - break; - - case STR_PAD_LEFT: - left_pad = num_pad_chars; - right_pad = 0; - break; - - case STR_PAD_BOTH: - left_pad = num_pad_chars / 2; - right_pad = num_pad_chars - left_pad; - break; - } - - /* First we pad on the left. */ - for (i = 0; i < left_pad; i++) - result[result_len++] = pad_str_val[i % pad_str_len]; - - /* Then we copy the input string. */ - memcpy(result + result_len, Z_STRVAL_PP(input), Z_STRLEN_PP(input)); - result_len += Z_STRLEN_PP(input); - - /* Finally, we pad on the right. */ - for (i = 0; i < right_pad; i++) - result[result_len++] = pad_str_val[i % pad_str_len]; - - result[result_len] = '\0'; - - RETURN_STRINGL(result, result_len, 0); -} -/* }}} */ - -/* {{{ proto mixed sscanf(string str, string format [, string ...]) - Implements an ANSI C compatible sscanf */ -PHP_FUNCTION(sscanf) -{ - zval ***args; - int result; - int argc = ZEND_NUM_ARGS(); - - if (argc < 2) { - WRONG_PARAM_COUNT; - } - - args = (zval ***) emalloc(argc * sizeof(zval **)); - if (zend_get_parameters_array_ex(argc, args) == FAILURE) { - efree(args); - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(args[0]); - convert_to_string_ex(args[1]); - - result = php_sscanf_internal(Z_STRVAL_PP(args[0]), - Z_STRVAL_PP(args[1]), - argc, args, - 2, &return_value TSRMLS_CC); - efree(args); - - if (SCAN_ERROR_WRONG_PARAM_COUNT == result) { - WRONG_PARAM_COUNT; - } -} -/* }}} */ - -static char rot13_from[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -static char rot13_to[] = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM"; - -/* {{{ proto string str_rot13(string str) - Perform the rot13 transform on a string */ -PHP_FUNCTION(str_rot13) -{ - zval **arg; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg)) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(arg); - *return_value = **arg; - zval_copy_ctor(return_value); - - php_strtr(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), rot13_from, rot13_to, 52); -} -/* }}} */ - - -static void php_string_shuffle(char *str, long len TSRMLS_DC) -{ - long n_elems, rnd_idx, n_left; - char temp; - /* The implementation is stolen from array_data_shuffle */ - /* Thus the characteristics of the randomization are the same */ - n_elems = len; - - if (n_elems <= 1) { - return; - } - - n_left = n_elems; - - while (--n_left) { - rnd_idx = php_rand(TSRMLS_C); - RAND_RANGE(rnd_idx, 0, n_left, PHP_RAND_MAX); - if (rnd_idx != n_left) { - temp = str[n_left]; - str[n_left] = str[rnd_idx]; - str[rnd_idx] = temp; - } - } -} - - -/* {{{ proto void str_shuffle(string str) - Shuffles string. One permutation of all possible is created */ -PHP_FUNCTION(str_shuffle) -{ - zval **arg; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg)) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(arg); - *return_value = **arg; - zval_copy_ctor(return_value); - if (Z_STRLEN_P(return_value) > 1) { - php_string_shuffle(Z_STRVAL_P(return_value), (long) Z_STRLEN_P(return_value) TSRMLS_CC); - } -} -/* }}} */ - -/* {{{ proto void str_word_count(string str, [int format]) - Counts the number of words inside a string. If format of 1 is specified, - then the function will return an array containing all the words - found inside the string. If format of 2 is specified, then the function - will return an associated array where the position of the word is the key - and the word itself is the value. - - For the purpose of this function, 'word' is defined as a locale dependent - string containing alphabetic characters, which also may contain, but not start - with "'" and "-" characters. -*/ -PHP_FUNCTION(str_word_count) -{ - zval **str, **o_format; - char *s, *e, *p, *buf; - int word_count = 0; - int type = 0; - int n_args = ZEND_NUM_ARGS(); - - if (n_args > 2 || n_args < 1 || zend_get_parameters_ex(n_args, &str, &o_format) == FAILURE) { - WRONG_PARAM_COUNT; - } - - if (n_args == 2) { - convert_to_long_ex(o_format); - type = Z_LVAL_PP(o_format); - - if (type != 1 && type != 2) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The specified format parameter, '%d' is invalid.", type); - RETURN_FALSE; - } - } - - convert_to_string_ex(str); - - p = s = Z_STRVAL_PP(str); - e = Z_STRVAL_PP(str) + Z_STRLEN_PP(str); - - if (type == 1 || type == 2) { - array_init(return_value); - } - - while (p < e) { - if (isalpha(*p++)) { - s = p - 1; - while (isalpha(*p) || *p == '\'' || (*p == '-' && isalpha(*(p+1)))) { - p++; - } - - switch (type) - { - case 1: - buf = estrndup(s, (p-s)); - add_next_index_stringl(return_value, buf, (p-s), 1); - efree(buf); - break; - case 2: - buf = estrndup(s, (p-s)); - add_index_stringl(return_value, (s - Z_STRVAL_PP(str)), buf, p-s, 1); - efree(buf); - break; - default: - word_count++; - break; - } - } - } - - if (!type) { - RETURN_LONG(word_count); - } -} - -/* }}} */ - -#if HAVE_STRFMON -/* {{{ proto string money_format(string format , float value) - Convert monetary value(s) to string */ -PHP_FUNCTION(money_format) -{ - int format_len = 0, str_len; - char *format, *str; - double value; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sd", &format, &format_len, &value) == FAILURE) { - return; - } - - str_len = format_len + 1024; - str = emalloc(str_len); - str_len = strfmon(str, str_len, format, value); - str[str_len] = 0; - - RETURN_STRINGL(erealloc(str, str_len + 1), str_len, 0); -} -/* }}} */ -#endif - -/* {{{ proto array str_split(string str [, int split_length]) - Convert a string to an array. If split_length is specified, break the string down into chunks each split_length characters long. */ -PHP_FUNCTION(str_split) -{ - char *str; - int str_len; - long split_length = 1; - char *p; - int n_reg_segments; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &split_length) == FAILURE) { - return; - } - - if (split_length <= 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The the length of each segment must be greater then zero."); - RETURN_FALSE; - } - - array_init(return_value); - - n_reg_segments = floor(str_len / split_length); - p = str; - - while (n_reg_segments-- > 0) { - add_next_index_stringl(return_value, p, split_length, 1); - p += split_length; - } - - if (p != (str + str_len)) { - add_next_index_stringl(return_value, p, (str + str_len - p), 1); - } -} -/* }}} */ - -/* {{{ proto array strpbrk(string haystack, string char_list) - Search a string for any of a set of characters */ -PHP_FUNCTION(strpbrk) -{ - char *haystack, *char_list; - int haystack_len, char_list_len; - char *p; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &haystack, &haystack_len, &char_list, &char_list_len) == FAILURE) { - RETURN_FALSE; - } - - if (!char_list_len) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "The character list cannot be empty."); - RETURN_FALSE; - } - - if ((p = strpbrk(haystack, char_list))) { - RETURN_STRINGL(p, (haystack + haystack_len - p), 1); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ |