cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_language_parser.y zend_language_scanner.l

[email protected] ("Stanislav Malyshev")
Newsgroups php.zend-engine.cvs
Message-ID <cvsstas1202778126@cvsserver>
stas		Tue Feb 12 01:02:06 2008 UTC

  Modified files:              
    /ZendEngine2	zend_compile.c zend_compile.h zend_language_parser.y 
                	zend_language_scanner.l 
  Log:
  MFB __DIR_ constant support
stas-20080212010206.txt (text/plain, 9.2 KB)
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.799&r2=1.800&diff_format=u
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.799 ZendEngine2/zend_compile.c:1.800
--- ZendEngine2/zend_compile.c:1.799	Tue Jan 29 00:06:42 2008
+++ ZendEngine2/zend_compile.c	Tue Feb 12 01:02:06 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_compile.c,v 1.799 2008/01/29 00:06:42 tony2001 Exp $ */
+/* $Id: zend_compile.c,v 1.800 2008/02/12 01:02:06 stas Exp $ */
 
 #include <zend_language_parser.h>
 #include "zend.h"
@@ -25,6 +25,7 @@
 #include "zend_constants.h"
 #include "zend_llist.h"
 #include "zend_API.h"
+#include "tsrm_virtual_cwd.h"
 
 ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
 ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename TSRMLS_DC);
@@ -5471,6 +5472,194 @@
 }
 /* }}} */
 
+/* {{{ zend_dirname
+   Returns directory name component of path */
+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;
+}
+/* }}} */
+/* {{{ zend_u_dirname
+   Returns directory name component of path */
+ZEND_API size_t zend_u_dirname(UChar *path, size_t 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;
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.h?r1=1.373&r2=1.374&diff_format=u
Index: ZendEngine2/zend_compile.h
diff -u ZendEngine2/zend_compile.h:1.373 ZendEngine2/zend_compile.h:1.374
--- ZendEngine2/zend_compile.h:1.373	Thu Jan 24 09:41:48 2008
+++ ZendEngine2/zend_compile.h	Tue Feb 12 01:02:06 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_compile.h,v 1.373 2008/01/24 09:41:48 dmitry Exp $ */
+/* $Id: zend_compile.h,v 1.374 2008/02/12 01:02:06 stas Exp $ */
 
 #ifndef ZEND_COMPILE_H
 #define ZEND_COMPILE_H
@@ -601,6 +601,8 @@
 ZEND_API zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint name_len TSRMLS_DC);
 ZEND_API zend_bool zend_u_is_auto_global_ex(zend_uchar type, zstr name, uint name_len, zend_bool runtime, zend_auto_global **ret 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);
+ZEND_API size_t zend_u_dirname(UChar *path, size_t len);
 
 int zendlex(znode *zendlval TSRMLS_DC);
 
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_language_parser.y?r1=1.199&r2=1.200&diff_format=u
Index: ZendEngine2/zend_language_parser.y
diff -u ZendEngine2/zend_language_parser.y:1.199 ZendEngine2/zend_language_parser.y:1.200
--- ZendEngine2/zend_language_parser.y:1.199	Mon Dec 31 07:12:07 2007
+++ ZendEngine2/zend_language_parser.y	Tue Feb 12 01:02:06 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_language_parser.y,v 1.199 2007/12/31 07:12:07 sebastian Exp $ */
+/* $Id: zend_language_parser.y,v 1.200 2008/02/12 01:02:06 stas Exp $ */
 
 /*
  * LALR shift/reduce conflicts and how they are resolved:
@@ -133,6 +133,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
@@ -721,6 +722,7 @@
 	|	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; }
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_language_scanner.l?r1=1.176&r2=1.177&diff_format=u
Index: ZendEngine2/zend_language_scanner.l
diff -u ZendEngine2/zend_language_scanner.l:1.176 ZendEngine2/zend_language_scanner.l:1.177
--- ZendEngine2/zend_language_scanner.l:1.176	Thu Jan 24 18:08:06 2008
+++ ZendEngine2/zend_language_scanner.l	Tue Feb 12 01:02:06 2008
@@ -19,7 +19,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_language_scanner.l,v 1.176 2008/01/24 18:08:06 dmitry Exp $ */
+/* $Id: zend_language_scanner.l,v 1.177 2008/02/12 01:02:06 stas Exp $ */
 
 #define yyleng SCNG(yy_leng)
 #define yytext SCNG(yy_text)
@@ -62,6 +62,8 @@
 #include "zend_API.h"
 #include "zend_strtod.h"
 #include "zend_unicode.h"
+#include "tsrm_virtual_cwd.h"
+#include "tsrm_config_common.h"
 
 #ifdef HAVE_STDARG_H
 # include <stdarg.h>
@@ -2031,6 +2033,33 @@
 	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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.