📄 string.c
字号:
} 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, chk; size_t alloced; 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_EMPTY_STRING(); } 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 + 1; } 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); newtext = safe_emalloc(chk, breakcharlen, textlen + 1); alloced = textlen + chk * breakcharlen + 1; } else { chk = textlen; newtext = safe_emalloc(textlen, (breakcharlen + 1), 1); alloced = textlen * (breakcharlen + 1) + 1; } /* 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(); 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); arr = *arg1; } else { if (Z_TYPE_PP(arg1) == IS_ARRAY) { SEPARATE_ZVAL(arg1); arr = *arg1; convert_to_string_ex(arg2); delim = *arg2; } else if (Z_TYPE_PP(arg2) == IS_ARRAY) { SEPARATE_ZVAL(arg2); 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 (argc == 1) { 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'; int cnt = len; 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; cnt -= sufflen; buf2 = *(c + 1); /* Save overwritten char */ *(c + 1) = '\0'; /* overwrite char */ p2 = c + 1; /* Save pointer to overwritten char */ } } /* strip trailing slashes */ while (cnt > 0 && (*c == '/'#ifdef PHP_WIN32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -