]> granicus.if.org Git - php/commitdiff
Upgrade dirname() to support IS_UNICODE.
authorAndrei Zmievski <andrei@php.net>
Fri, 4 Aug 2006 18:09:46 +0000 (18:09 +0000)
committerAndrei Zmievski <andrei@php.net>
Fri, 4 Aug 2006 18:09:46 +0000 (18:09 +0000)
ext/standard/php_string.h
ext/standard/string.c

index a63dc32bcda1c71ef9d8647d43460e554b77933e..bd87a3be66ca31ee8dd02b1c165dde2d6c29693e 100644 (file)
@@ -129,8 +129,10 @@ PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int freeit,
 PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC);
 PHPAPI void php_u_stripslashes(UChar *str, int *len TSRMLS_DC);
 PHPAPI void php_stripcslashes(char *str, int *len);
-PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len TSRMLS_DC);
-PHPAPI size_t php_dirname(char *str, size_t len);
+PHPAPI void php_u_basename(UChar *s, int len, UChar *suffix, int sufflen, UChar **p_ret, int *p_len TSRMLS_DC);
+PHPAPI void php_basename(char *s, int len, char *suffix, int sufflen, char **p_ret, int *p_len TSRMLS_DC);
+PHPAPI int php_u_dirname(UChar *str, int len);
+PHPAPI int php_dirname(char *str, int len);
 PHPAPI UChar *php_u_stristr(UChar *s, UChar *t, int s_len, int t_len);
 PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len);
 PHPAPI int php_u_strspn(UChar *s1, UChar *s2, UChar *s1_end, UChar *s2_end);
index 16d6fc4330f115df415efa58717b3bffd950f3c0..f76988408b2f1b1c8c093495531fdfba7393ceec 100644 (file)
@@ -1739,7 +1739,7 @@ PHPAPI void php_u_basename(UChar *s, int len, UChar *suffix, int sufflen, UChar
 
 /* {{{ php_basename
  */
-PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len TSRMLS_DC)
+PHPAPI void php_basename(char *s, int len, char *suffix, int sufflen, char **p_ret, int *p_len TSRMLS_DC)
 {
        char *ret = NULL, *c, *comp, *cend;
        size_t inc_len, cnt;
@@ -1833,9 +1833,104 @@ PHP_FUNCTION(basename)
 }
 /* }}} */
 
+/* {{{ php_u_dirname
+   Returns directory name component of path */
+PHPAPI int php_u_dirname(UChar *path, int len)
+{
+       register UChar *end = path + len - 1;
+       unsigned int len_adjust = 0;
+
+#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) && u_isalpha((UChar32)path[0]) && ((UChar)0x3a /*':'*/ == path[1])) {
+               /* Skip over the drive spec (if any) so as not to change */
+               path += 2;
+               len_adjust += 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 len;
+               }
+       }
+#elif defined(NETWARE)
+       /*
+        * Find the first occurence of : from the left
+        * move the path pointer to the position just after :
+        * increment the len_adjust to the length of path till colon character(inclusive)
+        * If there is no character beyond : simple return len
+        */
+       UChar *colonpos = NULL;
+       colonpos = u_strchr(path, (UChar) 0x3a /*':'*/);
+       if(colonpos != NULL) {
+               len_adjust = ((colonpos - path) + 1);
+               path += len_adjust;
+               if(len_adjust == len) {
+               return len;
+               }
+       }
+#endif
+
+       if (len == 0) {
+               /* Illegal use of this function */
+               return 0;
+       }
+
+       /* Strip trailing slashes */
+       while (end >= path && IS_U_SLASH_P(end)) {
+               end--;
+       }
+       if (end < path) {
+               /* The path only contained slashes */
+               path[0] = DEFAULT_U_SLASH;
+               path[1] = 0;
+               return 1 + len_adjust;
+       }
+
+       /* Strip filename */
+       while (end >= path && !IS_U_SLASH_P(end)) {
+               end--;
+       }
+       if (end < path) {
+               /* No slash found, therefore return '.' */
+#ifdef NETWARE
+               if(len_adjust == 0) {
+                       path[0] = (UChar) 0x2e /*'.'*/;
+                       path[1] = 0;
+                       return 1; //only one character
+               }
+               else {
+                       path[0] = 0;
+                       return len_adjust;
+               }
+#else
+               path[0] = (UChar) 0x2e /*'.'*/;
+               path[1] = 0;
+               return 1 + len_adjust;
+#endif
+       }
+
+       /* Strip slashes which came before the file name */
+       while (end >= path && IS_U_SLASH_P(end)) {
+               end--;
+       }
+       if (end < path) {
+               path[0] = DEFAULT_U_SLASH;
+               path[1] = 0;
+               return 1 + len_adjust;
+       }
+       *(end+1) = 0;
+
+       return (size_t)(end + 1 - path) + len_adjust;
+}
+/* }}} */
+
 /* {{{ php_dirname
    Returns directory name component of path */
-PHPAPI size_t php_dirname(char *path, size_t len)
+PHPAPI int php_dirname(char *path, int len)
 {
        register char *end = path + len - 1;
        unsigned int len_adjust = 0;
@@ -1928,26 +2023,30 @@ PHPAPI size_t php_dirname(char *path, size_t len)
 }
 /* }}} */
 
-/* {{{ proto string dirname(string path)
+/* {{{ proto string dirname(string path) U
    Returns the directory name component of the path */
 PHP_FUNCTION(dirname)
 {
-       zval **str;
-       char *ret;
-       size_t ret_len;
+       zstr str;
+       int str_len;
+       zend_uchar str_type;
+       zstr ret;
+       int ret_len;
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
-               WRONG_PARAM_COUNT;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &str, &str_len,
+                                                         &str_type) == FAILURE) {
+               return;
        }
-       convert_to_string_ex(str);
-
-       ret = estrndup(Z_STRVAL_PP(str), Z_STRLEN_PP(str));
-       ret_len = php_dirname(ret, Z_STRLEN_PP(str));
 
-       RETVAL_RT_STRINGL(ret, ret_len, 0);
-       if (UG(unicode)) {
-               efree(ret);
+       if (str_type == IS_UNICODE) {
+               ret.u = eustrndup(str.u, str_len);
+               ret_len = php_u_dirname(ret.u, str_len);
+       } else {
+               ret.s = estrndup(str.s, str_len);
+               ret_len = php_dirname(ret.s, str_len);
        }
+
+       RETURN_ZSTRL(ret, ret_len, str_type, 0);
 }
 /* }}} */
 
@@ -3048,7 +3147,6 @@ PHP_FUNCTION(substr)
 }
 /* }}} */
 
-
 /* {{{ php_adjust_limits
  */
 PHPAPI void php_adjust_limits(zval **str, int *f, int *l)
@@ -3315,9 +3413,6 @@ PHP_FUNCTION(substr_replace)
 }
 /* }}} */
 
-
-
-
 /* {{{ proto string quotemeta(string str)
    Quotes meta characters */
 PHP_FUNCTION(quotemeta)