]> granicus.if.org Git - php/commitdiff
[DOC] Add compile-time __DIR__ constant which implements dirname(__FILE__)
authorStanislav Malyshev <stas@php.net>
Tue, 12 Feb 2008 00:21:15 +0000 (00:21 +0000)
committerStanislav Malyshev <stas@php.net>
Tue, 12 Feb 2008 00:21:15 +0000 (00:21 +0000)
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y
Zend/zend_language_scanner.l
ext/standard/string.c

index 8ca24029690a1d64f727b070d7325a0d767c796c..e739f18684ee22bda99fa27937139a161a61c391 100644 (file)
@@ -26,6 +26,7 @@
 #include "zend_llist.h"
 #include "zend_API.h"
 #include "zend_exceptions.h"
+#include "tsrm_virtual_cwd.h"
 
 #ifdef ZEND_MULTIBYTE
 #include "zend_multibyte.h"
@@ -4944,6 +4945,97 @@ void zend_do_end_compilation(TSRMLS_D) /* {{{ */
 }
 /* }}} */
 
+ZEND_API size_t zend_dirname(char *path, size_t len)
+{
+       register char *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) && isalpha((int)((unsigned char *)path)[0]) && (':' == 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
+        */
+       char *colonpos = NULL;
+       colonpos = strchr(path, ':');
+       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_SLASH_P(end)) {
+               end--;
+       }
+       if (end < path) {
+               /* The path only contained slashes */
+               path[0] = DEFAULT_SLASH;
+               path[1] = '\0';
+               return 1 + len_adjust;
+       }
+
+       /* Strip filename */
+       while (end >= path && !IS_SLASH_P(end)) {
+               end--;
+       }
+       if (end < path) {
+               /* No slash found, therefore return '.' */
+#ifdef NETWARE
+               if (len_adjust == 0) {
+                       path[0] = '.';
+                       path[1] = '\0';
+                       return 1; //only one character
+               } else {
+                       path[0] = '\0';
+                       return len_adjust;
+               }
+#else
+               path[0] = '.';
+               path[1] = '\0';
+               return 1 + len_adjust;
+#endif
+       }
+
+       /* 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 1 + len_adjust;
+       }
+       *(end+1) = '\0';
+
+       return (size_t)(end + 1 - path) + len_adjust;
+}
+/* }}} */
 /*
  * Local variables:
  * tab-width: 4
index 91df3bfd3390839e8c4ab8bc5afccec60d3f02d2..fb87f5d8d2753af836473302c240869b9a5f9df2 100644 (file)
@@ -570,6 +570,7 @@ void zend_auto_global_dtor(zend_auto_global *auto_global);
 ZEND_API int zend_register_auto_global(char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC);
 ZEND_API zend_bool zend_is_auto_global(char *name, uint name_len TSRMLS_DC);
 ZEND_API int zend_auto_global_disable_jit(char *varname, zend_uint varname_length TSRMLS_DC);
+ZEND_API size_t zend_dirname(char *path, size_t len);
 
 int zendlex(znode *zendlval TSRMLS_DC);
 
index 8467581721dd55acd2e4875734a869432071b8d6..788d69dda3cb67136f601ec2dbca2ef563cbc8e4 100644 (file)
 %token T_FUNC_C
 %token T_LINE
 %token T_FILE
+%token T_DIR
 %token T_COMMENT
 %token T_DOC_COMMENT
 %token T_OPEN_TAG
@@ -715,6 +716,7 @@ common_scalar:
        |       T_CONSTANT_ENCAPSED_STRING      { $$ = $1; }
        |       T_LINE                                          { $$ = $1; }
        |       T_FILE                                          { $$ = $1; }
+       |       T_DIR                                           { $$ = $1; }
        |       T_CLASS_C                                       { $$ = $1; }
        |       T_METHOD_C                                      { $$ = $1; }
        |       T_FUNC_C                                        { $$ = $1; }
index 34078fdda0292707196ac007f1e13c85a82cc7e8..1f88f3b45134ca4ca19c92e19e13c498d233a048 100644 (file)
@@ -62,6 +62,8 @@
 #include "zend_API.h"
 #include "zend_strtod.h"
 #include "zend_exceptions.h"
+#include "tsrm_virtual_cwd.h"
+#include "tsrm_config_common.h"
 
 #ifdef HAVE_STDARG_H
 # include <stdarg.h>
@@ -1545,6 +1547,33 @@ HEREDOC_CHARS       ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({
        return T_FILE;
 }
 
+<ST_IN_SCRIPTING>"__DIR__" {
+       char *filename = zend_get_compiled_filename(TSRMLS_C);
+       const size_t filename_len = strlen(filename);
+       char *dirname;
+
+       if (!filename) {
+               filename = "";
+       }
+
+       dirname = estrndup(filename, filename_len);
+       zend_dirname(dirname, filename_len);
+
+       if (strcmp(dirname, ".") == 0) {
+               dirname = erealloc(dirname, MAXPATHLEN);
+#if HAVE_GETCWD
+               VCWD_GETCWD(dirname, MAXPATHLEN);
+#elif HAVE_GETWD
+               VCWD_GETWD(dirname);
+#endif
+       }
+
+       zendlval->value.str.len = strlen(dirname);
+       zendlval->value.str.val = dirname;
+       zendlval->type = IS_STRING;
+       return T_DIR;
+}
+
 <ST_IN_SCRIPTING>"__NAMESPACE__" {
        if (CG(current_namespace)) {
                *zendlval = *CG(current_namespace);
index 11ee543ab12a334cdf212412d8d18c19c2d3ea2f..89298eb4420b0cdd29197f8d93fcd3e1e7719cd7 100644 (file)
@@ -1444,94 +1444,7 @@ PHP_FUNCTION(basename)
    Returns directory name component of path */
 PHPAPI size_t php_dirname(char *path, size_t len)
 {
-       register char *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) && isalpha((int)((unsigned char *)path)[0]) && (':' == 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
-        */
-       char *colonpos = NULL;
-       colonpos = strchr(path, ':');
-       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_SLASH_P(end)) {
-               end--;
-       }
-       if (end < path) {
-               /* The path only contained slashes */
-               path[0] = DEFAULT_SLASH;
-               path[1] = '\0';
-               return 1 + len_adjust;
-       }
-
-       /* Strip filename */
-       while (end >= path && !IS_SLASH_P(end)) {
-               end--;
-       }
-       if (end < path) {
-               /* No slash found, therefore return '.' */
-#ifdef NETWARE
-               if(len_adjust == 0) {
-                       path[0] = '.';
-                       path[1] = '\0';
-                       return 1; //only one character
-               } 
-               else {
-                       path[0] = '\0';
-                       return len_adjust;
-               }
-#else
-               path[0] = '.';
-               path[1] = '\0';
-               return 1 + len_adjust;
-#endif
-       }
-
-       /* 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 1 + len_adjust;
-       }
-       *(end+1) = '\0';
-
-       return (size_t)(end + 1 - path) + len_adjust;
+       return zend_dirname(path, len);
 }
 /* }}} */