mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
[DOC] Add compile-time __DIR__ constant which implements dirname(__FILE__)
This commit is contained in:
parent
cf07e941f1
commit
fd597dce1b
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user