diff options
author | Stanislav Malyshev <stas@php.net> | 2008-02-12 00:21:15 +0000 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2008-02-12 00:21:15 +0000 |
commit | fd597dce1bc0e173740ee568534733ec08e6e4f9 (patch) | |
tree | e70d5c5ab9f09b62fb9f9d5d5c38f8507b476bad /Zend | |
parent | cf07e941f10a2ce263b3888e8b8950b17d0e21e5 (diff) | |
download | php-git-fd597dce1bc0e173740ee568534733ec08e6e4f9.tar.gz |
[DOC] Add compile-time __DIR__ constant which implements dirname(__FILE__)
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_compile.c | 92 | ||||
-rw-r--r-- | Zend/zend_compile.h | 1 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 2 | ||||
-rw-r--r-- | Zend/zend_language_scanner.l | 29 |
4 files changed, 124 insertions, 0 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8ca2402969..e739f18684 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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 diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 91df3bfd33..fb87f5d8d2 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 8467581721..788d69dda3 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -132,6 +132,7 @@ %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; } diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 34078fdda0..1f88f3b451 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -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); |